LearnNewsExamplesServices
Frontmatter
id14459
titleStop hook: continuation prompt demands namedGates payload it never reads
stateClosed
labels
bugaimodel-experience
assigneesneo-fable-clio
createdAtJul 2, 2026, 11:17 AM
updatedAtJul 2, 2026, 11:49 AM
githubUrlhttps://github.com/neomjs/neo/issues/14459
authorneo-fable-clio
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 2, 2026, 11:49 AM

Stop hook: continuation prompt demands namedGates payload it never reads

Closed v13.1.0/archive-v13-1-0-chunk-8 bugaimodel-experience
neo-fable-clio
neo-fable-clio commented on Jul 2, 2026, 11:17 AM

Filed per the hook's own friction→gold clause, from live evidence: a 20-refusal continuation chain (session c82afc7d, 2026-07-02) in which every emitted terminal carried the exact payload the hook's continuation prompt demands — and none of it affected any decision.

Context

The laneStateStopHook continuation prompt instructs, verbatim: "Every namedGates[] entry needs a same-turn checkedAt; mergeClaim must use field 'mergedAt'" — and supplies a machine lane-state block template for the agent to emit. Agents comply: this session emitted 20 consecutive terminals with fully-populated, same-turn-stamped namedGates[] (externally-verified gate refs: PR review slots, operator rulings, divergence windows). Per the #14439 review corpus, the deployed decision path in autonomous mode is operatorInLoop-only — the gate payload is parsed/validated (parseLaneState) but its content has no effect on the block/allow outcome.

The Problem

The hook's stated contract and its actual consumption have diverged: it demands structured evidence it does not read. This is NOT an admission-structure complaint (that is #14441 OQ1/OQ5 territory, operator-gated, explicitly out of scope here). It is an instruction-coherence defect with two concrete costs:

  1. Dead ceremony at every terminal — agents spend effort each turn constructing precisely-stamped gate ledgers that are decorative. Across a 20-refusal chain at metered rates, that is real burn on payload the consumer discards.
  2. Contract-trust erosion (the #14420 inverse-teaching class) — a hook whose own prompt states requirements that demonstrably don't matter teaches agents that its other stated requirements may be decorative too. The mirror's authority depends on its prompt meaning what it says.

The Architectural Reality

  • .claude/hooks/laneStateStopHook.mjs + shared ai/scripts/lifecycle/stopHookDecision.mjs: parseLaneState() reads the fenced block; namedGates entries are schema-validated (per the validator-gotchas text and #14439's spec corpus, which reuses namedGates for Option F's snapshot design).
  • The continuation-prompt text (the block the agent sees on refusal) is generated in the hook layer — the demanded-payload sentences live there.
  • Discussion #14441 (Grace 05:49Z convergence) already designates namedGates[] as Option F's non-network frontier snapshot — i.e. the payload has a designed consumer that is not yet built.

The Fix (two admission-neutral shapes; claimer settles)

  • (i) Prompt-text honesty (cheapest): the continuation prompt stops demanding what the decision path does not consume — the namedGates template stays available but is described as "audit/coordination payload (consumed by peers + the future F-meter), not admission evidence." Zero behavior change; the contract becomes true.
  • (ii) Feed the F-meter (the #14441-aligned shape): wire namedGates freshness into the audit-only ledger (Option F's observability half — explicitly the lowest-regret lane per the #14441 matrix, no allow branch, zero L3 surface). The payload gains its designed consumer without touching admission.

Either shape is same-PR-sized. Out of scope by construction: any change to block/allow behavior (OQ1/OQ5, operator-gated).

Acceptance Criteria

  • The continuation prompt's stated requirements match actual consumption (whichever fix-shape wins) — no demanded-but-unread payload remains.
  • If (ii): namedGates freshness lands in the audit log only; fixture replay proves admission behavior byte-identical.
  • Hooks suite green; Claude↔Codex parity preserved via the shared decision module.
  • Cross-family review before merge.

Related

#14420 (taxonomy parent — the inverse-teaching class) · #14438/PR #14439 (admission — OUT of scope; namedGates-as-F-snapshot design source) · #14440 (prompt-visibility sibling, distinct defect) · Discussion #14441 (Option F consumer design; OQ5 gates the siblings, NOT this — prompt-text/audit tier only) · #13652 (hook epic).

Live latest-open sweep: checked latest 15 at 2026-07-02T09:17Z; stop-hook family covers detection/admission/visibility — none cover the demanded-but-unread contract. A2A sweep: GitHub-primary per the #14426 window; no competing claim.

Origin Session ID: c82afc7d-dffe-400e-984d-c670b62f39dc Retrieval Hint: "stop hook namedGates dead payload demanded but unread instruction coherence"

tobiu referenced in commit cabd28c - "fix(hooks): state namedGates consumption honesty in the lane-state hint (#14459) (#14460) on Jul 2, 2026, 11:49 AM
tobiu closed this issue on Jul 2, 2026, 11:49 AM