# /execute change-impact checklist — post-impl-checklist phase

**Contract: v0.x soft — may change before v1.0.** This phase surfaces
targeted QA checks based on which files changed, so the pre-commit
cabinet sweep (Checkpoint 3) knows which dimensions matter for *these*
changes rather than reviewing a diff blind.

It ships with the `planning` module but stays completely silent until
the project opts in by creating `.claude/cabinet/qa-dimensions.yaml`.

## When this phase runs

Position: after the file-group implementation loop, before the
pre-commit cabinet sweep (Checkpoint 3). The order matters — the
checklist becomes pre-context for the sweep, so QA and other members
see the targeted checks *while* they review the full diff.

## No-op guard (checked first)

This phase emits nothing and writes nothing unless the project has
opted in:

```bash
test -f .claude/cabinet/qa-dimensions.yaml
```

If the file is **absent**, skip silently — no warning, no log line.
Absence is the normal state for projects that haven't opted in.

If the file is **present but malformed** (not valid YAML, missing the
top-level `dimensions:` map, or `dimensions:` is empty/null), do NOT
skip silently. Emit a loud one-line warning and stop the phase:

> ⚠ post-impl-checklist: `.claude/cabinet/qa-dimensions.yaml` exists but
> could not be parsed (<reason>). Fix the file or remove it. Skipping
> the checklist for this run.

The distinction is deliberate: absent = intentional opt-out; malformed =
a configuration error the operator needs to know about.

## How to run the checklist

### 1. Read the changed files

```bash
{ git diff HEAD --name-only; git ls-files --others --exclude-standard; } | sort -u
```

This captures both modified tracked files and brand-new untracked files.
The phase runs before the commit step, so all of this plan's changes
are still uncommitted and will appear here.

If the result is **empty** (zero files changed vs HEAD), emit the
trace line from step 4 with a count of 0 and stop — there is nothing
to match.

### 2. Match paths against dimensions

Read `.claude/cabinet/qa-dimensions.yaml`. For each dimension, test
every changed path against the dimension's `paths` globs. A dimension
is **triggered** if at least one changed path matches at least one of
its globs.

Apply these canonical glob rules (the template documents them too, so
config authors and this phase agree):

- Strip a leading `./` from both the pattern and the path before
  matching. Diff paths are repo-relative with no `./`.
- `*` matches within ONE segment (no `/`). `src/api/*` matches
  `src/api/foo.js` but not `src/api/v2/foo.js`.
- `**` matches across segments. `src/api/**` matches both.
- A trailing `/` means "directory and below": `src/api/` is treated
  as `src/api/**`.
- A bare extension glob like `*.md` is unrooted — it matches that
  extension at any depth. For root-only, use an explicit prefix:
  `README.md` or `docs/*.md` instead of bare `*.md`.

A single changed path may match multiple dimensions — that is expected.
Include the path's checks under every dimension it triggers; do not
deduplicate dimensions.

### 3. Collect and order the checks

For each triggered dimension, collect its `checks`. Order the output
by `severity`: `high` first, then `moderate`, then `info`.

**Cap:** if more than 10 dimensions trigger (large diff), surface the
10 highest-severity ones. Within the same severity, prefer dimensions
with more matching files (broader impact = higher priority). Append a
line noting how many more were triggered but not shown. Never silently
drop — say what was omitted.

### 4. Emit the checklist as pre-context for Checkpoint 3

Once past the no-op guard (the yaml exists and parsed), always emit a
one-line trace so the reader can distinguish the remaining states
(no dimensions matched vs. empty diff):

> post-impl-checklist: N files changed, M dimensions triggered.

When M > 0, follow the trace with a clearly labeled section. This
section becomes part of the context handed to the Checkpoint 3 cabinet
sweep — include it verbatim in each CP3 agent's prompt, with QA as the
primary consumer:

```
## Change-Impact Checklist

### data-coherence (severity: high)
- [run] Run schema validation if any schema or migration file changed.
- [review] Verify referential integrity for any new foreign keys.

### knowledge-layer (severity: moderate)
- [review] If user-facing behavior or vocabulary changed, check whether app-guide.md needs updating.
```

Render `[run]` and `[review]` tags exactly as written. They mean:

- `[run]` — a check the reviewer should actively execute (a command,
  a grep, a test). Not "already automated" — it means "run this now."
- `[review]` — a check requiring human or cabinet judgment.

### 5. Record fires to the stats sidecar

After the trace line (whether M is 0 or not), update
`.claude/cabinet/checklist-stats.json` following the write protocol in
`cabinet/checklist-stats-schema.md`:

- increment `runs` by 1 (every run past the no-op guard counts — runs
  with zero triggered dimensions are the denominator that makes
  "never fires" meaningful)
- for each triggered dimension: increment `dimensions.<name>.fires`
  and set `last_fired` to today

Bootstrap the skeleton if the file is absent; write temp + rename.
**Fail-open:** a stats failure never blocks the checklist or the CP3
sweep — emit one warning line and continue. This sidecar is what lets
the audit skill's `checklist-pruning` phase argue, with evidence, that
a dimension has earned removal.

## Relationship to the breadcrumb

This phase is advisory context for the sweep — it does not write to the
verification breadcrumb and does not gate completion on its own. The
checks it surfaces are verified through the normal Checkpoint 3 sweep
and the QA gate. If a surfaced `[run]` check fails during the
sweep, that failure flows through the existing AC/breadcrumb path, not
through this phase.

## Feedback loop

When a bug slips through despite (or because of a gap in) the checklist,
the `/debrief` `checklist-feedback` phase proposes sharpening or adding
a dimension. That is the reactive complement to this phase — keep the
two consistent if you edit either.
