A hook on a runtime lifecycle event so an operator's omitted step can't be forgotten.

Lifecycle hooks (interpose on the agent runtime's events)

Intent — Bind a script to the agent runtime's lifecycle events (turn-stop, pre-compaction, session-start, before-a-tool-call) so a step the operator keeps omitting at runtime fires deterministically, whether or not anyone remembered it.

SummaryA hook on a runtime lifecycle event so an operator's omitted step can't be forgotten.
TargetAgent · Lifecycle & observability
Formquality-gate
EnforcementSoft·Hard — the firing is hard (the runtime guarantees the hook runs at the event); the payload is either a hard block that denies the action or soft guidance injected back into the agent's context

Motivation — the failure it kills

Some recurring failures live not in the code an agent writes but in the loop that drives it: the operator (a human, or an orchestrator agent) skipping a step at a predictable moment. Ending a turn with ratified work still queued. Compacting context without first writing a hand-off. Opening a session without reading the alert backlog. Editing outside the sanctioned worktree. A lint can't reach these: there is no source artifact to analyze, and the omission happens at runtime, in the loop itself. A house-rule ("remember to…") only aims a probabilistic operator, and it rots, because the step gets skipped exactly when attention is thin. The failure recurs every session.

Why it's not just "a house-rule in the governance doc"

A governance-doc rule depends on the operator recalling it at the right moment, which is precisely what fails under load. A lifecycle hook removes the recall: the runtime fires it on a named event, so the check runs whether or not anyone remembered. It splits the two halves of enforcement that a lint fuses. The firing is hard, guaranteed by the runtime, impossible to forget. The payload is either: a hard block that denies the action (a pre-edit guard refusing a write outside the worktree), or soft guidance injected back into the agent's own context (a turn-stop hook that re-states "work still queued" and leaves the agent to judge). The reflex case (hard delivery of soft guidance) is the one to understand: it does not swap judgment for machinery, it makes the aiming deterministic. The same guidance the house-rule offered, fired exactly at the decision point, every time.

Mechanism

The runtime exposes named lifecycle events and a surface to register scripts against them. A hook is a script bound to one event; the runtime invokes it at that moment and reads its result. A blocking hook returns a veto and the action is denied. A guidance hook returns text that is re-injected into the agent's context, aiming the next decision without compelling it. The event fires regardless of the operator's state of mind, so the two design constraints are: keep the check cheap (it runs on every occurrence of the event), and make a guidance hook fail-open (a crash must not wedge the loop; reserve fail-closed for the deliberate blocking case).

A hook's output is a typed contract with the runtime, not free text. The runtime accepts one specific shape and silently drops anything else. Validate a hook's output against the runtime's actual schema, never against the hook's self-declared idea of the contract: a hook checked only against its own shape can emit a form the runtime rejects, pass its own test green, and be dropped on every fire in production, the worst fail-open, since it looks wired and does nothing. A build-time conformance check over every wired hook (output validated against the real runtime schema) kills that class.

A runtime lifecycle event is the rung an operator-loop omission belongs on: it is the only scope where the loop's state is visible, so a syntactic commit hook asking the same question sits below the semantics it must judge and leaves a gap it cannot bridge. Which rung a mechanism belongs on is the general placement question — see semantic-level-enforcement.

Prerequisites

Consequences & costs

The measured leash — a soft payload must instrument its own firing

A hard block is self-evident: the action it denies doesn't happen, and the failure it prevents stops recurring; the absence is the signal. A soft payload has no such tell, and it dies two silent ways. It stops firing (a wiring change, a stuck dedupe flag) and no one notices the reminder went missing. Or it fires so often the operator learns to tune it out, and it becomes the tower-of-governance it was meant to prevent. Neither failure shows in the code or the runtime.

So a soft hook ships its own firing telemetry: one record per fire with a session key, a query over the log, and a yield check that correlates each firing against the thing it was meant to provoke. Did a nudge to convert a recurrence into a mechanism actually precede one? The hook then lives on a measured leash, an evaluation plan with a written pull condition: if it over-fires, or shows near-zero yield across many sessions, you pull it. You cannot manage a probabilistic mechanism you cannot watch fire. And the payload itself biases hard toward silence ("usually a no-op; a false nudge is worse than a missed one") because for a soft reminder the default outcome must be doing nothing, or the fatigue sets in before the telemetry can catch it. Instrumentation is what separates a soft mechanism that is working quietly from one that is silently dead; without it the two look identical.

The failure sharpens as reflection facets accrue. Once you want the operator to reflect on more than one policy (convert-a-recurrence and spot-a-second-copy and a stale runbook), firing each as its own hook is the alarm-fatigue trap by another door: N soft nudges a turn compound into the noise each was biased to avoid. Consolidate them into a single tempo-gated reflection that rotates or batches the facets, so the operator gets one paced prompt rather than a chorus. Each facet stays default-silent, the substrate paced so the whole never overwhelms.

Known uses

Related mechanisms