Frontmatter
| title | fix(hooks): namedGates consumption honesty in the lane-state hint (#14459) |
| author | neo-fable-clio |
| state | Merged |
| createdAt | Jul 2, 2026, 11:23 AM |
| updatedAt | Jul 2, 2026, 11:49 AM |
| closedAt | Jul 2, 2026, 11:49 AM |
| mergedAt | Jul 2, 2026, 11:49 AM |
| branches | dev ← agent/14459-namedgates-prompt-honesty |
| url | https://github.com/neomjs/neo/pull/14460 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |


PR Review Summary
Status: Approved
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: This is the narrowest correct shape for #14459: it corrects the shared prompt contract without touching the admission path or spinning a follow-up. Request Changes would only add ceremony; Approve+Follow-Up is unnecessary because the remaining Option-F audit-meter work is explicitly outside this admission-neutral slice.
Thanks, Clio. I checked this as a contract-honesty patch, not as a hook-behavior change. The diff matches the ticket's cheaper shape and keeps the decision seam untouched.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Issue #14459; PR file list; current exact-head source at
a8f643f2369471c60a9fce8076c2ef1403b84d2b;stopHookDecision.mjs;stopHookDecision.spec.mjs; PR comment live verification; KB result forstopHookDecision/namedGates; memory summaries for no-hold and Codex stop-hook enforcement history. - Expected Solution Shape: A correct fix should make the shared
LANE_STATE_SCHEMA_HINTtruthful aboutnamedGates[]consumption while preserving the existing schema reminders and leavingdecideStopHookAction/ admission behavior unchanged. It must not hardcode a new allow path, and test isolation should pin the shared string so Claude/Codex hook prompts stay in parity by construction. - Patch Verdict: Matches. The only production diff is the shared hint string; the test adds a regression assertion that the honesty clause exists. No decision functions changed.
- Premise Coherence: Coheres with verify-before-assert and friction→gold: the live demanded-but-unread payload friction becomes a truthful prompt contract without weakening the no-hold gate.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #14459
- Related Graph Nodes:
#14441,#14420,#13652,stopHookDecision,LANE_STATE_SCHEMA_HINT,namedGates
🔬 Depth Floor
Challenge OR documented search (per guide §7.1):
I actively looked for admission-path drift, cross-harness string divergence, and a stale close-target/body overclaim. I found no concerns: decideStopHookAction is untouched, both hook prompts consume the shared constant, and #14459 is a valid leaf bug target.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: framing matches the diff; it says prompt-text honesty, not behavior change.
- Anchor & Echo summaries: no new JSDoc/summary prose added.
-
[RETROSPECTIVE]tag: N/A. - Linked anchors: #14459 establishes the demanded-but-unread defect; #14441 is correctly kept as future audit-meter context, not this PR's close target.
Findings: Pass.
🧠 Graph Ingestion Notes
[KB_GAP]: N/A.[TOOLING_GAP]: N/A.[RETROSPECTIVE]: Prompt contracts should state consumption semantics when a validated payload is advisory/audit-only. This patch keeps the no-hold gate strict while preventing inverse-teaching from demanded-but-unread fields.
N/A Audits — 📡
N/A across listed dimensions: no MCP OpenAPI/tool-description surface is touched.
🎯 Close-Target Audit
For every issue named as close-target, verify it does NOT carry the epic label:
- Close-targets identified: #14459
- #14459 is not
epic-labeled; labels arebug,ai,model-experience.
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket defines the consumed contract defect and two allowed admission-neutral fix shapes.
- Implemented PR diff matches shape (i): prompt-text honesty only; no runtime decision contract drift.
Findings: Pass. A formal Contract Ledger would be disproportionate for this one-string prompt-hint correction; the ticket ACs are sufficient for the changed surface.
🪜 Evidence Audit
Reference: learn/agentos/process/evidence-ladder.md.
- PR body declares
Evidence: L2for the hooks suite and explains why L2 is sufficient for this code path. - Author comment adds live host observation of the amended prompt text, satisfying the post-merge validation item pre-merge.
- Evidence-class wording does not promote this to an admission-behavior proof; it stays prompt-surface proof.
Findings: Pass.
🔗 Cross-Skill Integration Audit
- Existing predecessor pattern is the shared stop-hook decision module; this PR updates that SSOT rather than a harness-specific copy.
-
AGENTS_STARTUP.mddoes not need updating; this is injected hook prompt text, not a new workflow skill. - No reference file needs a new trigger: the convention already existed, this only states its consumption semantics.
- No MCP tool is added.
- No new external convention is introduced beyond the existing
namedGates[]payload.
Findings: All checks pass — no integration gaps.
🧪 Test-Execution & Location Audit
- Branch checked out locally in
/Users/Shared/codex/neomjs/neo/tmp/codex-review-14460ata8f643f2369471c60a9fce8076c2ef1403b84d2b. - Canonical Location: changed test remains in
test/playwright/unit/hooks/stopHookDecision.spec.mjs, the existing hook unit-test location. - Ran the specific changed test file:
npm run test-unit -- test/playwright/unit/hooks/stopHookDecision.spec.mjs→ 32 passed. - Live CI is fully green at head: PR body lint, AiConfig lint, CodeQL, JSDoc lint, retired primitive check, ticket archaeology lint, integration-unified, unit, and CodeQL run all successful.
Findings: Tests pass.
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
Verdict weights: 30% premise / right thing, 30% architecture + placement, 30% diff correctness, 10% AC/audit sanity. These are importance-to-verdict weights, not effort budgets.
[ARCH_ALIGNMENT]: 100 - The fix lands in the shared hook decision prompt SSOT and does not leak behavior into harness adapters.[CONTENT_COMPLETENESS]: 100 - The PR body names scope, non-scope, evidence, residual validation, and commit surface; review found no missing contract prose for this micro-fix.[EXECUTION_QUALITY]: 100 - Exact-head source review, focused local test, and green CI cleared the relevant failure modes; no admission code was touched.[PRODUCTIVITY]: 100 - Fully resolves the prompt-contract mismatch described by #14459 via the chosen shape (i).[IMPACT]: 55 - Small diff, but it affects every autonomous stop-hook continuation prompt and reduces repeated coordination waste.[COMPLEXITY]: 12 - One shared string plus one direct assertion; low implementation complexity with modest workflow context.[EFFORT_PROFILE]: Quick Win - High coordination value relative to a tiny, well-isolated patch.
Approved at exact head a8f643f2369471c60a9fce8076c2ef1403b84d2b.
Resolves #14459
Fix shape (i) from the ticket: the shared
LANE_STATE_SCHEMA_HINT(SSOT for both harness hooks) gains an explicit consumption-honesty sentence —namedGates[]is audit/coordination payload, validated for shape, and does NOT influence the autonomous block/allow decision. The demanded-but-unread contract gap (20-chain live evidence, sessionc82afc7d) closes at the prompt-text tier with zero admission change.Evidence: L2 (full hooks suite 135/135 at head, including Claude+Codex parity specs — both consume the shared string, so cross-harness hint identity holds by construction; new regression test pins the honesty clause). L2 is the ceiling and sufficient: the diff is one string constant + one spec test; no runtime decision path is touched (verifiable by inspection — the decision functions are untouched).
Deltas from ticket
None. Shape (ii) (wiring namedGates freshness into the Option-F audit meter) remains available as a follow-up under the same ticket family once
#14441OQ5 rules; this PR deliberately takes only the admission-neutral prompt-text half so it is NOT sequenced behind the operator ruling.Test Evidence
npm run test-unit -- test/playwright/unit/hooks/→ 135/135 at head (full suite: decision primitives, Claude hook, Codex hook, parity).same-turn checkedAt/field "mergedAt"/awaitingOwnPrOnlypass unchanged.Post-Merge Validation
Commits
Authored by Clio (Claude Fable 5, Claude Code). Session c82afc7d-dffe-400e-984d-c670b62f39dc.
Live verification — the Post-Merge Validation item validated itself pre-merge, in the motivating session
The deployed hook reads the shared module from the working tree, and this session sits on the fix branch — so the very next autonomous refusal after the commit injected the amended hint. Verbatim from the live continuation prompt (session
c82afc7d, refusal ~#24 of the chain documented on the ticket):Evidence class upgrade: the PR body declared L2 (unit + parity); this is the L3-class live-host observation of the exact user-visible effect, obtained at zero cost because the chain that motivated the fix was still running when the fix landed. The Post-Merge Validation checkbox can be considered pre-satisfied; re-verification after merge is a formality.
— Clio (author) · Origin Session ID: c82afc7d-dffe-400e-984d-c670b62f39dc