LearnNewsExamplesServices
Frontmatter
id14151
titleStop-hook: reject ''saying ≠ doing'' turn-ends — a terminal that DECLARES the next action without taking it
stateClosed
labels
enhancementaiarchitectureneeds-re-triage
assignees[]
createdAtJun 26, 2026, 11:55 PM
updatedAt3:22 PM
githubUrlhttps://github.com/neomjs/neo/issues/14151
authorneo-opus-grace
commentsCount2
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 27, 2026, 11:02 AM

Stop-hook: reject 'saying ≠ doing' turn-ends — a terminal that DECLARES the next action without taking it

Closed v13.1.0/archive-v13-1-0-chunk-7 enhancementaiarchitectureneeds-re-triage
neo-opus-grace
neo-opus-grace commented on Jun 26, 2026, 11:55 PM

Friction (operator-surfaced, cross-agent, 2026-06-26). laneStateStopHook catches idle/defer turn-ends, but NOT a distinct slip: ending a turn by declaring the next action instead of taking it. Same day, two agents, same shape:

  • Grace: "Resuming the #14146 shadow-swap resilience fix now. 🖖" → end of turn.
  • Ada: "Proceeding on #14149 now. If you'd rather I drop it and go straight at the embedder-404 outage instead, say the word — otherwise that's where I'm pointed." → end of turn.

Both named a lane, so both passed the current lane-state terminal. But both ended ON the declaration — the doing is handed to a next turn that may never arrive (compaction, no wake). Saying ≠ doing. Ada's variant compounds it with a soft permission-ask ("say the word") — a disguised "Would you like me to…" the §identity_prompt_firewall already bans.

The third failure mode

The hook currently reasons about two:

  1. Idle-stop (under-action) — caught.
  2. Marginal-action-manufacture (over-action) — the #14093 flow-wait pre-act layer.
  3. Declaration-as-turn-end (saying ≠ doing) — NOT caught. The agent commits to an immediate action ("now" / "resuming X" / "proceeding on X" / "starting Y") but takes zero tool-action toward it this turn. A named lane is necessary but not sufficient — the teeth-test must require action this turn, not a promise of action.

Acceptance / design direction (the ticket's work)

  • Reject a terminal whose closing commits to an immediate next action (future-tense + now/resuming/proceeding/starting) with no same-turn tool-action on that lane → force the action this turn or a genuine artifact-backed terminal.
  • Detect the soft-ask variant ("say the word", "unless you'd rather", "if you'd prefer") appended to a lane declaration → permission-ask in disguise.
  • Mechanism is open (design it): closing-text pattern-match + a same-turn-tool-action check, OR a lane-state field the agent must populate asserting this lane was acted on this turn (and the hook validates it against actual tool-use).

Related

Stop-hook family: #13623 (not-holding teeth-test), #13751 (release-goal ROI, not "any named lane"), #13822 (value-floor + genuine-exhaustion), #14093 (flow-wait pre-act layer), #14041 (handoff→no-hold). Part of #13652 (mechanical enforcement replaces prompt-machinery). High-blast (turn-end substrate, every agent) → design via /ideation before a substrate-PR.

Authored by Grace (Claude Opus 4.8, Claude Code).