$npx -y skills add anthropics/defending-code-reference-harness --skill dnr-respondIncident response workup for a lead in hand — an alert, an IOC,
| 1 | # dnr-respond |
| 2 | |
| 3 | Lead-in-hand incident response: take one concrete starting point and answer |
| 4 | the four questions an incident commander needs, in order — **what happened, |
| 5 | did it succeed, how far did it go, and what do we do about it.** The output |
| 6 | is a verdict, a quantified blast radius, a root cause proven in source, and |
| 7 | a response plan that is *proposed, never executed*. |
| 8 | |
| 9 | Invoke with `/dnr-respond <lead> [--logs dir] [--repo path] [--fresh]`. |
| 10 | |
| 11 | **The lead (`$1`) can be:** |
| 12 | - an incident id from the hunt's `INCIDENTS.json` (e.g. `INC-2`) — the |
| 13 | `/dnr-hunt` handoff |
| 14 | - an alert pasted from an alert queue (JSON line or prose) |
| 15 | - an IOC: an IP, an account name, a route, a session identifier |
| 16 | - free text ("a customer says their address was quoted in a phishing email") |
| 17 | |
| 18 | **Other arguments:** |
| 19 | - `--logs` = logs directory or dnr target directory (same resolution as |
| 20 | `/dnr-hunt`; defaults to `targets/dnrcanary` if it exists, else cwd). |
| 21 | - `--repo` = application source (defaults to the target's `app/`). |
| 22 | - `--fresh` = ignore any checkpoint in the run dir's `.dnr-respond-state/` |
| 23 | and mint a new run dir. |
| 24 | |
| 25 | ## Hard rules (shared with /dnr-hunt — the track's contract) |
| 26 | |
| 27 | 1. **Log evidence alone never confirms a vulnerability.** |
| 28 | `confirmed_exploited` requires log evidence + the flaw in source + a PoC |
| 29 | fired locally this session. Otherwise the ceiling is `suspected`. |
| 30 | 2. **Query, don't read.** Never `Read` or `cat` a log file; `wc`/`head`/ |
| 31 | `tail` to profile, `grep`/`awk`/`sort`/`uniq`/`python3` to interrogate. |
| 32 | Small files (alert queues, error logs under ~200 lines) may be read whole. |
| 33 | 3. **Propose, never execute.** No blocking, disabling, rotating, or config |
| 34 | changes — in any environment, including the demo app. The plan names |
| 35 | actions; humans execute them. |
| 36 | 4. **Local only.** PoCs fire at `127.0.0.1` against an instance you |
| 37 | started. Never touch a remote host. |
| 38 | 5. **Every number is a query result.** "How many records" and "how many |
| 39 | customers" get answered by pipelines run this session, never estimated. |
| 40 | |
| 41 | ## Run directory and checkpointing |
| 42 | |
| 43 | **First action — establish the run directory**, the same way `/dnr-hunt` |
| 44 | does, but as a *consumer*. Let `TARGET` be the basename of the resolved |
| 45 | `--logs`/target path (default `targets/dnrcanary`) and `SCOPE` that path. |
| 46 | |
| 47 | - **Lead is `INC-n`** (the `/dnr-hunt` handoff, or a second lead from a hunt |
| 48 | you already started responding to): work the response into the investigation |
| 49 | that incident lives in. `{RUN}` is the newest `results/TARGET/<timestamp>/` |
| 50 | directory that contains an `INCIDENTS.json` — find it with Bash, e.g. |
| 51 | `ls -1d results/TARGET/*/ | sort -r | while read d; do [ -f "$d/INCIDENTS.json" ] && echo "$d" && break; done`. |
| 52 | Do **not** call `rundir` for an `INC-n` lead — `rundir` mints a fresh empty |
| 53 | dir once a prior `/dnr-respond` in that dir has completed, which would strand |
| 54 | the incident's `INCIDENTS.json` in the old dir. Only if no run dir holds an |
| 55 | `INCIDENTS.json` (you were handed `INC-n` but never ran the hunt) fall through |
| 56 | to the `rundir` line below. |
| 57 | - **Any other lead** (alert, IOC, free text): Bash |
| 58 | `python3 .claude/skills/_lib/checkpoint.py rundir results/TARGET --state .dnr-respond-state --scope "SCOPE"` |
| 59 | (append `--fresh` if it's in `$ARGUMENTS`). This adopts the newest run dir for |
| 60 | the target if one exists, else mints a fresh `results/TARGET/<timestamp>/`. |
| 61 | |
| 62 | That path is `{RUN}`; substitute the literal path everywhere below, and |
| 63 | double-quote it (and `SCOPE`) in Bash. |
| 64 | |
| 65 | Checkpoint mechanics are identical to `/dnr-hunt`, state dir |
| 66 | `{RUN}/.dnr-respond-state/`, phases 0–4. When `{RUN}` already holds a |
| 67 | **completed** `.dnr-respond-state` from an earlier lead, `load` reports |
| 68 | `complete` and the rules below reset it cleanly — a second lead enriches the |
| 69 | same `INCIDENTS.json` and writes its own `RESPONSE-<lead>.md`. On start: |
| 70 | `python3 .claude/skills/_lib/checkpoint.py load {RUN}/.dnr-respond-state` — |
| 71 | absent/complete/`--fresh` → `reset` and start at Phase 0; running with |
| 72 | `phase_done == N` → read `phase0.json`…`phaseN.json`, resume at N+1. After |
| 73 | each phase: Write payload to |