diff --git a/.ai/commit-msg/style-guide-reference.md b/.ai/commit-msg/style-guide-reference.md new file mode 100644 index 00000000..3c9fe180 --- /dev/null +++ b/.ai/commit-msg/style-guide-reference.md @@ -0,0 +1,225 @@ +# Commit Message Style Guide for `tractor` + +Analysis based on 500 recent commits from the `tractor` repository. + +## Core Principles + +Write commit messages that are technically precise yet casual in +tone. Use abbreviations and informal language while maintaining +clarity about what changed and why. + +## Subject Line Format + +### Length and Structure +- Target: ~50 chars with a hard-max of 67. +- Use backticks around code elements (72.2% of commits) +- Rarely use colons (5.2%), except for file prefixes +- End with '?' for uncertain changes (rare: 0.8%) +- End with '!' for important changes (rare: 2.0%) + +### Opening Verbs (Present Tense) + +Most common verbs from analysis: +- `Add` (14.4%) - wholly new features/functionality +- `Use` (4.4%) - adopt new approach/tool +- `Drop` (3.6%) - remove code/feature +- `Fix` (2.4%) - bug fixes +- `Move`/`Mv` (3.6%) - relocate code +- `Adjust` (2.0%) - minor tweaks +- `Update` (1.6%) - enhance existing feature +- `Bump` (1.2%) - dependency updates +- `Rename` (1.2%) - identifier changes +- `Set` (1.2%) - configuration changes +- `Handle` (1.0%) - add handling logic +- `Raise` (1.0%) - add error raising +- `Pass` (0.8%) - pass parameters/values +- `Support` (0.8%) - add support for something +- `Hide` (1.4%) - make private/internal +- `Always` (1.4%) - enforce consistent behavior +- `Mk` (1.4%) - make/create (abbreviated) +- `Start` (1.0%) - begin implementation + +Other frequent verbs: `More`, `Change`, `Extend`, `Disable`, `Log`, +`Enable`, `Ensure`, `Expose`, `Allow` + +### Backtick Usage + +Always use backticks for: +- Module names: `trio`, `asyncio`, `msgspec`, `greenback`, `stackscope` +- Class names: `Context`, `Actor`, `Address`, `PldRx`, `SpawnSpec` +- Method names: `.pause_from_sync()`, `._pause()`, `.cancel()` +- Function names: `breakpoint()`, `collapse_eg()`, `open_root_actor()` +- Decorators: `@acm`, `@context` +- Exceptions: `Cancelled`, `TransportClosed`, `MsgTypeError` +- Keywords: `finally`, `None`, `False` +- Variable names: `tn`, `debug_mode` +- Complex expressions: `trio.Cancelled`, `asyncio.Task` + +Most backticked terms in tractor: +`trio`, `asyncio`, `Context`, `.pause_from_sync()`, `tn`, +`._pause()`, `breakpoint()`, `collapse_eg()`, `Actor`, `@acm`, +`.cancel()`, `Cancelled`, `open_root_actor()`, `greenback` + +### Examples + +Good subject lines: +``` +Add `uds` to `._multiaddr`, tweak typing +Drop `DebugStatus.shield` attr, add `.req_finished` +Use `stackscope` for all actor-tree rendered "views" +Fix `.to_asyncio` inter-task-cancellation! +Bump `ruff.toml` to target py313 +Mv `load_module_from_path()` to new `._code_load` submod +Always use `tuple`-cast for singleton parent addrs +``` + +## Body Format + +### General Structure +- 43.2% of commits have no body (simple changes) +- Use blank line after subject +- Max line length: 67 chars +- Use `-` bullets for lists (28.0% of commits) +- Rarely use `*` bullets (2.4%) + +### Section Markers + +Use these markers to organize longer commit bodies: +- `Also,` (most common: 26 occurrences) +- `Other,` (13 occurrences) +- `Deats,` (11 occurrences) - for implementation details +- `Further,` (7 occurrences) +- `TODO,` (3 occurrences) +- `Impl details,` (2 occurrences) +- `Notes,` (1 occurrence) + +### Common Abbreviations + +Use these freely (sorted by frequency): +- `msg` (63) - message +- `bg` (37) - background +- `ctx` (30) - context +- `impl` (27) - implementation +- `mod` (26) - module +- `obvi` (17) - obviously +- `tn` (16) - task name +- `fn` (15) - function +- `vs` (15) - versus +- `bc` (14) - because +- `var` (14) - variable +- `prolly` (9) - probably +- `ep` (6) - entry point +- `OW` (5) - otherwise +- `rn` (4) - right now +- `sig` (4) - signal/signature +- `deps` (3) - dependencies +- `iface` (2) - interface +- `subproc` (2) - subprocess +- `tho` (2) - though +- `ofc` (2) - of course + +### Tone and Style + +- Casual but technical (use `XD` for humor: 23 times) +- Use `..` for trailing thoughts (108 occurrences) +- Use `Woops,` to acknowledge mistakes (4 subject lines) +- Don't be afraid to show personality while being precise + +### Example Bodies + +Simple with bullets: +``` +Add `multiaddr` and bump up some deps + +Since we're planning to use it for (discovery) +addressing, allowing replacement of the hacky (pretend) +attempt in `tractor._multiaddr` Bp + +Also pin some deps, +- make us py312+ +- use `pdbp` with my frame indexing fix. +- mv to latest `xonsh` for fancy cmd/suggestion injections. + +Bump lock file to match obvi! +``` + +With section markers: +``` +Use `stackscope` for all actor-tree rendered "views" + +Instead of the (much more) limited and hacky `.devx._code` +impls, move to using the new `.devx._stackscope` API which +wraps the `stackscope` project. + +Deats, +- make new `stackscope.extract_stack()` wrapper +- port over frame-descing to `_stackscope.pformat_stack()` +- move `PdbREPL` to use `stackscope` render approach +- update tests for new stack output format + +Also, +- tweak log formatting for consistency +- add typing hints throughout +``` + +## Special Patterns + +### WIP Commits +Rare (0.2%) - avoid committing WIP if possible + +### Merge Commits +Auto-generated (4.4%), don't worry about style + +### File References +- Use `module.py` or `.submodule` style +- Rarely use `file.py:line` references (0 in analysis) + +### Links +- GitHub links used sparingly (3 total) +- Prefer code references over external links + +## Footer + +The default footer should credit `claude` (you) for helping generate +the commit msg content: + +``` +(this commit msg was generated in some part by [`claude-code`][claude-code-gh]) +[claude-code-gh]: https://github.com/anthropics/claude-code +``` + +Further, if the patch was solely or in part written +by `claude`, instead add: + +``` +(this patch was generated in some part by [`claude-code`][claude-code-gh]) +[claude-code-gh]: https://github.com/anthropics/claude-code +``` + +## Summary Checklist + +Before committing, verify: +- [ ] Subject line uses present tense verb +- [ ] Subject line ~50 chars (hard max 67) +- [ ] Code elements wrapped in backticks +- [ ] Body lines ≤67 chars +- [ ] Abbreviations used where natural +- [ ] Casual yet precise tone +- [ ] Section markers if body >3 paragraphs +- [ ] Technical accuracy maintained + +## Analysis Metadata + +``` +Source: tractor repository +Commits analyzed: 500 +Date range: 2019-2025 +Analysis date: 2026-02-08 +``` + +--- + +(this style guide was generated by [`claude-code`][claude-code-gh] +analyzing commit history) + +[claude-code-gh]: https://github.com/anthropics/claude-code diff --git a/.ai/run-tests/test-harness-reference.md b/.ai/run-tests/test-harness-reference.md new file mode 100644 index 00000000..95adf633 --- /dev/null +++ b/.ai/run-tests/test-harness-reference.md @@ -0,0 +1,255 @@ +# Tractor Test Harness Reference + +This repository-local file supplements the canonical [`/run-tests` skill][1] +from the [`ai.skillz` repository][2]. Its deployer links the shared `SKILL.md` +into both +`.claude/skills/run-tests/` and `.opencode/skills/run-tests/` while preserving +this project-owned reference: + +```text +bash /path/to/ai.skillz/scripts/deploy.sh run-tests /path/to/tractor --provider all --method symlink +``` + +Keep shared environment permission, process-signal safety, target selection, +failure inspection, and result reporting policy in the deployed `SKILL.md`. + +[1]: https://github.com/baudco/ai.skillz/blob/2d4896ca7e38fe2cb3090cdefc7245be4241a6d2/skills/run-tests/SKILL.md +[2]: https://github.com/baudco/ai.skillz + +## Project And Environment + +- Project/import: `tractor` +- Test root: `tests/` +- Supported Python: `>=3.13,<3.15` +- Runner: pytest `>=9.0.3` +- Test dependencies: the `dev` group includes the `testing` group +- CI uses uv's default `.venv`; the Nix flake uses `py313`. +- Run from the repository root so pytest loads `pyproject.toml`. +- Do not use `default.nix` as current test-environment authority; it still + selects unsupported Python 3.12. + +Environment directory naming is not a harness invariant. Use an already +verified active project environment when available. Otherwise, use an +existing uv environment without syncing it: + +```text +uv run --frozen --no-sync python -c 'import pathlib, sys, tractor; root = pathlib.Path.cwd().resolve(); mod = pathlib.Path(tractor.__file__).resolve(); print(sys.executable); print(mod); assert mod.is_relative_to(root)' +``` + +After module moves or collection failures, check collection with: + +```text +uv run --frozen --no-sync pytest --collect-only -q tests/ +``` + +Collection is not a mandatory precursor to every narrow run. Ask before +provisioning or changing an environment. + +Before trusting CLI-selected runtime settings, inspect +`TRACTOR_SPAWN_METHOD` and `TRACTOR_LOGLEVEL`. They override the spawn method +and runtime log level passed by callers, so report active values with test +results rather than claiming the CLI flags alone selected the runtime. + +## Pytest Configuration And Commands + +`pyproject.toml` configures: + +- `testpaths = ["tests"]` and `--rootdir=./tests`; +- importlib import mode; +- the `tractor._testing.pytest` plugin; +- xonsh plugin disablement; +- `--show-capture=no` and `--capture=fd`. + +Do not silently add `-x`, `--tb=short`, or `--no-header`; those are not +project defaults. In a verified active environment, replace `uv run +--frozen --no-sync pytest` below with `python -m pytest`. + +```text +# Full suite +uv run --frozen --no-sync pytest tests/ + +# Narrow file +uv run --frozen --no-sync pytest tests/test_local.py + +# Exact node +uv run --frozen --no-sync pytest tests/discovery/test_registrar.py::test_reg_then_unreg + +# Keyword selection +uv run --frozen --no-sync pytest tests/ -k 'cancel and not slow' + +# Previous failures +uv run --frozen --no-sync pytest --lf +``` + +After verifying that the no-sync environment is current, these pytest +arguments match the Linux TCP CI row: + +```text +CI=1 uv run --frozen --no-sync pytest tests/ -rsx --spawn-backend=trio --tpt-proto=tcp --capture=fd +``` + +## Plugin Options And Matrices + +Supported spawn backends: + +- `trio` (default) +- `mp_spawn` +- `mp_forkserver` + +Do not advertise `subint`, `subint_forkserver`, or +`main_thread_forkserver` as runnable backends. Supported transports are +`tcp` (default) and `uds`. Run one transport per pytest session. +`mp_forkserver` and UDS are POSIX-only. + +Other Tractor plugin options include: + +- `--tpdb` / `--debug-mode` +- `--ll` / `--loglevel` +- `--tl` / `--tractor-loglevel` +- `--enable-stackscope` + +Examples: + +```text +uv run --frozen --no-sync pytest tests/ipc/ --tpt-proto=uds +uv run --frozen --no-sync pytest tests/test_spawning.py --spawn-backend=mp_spawn +uv run --frozen --no-sync pytest tests/test_spawning.py --spawn-backend=mp_forkserver --capture=sys +``` + +CI currently exercises Python 3.13 with the `trio` backend: TCP and UDS on +Linux and macOS, plus an informational TCP row on Windows whose pytest step +uses `continue-on-error`. + +## Registry And Transport Isolation + +Tests requesting the `reg_addr` fixture use addresses randomized per session: +an unreserved unprivileged loopback port for TCP or a unique socket name under +the platform runtime directory for UDS. A TCP collision remains possible. + +The runtime fallback remains `127.0.0.1:1616` or `registry@1616.sock`. +Inspect that fallback only when the selected test intentionally uses runtime +defaults or a failure identifies that address. Do not perform a mandatory +`:1616` preflight or assume UDS sockets live under `/tmp`. + +## Capture And Hang Diagnosis + +Normal capture is `fd`. Use `--capture=sys` with `mp_forkserver`; some tests +switch to `capsys`, but the harness does not enforce that suite-wide. + +For a suspected capture interaction, compare only the exact node: + +```text +uv run --frozen --no-sync pytest --capture=sys +uv run --frozen --no-sync pytest -s +``` + +Treat `-s` as a diagnostic comparison, not a pass-equivalent workaround. Do +not use it to reinterpret an ordinary captured pass. Interactive `--tpdb` or +`tractor.pause()` sessions are different: they require a real TTY and disabled +capture, normally `-s`. + +Do not add a global pytest timeout. `fail_after_w_trace` is Trio-cooperative; +`afk_alarm_w_trace` is a POSIX main-thread `SIGALRM` hard backstop and can +raise asynchronously. Use the latter only as a last resort, not as a generally +Trio-safe timeout replacement. + +For live task-tree diagnosis: + +```text +uv run --frozen --no-sync python -c 'import stackscope' +uv run --frozen --no-sync pytest --enable-stackscope --capture=sys +kill -USR1 +``` + +The import check and pytest command must use the same environment. Do not send +SIGUSR1 if the import fails or setup warns that stackscope or SIGUSR1 is +unavailable: without the installed handler, SIGUSR1 normally terminates the +target process. Signal a subactor only after separately confirming that it +installed the same handler. + +Stackscope appends dumps to `/tmp/tractor-stackscope-.log`, including when +pytest capture hides terminal output. SIGUSR1 stackscope is unavailable on +Windows and degrades to a no-op there. + +When a trace guard actually fires and snapshot capture succeeds, it writes +under `$XDG_CACHE_HOME/tractor/hung-dumps/`, falling back beneath +`~/.cache/tractor/hung-dumps/`, and prints an end-of-session index. A normal +non-timeout run creates no snapshot. + +## Cleanup And `tractor-reap` + +On Linux, normal pytest teardown discovers surviving descendants through +`/proc`, sends SIGINT, waits three seconds, then escalates survivors to +SIGKILL. It does not sweep shared memory and cannot run if pytest never reaches +fixture teardown. + +Process discovery is a no-op off Linux. UDS PID liveness also depends on +`/proc`; on macOS, recognized PID-named sockets can therefore be classified as +dead without proof. The session-scoped autouse fixture currently passes those +candidates directly to `reap_uds()` at teardown. Do not treat its non-Linux +classification as proof of orphanhood or run concurrent live Tractor sessions +against the same UDS bindspace. + +Use the CLI in inspection-only mode first: + +`--shm` and `--shm-only` are Linux/FreeBSD-only and raise +`NotImplementedError` elsewhere. On other platforms, use the UDS-only command. + +```text +uv run --frozen --no-sync scripts/tractor-reap -n +uv run --frozen --no-sync scripts/tractor-reap --parent -n +uv run --frozen --no-sync scripts/tractor-reap --shm --uds -n +uv run --frozen --no-sync scripts/tractor-reap --uds-only -n +``` + +Direct `scripts/tractor-reap` execution is acceptable only after verifying its +`python3` shebang resolves the intended project environment. + +Review every candidate before requesting a mutating run: + +- default orphan mode is not repository-scoped; +- `--parent` trusts the supplied PID and can include non-Tractor children; +- `--shm` scans all current-user candidate files, not just Tractor-named + files; +- `--uds` treats `registry@1616.sock` as removable even if a live default UDS + registrar uses it. + +Dry-run output prints only the initially matched root PIDs. A mutating run can +recursively expand those roots to additional descendants when `psutil` is +available. Inspect the descendant process tree separately; `-n` is not exact +signal-set parity and does not by itself authorize signaling unseen children. + +The canonical skill owns signaling and unlinking authorization. + +## Test Layout And Change Mapping + +| Changed area | Run first | +|---|---| +| `tractor/runtime/_runtime.py`, `_state.py`, `tractor/_root.py` | `tests/test_local.py`, `tests/test_root_runtime.py`, `tests/test_runtime.py`, `tests/test_rpc.py` | +| `tractor/runtime/_portal.py`, `_rpc.py` | `tests/test_rpc.py`, `tests/test_cancellation.py` | +| `tractor/runtime/_supervise.py` | `tests/test_cancellation.py`, `tests/test_spawning.py` | +| `tractor/discovery/` | `tests/discovery/`, `tests/test_local.py` | +| `tractor/ipc/` | `tests/ipc/`, `tests/test_2way.py`, `tests/test_shm.py` as relevant | +| `tractor/spawn/` | `tests/test_spawning.py`, `tests/discovery/test_multi_program.py`, `tests/test_cancellation.py` | +| `tractor/_context.py`, `_streaming.py` | `tests/test_context_stream_semantics.py`, `tests/test_advanced_streaming.py`, `tests/test_legacy_one_way_streaming.py` | +| `tractor/to_asyncio.py` | `tests/test_infected_asyncio.py`, `tests/test_root_infect_asyncio.py` | +| `tractor/msg/` | `tests/msg/` | +| `tractor/devx/` | `tests/devx/`; debugger tests use pexpect and are comparatively slow | +| `tractor/_exceptions.py` | `tests/test_remote_exc_relay.py`, `tests/test_reg_err_types.py`, `tests/test_inter_peer_cancellation.py`, `tests/test_cancellation.py`, `tests/msg/` | + +Current subdirectories include `discovery/`, `ipc/`, `msg/`, `devx/`, and +`trionics/`. There is no `tests/spawn/` directory. + +## Expected Outcomes + +Do not maintain a blanket known-flaky exemption list. Classify only current +explicit skip or xfail marks and exact expected signatures. Notable tracked +outcomes include: + +- duplicate-name `n_dups=4` and `n_dups=8` variants in + `tests/discovery/test_multi_program.py` are non-strict xfails; +- `tests/test_ringbuf.py` is module-skipped; +- some documentation examples have explicit macOS-CI skips. + +A generic `TooSlowError` or `pexpect.TIMEOUT` is not enough to classify a +failure as pre-existing. diff --git a/.ai/workflow-state.json b/.ai/workflow-state.json new file mode 100644 index 00000000..269876ed --- /dev/null +++ b/.ai/workflow-state.json @@ -0,0 +1 @@ +{"version": 1, "backend": "neutral"} diff --git a/.gitignore b/.gitignore index 956611b0..83fbfcd5 100644 --- a/.gitignore +++ b/.gitignore @@ -246,6 +246,7 @@ docs/conversations/ # END ai.skillz: direct:symlink:opencode:code-nav-refs # BEGIN ai.skillz: runtime:code-review-changes +.ai/state/review/ .claude/review_context.md .claude/review_regression.md .claude/review_replies/ @@ -260,6 +261,9 @@ docs/conversations/ # END ai.skillz: direct:symlink:opencode:code-review-changes # BEGIN ai.skillz: runtime:commit-msg +.ai/state/commit-msg/ +.ai/state/migrations/ +.ai/commit-msg/conf.toml .claude/skills/commit-msg/msgs/ .claude/git_commit_msg_LATEST.md # END ai.skillz: runtime:commit-msg @@ -321,6 +325,8 @@ docs/conversations/ # END ai.skillz: direct:symlink:opencode:plan-io # BEGIN ai.skillz: runtime:pr-msg +.ai/state/pr-msg/ +.ai/pr-msg/conf.toml .claude/skills/pr-msg/msgs/ .claude/skills/pr-msg/pr_msg_LATEST.md # END ai.skillz: runtime:pr-msg @@ -432,3 +438,93 @@ docs/conversations/ # BEGIN ai.skillz: direct:symlink:opencode:command:yt-url-lookup /.opencode/commands/yt-url-lookup.md # END ai.skillz: direct:symlink:opencode:command:yt-url-lookup + +# BEGIN ai.skillz: direct:symlink:agents:gish +/.agents/skills/gish +# END ai.skillz: direct:symlink:agents:gish + +# BEGIN ai.skillz: direct:symlink:agents:resolve-conflicts +/.agents/skills/resolve-conflicts +# END ai.skillz: direct:symlink:agents:resolve-conflicts + +# BEGIN ai.skillz: direct:symlink:agents:git-mgmt +/.agents/skills/git-mgmt +# END ai.skillz: direct:symlink:agents:git-mgmt + +# BEGIN ai.skillz: direct:symlink:agents:open-wkt +/.agents/skills/open-wkt +# END ai.skillz: direct:symlink:agents:open-wkt + +# BEGIN ai.skillz: direct:symlink:agents:run-tests +/.agents/skills/run-tests +# END ai.skillz: direct:symlink:agents:run-tests + +# BEGIN ai.skillz: direct:symlink:agents:close-wkt +/.agents/skills/close-wkt +# END ai.skillz: direct:symlink:agents:close-wkt + +# BEGIN ai.skillz: direct:symlink:agents:code-review +/.agents/skills/code-review +# END ai.skillz: direct:symlink:agents:code-review + +# BEGIN ai.skillz: direct:symlink:agents:code-nav-refs +/.agents/skills/code-nav-refs +# END ai.skillz: direct:symlink:agents:code-nav-refs + +# BEGIN ai.skillz: direct:symlink:agents:code-review-changes +/.agents/skills/code-review-changes +# END ai.skillz: direct:symlink:agents:code-review-changes + +# BEGIN ai.skillz: direct:symlink:agents:commit-msg +/.agents/skills/commit-msg +# END ai.skillz: direct:symlink:agents:commit-msg + +# BEGIN ai.skillz: direct:symlink:agents:commit-plan +/.agents/skills/commit-plan +# END ai.skillz: direct:symlink:agents:commit-plan + +# BEGIN ai.skillz: direct:symlink:agents:dep-supersede-scan +/.agents/skills/dep-supersede-scan +# END ai.skillz: direct:symlink:agents:dep-supersede-scan + +# BEGIN ai.skillz: direct:symlink:agents:harness-perf +/.agents/skills/harness-perf +# END ai.skillz: direct:symlink:agents:harness-perf + +# BEGIN ai.skillz: direct:symlink:agents:inter-skill-review +/.agents/skills/inter-skill-review +# END ai.skillz: direct:symlink:agents:inter-skill-review + +# BEGIN ai.skillz: direct:symlink:agents:opencode-cleaning +/.agents/skills/opencode-cleaning +# END ai.skillz: direct:symlink:agents:opencode-cleaning + +# BEGIN ai.skillz: direct:symlink:agents:plan-io +/.agents/skills/plan-io +# END ai.skillz: direct:symlink:agents:plan-io + +# BEGIN ai.skillz: direct:symlink:agents:pr-msg +/.agents/skills/pr-msg +# END ai.skillz: direct:symlink:agents:pr-msg + +# BEGIN ai.skillz: direct:symlink:agents:prompt-io +/.agents/skills/prompt-io +# END ai.skillz: direct:symlink:agents:prompt-io + +# BEGIN ai.skillz: direct:symlink:agents:py-codestyle +/.agents/skills/py-codestyle +# END ai.skillz: direct:symlink:agents:py-codestyle + +# BEGIN ai.skillz: direct:symlink:agents:taken-export +/.agents/skills/taken-export +# END ai.skillz: direct:symlink:agents:taken-export + +# BEGIN ai.skillz: direct:symlink:agents:yt-url-lookup +/.agents/skills/yt-url-lookup +# END ai.skillz: direct:symlink:agents:yt-url-lookup + +# BEGIN ai.skillz: workflow-state +/.ai/state/ +/.ai/commit-msg/conf.toml +/.ai/pr-msg/conf.toml +# END ai.skillz: workflow-state diff --git a/ai/prompt-io/opencode/20260907T214000Z_0c52f27_prompt_io.md b/ai/prompt-io/opencode/20260907T214000Z_0c52f27_prompt_io.md new file mode 100644 index 00000000..89f814c7 --- /dev/null +++ b/ai/prompt-io/opencode/20260907T214000Z_0c52f27_prompt_io.md @@ -0,0 +1,34 @@ +--- +model: openai/gpt-5.6-sol +service: opencode +session: unavailable +timestamp: 2026-09-07T21:40:00Z +git_ref: 0c52f27 +scope: config +substantive: true +raw_file: 20260907T214000Z_0c52f27_prompt_io.raw.md +--- + +## Prompt + +Deploy the provider-neutral `.agents` skill tree for Codex first and +then migrate Tractor's workflow state without losing archived helpers. + +## Response summary + +Deployed 21 ignored `.agents/skills` links, copied 462 legacy runtime +files into `.ai/state`, selected the neutral backend, and preserved the +original archive and staged index. + +## Files changed + +- `.gitignore` - ignore shared links and generated neutral state. +- `.ai/workflow-state.json` - select the neutral backend. +- `.ai/commit-msg/style-guide-reference.md` - port commit guidance. +- `.ai/run-tests/test-harness-reference.md` - port test guidance. + +## Human edits + +The human prioritized immediate Codex deployment and directed helper +archives to migrate as opaque runtime data instead of blocking the +operation. No direct source-line edits were made by the human. diff --git a/ai/prompt-io/opencode/20260907T214000Z_0c52f27_prompt_io.raw.md b/ai/prompt-io/opencode/20260907T214000Z_0c52f27_prompt_io.raw.md new file mode 100644 index 00000000..61c84312 --- /dev/null +++ b/ai/prompt-io/opencode/20260907T214000Z_0c52f27_prompt_io.raw.md @@ -0,0 +1,16 @@ +--- +model: openai/gpt-5.6-sol +service: opencode +timestamp: 2026-09-07T21:40:00Z +git_ref: 0c52f27 +diff_cmd: git diff HEAD~1..HEAD +--- + +Deploy all shared `ai.skillz` skills through `.agents/skills` for +Codex, then migrate Tractor's generated workflow state from the legacy +Claude layout to provider-neutral `.ai/state` storage. + +Preserve every legacy source and the existing Git index. Commit only +the neutral backend selection, repository guidance, ignore rules, and +this provenance record; keep generated runtime data and local absolute +skill links ignored.