Repository navigation
Make the macOS signal-injection tests target the script PID (not $PPID) - #146
Merged
seathatflowsinourveins merged 3 commits intoSep 23, 2026
Merged
Conversation
…al deadlock in the first draft of the timing fix
e7's report: signal-injection tests fail on unmodified main under this
WSL host's own load (~20 avg): 3 failures in isolated module runs, 9 in
the full suite, symptom "return code 0, as if never interrupted". Two
suspected causes: $PPID resolving to a command-substitution subshell
instead of the script, and a fixed `sleep 0.3` racing the trap it is
meant to reach.
What this round did, honestly, in the order it actually happened:
1. Reproduction. nproc*2 full-core busy loops (0/81 runs), then the same
plus fork-churn (0/45), then full-core confined to 2 CPUs with 5
burners (0/90): none reproduced e7's failure. Per the coordinator's
revised, shared-host-safe method (taskset-confined contention instead
of loading every core), single-CPU confinement with 6 burners on core
0 reproduced ONE failure in 15 runs of the launchd convergence-matrix
test on the OLD code -- the only reproduction this round achieved.
e7's own heavier-load failure was not recreated.
2. First fix draft: ADOPTION_SCRIPT_PID (exported by each script next to
its own `set -Eeuo pipefail`) replaces $PPID as the signal target in
every fault-injection shim, and a poll loop (`while kill -0 "$target"`)
replaces the fixed sleep, meant to block until the target has actually
exited. This draft was WRONG: every shim here is the target script's
own SYNCHRONOUS foreground child (exactly how real npm/mv/ln/launchctl
are invoked), so the target's `wait()` cannot return -- it cannot
exit -- while still blocked waiting for this shim. Polling the
target's own pid from inside its own foreground child is circular, not
a handshake, and does not fail loud either: its 30s bound always
fired, silently producing the nonzero exit these tests already
expected. Measured directly: every affected test took ~30-63s per run
under this draft, passing for the wrong reason.
3. Second, corrected draft (this commit). Two things are actually true,
confirmed by direct, repeated (bash 5.2, this host, 10/10 each)
testing, not assumed:
- The PID-targeting bug is real and load-independent: a shim invoked
from inside $(...) -- the exact shape of the pre-round-3i
bootout_and_wait bug this project already fixed once -- signals a
subshell that has no trap of its own, every single time, regardless
of load. ADOPTION_SCRIPT_PID (bash's `$$`, inherited unchanged into
any subshell) fixes this unconditionally.
- The "fixed sleep races the trap" theory does not hold for any of
the current call sites: bash defers a trapped signal's handler
until whatever is CURRENTLY in the foreground -- here, the shim
itself -- finishes, then services it immediately afterward, before
the script's next line, regardless of how long that takes (0s and
0.5s post-kill sleeps both tested 10/10). Ordering is already
guaranteed by bash's synchronous foreground-child execution model
once the signal reaches the right PID.
_signal_and_wait_for_exit now sends the signal to ADOPTION_SCRIPT_PID
and sleeps a short, fixed 0.5s (defensive margin only, not a race)
instead of polling. Confirmed fast and correct: the three affected
bootstrap-macos tests run in 8.8s combined (was 60s+ each under the
deadlocked draft); the three affected launchd tests in 15s.
4. New deterministic (load-independent) proof:
SignalShimMechanismProofTests in tests/test_adoption_launchd.py, two
tests, no busy loops or taskset involved:
- test_ppid_inside_a_command_substitution_subshell_is_not_the_script:
$PPID from inside $(...) never reaches the script's trap;
ADOPTION_SCRIPT_PID always does.
- test_the_trap_runs_before_the_scripts_next_line_once_the_shim_exits:
the trap always preempts the script's own next line once the shim
(its synchronous foreground child) exits, with or without a
post-kill sleep.
5. Residual: the convergence-matrix test's 1/15 failure under 6-burners-
on-1-core is UNCHANGED by this fix -- it recurs at the same ~1/15 rate
on the fixed code, under the same extreme single-core confinement
only (never reproduced under 2-core/5-burner confinement, nor in any
full-core load attempt). Same test, same rate, before and after:
this points away from the signal-targeting/handshake mechanism this
round addresses and toward something else entirely under EXTREME
single-core starvation (most plausibly an unrelated timeout
elsewhere in that test's own dozen subprocess invocations). Time-
boxed per the coordinator's instruction rather than chased further;
left open, not claimed fixed.
Acceptance re-run on this commit: full module suite 182/182 (2 new
mechanism-proof tests), bash -n and shellcheck clean on bash 5.2 and
real bash 3.2, ScriptBehaviorUnderRealBash32Tests 3/3 under
BASH32_BINARY, confined-load (taskset -c 0,1, 5 burners) 10/10 on all
six affected tests, single-core confined (taskset -c 0, 6 burners)
15/15 on five of six and 14/15 on the convergence-matrix residual
above, scripts/validate.py and evidence_manifest.py --check passed,
manifests/evidence.json re-registered for all four changed files.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…terminism-20260923 # Conflicts: # manifests/evidence.json
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
P2: SignalShimMechanismProofTests' two existing tests each build their
OWN shim script by hand, so neither would notice a regression in
_signal_and_wait_for_exit itself -- the class would still pass even if
the real fix were reverted. Adds
test_the_actual_helper_through_a_subshell_uses_the_fixed_target_not_ppid,
which runs the ACTUAL helper's generated text (not a hand-written
stand-in) as the shim, through the same non-optimizable command-
substitution subshell as the existing $PPID test, against a script
that exports ADOPTION_SCRIPT_PID exactly like the real product scripts.
Manually confirmed before committing: temporarily changing
_signal_and_wait_for_exit's own target_var default back to "PPID" makes
this exact test fail (marker never created, rc=143 from errexit on the
subshell's own uncaught SIGTERM, not from the script's trap); the
default was restored to "ADOPTION_SCRIPT_PID" immediately after and
re-verified passing before this commit.
P3: the comment at the mv-migration signal shim (test_adoption_bootstrap_
macos.py, "test_signal_between_the_one_time_migration_and_the_flip...")
still described the FIRST, reverted draft of the helper ("blocks until
the parent has actually exited"). Rewritten to describe what the code
actually does: signal ADOPTION_SCRIPT_PID, then pause briefly (0.5s,
defensive margin only) -- it cannot block on the parent's exit, since
this shim is the parent's own synchronous foreground child.
Full module suite: 186 tests, OK (skipped=3). shellcheck -S style clean
on both product scripts (unchanged this round). ScriptBehaviorUnderRealBash32Tests
3/3 under BASH32_BINARY (real bash 3.2.0). scripts/validate.py and
evidence_manifest.py --check passed; manifests/evidence.json
re-registered for both changed test files.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
seathatflowsinourveins
deleted the
claude/signal-test-determinism-20260923
branch
September 23, 2026 20:49
5 tasks done
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 6, 2026
### Scope - **What this PR changes:** it removes the 2026-10-04 hcom safety posture from main. The user decided at 2026-10-06T03:03:10Z (11:03 PM EDT on October 5) to relax the hcom deny list; the safety rules give way to the seamless, LLM-native workflow. The PR removes: - the 52 Claude deny entries; - `config/hcom-deny.rules`; - the adapter's running-Codex interlock and its empty-deny refusal; - the acceptance checks that required `forbidden` decisions. Peer text stays data and never counts as the user's approval. Upstream `hcom.rules` becomes the only Codex hcom policy. - **Base commit:** `ecfa112764c664d35377dd66b8cfcb67e5a94d60` - **Lane:** `lane:foundation` - **Owned paths touched:** - `adoption/new-wsl/client-config-map.json` - under `evidence/artifacts/new-wsl-install-plan-20261002/`: `config/hcom-client-config.py`, `config/hcom-deny.rules` (deleted), `install-plan.json`, `install.sh`, `accept.sh`, `check_plan.py`, `README.md` and `SOURCES.md` - `tests/test_new_wsl_client_config.py` and `tests/test_codex_hook_trust.py` - `docs/decisions/2026-10-06-hcom-relaxation.md` (new) - `docs/decisions/2026-10-04-round2-plan-g1-messaging.md` (an inline pointer only; no line moves) - `manifests/evidence.json`, in the last commit only | Verdict P1-1 item | Main ecfa112 | Change | | --- | --- | --- | | `claude_settings.permissions.deny` | map :912-963 (52 entries) | The whole `claude_settings` object is removed. An empty object would still go through the settings merge. | | Prohibition sentence in `hcom_config.launch.hints` | map :977 | Removed. The data, approval and configuration sentences stay. | | `codex_rule_file` and `config/hcom-deny.rules` | map :983 | Removed. Upstream `hcom.rules` is the only Codex hcom policy. | | Prohibition sentences in `peer_instructions` | map :984 | Removed, including the `hcom claude` prohibition (see below). The data and approval sentences stay. | | Quiet interlock and empty-deny refusal | adapter :123-128 and :61 | Removed. The adapter also no longer merges settings (:98-106), installs rules (:108-114) or runs the forbidden check (:145-150). | | Contract | `check_plan.py` :179-196 | Replaced by the relaxed contract (below). | | post_install `--check` | install-plan row | Dropped. post_install is the upstream-derived smoke only. | | after_sign_in | install-plan row | Reduced, not deleted, so stage counts and the after-sign-in owner lists stay valid. Revised at 7eb9bea: it takes the Codex home the way hcom does (`CODEX_HOME`, else the parent of `HCOM_DIR`). It exits 78 while retired Claude hcom deny entries remain and until `hcom codex` writes `hcom.rules`. Then it passes every `*.rules` file there to `codex execpolicy check`; `hcom send` and `hcom term inject` must both be `allow`, so a leftover `hcom-deny.rules` exits 78. | | Decision record | supersedes `2026-10-04-round2-plan-g1-messaging.md:65-72` | `docs/decisions/2026-10-06-hcom-relaxation.md` | The verdict cites the same pieces at #723's head, at other lines (map :894-951, :962, :968 and :969; checker :180-197). The table uses main's lines. The relaxed `check_plan.py` contract keeps the four `hcom_config` value checks and the smoke tokens. It asserts three things: - no Codex rule file and no Claude hcom settings are mapped; - both peer texts keep the data and approval sentences; - after_sign_in derives the Codex home from `HCOM_DIR`, evaluates every rules file there and checks the retired Claude denies. ### The `hcom claude` rule: hook-gap finding at hcom's current release - **Current release.** `gh api repos/aannoo/hcom/releases/latest` returns **v0.7.27, still the latest** (published 2026-10-01T02:11:55Z, target `2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b`, the existing pin). - **The gap still holds.** Hooks load only in `hcom <tool>` sessions ([release notes, #146](https://github.com/aannoo/hcom/releases/tag/v0.7.27)). The Claude hook handler exits 0 silently without `HCOM_PROCESS_ID` ([claude.rs:135-140](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/hooks/claude.rs#L135)). A plain `claude` has no hooks ([start.rs:412-417](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/commands/start.rs#L412)). Only `hcom claude` gets automatic delivery; anything else uses manual `hcom listen` ([README.md:230-246](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/README.md#L230)). - **Upstream main.** Main is 20 unreleased commits ahead, and its claude.rs diff leaves the guard untouched. - **The sentence is dropped** (the command center's read at 247d71e, finding P2, option a). - The sentence met the task's "stays only if" test, which is a necessary condition, not a sufficient one. - The gap is the *cost* of not launching through `hcom claude`, not a reason against it. - The peer-instruction block now keeps only the neutral route facts: a plain Claude session uses `hcom start` and `hcom listen`, which do not wake it when idle, and `hcom claude` is upstream's automatic-delivery route for Claude Code. - **Why not option b.** Option (b) would keep the rule on the wave-5 transport-scoping basis and add Claude lanes to the command center's orchestration decision. That changes the command center's own decision, so it is not this lane's to make. - **No recipes.** This PR adds no launch, kill, term or transcript recipe. ### Fixes after the command center's read at 247d71e (ACK_AFTER) | Finding | Fix | | --- | --- | | P2: the kept `hcom claude` sentence | Option (a): `peer_instructions` drops "Never launch Claude lanes through hcom claude" and "Claude lanes stay plain Claude sessions" and keeps the route facts. The record's Result and overturn sections are rewritten. | | P3: no supersession pointer for the 2026-10-05 combined-rules acceptance | Inline pointer at the start of the old record's :196. No line moves; :65, :109 and :196 stay where the new record cites them. | | P3: rc 3 at `--apply` when the user's own `~/.hcom/config.toml` differs (pre-existing) | Recorded in the decision's host section (see Host evidence below). No code change: `run_slot` scores any non-zero rc, 78 included, as failed. | | P3: the adapter's `--check` has no caller | The docstring marks it a manual operator check that no plan stage runs. The record's post_install row says the same. | | P3: the `exec_rules_reviewed.json` entry stays | No change. The read accepts the deviation. | The history was rebuilt so that `manifests/evidence.json` changes only in the last commit (`docs/lanes.md:96-128`): - `f0d9b2f5`: the relaxation; - `88eb3981`: the read's fixes; - `10160d89`: the registry. It was pushed with `--force-with-lease`, replacing 247d71e. ### Deliberate non-changes - **`tools/adoption/exec_rules_reviewed.json` keeps its `hcom-deny.rules` entry.** This is a deliberate non-change to the verdict's item (e). The entry reviews one exact file for the RTK Codex hook-trust tool and enforces nothing. Removing it would rewrite about twenty trust tests and `rtk-rewrite-heads-check.json`. It would also make `codex_hook_trust.py` refuse on any host that did install the file. The plan-wide test that every plan rule file is reviewed or allow-only stays; only its docstring changed, and it is vacuous while the plan ships none. - **The verdict's item (f) quiet-interlock and quiet-apply wording exists only in #723.** On main, `git grep -i -E 'quiet (interlock|apply|point)'` returns nothing. - **Configuration values are unchanged.** These are `title_mode=off`, `relay.enabled=false`, `auto_trust_workspace=false` and `auto_approve=true`. The verdict reserves `auto_trust_workspace` and `title_mode` to the user. ### SOTA sources - **aannoo/hcom v0.7.27** at `2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b` (https://github.com/aannoo/hcom/releases/tag/v0.7.27), still the latest release, read with `gh api repos/aannoo/hcom/releases/latest` on 2026-10-06: - **Upstream `hcom.rules`, the only Codex hcom policy:** - [src/hooks/codex.rs:1538-1563](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/hooks/codex.rs#L1538) (`build_codex_rules`); - [:1566-1579](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/hooks/codex.rs#L1566), which writes `<codex home>/rules/hcom.rules`; - [:337-350](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/hooks/codex.rs#L337), the call made when `auto_approve=true`; - [:72-75](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/hooks/codex.rs#L72), the Codex home; - [src/hooks/common.rs:46-72](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/hooks/common.rs#L46), the command list. - **Hook-gap check:** - the release notes (#146); - [src/hooks/claude.rs:135-140](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/hooks/claude.rs#L135); - [src/launcher.rs:920](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/launcher.rs#L920); - [src/commands/start.rs:412-417](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/commands/start.rs#L412); - [README.md:230-246](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/README.md#L230). - **Mapped configuration fields:** [src/config.rs:126-152](https://github.com/aannoo/hcom/blob/2c5f343b2f9ec4bf2acf49c0431860e7c2ae578b/src/config.rs#L126). - **Codex native policy checker:** https://developers.openai.com/codex/rules, and the installed codex-cli 0.160.0 `codex execpolicy check --help` (repeatable `--rules`, JSON `decision`). ### Evidence-class table | Claim | Evidence class | Command / receipt | | --- | --- | --- | | The plan rows, `install.sh`, `accept.sh`, the map and the relaxed contract agree | `local_integration` | `check_plan.py` exit 0 | | The adapter applies while a Codex PID is reported, leaves Claude settings unchanged, writes no Codex rules directory, runs no subprocess and keeps the data and approval sentences | `synthetic` | `test_hcom_apply_never_grants_inbound_authorization_or_requires_codex` | | `copy_config` still refreshes plan-owned helpers and keeps operator files | `synthetic` | `test_plan_owned_helpers_refresh_without_overwriting_operator_configuration` | | The contract fails if after_sign_in falls back to a fixed `$HOME/.codex` | `synthetic` (throwaway negative control, not committed) | `check_plan.py --plan-dir <mutated copy>`: exit 1, "after sign-in must evaluate every rules file in the Codex home that hcom derives from HCOM_DIR, and report retired Claude hcom denies" | | Native-checker probes and the after_sign_in program on frozen fixtures | `synthetic` (real codex-cli 0.160.1 and jq 1.8.1 with scratch homes) | Retained receipt `evidence/artifacts/hcom-relaxation-20261006/probe-receipt.json`, run at 13:11:32Z: `allow`/`allow`/no decision over `hcom.rules` alone, `forbidden` for term with the retired file, and 8 after_sign_in runs with the expected exits 78,0,78,0,78,0,78,0 | | The after_sign_in shell logic (`HCOM_DIR` derivation, every rules file, retired Claude entries) | `synthetic` (stub codex) | `test_hcom_after_sign_in_reads_hcoms_codex_home_and_every_rules_file` | | hcom v0.7.27 is the latest release, and the plain-Claude hook gap holds there | `source_review` | `gh api` releases, tags and compare; pinned source read | | No host changed | (scope) | no `install.sh`, `accept.sh` or `--only agent-messaging` run; NativeStack2604 never had the posture (the command center's read-only check) | ### Review threads at 3b6ea9d, fixed at 7eb9bea The fix commit is `2c8890c9`, and the registry and regenerated outputs are the last commit, `7eb9beaa`. | Thread | Fix | | --- | --- | | P1, decision record :131: retain the probe's actual result | `evidence/artifacts/hcom-relaxation-20261006/` keeps the frozen synthetic `hcom.rules` (sha256 `2a667dcb…`) and `probe-receipt.json` (every argv, sanitized environment, UTC times, exit codes, stdout and stderr). The record's Evidence section cites it. | | P2, accept.sh:330: resolve under the Codex home hcom derives from HCOM_DIR | The after_sign_in derives `CODEX_HOME`, else the parent of `HCOM_DIR` (hcom `src/hooks/codex.rs:72-75`, `src/paths.rs:26-53`). The check_plan contract requires it. | | P2, accept.sh:335: check the effective policy | Every `*.rules` file in that home goes to the native checker, as Codex loads them (openai/codex rust-v0.160.0 `exec_policy.rs:662-700`). `hcom send` and `hcom term inject` must both be `allow`. A leftover `hcom-deny.rules`, or any of the 52 retired Claude hcom deny entries, reports needs_user (78). | | P2, README.md:476: the generated handbook still stated the retired posture | The handbook's source record (layer consensus, wave 5, agent-messaging) and the WSL recipe's exec-rules sentence were updated. `assemble_manifest.py` and `scripts/build_new_wsl_handbook.py --write` then regenerated the outputs, and the handbook receipt follows them. | The installed Codex is now 0.160.1, which adds two commits to rust-v0.160.0, neither touching exec policy. ### Local commands run Run at head `7eb9beaaf9680acebe0d8d1c8b0331cb50e4ff2a` with `nice -n 19` and `PYTHONDONTWRITEBYTECODE=1`: ``` $ python3 scripts/validate.py exit 0: {"components": 69, "hashed_files": 10322, "profiles": 4, "receipts": 212, "status": "passed"} $ python3 evidence/artifacts/new-wsl-install-plan-20261002/check_plan.py exit 0: OK: 84 rows ... 185 commands and 113 acceptance entries agree with the scripts (2 additional checks included) $ python3 tools/adoption/new_wsl_client_config.py --check exit 0: check passed (two existing MCP_AUTO_OPEN_ENABLED warnings) $ python3 scripts/build_new_wsl_handbook.py --check exit 0 $ (cd evidence/artifacts/new-wsl-definitive-defaults-20261001 && python3 assemble_manifest.py --check && python3 render_tables.py --check ../../../docs/decisions/2026-10-01-new-wsl-definitive-defaults.md) exit 0, exit 0 $ bash -n install.sh && bash -n accept.sh; git diff --check 3b6ea9d..HEAD exit 0, exit 0 $ python3 -m unittest <the 6 touched modules>; python3 -m unittest <the 4 other pinning modules> exit 0: 567 tests OK (skipped=3); exit 0: 122 tests OK (skipped=1) ``` The earlier runs at 10160d8 and 247d71e follow. ``` $ python3 scripts/validate.py exit 0: {"components": 69, "hashed_files": 10271, "profiles": 4, "receipts": 212, "status": "passed"} $ python3 evidence/artifacts/new-wsl-install-plan-20261002/check_plan.py exit 0: OK: 84 rows ... 185 commands and 113 acceptance entries agree with the scripts (2 additional checks included). Base ecfa112 gives the same counts, so no stage was dropped. $ python3 tools/adoption/new_wsl_client_config.py --check exit 0: check passed, with two MCP_AUTO_OPEN_ENABLED warnings. Base ecfa112, run in a `git archive` extraction, gives the same exit 0 and the same two warnings. $ python3 scripts/build_new_wsl_handbook.py --check exit 0: status passed (no regeneration needed) $ python3 evidence/artifacts/new-wsl-install-plan-20261002/config/hcom-client-config.py --repo-root . --check-map exit 0 $ bash -n evidence/artifacts/new-wsl-install-plan-20261002/install.sh && bash -n evidence/artifacts/new-wsl-install-plan-20261002/accept.sh exit 0 $ git diff --check origin/main...HEAD exit 0 $ python3 -m unittest tests.test_codex_hook_trust tests.test_new_wsl_client_config tests.test_new_wsl_definitive_defaults tests.test_new_wsl_handbook tests.test_new_wsl_profile tests.test_wsl_new_distro_recipe tests.test_gpt6_family_tiering_20260926 tests.test_gpu_inference tests.test_local_inference_latest_20260926 tests.test_workflow_policy exit 0: Ran 670 tests in 176.855s, OK (skipped=4) $ python3 scripts/component_matrix.py --write && python3 scripts/new_host_grand_list.py --write exit 0, exit 0: no output change ``` The module list covers every test module that names hcom, agent-messaging, hcom-deny, the plan directory, the map, `check_plan`, `exec_rules_reviewed` or the round-2 record. It is the `git grep -l` over `tests/`. ### Decision record `docs/decisions/2026-10-06-hcom-relaxation.md` records: - the user's decision, described rather than quoted; - the sources; - six alternatives; - the overturn conditions, both for the posture and for reinstating an `hcom claude` launch rule; - the host boundaries and a completeness critic. It supersedes `docs/decisions/2026-10-04-round2-plan-g1-messaging.md:65-72`, plus that record's 2026-10-05 combined-rules acceptance. ### Host evidence Not applicable: no `evidence/hosts/` change. NativeStack2604 never had the posture applied, so nothing needs undoing. A host that did apply it keeps its hcom deny entries and `~/.codex/rules/hcom-deny.rules` until that host's owner removes them; none is known. **Expected after landing on NativeStack2604.** This behavior is unchanged from base. - The user's own `~/.hcom/config.toml` already exists there. - Unless it matches the mapped template's digest, `install.sh --only agent-messaging` writes the two instruction blocks, keeps the file, prints `needs_user` and prints `agent-messaging | install | 3`. `run_slot` scores that rc as failed. - The four mapped hcom values are not written there. ### Integration - Hot files are in the last commit only (`docs/lanes.md:96-128`). That commit removes the retired file's registry entry and re-registers the ten changed registered files. - #723 rebases onto this PR after it lands, in the fixwave-defects lane. ### Checklist - [x] New/changed GitHub Actions are pinned to a full commit SHA with a version comment (no floating tags). No workflow changes. - [x] New/changed workflows declare top-level `permissions: {}` and grant each job only what it needs (`contents: read`, or an explicitly justified addition). No workflow changes. - [x] No secrets are printed, logged or committed; no new required secret was added without a documented owner. - [x] No new paid hosting, subscription or billing surface was introduced. - [x] Peer-owned untracked files and worktrees were preserved (not deleted, moved or overwritten). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 10, 2026
The command center's correction #146: no personal copy of claude-native-practice is installed on this host; sessions load the checkout's project skill. The follow-up is now stated neutrally: the skill rows for the retired route are updated in a cc-native-practice pull request, then re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 10, 2026
The command center's correction #146: no personal copy of claude-native-practice is installed on this host; sessions load the checkout's project skill. The follow-up is now stated neutrally: the skill rows for the retired route are updated in a cc-native-practice pull request, then re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 10, 2026
The command center's correction #146: no personal copy of claude-native-practice is installed on this host; sessions load the checkout's project skill. The follow-up is now stated neutrally: the skill rows for the retired route are updated in a cc-native-practice pull request, then re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 10, 2026
The command center's correction #146: no personal copy of claude-native-practice is installed on this host; sessions load the checkout's project skill. The follow-up is now stated neutrally: the skill rows for the retired route are updated in a cc-native-practice pull request, then re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 11, 2026
The command center's correction #146: no personal copy of claude-native-practice is installed on this host; sessions load the checkout's project skill. The follow-up is now stated neutrally: the skill rows for the retired route are updated in a cc-native-practice pull request, then re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 11, 2026
The command center's correction #146: no personal copy of claude-native-practice is installed on this host; sessions load the checkout's project skill. The follow-up is now stated neutrally: the skill rows for the retired route are updated in a cc-native-practice pull request, then re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 11, 2026
* Retire Claude review inside GitHub; AI reviews run locally The owner decided on 2026-10-10 (about 17:15Z, relayed by the command center) that Claude review no longer runs inside GitHub: AI reviews run on the local host and GitHub enforces the gates. The API refused every request that carried claude-code-action's attribution (CLAUDE_CODE_ENTRYPOINT=claude-code-github-action, base-action/src/parse-sdk-options.ts:284 at 2dca132f) on all five Console keys, while the same keys work from the CLI and the Agent SDK (the command center's correction #141, measured). Removed: claude-pr-review.yml, claude-pr-toolkit-review.yml, harness-audit.yml and their three test modules, their zizmor-coverage entries and their local-pages inventory paths. test_claude_federation_diagnostics keeps its retained-snapshot and decision-claim tests. A new InGitHubClaudeReviewRetiredTests keeps the three files absent and no workflow running the Claude action or naming an Anthropic key. New record docs/decisions/2026-10-10-retire-in-github-claude-review.md (cause, what remains, revisit triggers, inverse); supersession notes in the four claude-actions/federation records and the decision-record index; docs/github-automation.md's current practice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pin the repository grant count at 90 after the retirement The three removed workflows were in the local-pages repository grants. At the landing base, main f38116f (93 grants), the test's own derivation (grants.inventory_paths over git ls-files) gives 90 for this branch, equal to the policy's repository grants, and the test pins 90. At the earlier bases eb31d23 and 9d4c00c the same derivation gave 90 and 89. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Take up the command center's notes on the retirement - .github/actions-permissions.json drops anthropics/claude-code-action@* and oven-sh/setup-bun@*: no workflow uses them; a new test keeps every allowed pattern in use, and the record's inverse puts them back. - docs/github-automation.md: the allow-list text, no "harness description", no "still awaits hosted acceptance" clause. - The retirement test catches the claude-review environment in its plain, name: and quoted forms, and reads *.yaml as well. - Record nits: #953 marked open, the check is named sota-sources, and the federation-diagnostics note says the three workflows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Cite #968's real merge commit in the inverse The record's inverse named a SHA that does not exist; #968's merge commit is 9d4c00c (git rev-parse 9d4c00c). The federation note now says the history of those workflows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Read each job's environment in the retirement guard The GPT read at 48e4bd3 found three valid YAML forms of the claude-review environment that the regex guard let through: a flow mapping, a quoted name key, and a comment after the key. The guard now reads each job's environment as a scalar or a mapping's name (job_environments), cross-checked against PyYAML when it is installed; all three forms are regressions, each caught here and missed at e46f68e, and actionlint accepts each fixture. The record names the claude-native-practice skill rows as a dated follow-up for cc-native-practice (the command center's ruling at 20:19Z). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Word the skill-row follow-up without the pinned-copy premise The command center's correction #146: no personal copy of claude-native-practice is installed on this host; sessions load the checkout's project skill. The follow-up is now stated neutrally: the skill rows for the retired route are updated in a cc-native-practice pull request, then re-pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * State what the environment reading covers, and what PyYAML covers The docstring claimed comments in general; the text reading handles a comment after the key, not a comment line before name: at the job's indentation or a multi-line flow mapping. The PyYAML comparison covers those, and CI runs it (validate run 38084944806, passed, not skipped). The command center's micro at 08a76ab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Cite the environment forms' sources, and test the inverse pin against git The GPT read at 13d1eb7 asked, under the correction rule, for: - the upstream sources of the environment reading: GitHub's workflow syntax for jobs.<job_id>.environment (a name, or an object with name and url) and YAML 1.2.2's block and flow mappings, quoted keys and comments, cited with page digests in the record and next to the regression cases; - a regression for the corrected inverse pin: RetirementInversePinTests reads the pin from the record and checks it is #968's merge commit holding the three workflows. It fails on the former SHA (no such commit) and is skipped, with the reason, only outside a worktree or in a shallow clone (CI clones with fetch-depth 0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
agent-lab-e7 reported that #94's signal-injection tests fail on a heavily loaded WSL host (load average about 20). The failures were 3 in isolated runs and 9 in the full suite. The same tests pass on hosted CI.
Fix
$PPID. When a shim runs inside$(...),$PPIDis the command-substitution subshell, whose traps are reset, so the signal never reached the script under test. Both product scripts now exportADOPTION_SCRIPT_PID, and the shims signal that PID. This is a real bug that doesn't depend on load; the pre-round-3ibootout_and_waitbug had the same shape.SignalShimMechanismProofTestsclass adds two tests:$PPIDinside$(...)never reaches the script, whileADOPTION_SCRIPT_PIDalways does;Evidence (this WSL host)
Reproduction runs:
e7's heavier-load failure did not reproduce on this host at this time.
Before and after the fix:
test_convergence_matrix_every_step_x_failure_term_int_then_fault_free_retry, seen only under single-core starvation, is unchanged by this PR. It is left open, not claimed fixed. Likely cause: a timeout among that test's many subprocess calls.🤖 Generated with Claude Code