Skip to content

fix(codex): anchor trusted hook payloads - #2218

Closed
coreldh wants to merge 4 commits into
kunchenguid:mainfrom
coreldh:fm/c0806n-fm-1537b-route-b
Closed

coreldh wants to merge 4 commits into
kunchenguid:mainfrom
coreldh:fm/c0806n-fm-1537b-route-b

Conversation

@coreldh

@coreldh coreldh commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Intent

Publish the actual PR 1537B Route B branch, not the stale recorded branch. Preserve the trusted Codex hook executable-root boundary while rebasing it onto current upstream main, carrying the documentation and regression coverage needed to keep worker-controlled worktrees from retargeting trusted hook payloads. Gate the exact rebased commit locally, push only through the configured fork path, open exactly one pull request against kunchenguid/firstmate main, and do not merge, self-approve, force-push, or bypass any ask-user decision.

What Changed

  • Anchor Codex hook executables to the trusted parent or secondmate root while preserving each worker’s canonical worktree for scope classification.
  • Resolve the cd command policy from the trusted wrapper directory and add regressions for payload substitution, linked-worktree exemptions, and Codex spawn bindings.
  • Document the trusted executable-root/worktree-scope boundary across Codex hook and supervision guidance.

Risk Assessment

✅ Low: The rebased change consistently separates trusted hook payload resolution from worker worktree scope, with matching regression coverage and no source-verifiable defect found.

Testing

Targeted CLI-only validation exercised substituted worktree payloads, untrusted hook CWD, CD policy ownership, and generated Codex launch bindings; all completed successfully with transcripts captured. No visual evidence applies because this change exposes no rendered UI. Live Codex trust-dialog re-prompt behavior is NOT_VERIFIABLE in the offline fixture.

Evidence: Trusted-hook end-to-end transcript

Legacy worker payload executed; anchored hook refused worker and untrusted-cwd payloads while executing trusted payload. Live Codex trust-dialog behavior remains NOT_VERIFIABLE.

evidence before: status=0 worktree_payload=EXECUTED modeled_trust_file_unchanged=yes
evidence after-worktree: status=0 worktree_payload=REFUSED trusted_payload=EXECUTED linked_worktree=EXEMPT
evidence after-untrusted-cwd: status=2 cwd_payload=REFUSED trusted_payload=EXECUTED trusted_scope=ACTIVE
evidence trust model: file_sha256=0dc9a8054ab0bc55b7e89bb5d1ee2f4fc3433b39e0fc945d55408e1f7616d8d2 unchanged=yes
NOT_VERIFIABLE: live Codex trust-dialog re-prompt count; this offline test models config.toml and never invokes Codex.
ok - Codex trusted-hook text cannot be retargeted to a worker-controlled payload root
Evidence: CD-hook boundary transcript

Codex CD hook exercised trusted executable code versus worker-controlled runtime scope.

ok - cd-guard acceptance matrix: 63 cases x 5 harness entry forms, block/allow all correct
ok - cd-guard: fires in a secondmate home (its own primary session is a primary)
ok - cd-guard: inert in a crewmate/scout task worktree (linked git worktree)
ok - cd-guard: inert in a non-firstmate repo (no AGENTS.md)
ok - cd-guard: inert when not inside a git repo
ok - cd-guard: reproduces the cwd leak and denies the exact command that causes it
ok - cd-guard: fails open on empty stdin
ok - cd-guard: fails open on unparseable stdin JSON
ok - cd-guard: fails open (never blocks) when node is missing
ok - cd-guard: fails open on the stdin path when jq is missing
ok - cd-guard: prefilter fast-allows (skips node) when no cd/pushd/popd substring is present
ok - cd-guard: fm-cd-command-policy.mjs CLI honors the deny/allow output contract
ok - .codex/hooks.json: cd hook separates trusted executable code from runtime scope
ok - shellcheck not installed, skipping
Evidence: Codex launch-root transcript

Captured fake-tmux launch construction, including trusted parent root for crewmates and secondmate root binding.

ok - no --model/--effort records defaults and types the claude launch instructions
ok - relative home overrides ignore CDPATH and become absolute before spawn launch construction
ok - FM_HOME defaults resolve relative paths and preserve absolute spellings
ok - absolute override spellings are preserved in spawn launch paths
ok - unresolvable relative spawn overrides fail with named diagnostics
ok - active crew-dispatch profile requires an explicit harness for ship spawns
ok - active crew-dispatch profile requires an explicit harness for scout spawns
ok - active crew-dispatch profile allows an explicit resolved harness
ok - active crew-dispatch profile allows the legacy positional harness form
ok - active crew-dispatch profile allows the raw launch-command escape hatch
ok - claude receives --model and --effort profile flags
ok - codex receives --model and model_reasoning_effort profile flags
ok - codex omits unsupported max effort instead of passing a bad config value
ok - grok receives --model and --reasoning-effort profile flags
ok - grok omits unsupported max reasoning effort
ok - grok omits unsupported xhigh reasoning effort
ok - opencode receives --model and omits the unsupported effort axis
ok - pi receives --model and --thinking max profile flags
ok - Pi launch probing omits --tui-mode on older Pi and preserves it on supporting Pi
ok - pi-signed shares Pi launch semantics while preserving its configured and recorded identity
ok - pi-signed refuses safely and actionably when the selected executable is unavailable
ok - pi-signed is a distinct persistent secondmate runtime with shared Pi supervision semantics
ok - batch dispatch forwards shared --harness, --model, and --effort to every pair
ok - claude forwards firstmate's CLAUDE_CONFIG_DIR so the crewmate uses the same credential store
ok - claude omits the config-dir prefix when firstmate runs with the single-store default
ok - non-claude harnesses do not receive the claude CLAUDE_CONFIG_DIR prefix
ok - active crew-dispatch profile does not block secondmate launches
# all fm-spawn-dispatch-profile tests passed

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

⚠️ **Rebase** - 1 warning
  • ⚠️ docs/turnend-guard.md - merge conflict rebasing onto refs/remotes/no-mistakes-push/fm/c0806n-fm-1537b-route-b
✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • env PATH='/Users/admin/.hermes/node/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin' bash tests/fm-codex-hook-integrity.test.sh
  • env PATH='/Users/admin/.hermes/node/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin' bash tests/fm-cd-pretool-check.test.sh (ShellCheck intentionally unavailable, so its optional lint check skipped)
  • bash tests/fm-spawn-dispatch-profile.test.sh
  • git diff --check b5d430d6fdcd961ce9b681bf196f365c1825c284 7d2c34a1040b729c5a7b22be491f2d2c4e3da27c
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@coreldh

coreldh commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Status refresh, verified live on 2026-08-12 at 17:07 UTC.

  • Head: 530a81987a7adfd4a7e6ae44a8e503f1b8c9c073
  • Checks on that head: 13 check runs, all with conclusion success (Repo invariants, Lint shell scripts, Test coverage guard, Stock macOS Bash snapshot compatibility, Behavior timing aggregate, Behavior tests (Herdr), Behavior portable serial 1-4, Behavior portable parallel 1-2, PR must be raised via no-mistakes).
  • Mergeability as reported by the API at that moment: mergeable: true, mergeable_state: clean.

Bounded purpose of this PR: anchor Codex hook executables to the trusted parent or secondmate root while preserving each worker's canonical worktree for scope classification, so a worker-controlled worktree cannot retarget a trusted hook payload. Regression coverage accompanies payload substitution, linked-worktree exemptions, and Codex spawn bindings.

Posting this only so the current state is on the record; no action is requested here.

@coreldh

coreldh commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Closing this — main now launches Codex crewmates and scouts with the hook layer disabled (#4689), so worker worktrees can no longer supply hook payloads. Thanks!

@coreldh coreldh closed this Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant