# Surface tracked corrections

> When a session ends on a durable correction in the user's own words, point them at `capt-hook status` so the session reviewer can mine it into a hook PR.

You keep correcting Claude on the same rule -- "never force-push", "use `uv`, not `pip`" -- and writing the hook by hand is friction you skip in the moment. The [session reviewer](../../docs/guide/session-reviewer.md) already mines those corrections into hook PRs. The nudge below scores the last few transcript messages for that correction shape and, when one clears the threshold, points you at `uvx capt-hook status` so you can watch the lifecycle instead of hand-writing the hook.

``` python
"""Nudge toward the corrections lifecycle when a session ends on a durable correction."""

from __future__ import annotations

import re

from captain_hook import Allow, Event, Input, Signal, Signals, T, Warn, nudge

CORRECTION_SIGNALS = Signals(
    patterns=[
        Signal(pattern=r"\bnever\b", weight=2, flags=re.IGNORECASE),
        Signal(pattern=r"\b(always|from now on)\b", weight=2, flags=re.IGNORECASE),
        Signal(pattern=r"\b(use|prefer)\b.+\b(not|instead of)\b", weight=2, flags=re.IGNORECASE),
        Signal(pattern=r"\b(stop|don'?t)\b", weight=1, flags=re.IGNORECASE),
        Signal(pattern=r"\b(no,|actually,|that'?s wrong|i told you)\b", weight=1, flags=re.IGNORECASE),
    ],
    threshold=3,
    window=6,
    origin="any",
)


nudge(
    "You just took a durable correction from the user. You don't have to hand-write the hook: "
    "captain-hook's session reviewer is already mining corrections like this one. Run "
    "`uvx capt-hook status` to watch it climb toward a hook pull request.",
    signals=CORRECTION_SIGNALS,
    events=Event.Stop,
    max_fires=1,
    tests={
        Input(transcript=[T.user("No -- never force-push to main, always open a pull request.")]): Warn(
            pattern="capt-hook status"
        ),
        Input(transcript=[T.user("Looks good to me, ship it.")]): Allow(),
    },
)
```


# What it catches

``` python
"No -- never force-push to main, always open a pull request."  # stacks "No --", "never", and "always" past threshold=3
```


# What it allows

``` python
"Looks good to me, ship it."  # plain approval, no correction signals
```

*The catch / allow split mirrors the hook inline `tests`, so it stays true as the hook evolves.*


# Run it yourself

``` bash
uvx capt-hook --hooks docs/examples test
```


# See also

- [Signals guide](../../docs/guide/llm-hooks.md#score-patterns-with-signals)
- [Primitives guide](../../docs/guide/primitives.md)
- [Corrections lifecycle](../../docs/guide/session-reviewer.md)
