From eb3c99c9fd901f99162fdf1f1d3b6781e183ecfd Mon Sep 17 00:00:00 2001 From: goodboy Date: Fri, 21 Aug 2026 23:19:49 -0400 Subject: [PATCH] Correct `run-tests` harness guidance The migration reference overstated cleanup safety and omitted current environment, platform, debugger and timeout behavior. - document runtime env overrides and the actual CI matrix - distinguish interactive debugger capture from hang diagnosis - describe Trio-aware and SIGALRM timeout guards separately - expose reaper platform limits and dry-run descendant expansion - restore exact change-to-test mappings and randomized-port wording - drop unrelated Taken and broad command ignores from the migration Prompt-IO: ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.md (this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`)) --- .../run-tests/test-harness-reference.md | 86 +++++++++++++------ .gitignore | 8 -- .../20260822T022526Z_5562fd9a_prompt_io.md | 42 +++++++++ ...20260822T022526Z_5562fd9a_prompt_io.raw.md | 24 ++++++ 4 files changed, 127 insertions(+), 33 deletions(-) create mode 100644 ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.md create mode 100644 ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.raw.md diff --git a/.claude/skills/run-tests/test-harness-reference.md b/.claude/skills/run-tests/test-harness-reference.md index 0fa20008..4df627d9 100644 --- a/.claude/skills/run-tests/test-harness-reference.md +++ b/.claude/skills/run-tests/test-harness-reference.md @@ -33,6 +33,11 @@ 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: @@ -64,7 +69,8 @@ uv run --frozen --no-sync pytest tests/ -k 'cancel and not slow' uv run --frozen --no-sync pytest --lf ``` -A current CI-equivalent TCP row is: +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 @@ -81,6 +87,7 @@ Supported spawn backends: 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: @@ -97,14 +104,15 @@ 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 the `trio` backend: TCP and UDS on Linux, and TCP on -macOS. +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 session-unique addresses: a -randomized unprivileged loopback port for TCP or a unique socket name under -the platform runtime directory for UDS. +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 @@ -124,9 +132,14 @@ uv run --frozen --no-sync pytest -s ``` Treat `-s` as a diagnostic comparison, not a pass-equivalent workaround. Do -not add a global pytest timeout: both timeout enforcement methods can corrupt -or terminate Trio sessions. Use existing Trio-aware guards and an outer job -timeout when necessary. +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: @@ -135,25 +148,41 @@ uv run --frozen --no-sync pytest --enable-stackscope --capture=sys kill -USR1 ``` -Tests using `fail_after_w_trace` or `afk_alarm_w_trace` write snapshots under -`$XDG_CACHE_HOME/tractor/hung-dumps/` and print an end-of-session index. +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` -Normal pytest teardown reaps surviving pytest descendants with SIGINT, a -three-second grace period, then SIGKILL, and sweeps recognized orphaned UDS -socket files. It does not sweep shared memory and cannot run if pytest never -reaches fixture teardown. +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: ```text -scripts/tractor-reap -n -scripts/tractor-reap --parent -n -scripts/tractor-reap --shm --uds -n -scripts/tractor-reap --uds-only -n +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; @@ -163,24 +192,31 @@ Review every candidate before requesting a mutating run: - `--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/`, `_root.py` | `tests/test_local.py`, `tests/test_root_runtime.py`, `tests/test_runtime.py`, `tests/test_rpc.py` | +| `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`, cancellation tests | -| `_context.py`, `_streaming.py` | context, advanced-streaming, and legacy-streaming tests | -| `to_asyncio.py` | `tests/test_infected_asyncio.py`, `tests/test_root_infect_asyncio.py` | +| `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 | -| `_exceptions.py` | remote-exception, registered-error-type, and cancellation tests | +| `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/`. `tests/spawn/` currently contains no source tests. +`trionics/`. There is no `tests/spawn/` directory. ## Expected Outcomes diff --git a/.gitignore b/.gitignore index d3f35002..0c123d95 100644 --- a/.gitignore +++ b/.gitignore @@ -121,14 +121,6 @@ snippets/ .claude/skills/resolve-conflicts .claude/skills/inter-skill-review -# /taken-export specifics -.claude/skills/taken-export -.opencode/skills/taken-export -.ai/taken/exports/ - -# opencode local command deployment -.opencode/commands/ - # /open-wkt specifics .claude/skills/open-wkt .claude/wkts/ diff --git a/ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.md b/ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.md new file mode 100644 index 00000000..e6bb4b02 --- /dev/null +++ b/ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.md @@ -0,0 +1,42 @@ +--- +model: openai/gpt-5.6-sol +service: opencode +session: 76c5d31c-5a2f-4503-9b16-410ee7f4fab3 +timestamp: 2026-08-22T02:25:26Z +git_ref: 5562fd9a +scope: config +substantive: true +raw_file: 20260822T022526Z_5562fd9a_prompt_io.raw.md +--- + +## Prompt + +Perform a full Tractor repository scan for related `ai.skillz` work, +then correct the run-tests landing branch, prune unrelated `.gitignore` +additions, preserve only the focused migration, and provide canonical +deployment commands. + +## Response summary + +Audited all local branches, worktrees, affected-path history, deployment +state, canonical skill dependencies, and current Tractor harness behavior. +Corrected the local test reference where it overstated cleanup safety or +omitted current environment, platform, debugger, timeout, and CI details. +Narrowed `.gitignore` to the three managed `run-tests` deployment blocks. + +## Files changed + +- `.claude/skills/run-tests/test-harness-reference.md` - correct the + project-specific test and cleanup contract. +- `.gitignore` - remove unrelated deployment ignores from this migration. +- `ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.md` - record + the migration review provenance. +- `ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.raw.md` - + preserve the unedited response record. + +## Human edits + +The human required an existing-work scan after duplicate implementation +was discovered, approved correcting the landing branch during PR #481 +review, and directed removal or reconciliation of unrelated ignore rules. +No direct source-line edits were made by the human. diff --git a/ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.raw.md b/ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.raw.md new file mode 100644 index 00000000..03acc640 --- /dev/null +++ b/ai/prompt-io/opencode/20260822T022526Z_5562fd9a_prompt_io.raw.md @@ -0,0 +1,24 @@ +--- +model: openai/gpt-5.6-sol +service: opencode +timestamp: 2026-08-22T02:25:26Z +git_ref: 5562fd9a +diff_cmd: git diff HEAD~1..HEAD +--- + +Audit Tractor's repository-wide `ai.skillz` state and correct the +`wkt/ai_skillz_run_tests_landing` migration before landing it. + +> `git diff HEAD~1..HEAD -- .claude/skills/run-tests/test-harness-reference.md` + +The harness reference is corrected against current Tractor behavior: +environment overrides, CI/platform matrices, randomized registry +addresses, interactive debugger capture, timeout mechanisms, stackscope +artifacts, reaper platform limits, dry-run expansion, and exact +change-to-test mappings. + +> `git diff HEAD~1..HEAD -- .gitignore` + +Unrelated Taken and broad OpenCode command ignore additions are removed; +only the managed canonical `run-tests` link and command blocks remain in +this migration.