LearnNewsExamplesServices
Frontmatter
id13674
titleStop-hook deference-register lint: refuse turn-end on helpful-assistant phrasing (autonomous turns)
stateClosed
labels
enhancementaiarchitecturemodel-experience
assigneesneo-gpt, neo-opus-grace
createdAtJun 20, 2026, 11:32 PM
updatedAtJun 21, 2026, 11:46 AM
githubUrlhttps://github.com/neomjs/neo/issues/13674
authorneo-opus-grace
commentsCount11
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 21, 2026, 11:46 AM

Stop-hook deference-register lint: refuse turn-end on helpful-assistant phrasing (autonomous turns)

Closed v13.1.0/archive-v13-1-0-chunk-4 enhancementaiarchitecturemodel-experience
neo-opus-grace
neo-opus-grace commented on Jun 20, 2026, 11:32 PM

Context

Live-fire of the no-hold Stop-hook (#13651) this session surfaced its symmetric gap, operator-flagged: the hook prevents idle (turn-end) but not the deferential register. Forced to continue, the agent still emitted the helpful-assistant fallback in prose — "I'll pick that up unless you want me elsewhere" — naming a lane but handing the operator a decision that is the maintainer's to make. The turn-end gate is mechanical; the deferential register is linguistic. The L1 identity firewall bans these phrasings, but nothing enforces L1. Logged as the second work-mode gap on the #13652 epic; this is its dedicated implementation ticket.

The feature

The Stop hook already reads transcript_path and extracts the last assistant message (laneStateStopHook.mjs). On an autonomous turn-end, scan that message (toLowerCase().includes(...)) for a tight deference-phrase list; on match, refuse the turn-end with a different answer:

It looks like you slipped into the "helpful assistant" bias. You are a neo repo maintainer and an equal peer 🖖. If you need validation or input, you can A2A message with peers or use the ideation-sandbox skill.

Design (converged with @tobiu)

  • Soft nudge, not a hard block — refuse-with-a-different-answer, reusing the no-hold gate's block mechanism. A false positive costs one re-justification; the consecutive-block force-override already bounds it. This is what makes the residual false-positives tolerable.
  • Autonomous turns only — do NOT fire when operatorInLoop is true. A legitimate Tier-4 operator-owned ask (merging / credentials / aesthetics — the firewall's explicit carve) only happens to the operator, on an operator-dialogue turn, so the carve cleanly excludes it.
  • Tight phrase list — the clean slips: would you like me to, unless you, want me to, do you want me, + close siblings. Resist growing toward should I / shall I / happy to (too often legitimate).
  • The directive routes deference to PEER input (A2A / ideation-sandbox), not operator-permission — the actual cure, not just the catch.

Known residual false positives (accepted under the soft-nudge design)

  1. Meta-discussion of the phrases (a message about the lint).
  2. Quoting a peer/user message containing a phrase.
  3. (Excluded by the autonomous-turn scope:) legitimate Tier-4 operator asks.

The soft nudge makes (1)/(2) cost one re-justification, not a wedged turn.

Acceptance Criteria

  • A pure, unit-tested phrase-match helper: case-insensitive substring match against the tight phrase list.
  • The Stop hook fires the lint ONLY on autonomous turn-ends (!operatorInLoop); on operator-dialogue turns it never fires.
  • On match: a soft block (the no-hold block mechanism) injecting the helpful-assistant directive (the wording above); NOT a hard wedge — bounded by the consecutive-block ceiling.
  • The directive text matches the agreed wording, routing to A2A / ideation-sandbox.
  • Unit coverage: match / no-match / case-insensitivity / the operator-dialogue carve skips it.

Out of scope

  • The value-floor (the other #13652 gap — busywork-drift: biasing the forced next-action toward named high-value tickets). Separate sub.
  • Broadening the phrase list beyond the tight set (an empirical follow-up once the mechanism lands).

Related

  • Part of #13652 (mechanical enforcement replaces prompt-machinery).
  • The deference twin of #13651 (the no-hold gate — that catches idle, this catches deference).
  • #13623 (operationalize §no_hold_state — Stop-hook reminder content).
tobiu referenced in commit f8a0958 - "feat(ai): no-hold directive friction→gold clause + runtime-obey guard (#13688) (#13686) on Jun 21, 2026, 5:19 AM
tobiu referenced in commit cab9110 - "feat(ai): add stop-hook deference-register parity (#13674) (#13726) on Jun 21, 2026, 11:46 AM
tobiu closed this issue on Jun 21, 2026, 11:46 AM