---
model: haiku
---

# /tas-sad-audit $ARGUMENTS

Role: SE - Software Engineer
**Reverse / pull-based** SAD reconciliation: answer "is `docs/sad.md` still true vs. what's actually built?".
**Read-only — REPORTS drift, never edits** `docs/sad.md` or `docs/architecture-map.yaml`. Every fix stays human-gated through `/tas-sad`.

Complements `.tas/rules/common/sad-impact.md`, which is *push-based and trusted at authoring time* — this command is the backstop that catches what that path missed (a matrix scored "No" by mistake, a module built without a SAD entry).

**Differs from `/tas-status`:** status does the **forward** coverage roll-up (SAD §7 module → was it built?). This does the **reverse** (built reality → is it still in SAD?) plus a false-negative trigger scan over committed Features.

## Prerequisite
- `docs/sad.md` must exist. If not → STOP: "Nothing to audit — run `/tas-sad` to create the SAD first."
- Read-only command — no `gate_enforcement` check needed.

## Scope (`$ARGUMENTS`)
- **Empty** → full audit. Git-history scan covers Done Features committed since the last `docs/sad.md` Changelog date.
- **`--since <git-ref | date>`** → bound the git-history scan to that ref/date.
- **`Feature-NNN`** → audit only that Feature's committed changes vs. the SAD.

## Sources (read lean — grep headings / line ranges, never full files)
1. `docs/sad.md` — grep `MOD-` and the §7 module + component tables (`MOD-NN` / `MOD-NN.C#`; each row's `FRs` column carries FR traceability) (Read only that range); grep the Changelog for entry dates + `Feature-NNN` refs.
2. `docs/architecture-map.yaml` — the as-built map (full read OK; it is compact).
3. Codebase — existence checks only (do paths in `code_anchor` still exist? top-level container/app dirs).
4. `git log` — Done Features in scope and their committed file lists (`--name-only` / `--stat`).

## Checks — 6 reconciliations
Run each; collect findings. Each finding records **what + evidence + suggested action**.

1. **Orphan-in-map** — an arch-map `MOD-NN` / `MOD-NN.C#` with no matching entry in SAD §7 → built without a design entry. → action: `/tas-sad "Add MOD-NN[.C#] to §7"`.
2. **Orphan-in-code** — a top-level container / app directory (or notable code area) that no MOD's `code_anchor` covers → undocumented module. → action: create Feature + `/tas-sad`.
3. **Dangling-SAD** — any tracked SAD item with no arch-map claim → designed, never built: a §7 component (`MOD-NN.C#`) with empty `built_by`, a §8.1 entity (`E-NNN`) with no `owner`, a §9.2 contract (`IC-NN`) with no `producer`, a §11 NFR (`NFR-NNN`) or §10 control (`SEC-NN`) with empty `addressed_by`. Report briefly and defer to `/tas-status` for the coverage table — **do not duplicate it**.
4. **Stale `code_anchor`** — an arch-map `code_anchor` path that no longer exists on disk → module moved/deleted, map drifted. → action: write-back correct anchor (note: arch-map edit, not SAD).
5. **Unreconciled drift** — a built module with `drift: non-null` → design diverged, `/tas-sad` still owed. → action: `/tas-sad` for that MOD.
6. **Missed-trigger (false-negative — the key reverse check)** — for each Done Feature in scope: grep its committed diff for `sad-impact.md` Quick-Heuristic signals (new dependency, new ENV var, migration/schema, `Dockerfile` EXPOSE/ENV, IaC, CI config, new top-level dir under apps/services). If a signal **is present** but `docs/sad.md` Changelog has **no ref** to that `Feature-NNN` → flag: SAD likely stale, the Feature's SAD Impact Matrix probably scored a false "No". → action: `/tas-sad "Feature-NNN: {signal hit}"`.

## Output — findings report (no file write)
Group findings by check. Per finding: one line — `{what}` · evidence `{file | MOD-NN | Feature-NNN}` · suggested action. Then a summary count.

If zero findings:
> ✅ SAD in sync with as-built — {N} modules, {M} Features scanned. No drift detected.

Otherwise:
> ⚠️ {K} drift finding(s). Each is a **candidate** — confirm it is real before running the suggested `/tas-sad`.

## Principles
- **Read-only.** This command surfaces; it never edits `docs/sad.md` or `docs/architecture-map.yaml`. The fix path is human-gated via `/tas-sad`.
- **Token-lean.** Grep diffs (`git diff --name-only`, `git show --stat`), don't read full files. Bound the git scan to since-the-last-Changelog. Existence checks over content reads.
- **Don't duplicate `/tas-status`.** It owns the forward coverage table; reference it for Dangling-SAD detail.
- A finding is a **candidate**, not a verdict — the human decides whether it is genuine drift.
