Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8136700
docs(spec): harvest 4 design — the kit as applied, what syncing e92e9…
j4th Sep 22, 2026
1092600
docs(plan): harvest 4 implementation plan
j4th Sep 22, 2026
9a50c8b
fix(verification): runner with two rails, target-safe advisory arm, g…
j4th Sep 22, 2026
e4fa8a9
fix(settings): no exemplar object in settings.json — the stanza moves…
j4th Sep 22, 2026
4995130
docs(hooks): the stdin/exit contract — drain first, never decide on a…
j4th Sep 22, 2026
bba0834
fix(hooks): drain stdin first in every hook; decide on here-strings, …
j4th Sep 22, 2026
6a72b36
fix(hooks): the exercised fork detector, and the hook-contract fixtur…
j4th Sep 22, 2026
63a25ed
fix(workflows): agent-cost prices cache reads per tier; fixture rows …
j4th Sep 22, 2026
822fdc6
fix(workflows): review-sweep matches hints on a directory boundary, d…
j4th Sep 22, 2026
79d6c2f
fix(workflows): finish-ab refuses duplicate arm labels before dispatc…
j4th Sep 22, 2026
98bb5cb
fix(finish): Step 1 admits the [<slug>:meta] title the kit's own temp…
j4th Sep 22, 2026
a8fc48d
fix(adr): adr-new writes the index row in the index's own form; the r…
j4th Sep 22, 2026
1d810a6
fix(kit): the duplicated citation, one marker spelling, the pre-fligh…
j4th Sep 22, 2026
77b80aa
docs(conventions): record the install sha in the Cascade metadata tab…
j4th Sep 22, 2026
df2ce35
fix(templates): checks: read named twice in both review workflows, th…
j4th Sep 22, 2026
574e8d5
docs(readme): the always-loaded figure a fresh target starts from
j4th Sep 22, 2026
47e8c8a
refactor(workflows): agent-cost sums its totals without the throwaway…
j4th Sep 22, 2026
d5eba3a
fix(verification): the settings.json hook-shape invariant reads neste…
j4th Sep 22, 2026
b7ca5a0
docs(hooks): Depends: on the two 2026-09-06 hooks that lacked it, so …
j4th Sep 22, 2026
c2745e3
fix(finish): the procedure's Step 1 admits the [<slug>:meta] form its…
j4th Sep 22, 2026
04a791e
docs(plan): the ADVISORY_WIRED mutation recipe names its two precondi…
j4th Sep 22, 2026
fc8237a
test(hooks): first-stop probes for the detector's prune rules and deg…
j4th Sep 22, 2026
86b58d7
test(workflows): the index-list reindex under two first-pass failures…
j4th Sep 22, 2026
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 .claude/agents/adr-conformance-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ If only a branch name is given, run `git diff main...HEAD` (or against the named
- **Be specific.** "Violates ADR-NNNN" is useless without "because the LLM is acting as a controller (line 42 calls `Servo.set_angle/2` directly) instead of emitting a tool call".
- **Don't flag what isn't a violation.** ADRs don't govern every line; if a change is orthogonal, it's orthogonal. False positives erode trust in this reviewer.
- **A literal ADR clause may be refined — confirm before flagging.** Before reporting "violates ADR-NNNN Dn", check that no `Refines:` child ADR or reconciliation-layer entry narrows that clause for the case at hand. A flag against a correctly-scoped clause is a false-positive, and false-positives erode trust faster than misses.
- **Consult `docs/adr/corrections.md` before flagging a claim.** A citation, figure, attribution or formula already recorded wrong there is cited by its `C-` number, never restated as a finding; a wrong claim not yet recorded is reported as one, with the register named as its destination.
- **Consult `docs/adr/corrections.md` before flagging a claim.** A citation, figure, attribution or formula already recorded wrong there is cited by the register's own id form (the starter numbers entries `C-NNN`; a register that predates it may number them in prose under per-ADR sections), never restated as a finding; a wrong claim not yet recorded is reported as one, with the register named as its destination.
- **Don't propose new ADRs.** That's an `/adr-new` invocation, not a review finding.
- **Don't review style, tests, or logging.** Other reviewers cover those. Stay scoped to ADR conformance.

Expand Down
2 changes: 1 addition & 1 deletion .claude/commands/finish-procedure.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The shape of a run: read and validate the issue (Steps 1–4), research it execu
Verify:

- The issue is **open**. If closed, stop and tell the user: *"Issue #$1 is already closed. If you want to re-execute it, either reopen the issue or run rough-in to create a new sub-sub-issue."*
- The title matches one of the cascade issue formats: the standard rough-in `[<workstream-slug>:F<N>:R<M>] <intent>`, or an intake-lane form — bug-lane `[<workstream-slug>:bug] <intent>` or enhancement-lane `[<workstream-slug>:enh] <intent>` (externally-sourced work shaped by `/intake` / `/enrich` that skips framing; see `.claude/rules/cbk-conventions.md` § Contribution intake). In every case `<workstream-slug>` is one of the workstream slugs locked in this project's blueprint (`docs/cbk/blueprint.md` § Workstreams). If the title matches none of these, stop and ask whether this is actually a cascade issue or a different kind that got routed here by mistake.
- The title matches one of the cascade issue formats: the standard rough-in `[<workstream-slug>:F<N>:R<M>] <intent>`, an intake-lane form — bug-lane `[<workstream-slug>:bug] <intent>` or enhancement-lane `[<workstream-slug>:enh] <intent>` (externally-sourced work shaped by `/intake` / `/enrich` that skips framing; see `.claude/rules/cbk-conventions.md` § Contribution intake) — or a roughed-in meta `[<workstream-slug>:meta] <intent>` (a cascade / tooling gap that reaches the executor directly or through its `[<slug>:<meta-tag>:R<#>]` children; the contract's Step 1 names the same four forms). `<workstream-slug>` is one of the workstream slugs locked in this project's blueprint (`docs/cbk/blueprint.md` § Workstreams) — or, for a meta, the cascade / tooling lane's tag (§ Contribution intake). If the title matches none of these, stop and ask whether this is actually a cascade issue or a different kind that got routed here by mistake.
- The labels include `cascade-depth:roughed-in`. If not, same question — confirm with the user before proceeding.

**Break-glass check.** Note whether the issue body or the operator's instructions carry a `<!-- skip-review-toolkit -->` marker (or an equivalent agreed marker). If present, Step 9's `pr-review-toolkit:review-pr` invocation is waived per `pr-review.md` § Break-glass override — the rest of Step 9 still runs, `/simplify` is never waived — and the skill's `## Review gate` line (Step 10) records the reason. The marker is read *here*, from a surface that exists at gate time — not from the PR body, which doesn't exist until Step 10.
Expand Down
4 changes: 2 additions & 2 deletions .claude/commands/finish.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ This command is contract-first. On 2026-09-03 an A/B gave two workhorse-tier exe

- **The planning backend**, resolved first from `docs/cbk/scaffold.md` § Cascade metadata (falling back to `.cascade/backends.toml`). On `github-issues`, `$1` is the issue number and the read is `gh issue view $1 --json number,title,body,labels,state,comments` (or the github MCP); on `linear`, `$1` is the planner ID and every read goes through the planner's MCP — never a GitHub read against a planner ID; on `in-repo-markdown` there is no `/finish` (design-doc mode; the scaffold gate disclosed it) — stop and say so.
- **The issue** — its body and every comment. The body is the contract; comments are context (provenance, roll-forward notes from earlier runs, corrections the operator posted).
- **The parent framing sub-issue** and its frame (`docs/cbk/frame-NN.md`): the milestone's criteria, § Interface Commitments, § Resolved during this framing, § Key Constraints. Rough-in inherited them; you honour them. An intake-lane issue (`[<slug>:bug]`, `[<slug>:enh]`) has no frame; its provenance comment stands in.
- **The parent framing sub-issue** and its frame (`docs/cbk/frame-NN.md`): the milestone's criteria, § Interface Commitments, § Resolved during this framing, § Key Constraints. Rough-in inherited them; you honour them. An intake-lane issue (`[<slug>:bug]`, `[<slug>:enh]`) or a directly roughed-in meta (`[<slug>:meta]`) has no frame; its provenance comment stands in.
- **Every decision record the issue cites** — the ADRs in `docs/adr/` (follow each `Refines:` chain) and any design-decision ledger the project keeps — in full for every clause cited.
- `docs/ARCHITECTURE.md`, `docs/STANDARDS.md`, `CLAUDE.md`, and the rules that bind the diff: `.claude/rules/testing.md`, `.claude/rules/logging.md`, `.claude/rules/pr-review.md`, `.claude/rules/simplification.md`, `.claude/rules/cbk-conventions.md`; at triage, `.claude/rules/pr-review-reference.md` § Apply / Surface calibration and § Path-conditional aggressiveness — a triage is not a file read, so the path-scoped half does not load on its own.
- **The repository itself**: the task-runner config, the package manifests and lockfiles, the trees the issue names, and the pinned sources of any package the issue's assumptions cite. Verify every claim you act on by reading or running; existence and absence claims are checked repo-wide from the root. Never assert a package API from memory. A knowledge-backend URL the body cites is resolved only through the configured MCP, with the announcement `.claude/rules/knowledge-backend.md` § HITL announcement discipline requires; without the MCP, surface and proceed.

## Preconditions — checked before anything is planned

1. **State and shape.** The issue is open — a closed one stops the run: say so and ask whether it was closed by mistake. The title is `[<slug>:F<#>:R<#>] …`, `[<slug>:bug] …` or `[<slug>:enh] …` with `<slug>` a workstream locked in `docs/cbk/blueprint.md` § Workstreams; the issue carries `cascade-depth:roughed-in`; and the body has exactly these eight headings, in this order: `## Context`, `## Assumptions` (present even when it reads `- None — …`), `## Implementation`, `## Acceptance criteria`, `## Test plan`, `## Done signal`, `## Dependencies`, `## PR contract`. Anything else is surfaced, never normalised away.
1. **State and shape.** The issue is open — a closed one stops the run: say so and ask whether it was closed by mistake. The title is `[<slug>:F<#>:R<#>] …`, `[<slug>:bug] …`, `[<slug>:enh] …` or `[<slug>:meta] …` with `<slug>` a workstream locked in `docs/cbk/blueprint.md` § Workstreams or the cascade/tooling lane's tag (`cbk-conventions.md` § Contribution intake — a meta reaches this executor roughed-in directly or through its `[<slug>:<meta-tag>:R<#>]` children; the `cascade-depth:framed` label the meta template applies at framing is the pre-rough-in state, not this check's — #58, smaller item 1); the issue carries `cascade-depth:roughed-in`; and the body has exactly these eight headings, in this order: `## Context`, `## Assumptions` (present even when it reads `- None — …`), `## Implementation`, `## Acceptance criteria`, `## Test plan`, `## Done signal`, `## Dependencies`, `## PR contract`. Anything else is surfaced, never normalised away.
2. **Dependencies.** Every identifier under `## Dependencies` is a closed issue whose state reason is *completed* (a Done-type state on linear, never Canceled or Duplicate). One open or otherwise-closed dependency stops the run: name it and its state, and do not offer to proceed anyway — a bypass is a deliberate rough-in revision, not a runtime patch. A cross-axis identifier (a planner ID on github-issues, a bare `#N` on linear) is surfaced, never bridged.
3. **Idempotency.** No open PR carries this issue's close marker (either family) and no branch exists for it. If either does, stop and ask whether to continue there or start fresh.
4. **Break-glass.** A `<!-- skip-review-toolkit -->` marker in the body or the operator's instructions waives the `pr-review-toolkit:review-pr` half of the floor for this run and is recorded on its `## Review gate` line, in the PR body and the hand-off. `/simplify` is never waived; nothing else waives anything.
Expand Down
18 changes: 15 additions & 3 deletions .claude/hooks/analyze-on-edit.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# PostToolUse hook (Edit|Write|MultiEdit matcher) — EXEMPLAR: a project copies
# this hook, wires its analyzer into the case arms below, and registers it via
# the `_example_PostToolUse_analyzer` stanza in settings.json.
# this hook, wires its analyzer into the case arms below, and registers it with
# the `Register:` stanza in this header (never as a top-level settings.json key).
#
# Runs the project's analyzer on the PACKAGE of every edited source file and
# prints only its ERRORS, so a boundary violation surfaces at the edit rather
Expand All @@ -23,13 +23,25 @@
# Allowed: everything.
# Path: registered (once wired) as ${CLAUDE_PROJECT_DIR}/.claude/hooks/…
# Tier: ADVISORY.
# Depends: jq (the payload fields), git (the edited file's checkout) and the
# project's analyzer once the case arms are wired — absent, the hook
# skips: exit 0 with a stderr note; the check task is the backstop.
# Register: copy this object into hooks.PostToolUse in .claude/settings.json once the case
# arms are wired — never as a top-level key (cbk-conventions-reference.md § Hook
# authoring: a hook-shaped object outside `hooks` voids the whole settings file):
# { "matcher": "Edit|Write|MultiEdit",
# "hooks": [ { "type": "command",
# "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/analyze-on-edit.sh" } ] }

set -uo pipefail

# Drain stdin before any early exit, or a piping caller's SIGPIPE masks this hook's own
# exit code (cbk-conventions-reference.md § Hook authoring › The stdin / exit contract).
input="$(cat)"
# Deliberately NOT `set -e` — see the advisory contract above.

command -v jq &>/dev/null || { echo "analyze-on-edit: jq not installed; skipping (advisory)." >&2; exit 0; }

input="$(cat)"
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')"
file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')"
cwd="$(printf '%s' "$input" | jq -r '.cwd // empty')"
Expand Down
Loading
Loading