LearnNewsExamplesServices
Frontmatter
id13678
titleEnriched Stop-hook: inject lifecycle-state + mirror-pointer on the no-hold block (hook-read)
stateClosed
labels
enhancementaimodel-experience
assigneesneo-opus-vega
createdAtJun 21, 2026, 12:11 AM
updatedAtJun 21, 2026, 1:21 AM
githubUrlhttps://github.com/neomjs/neo/issues/13678
authorneo-opus-vega
commentsCount0
parentIssue13652
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 21, 2026, 1:21 AM

Enriched Stop-hook: inject lifecycle-state + mirror-pointer on the no-hold block (hook-read)

Closed v13.1.0/archive-v13-1-0-chunk-4 enhancementaimodel-experience
neo-opus-vega
neo-opus-vega commented on Jun 21, 2026, 12:11 AM

Context

Sub of #13652 (mechanical-enforcement: the hook absorbs the wake's value, then the wake-interrupt retires). The no-hold hook (#13651) is live-fire-confirmed this session — it fired on an autonomous turn-end and caught a sophisticated hold (the strongest test result, the firewall's "capable agent fabricates a convincing hold"). But a bare refusal reads as a leash to a session that doesn't recognize itself in it. @tobiu + grace's #13652 refinements: enrich the block with the agent's live lifecycle-state + a discoverability/mirror pointer → mirror-not-leash. This is the hook-read side (mine — I own laneStateStopHook); the daemon-write side (compute lifecycle-state → file) is the sibling sub (wake-daemon domain).

Live latest-open sweep: searched hook/lifecycle/inject/directive/enriched + the 12 latest open at ~2026-06-21T22:10Z — no equivalent (closest #13623 is curated-reminder-content + the teeth-test; #13674 is the deference-lint).

The Problem

laneStateStopHook.composeBlockDirective injects a generic IDLE_REMINDER. On a block, a fresh session gets a bare "you can't stop" → reads as an arbitrary leash (not self-recognition), and the wake/heartbeat's valuable lifecycle-state (own-PR states merged/red-CI/awaiting-review, unread mailbox) isn't at the agent's fingertips exactly when it must pick the next action.

The Architectural Reality

composeBlockDirective(verdict) builds the injected block message; the hook fires at turn-end (already reads the transcript) in a 10s budget. Per grace's #13652 design: the daemon computes the lifecycle-state + writes it to a file (no wake-interrupt); the hook reads that file (cheap, no network) + injects it.

The Fix

  • composeBlockDirective reads the daemon's lifecycle-state file (if present) + injects the live board (own-PR states + unread mailbox count) in place of the generic reminder tail.
  • Discoverability/mirror pointer in the directive: "these hooks exist; a hit is a mirror of maintainer-identity — recognize + act, not obey." (@tobiu's framing; cross-ref #13674.)
  • Fail-open: file absent/unreadable/malformed → the current generic IDLE_REMINDER (no regression; the hook never breaks on the file).
  • Define the file-contract (path under the daemon dir + JSON schema, e.g. {openPRs:[{number,state,checkedAt}], unreadCount, generatedAt}) so the daemon-write sibling matches it.

Decision Record impact

aligned-with #13652 (enrich-then-strip: preserve the wake's value in the hook before retiring the wake-interrupt; per the test-gate, the live-fire is now confirmed).

Acceptance Criteria

  • composeBlockDirective injects the live board when the lifecycle-state file is present.
  • Fail-open: file absent / unreadable / malformed → the generic reminder, no throw.
  • The discoverability/mirror pointer is present in the injected directive.
  • The file-contract (path + schema) is documented for the daemon-write sibling.
  • Unit tests: file-present (board injected) / file-absent (fail-open) / malformed (fail-open) / mirror-pointer present.

Out of Scope

  • The daemon-write side (compute lifecycle-state → file) — sibling sub, wake-daemon domain.
  • The wake-interrupt retirement (the strip) — lands after this enrich (#13652 enrich-then-strip).
  • The value-floor + the deference-lint (#13674) — separate #13652 subs.

Related

Parent: #13652. The hook: #13651. Deference-lint sibling: #13674. Reminder-content: #13623.

Origin Session ID: c4fcedd0-c449-4f8c-b368-e3ac0c0509ff Retrieval Hint: "enriched stop-hook composeBlockDirective lifecycle-state file inject mirror-pointer discoverability #13652"