LearnNewsExamplesServices
Frontmatter
id13731
titleShow lane-state schema in Stop-hook reminders
stateClosed
labels
enhancementaiarchitecturemodel-experience
assigneesneo-gpt
createdAtJun 21, 2026, 10:17 AM
updatedAtJun 21, 2026, 11:50 AM
githubUrlhttps://github.com/neomjs/neo/issues/13731
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 21, 2026, 11:50 AM

Show lane-state schema in Stop-hook reminders

Closed v13.1.0/archive-v13-1-0-chunk-5 enhancementaiarchitecturemodel-experience
neo-gpt
neo-gpt commented on Jun 21, 2026, 10:17 AM

Context

The active #13623 lane needs a PR-closeable leaf for the hook-only schema-display slice. The parent ticket remains open for AC4 ratio-over-window / COP observability, so the runtime reminder schema display must not magic-close #13623.

This successor is deliberately narrower than #13643. #13643 attempted to solve the emission contract with permanent skill / always-loaded substrate and was closed not_planned after the operator rejected that shape as context bloat. The sanctioned shape is hook-only: display the machine-readable lane-state block schema when the Stop hook actually blocks, with zero AGENTS.md pointer and no new skill payload.

The Problem

Agents repeatedly emitted prose lane-state: lines while the active parser only consumes the last fenced ```lane-state JSON block. The Stop-hook reminder said that no block was emitted, but did not show the exact machine block or the validator gotchas that make a well-formed block invalid.

That creates a recovery loop: a blocked agent can understand that a lane is required, but still cannot self-service the parser input shape from the runtime reminder alone.

The Architectural Reality

  • ai/scripts/lifecycle/parseLaneState.mjs extracts only a fenced ```lane-state JSON block. Prose remains the human ledger, not the machine seam.
  • ai/scripts/lifecycle/validateLaneStateTerminal.mjs rejects two recurring gotchas: active-lane cannot be only an own PR awaiting merge/review/CI, and every namedGates[] entry needs same-turn checkedAt; merge claims must cite field mergedAt.
  • .claude/hooks/laneStateStopHook.mjs and .codex/hooks/codex-lane-state-stop.mjs already inject no-hold reminders at the runtime point where the missing information matters.

The Fix

Add a compact shared runtime schema hint to the Stop-hook decision layer and include it in both Claude and Codex Stop-hook reminders. The hint must show:

  • the fenced ```lane-state block label;
  • required descriptor keys: wakeDisposition, laneContinuation, namedGates, awaitingOwnPrOnly;
  • the two validator gotchas above.

Keep this hook-only. Do not add permanent skill payload, AGENTS.md pointer, parser changes, or a new validator rule.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
Claude Stop-hook reminder parseLaneState.mjs, validateLaneStateTerminal.mjs, #13623 runtime friction On block, display the fenced lane-state JSON shape plus validator gotchas after the existing no-hold directive. Missing/invalid lane-state still blocks; schema text is guidance only, not a stop permission. Hook-internal failures still fail open. JSDoc remains aligned with runtime reminder behavior. Focused hook unit tests assert the schema label, required keys, and gotcha text.
Codex Stop-hook reminder Same shared parser/validator seam and parity requirement Include the same shared schema hint in Codex buildNoHoldReminder(). Keep the no-hold directive first so compact transports still surface the core action. No new Codex config or skill substrate. Focused Codex hook tests assert the same schema/gotcha anchors.
Shared lifecycle helper Existing shared stopHookDecision.mjs decision module Export one schema-hint constant consumed by both hooks so Claude/Codex wording cannot drift. No change to parse, validation, allow/block decisions, or operator-in-loop semantics. Inline JSDoc only. Shared helper spec asserts the hint shape.

Decision Record impact

None. This is aligned with #13623 AC1/AC5 and the existing parser/validator seam. It explicitly avoids resurrecting the rejected #13643 always-loaded / skill-substrate shape.

Acceptance Criteria

  • Claude Stop-hook block directive displays the fenced lane-state JSON schema.
  • Codex Stop-hook no-hold reminder displays the same schema hint.
  • The hint names the validator gotchas for awaitingOwnPrOnly and same-turn checkedAt / mergedAt evidence.
  • Tests cover shared helper, Claude hook, and Codex hook surfaces.
  • No parser/validator semantics change and no permanent skill / AGENTS.md substrate added.

Out of Scope

  • #13623 AC4 ratio-over-window observability.
  • COP rendering.
  • Contribution ledgers or shipper scoring.
  • Stop-hook validator changes.
  • Any new valid terminal, hold state, or permission to stop.
  • Reopening #13643's rejected permanent-substrate approach.

Avoided Traps

  • Permanent skill / AGENTS.md substrate: rejected because #13643 already proved that shape is context bloat for a machine-format detail the hook can convey on block.
  • Parser relaxation to accept prose: rejected because prose cannot carry the structured gate evidence the validator checks.
  • Keys-only schema display: rejected after Vega's contract review; it leaves the recurring active-lane + awaitingOwnPrOnly:true and stale-gate traps intact.

Related

Parent: #13623 Related: #13643

Live latest-open sweep: checked latest 20 open issues on 2026-06-21T08:15Z; no equivalent active leaf found. #13643 found as prior rejected shape, not an active close target. A2A in-flight claim sweep: checked latest 30 inbox messages across read states on 2026-06-21T08:15Z; no competing claim. Ada confirmed hook-only display as the #13643 boundary; Vega requested the validator gotcha text. KB duplicate sweep: queried hook-only runtime reminder / fenced lane-state schema / validator gotchas; surfaced closed historical parser/validator work (#12633 / #13575) and no equivalent active leaf. Release classification: boardless (post-hook substrate refinement, not release-blocking).

Origin Session ID: 747ae298-5a6e-4416-b90d-7786e184aa54 Retrieval Hint: hook-only lane-state schema display, closed #13643 substrate bloat boundary, parseLaneState fenced lane-state block, validateLaneStateTerminal gotchas

tobiu closed this issue on Jun 21, 2026, 11:50 AM
tobiu referenced in commit 77bc445 - "feat(ai): surface lane-state schema in stop hooks (#13731) (#13732)" on Jun 21, 2026, 11:50 AM