Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ Full sourcing notes, including what was left out and why: [docs/provenance.md](d
| `restated-constraint` | User repeats a must/never/don't they already gave: apply it, don't re-acknowledge it. |
| `named-verb-guard` | User said test/repro/run/show/delete/revert/stop, or asked for proof twice: the reply must carry the evidence. |
| `wait-needs-wakeup` | Waiting on CI, a queue, a subagent, or a job: schedule a wakeup and name a clock-time ETA. Blocks foreground poll loops and ETA-less "will report" replies. |
| `hedge-runs-prove-it` | "I think" / "probably" / "should work" / bare `UNVERIFIED:` about code with nothing run this turn: verify now or say why you cannot. |
| `hedge-runs-prove-it` | "I think" / "probably" / "should work" / a retired bare `UNVERIFIED:` about code with nothing run this turn: verify now, or tag the claim and name the blocker. |
| `new-file-callout` | A new untracked file at the repo root or under `scripts/`: the reply must name it and say why. |
| `agent-relay-attribution` | Advisory: facts relayed from a subagent's report must say so or be re-verified. |
| `scratchpad-collision` | Two agents writing the same scratchpad file within ten minutes: use a uniquely named file. |
Expand Down
2 changes: 1 addition & 1 deletion always-on/evidence-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A Grep or name hit is **not** a check.
- Do not cite a file, line, or "the bug is X" until this turn's Read or
command output is in the same message.
- If two files could match, Read both before picking one.
- Prefix `UNVERIFIED:` until you have that evidence.
- Run the check. Only when it cannot run, tag the claim `{{CAT-UNVERIFIED: <claim> -- cannot verify: <reason>}}`; bare `UNVERIFIED:` is retired and excuses nothing.
- "My earlier check was wrong" means the claim went out before the check —
that is a process failure, not a polite recovery. The
`wrong-check-reflect` hook will force `/reflect` when it sees that
Expand Down
2 changes: 1 addition & 1 deletion corpus/CLAUDE.learned.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Engine-only install drops this file; reflect Accepted global rules land here.
- Never accept a dry run as proof of a write path. Dry run proves the decision and never the effect. Guards, permission checks, and connections to a running service fire only on the real write, so a `--dry-run` that lists what it would create (PRs, filed items) says nothing about whether they get created. Prove the write by the artifact it leaves: the PR exists, the row is filed, the tick reports success.
- When a fix changes which identity, binary, or database a process uses, verify the one the *service* resolves, not the one your shell resolves. A login shell's `PATH` can pick a different install (a system `/usr/lib/node_modules` copy versus a user `~/.local/npm-global/bin` copy), and a helper script run from a checkout can open a stale copy of the database instead of the live one. Read the running process's own view — `/proc/<pid>/environ` for its `PATH`, `/proc/<pid>/exe` for its binary, its open files or config for its database — and check that the data is current (newest record, row count) before trusting a query.
- Absence of a field in a projection (CLI, MCP, or API output) is not proof of absent state. Say "not projected" and find the emitter before retrying, resubmitting, or switching agents. A status reason the owner stores but no headless query prints (for example, why a task sits in `needs_input`) is still there; guessing causes and resubmitting cannot change state that was never missing. Read the emitter or the stored record first.
- When delegating a file-finding task to a subagent and two files could plausibly hold the same answer (a duplicate, a moved file, a same-named symbol in two packages), tell the subagent to state whether each file:line claim is "read-confirmed" (it opened the actual reference/import and traced it) or "name-matched" (it assumes the file is the one in use because the name/path looked right). A subagent that reasons by name-proximity instead of tracing the real reference can hand back a confident wrong file — a judgment call about how the subagent qualifies its own confidence, not something a mechanical check can catch. Relay a name-matched citation as `UNVERIFIED:` until a direct Read traces the real reference, because a dead duplicate file matches by name exactly as well as the live one.
- When delegating a file-finding task to a subagent and two files could plausibly hold the same answer (a duplicate, a moved file, a same-named symbol in two packages), tell the subagent to state whether each file:line claim is "read-confirmed" (it opened the actual reference/import and traced it) or "name-matched" (it assumes the file is the one in use because the name/path looked right). A subagent that reasons by name-proximity instead of tracing the real reference can hand back a confident wrong file — a judgment call about how the subagent qualifies its own confidence, not something a mechanical check can catch. Relay a name-matched citation tagged `{{CAT-UNVERIFIED: <claim> -- cannot verify: <reason>}}` until a direct Read traces the real reference, because a dead duplicate file matches by name exactly as well as the live one.
- A `file:line` citation, mine or a subagent's, also names the ref it was read at: working tree, `HEAD`, `origin/<base>`, or the installed bundle. A working-tree read in a checkout with untracked or modified files under the cited path is name-matched, not read-confirmed, until the same line is shown at the ref the change will actually run on. Subagent prompts that ask for read-confirmed vs name-matched must also ask for the ref. Show the line at that ref with `git show <ref>:<path>` or `git grep -n <pattern> <ref> -- <path>`; a feature branch or an untracked copy can hold a line the base branch has already removed or changed.
- When a pipeline switches from test/synthetic inputs to my real inputs, re-derive or explicitly re-validate every artifact built under the old conditions — voice clones, cached device lists, presigned URLs, browser sessions that predate a driver install. State which artifacts were rebuilt and which were kept. An artifact carries the inputs it was built from, so a clone trained on a test recording stays a clone of the test recording; and a process enumerates devices at startup, so a browser started before an audio driver install will not see the new device until it is fully relaunched.

Expand Down
2 changes: 1 addition & 1 deletion docs/hooks-gap-analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Tiers follow the reflect fix hierarchy in
| Class | What the user had to do | Existing cover | Verdict | Cheapest tier |
| --- | --- | --- | --- | --- |
| A. invent-under-prohibition | Told the agent not to fabricate values; it did anyway; escalated to all-caps | none that sees values | **Not a catstack hook.** Whether a number was invented needs the data source; only the product repo can check it. Tier 1 in the product: an export gate that fails any row without a source citation. Catstack covers the *repeat* of the prohibition (class C). | 1 (product) |
| B. done/PASS without proof | Asked "did you run it?" after bare "tests pass" / "fixed" | `diu-stop` (banned openers, causal claims), `prove-it-ship-gate` (live nouns only), `wrong-check-reflect` (after the retraction) | **GAP, built: `named-verb-guard`.** Stop hook. Trigger: the user's last message named test / repro / run / rerun / regenerate / prove / show / delete / revert / a short "stop". Rule: the reply must carry a closed fenced block or `path:line` (URL or table row also count for run / regenerate / show; a delete command this turn for delete / revert; no mutating tool calls for stop). Guards: imperative position only, `UNVERIFIED:` or a question always passes, hook-feedback lines are not the user. Blocking. | 3 |
| B. done/PASS without proof | Asked "did you run it?" after bare "tests pass" / "fixed" | `diu-stop` (banned openers, causal claims), `prove-it-ship-gate` (live nouns only), `wrong-check-reflect` (after the retraction) | **GAP, built: `named-verb-guard`.** Stop hook. Trigger: the user's last message named test / repro / run / rerun / regenerate / prove / show / delete / revert / a short "stop". Rule: the reply must carry a closed fenced block or `path:line` (URL or table row also count for run / regenerate / show; a delete command this turn for delete / revert; no mutating tool calls for stop). Guards: imperative position only, a well-formed `{{CAT-UNVERIFIED}}` tag or a question always passes, hook-feedback lines are not the user. Blocking. | 3 |
| C. restated constraint | Re-typed "stock-agnostic" three times, "one parser per form type", lookback semantics | `frustration-watchdog` (only verbatim re-sends within 10 min) | **GAP, built: `restated-constraint`.** UserPromptSubmit hook. Trigger: prompt carries must / never / always / don't / one-X-per-Y / again / I told you, and an earlier human message shares a hyphenated term, the same constraint clause, or is a near-duplicate. Injects "already named at turn N, FAIL class, apply before replying". Guards: generic hyphen words (`to-do`, `follow-up`) never match; a prompt re-sent 3+ times is a template, not a correction; the transcript's own copy of the current prompt is skipped. Advisory. | 3 |
| D. proof polling | "prove it" / "show me" / "are you sure" repeated (7 times) because rows carried no citation | none | **Folded into `named-verb-guard`.** Second proof demand in a session requires a fenced block, `path:line`, or URL in the reply. Same evidence parser, so one hook instead of two. | 3 |
| E. hook feedback counted as the user | `frustration-watchdog` read `Stop hook feedback:` lines as human turns | `frustration-watchdog` | **Fixed in place.** Hook-feedback prefixes join the injected-line skip list; a verbatim re-send is no longer pushed out of the 8-message window by nine diu blocks. | 3 |
Expand Down
Loading