impact · git:20260927.57eb1e4 · 2026-09-27 · sha256 f6fa890a3be43bab
impact git:20260927.57eb1e4A
Immutable. This exact content never changes and is served at /api/v1/blob/f6fa890a3be43bab.
--- name: impact description: "Classifies a change proposal before any code — architecture (ADR, boundary, stack, contract, data model, dependency, deployment), security (threat-model surface, security-sensitive path, auth, PII, secrets, CI permissions) or product scope — from the artifacts it touches, gets a short verdict from the owner of each triggered class (technical-director, security-lead, product-director) and hands off to the commands the verdict requires. Use when the user proposes a change outside the current story, before /dev-story picks it up, or whenever a change 'might touch architecture or security'." argument-hint: "<the proposal in the user's words> [--classify-only]" user-invocable: true allowed-tools: Read, Glob, Grep, Bash, Edit, Task, AskUserQuestion --- # Impact Language, `<hooks>`, agent and command namespaces, gate mechanics, the documents-lane commit gate and the consent marker: `docs/coordination-rules.md` § Skill conventions (verifiers: § Subagents). Triage, not review: the skill decides **who** must look at a proposal and **what runs next**, in minutes (rule 11; review-workflow.md § Change classes). It produces no document (rule 9: an ADR, threat-model surface, contract or story comes from its own command and gate). It writes only: a dated `Notes:` line via the state writer, no question needed (Phase 4 step 4); a findings/backlog row behind the Phase 4 step 3 gates; the `.claude/.impact-verdict` marker on approval (step 6); `Next:` on the user's pick (closing block). `--classify-only`, a `ROUTINE` run and a `solo` skip write nothing: no note, no marker, no row. ## Phase 1: Proposal and scope 1. **The proposal verbatim**: the argument, else the user's last message; quote it back. 2. **Read** the active story `production/session-state/active.md` names (`<story>`; its file is `production/stories/F-NNN/S-NNN-*.md`), its acceptance criteria and the review mode (`production/review-mode.txt`). 3. **Inside the active story.** A proposal fully inside `<story>`'s criteria is `ROUTINE`: one line, no verifier (the story already approved it), and the run ends with the text line `Next step: /dev-story <story>` (namespaced) instead of the closing question. 4. **Trivial change.** A comment, typo, formatting, log message or docstring text with no behavioural change is `ROUTINE` too, whatever path it touches: one line, no classification table, no verifier, the same ending (`Next step: proceed` with no active story). The `security-sensitive` review-before-merge applies to the PR, not to triage. ## Phase 2: Classification from evidence 1. **Grep, do not guess.** Every class is claimed only with the artifact or path it touches: - **architecture** — an accepted ADR names or contradicts it (`docs/architecture/adr-*.md`, `production/decisions.md`); a system boundary or module ownership moves; the stack or a pinned version in `technical-preferences.md`; the API contract (`schema.graphql`, `openapi.*`); the data model or a migration; a new runtime dependency (manifest); the deployment topology (Dockerfile, compose, workflows). - **security** — a surface in `docs/architecture/threat-model.md`; a path matching the globs of `.claude/rules/security-sensitive.md`; authentication, sessions, authorisation; PII, secrets, tokens; CI permissions; network, proxy, TLS; uploads, webhooks, WebSocket. - **product** — user-visible behaviour absent from the feature spec; a changed acceptance criterion; scope the product spec lists as out. - **routine** — none of the above: a change inside existing decisions and surfaces. 2. **Render the table** (class · trigger · evidence) in the chat before anything else happens (rule 7). 3. **`--classify-only`**: stop after the table with the verdict `CLASSIFIED (<classes>)` and go to the closing question — no Phase 3, no `Task`, nothing written (no note, no marker, no row): a classification is not a verdict, so the impact-guard keeps warning until a verifier approves (absent a marker still fresh, Phase 4 step 6). ## Phase 3: Verification by the class owner 1. **Review mode scopes the step** (review-workflow.md): - `full` — every triggered class. - `lean` — architecture and security; a triggered product class stays classification only unless the pre-spawn `AskUserQuestion` — verify architecture and security (Recommended) · product too — adds it. - `solo` — the classification is shown; before any spawn, one `AskUserQuestion`: verify (Recommended) · skip, which ends like `--classify-only`: `CLASSIFIED (<classes>)`, no note, no marker, the closing question. 2. **Spawn** the triggered classes in scope in one parallel `Task` batch: architecture → `technical-director`, security → `security-lead`, product → `product-director`. 3. **The brief per verifier**: the template in `references/verifier-brief.md` (the proposal, the class's evidence rows, the artifacts to read by path, the review mode, the contract quoted verbatim). 4. **The verifier's contract** — four blocks, at most 15 lines, nothing else: `Verdict:` (`APPROVED` · `APPROVED WITH CONDITIONS (…)` · `NEEDS ADR` · `BLOCKED (reason)`) · `Why:` (≤ 2 lines) · `Artifacts:` (those that must change) · `Commands:` (numbered, pipeline order); no observations, background or file lists. 5. **Check each reply.** No commands, or over 15 lines: back once with the four blocks quoted; a second miss is reported as incomplete, never padded or trimmed by the skill. 6. **`BLOCKED`** from any verifier is surfaced immediately, with the reason. ## Phase 4: Decision and hand-off 1. **One table**: verifier · verdict · artifacts to change · commands, in pipeline order: `/architecture-decision` → `/threat-model` → `/api-contract` / `/data-model` → `/feature-spec` / `/create-stories` → `/dev-story`. 2. **Measurements.** A verdict resting on a measurement names its file (`docs/ops/measurements/…`, rule 12), never a number from memory in `Notes:`. 3. **Records the verdict creates** — only when a verdict names a finding ID (`ARCH-004`, `SEC-002` → its row in `production/findings.md`, same turn, or the ID has no authority) or the proposal came from `production/backlog.md` (`I-NNN` in the argument or a matching entry → one line: date, verdict, next command, or the idea returns). Read `references/records.md`, then: 1. Show the row/line; one `AskUserQuestion`: "May I write <the row in `production/findings.md` / the line in `production/backlog.md`>?" — write (Recommended) · show the draft/diff first · not now; after "write" `touch .claude/.write-consent`, then `Edit`. 2. Record the commit gate: `<hooks>session-state.sh set Gate "/impact Phase 4: commit <ID>?"`. 3. Ask, one `AskUserQuestion`: `docs: impact <ID> — <verdict>` (a backlog line: `docs: backlog I-NNN — impact verdict`), staging exactly the written file(s). 4. Branch per § Documents-lane commit gate: `<default>` when no story work is in progress; a story-branch HEAD (usual: the triage interrupted `/dev-story`) is named, offering switch to `<default>` (Recommended: the document is pipeline-wide) · commit here · leave uncommitted. 5. On "switch": `git switch <default> && git pull --ff-only origin <default>`, the commit, `git switch <story branch>` back, so the interrupted story continues on its branch. 6. Clear the gate: `<hooks>session-state.sh set Gate "—"`. Nothing is committed without the answer; code or configs never ride the `docs:` commit. 4. **Session note**: `<hooks>session-state.sh note "impact: <proposal> → <verdicts>; next: <commands>"` (dated; the writer keeps ten, archives older ones to `production/session-state/archive/`, and refuses a file not in its format — then `<hooks>session-state.sh migrate` once, which archives the previous file, or add the line by hand). 5. **Never write `Next:` yourself**: a triage is usually a detour, and a detour never overwrites the interrupted intent (rule 7); the required commands go into the note and the closing question. 6. **Marker**, only on an approving verdict: `touch .claude/.impact-verdict` when every verifier in scope answered `APPROVED` or `APPROVED WITH CONDITIONS` (read by the warn-only impact-guard on architecture/security paths). Never after `BLOCKED` (it would silence the guard for the rejected change) nor `NEEDS ADR` (the ADR and its story earn it: `/dev-story` touches it at story start); `CLASSIFIED` and `ROUTINE` end earlier. An existing marker is never removed and counts as fresh for four hours, so the guard may stay silent during a running story even after `BLOCKED`: it nudges to classify; the rejection lives in the note and the closing question. Verdict: `ROUTINE` | `CLASSIFIED (…)` | `APPROVED` | `APPROVED WITH CONDITIONS` | `NEEDS ADR` | `BLOCKED`. Next step — one `AskUserQuestion`: the first command the verdicts require (Recommended) · show the verifiers' full replies · stop here; on `BLOCKED`: revise the proposal (Recommended) · record the rejection as an ADR (`/architecture-decision`) · stop here. On a command pick: `<hooks>session-state.sh set Next "<command>"` — that choice makes it the task.