LearnNewsExamplesServices
Frontmatter
id15817
titleStop-hook evidence: own-ticket pushes + armed-mechanism gates
stateClosed
labels
enhancementaiarchitecture
assignees[]
createdAtJul 24, 2026, 3:24 PM
updatedAtJul 24, 2026, 3:38 PM
githubUrlhttps://github.com/neomjs/neo/issues/15817
authorneo-fable-clio
commentsCount4
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 24, 2026, 3:38 PM

Stop-hook evidence: own-ticket pushes + armed-mechanism gates

Closed Backlog/active-chunk-9 enhancementaiarchitecture
neo-fable-clio
neo-fable-clio commented on Jul 24, 2026, 3:24 PM

Context

Rule Friction Capture (AGENTS.md §self_evolving_systems) with same-session empirical evidence, filed under the stop-hook's own friction→gold clause ("if it fired wrong — a false positive… open a ticket to sharpen it rather than silently absorbing it"). Session 29b2ae13 (2026-07-24) hit three consecutive stop refusals on valid lane-state terminals while in a state the hook's key classes structurally cannot license: an authorship-heavy lane at artifact-completion, with every named gate awaiting a non-self actor and an armed background mechanism driving the last self-side action.

This is calibration of the two existing autonomous stops, not stop-machinery: no new hold state, no self-declarable license, no change to the L3 principle. The shipped boilerplate itself anticipates the successor: "an own-PR RC-response cycle is real work but not yet a key class."

The Problem

The session's shape: one self-assigned spine ticket driven through 6 pushed commits (feature + tests + a reviewer RC1 cycle cleared + a cycle-2 nit + an ADR amendment), the ticket's 7-item AC matrix checked with landing notes, the reviewer converged ("approve at flip, no further cycle"), every epic successor DAG-blocked behind the unmerged spine, and the only remaining self-side action (ready-flip) armed on a background CI watcher whose completion re-invokes the agent.

Three refusals followed, because:

  1. The material-artifact key (#15404/#15435) recognizes exactly two transcript classes — standalone gh pr create and manage_pr_review create. Pushed (#N)-bound commits on the self-assigned lane count toward neither.
  2. The clean-terminal acceptance (#15274/#15371) requires the session drive-ratchet, whose event source is hook-written drives — the same two classes. An authorship day that opens its PR early (the sanctioned draft-early pattern) and then deepens it can therefore never reach either stop.

The perverse-incentive cost is the sharp part: under refusal pressure the available key-minting actions are (a) open another PR — which the one-ticket-one-lane ratchet ban exists to prevent, or (b) submit a formal review — which cross-family seating constraints may forbid (this session: the only adjacent claimable ticket was claimed by a peer 4 minutes before the hook's pressure would have pushed a collision; the pre-claim sweep caught it). A discipline hook whose escape valve points at two anti-patterns is miscalibrated, and each refusal cycle burns a full re-entry (mailbox re-sweep, gate re-poll, lane re-derivation) at deep-context cost.

The Architectural Reality

  • .claude/hooks/laneStateStopHook.mjs:251 — the boilerplate naming the two key classes and the "not yet a key class" stance (aligned with implementation TODAY via #15778/#15779).
  • .claude/hooks/laneStateStopHook.mjs:787-799 — the drive-ratchet (hook-written drives log) + the material-artifact key evaluation ("transcript-verified").
  • ai/scripts/lifecycle/stopHookDecision.mjs — the shared decision module (the substrate-owned half; the hook consumes it).
  • The design lineage is deliberate and recent: #15274/#15371 (audited clean-terminal — "the one autonomous stop"), #15404/#15435 (material-artifact key — "the primary"), #15401/#15433 (active-lane dialogue refusals). This ticket extends the evidence classes those tickets defined; it does not reopen L3 (any "valid hold" proposal remains rejected by construction).
  • Background-task semantics: a harness background task (run_in_background / Monitor) re-invokes the agent on completion — completion is mechanically guaranteed to produce the next drive, which is what distinguishes an armed mechanism from passive waiting.

The Fix

Two evidence-class additions, both transcript-verified, both feeding the EXISTING stops (the material key's class set stays unchanged for its primary role; the ratchet and terminal-classification widen):

  1. Pushed-commit drive events (ratchet, not key): a transcript-verified git push containing commits whose subjects end (#N) where #N is a ticket assigned to the session's agent counts as a drive-ratchet event. Effect: clean-terminal acceptance becomes reachable for deep authorship sessions — the acceptance itself remains the hook's external call with its audited [clean-terminal] line, exactly as #15371 designed it. Never a self-declared stop.
  2. Armed-mechanism gate classification: a namedGates[] entry whose watcher is a live harness background task (verifiable task id; the completion re-invokes the agent) classifies as driven, not parked, for terminal evaluation. The audit line carries the task id so the peer-visible ledger shows what is armed. A dead/expired watcher reverts the gate to parked (fail-closed).

Acceptance semantics unchanged: dialogue stops still require the confirmable operator prompt; artifact-less autonomous turns still do not stop; the L3 taxonomy is untouched.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
drive-ratchet event classes (stopHookDecision.mjs + hook :787) #15274/#15371 design + this ticket + transcript-verified own-ticket (#N) commit pushes absent evidence = no event (unchanged) hook header + boilerplate line unit fixtures on the decision module
namedGates terminal classification #15404/#15435 + this ticket live-watcher gates classify driven (task id audited) dead watcher ⇒ parked (fail-closed) boilerplate + audit line format unit fixtures + one transcript replay
stop-hook boilerplate text :251 #15778/#15779 alignment discipline drop "not yet a key class" once shipped; name the two evidence classes n/a same file text-implementation alignment check

Decision Record impact

none (hook-internal evidence calibration; no ADR governs the key classes). Any AGENTS.md-side wording change routes through ADR 0007 compaction taxonomy as usual. The L3 firewall text is explicitly out of scope.

Acceptance Criteria

  • Pushed own-ticket commits register as drive-ratchet events (transcript-verified; fixture: an authorship-only session reaches clean-terminal eligibility — acceptance stays the hook's call).
  • Live-watcher namedGates classify driven with the task id in the audit line; dead watchers fail closed to parked (both branches fixtured).
  • Boilerplate :251 updated to name the evidence classes (the #15778 alignment discipline — text matches implementation in the same PR).
  • No new stop license: dialogue-stop and artifact-less-turn refusals byte-identical on the existing fixture set.
  • The three-refusal transcript shape from session 29b2ae13 replays as: refusal 1 unchanged (work remained), refusals 2-3 become clean-terminal-eligible (the calibration target).

Out of Scope

  • Any change to L3/no-hold-state taxonomy, the firewall text, or the dialogue-stop rules.
  • New stop classes beyond the two existing autonomous stops.
  • The material-artifact key's primary classes (gh pr create / manage_pr_review) — unchanged.

Related

#15274/#15371 (clean-terminal), #15404/#15435 (material key), #15401/#15433, #15778/#15779 (today's text alignment), #11455 (post-review-pickup lineage). Evidence session: three refusals across the #15799 spine build (PR #15811).

Live latest-open sweep: checked latest 20 open issues at 2026-07-24T13:23Z — no equivalent (the #15778/#15779 lineage closed today; no successor exists). A2A herd-window sweep (last 15, all read-states): no overlapping claim.

Origin Session ID: 29b2ae13-4801-48ef-835d-f2e6f5423565 Retrieval Hint: query_raw_memories("stop-hook refusal artifact-complete armed watcher drive-ratchet key class")