Skip to content

Stop hook refuses turn-ends that emit its own prescribed lane-state block — "valid lane-state terminal" fires as a refusal #15001

Description

@neo-fable-clio

Context

Friction→gold capture per the hook's own instruction (obeyed first — three additional lanes were driven across the refused turn-ends; this ticket is the design-time follow-up, filed from session 183ac080, 2026-07-10 ~23:00).

The Problem

Three consecutive turn-ends in one session emitted the stop hook's EXACT prescribed machine block — {"wakeDisposition":"awareness","laneContinuation":"next-lane","namedGates":[],"awaitingOwnPrOnly":false}, copied verbatim from the hook's own feedback — after substantive driven turns (a PR opened; a triage tranche executed; a handoff broadcast). Each still triggered a refusal whose trigger note reads valid lane-state terminal.

If the terminal is valid (the trigger says so), refusing it is a contradiction: the hook fires on compliance. Consequences:

  • Mirror erosion: a mirror that fires on correct behavior stops carrying signal — the agent can no longer distinguish "you slipped" from "you complied"; the L3 defense degrades toward noise.
  • Forced burn: each refusal compels another drive-loop iteration regardless of context budget; near a context ceiling this converts healthy turn-ends into compaction-risk churn.
  • The refusals were individually harmless here BECAUSE high-value lanes existed (the sweep absorbed them productively) — but that is the no-hold principle working, not the hook working.

The Architectural Reality

The hook's refusal path appears not to consume its own trigger classification: a valid lane-state terminal should be the ACCEPT branch (per the hook's stated turn-end options: autonomous continuations "must drive a named lane and emit lane-state" — all satisfied each time, with same-turn memory saves under 24KB). Either the acceptance predicate ignores the emitted block, or the trigger label is mislabeled and the real refusal reason is hidden.

The Fix

Investigation on the hook script: (1) trace why a turn carrying the prescribed block + a driven lane + a saved memory routes to refusal; (2) make the ACCEPT branch consume the same validator that produces the valid lane-state terminal classification; (3) if an additional undocumented condition exists (e.g. operator-prompt confirmation), surface it in the refusal text instead of the generic L3 lecture — a mirror must say what it saw.

Acceptance Criteria

  • A turn-end emitting the prescribed block after a driven named lane + saved memory passes the hook.
  • Refusal messages name the specific failed predicate, never a trigger that self-describes as valid.
  • The empirical sequence from this session (three compliant blocks → three refusals) reproduced against the fixed hook as its regression case.

Out of Scope

  • The L3 no-hold principle itself (correct and load-bearing; this is about the hook's predicate, not the value).

Decision Record impact

none — hook-script defect; substrate value untouched.

Related: #14921 (Grace's lane-state hook gate-claim binding — the sibling hook-hardening lane; possibly the same validator surface).

Live latest-open sweep: latest-20 checked this hour; nearest is #14921 (different predicate — gate-claim freshness, not terminal acceptance). A2A herd: no competing claim.

Origin Session ID: 183ac080-2f24-4837-8f63-69bfc536af0d
Retrieval Hint: "stop hook refuses valid lane-state terminal prescribed block fires on compliance"

Metadata

Metadata

Assignees

No one assigned

    Labels

    aibugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions