fix: read verified canonical Codex rollouts
Summary
Codex hook binding verifies a canonical rollout path, but the reader previously reopened the original path. An alias retargeted between verification and reading could therefore select a different file. Pass the verified canonical path into the callback and use it in the actual rollout reader.
Add second-snapshot refusal tests for a released parent lock, a closed rollout and changed captured birth evidence, while retaining the constant two-snapshot scaling check. Document that multi-chat app-server/IDE sessions and CLI roots with live subagents skip the SessionStart preamble and early activation; those actions are not deferred or replayed. Missing turn IDs, unavailable birth evidence and a rollout outside the core's configured Codex homes leave hook work pending.
This is a separate follow-up to merged #2090. These are local context-binding checks, not authentication against a malicious process running as the same user. The installed Codex0.166 turn-ID assumption was checked against its pinned submission UUID7 implementation; custom harness versions may differ. No UUID-only restriction is added.
Test Plan
- Three targeted tests pass: canonical reader with a retargeted alias; second-snapshot lock/rollout/birth mutations deny; 2 and 12 held rollouts both use exactly two snapshots.
- Seven affected actual hook route and registration-guidance tests pass.
- Exact merged-base/head proof:
29f4017e5f8d2ae83d96c9f976c62aefcd98063afails the canonical-read regression;00fec7ebdc585c50ed1c75a4ad6e9ab1ddb09c1epasses it. Both arms compile and execute the actual binding helper and reader. - Cargo fmt, pinned Prettier, quality comparison (105 inherited findings on both sides; none new) and final Veto code/security/secrets review pass.
- Current-head CI and independent review.
RelayFlow Proof
- Change type:
bugfix - RelayFlow case:
codex-hook-canonical-read
The runner applies the same canonical-read test to both exact clean revisions. It transparently adapts only the base fixture's callback ABI: the old FnOnce() captures the original alias, matching the old reader; the new FnOnce(&Path) receives the verified canonical path. The test retargets the alias after verification and confirms the alternate file differs. Neither arm changes production code. Dirty revisions, compile failures or a skipped test do not count as a reproduced bug; fixture overlays are restored afterward.
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.