# ADR-107: `/mdd-reverse` ADR Verification Is an Active Per-Pattern Checklist, Not a Passive Citation Instruction — And Its Exemplars Must Model That

## Status

Accepted, 2026-07-03 (skill fix applied and empirically validated same day).

## Status History

```yaml
status_history:
  - date: 2026-07-03
    status: Proposed
    changed_by: RESEARCH session (hkl requested root-cause + fix + verification)
    reason: |
      2026-07-03 MDD sweep produced 16/29 MDDs with zero ADR citations despite the
      skill instructing "cite governing ADRs inline". Root-caused, fixed, and
      blind-validated same day (fresh agent independently reproduced a known
      violation using only the updated instructions).
    changed_via: manual (adr-kit conventions followed by hand)
  - date: 2026-07-03
    status: Accepted
    changed_by: hkl (via RESEARCH session)
    reason: Fix validated empirically before acceptance; user requested this be formalized as an ADR
    changed_via: manual
```

## Context

The `/mdd-reverse` skill's step 4 said: "...use cases. Cite governing ADRs inline." A single prose clause, alongside the mechanical, well-specified instructions for extracting schema/RPC/screen truth from code.

Running an 8-queue, 24-agent sweep to backfill missing MDDs across the 360LM platform (2026-07-03) produced 16 of 29 MDDs with **zero** ADR citations. A follow-up compliance audit then found 5 real, undetected code violations (ADR-001 `?next=` missing on 5 PWAs, ADR-081 `safe-bottom.css` missing on 4) — exactly the class of defect a proper ADR-citation pass should have caught during MDD generation, not after.

### Root cause (verified, not inferred)

1. **The skill's own named exemplars were themselves thin on this dimension.** Agents were told to read `counters/MDD_counters.md` (primary exemplar) and `recce-client/MDD_recce_client.md` (secondary) to learn the house format. Checked directly: `counters` cited exactly 1 ADR; `recce-client` cited 0 before this session's manual correction. Agents learn far more from a demonstrated example than from one line of prose — the exemplars taught "light citation is acceptable" by demonstration, silently overriding the written instruction.
2. **Task-type mismatch bundled into one instruction.** Documenting what code IS (schema, RPCs, screens) is mechanical — grep and report. Checking code AGAINST ~20 mandatory house-pattern ADRs (does this specific PWA link safe-bottom.css? does its specific no-session gate include `?next=`? does its Indian-currency display use `en-IN`?) requires actively testing each pattern, one at a time, against the file — a materially different and more effortful activity that a single line ("cite governing ADRs inline") does not resource or specify.
3. **No verification gate for this specific requirement.** The skill's mandatory "Verify pass" (formerly step 5) checked that schema/RPC/flow *claims* trace to evidence — it had no equivalent forcing function for "did we test every applicable house-standard ADR."
4. **No cross-queue QA** in the fan-out that generated the MDDs. The gap surfaced only because the user separately requested a compliance audit — the generation pipeline itself had no self-check for this one instruction.

## Decision

Rewrote `docs/../skills/mdd-reverse/SKILL.md` (full diff in project memory `mdd_reverse_skill_fix.md`):

1. **Exemplars changed and the reason stated inline.** `hr/MDD_hr.md` and `rentveh/MDD_rentveh.md` (15 and 19 citations respectively, both now verified accurate) replace `counters` as the ADR-citation exemplar; the skill text explicitly says NOT to use `counters` for that dimension, with the reason given, so a future editor doesn't quietly revert it.
2. **"Cite governing ADRs inline" replaced with a mandatory, standalone step** — a concrete 7-item checklist (ADR-009 schema-per-PWA, ADR-011/012 PIN+SSO, ADR-001 `?next=`, ADR-070/071 IST/Indian formatting, ADR-074 Accept-Profile headers, ADR-081 safe-bottom.css, ADR-106 cross-schema access), each requiring an explicit verdict: **implemented** / **⚠️ NOT implemented (evidence + line)** / **not applicable (why)**. Silence on any item is disallowed.
3. **The two costliest false-positive/false-negative sources found this session are now spelled out in the checklist itself**, not left to inference: ADR-001 only applies to a real no-session login *gate*, not a plain nav-button link to `/hub/` (conflating the two produced both false positives and false negatives during the audit); ADR-081 only applies where fixed-position bottom UI chrome actually exists.
4. **ADR-106's cross-schema decision tree is now inline**: is the call site live or dead code? Is it an RPC call to the *owning* schema (sanctioned) or a bare-table read/write? For writes, does the owning schema's own code route through an RPC this bypasses? This was the single most error-prone judgment call found in the audit (an earlier draft finding wrongly used "includes a write" as the risk signal — corrected in ADR-106 itself).
5. **Register step now requires flagging any `⚠️ NOT implemented` verdict into `dbt_pending.md`**, not leaving it inside the MDD where nobody doing cross-PWA planning will see it.
6. **Subagent delegation note added**: pass the checklist verbatim to subagents, never a summarized version — summarizing to "cite governing ADRs inline" is exactly how the checklist got lost the first time.

### Empirical validation (same day, before Accept)

A fresh agent, given zero memory of this investigation and only the updated skill text, was asked to blind-run `/mdd-reverse` against `vrs` (a module with a known, real ADR-081 violation), writing to a scratch path rather than the live MDD. It **independently reproduced the exact same violation** with no hints beyond the skill text, correctly reasoned through the ADR-001 gate-vs-button distinction, and surfaced one additional legitimate question (a cross-schema grant it couldn't verify from its module-scoped vantage point — resolved directly against `information_schema.role_table_grants`, and found to be a non-issue, not a skill defect).

Reported cost: the ADR checklist took ~35-40% longer than the structural documentation step. This is treated as evidence the split was correct, not as a reason to weaken it — the original one-line instruction was cheap because it did nothing.

## Alternatives Considered

- **Leave the single prose instruction and rely on the "Verify pass" to catch citation gaps.** Rejected: the verify pass's own mandate is narrower (claims trace to evidence), and this was tried — it's exactly what produced 16/29 zero-citation MDDs.
- **Make ADR-compliance checking a fully separate skill/pass, run after MDD generation.** Rejected: doubles the read-the-codebase cost (both passes need to load the same file), and the audit showed the two activities benefit from happening in the same sitting — the agent doing schema extraction already has the file open and the context loaded.
- **Swap exemplars but leave the instruction as one line.** Rejected: the exemplar swap alone helps (agents copy good examples), but the task-type mismatch (root cause #2) would persist — a thorough exemplar still doesn't tell a future agent *how* to test ADR-001 vs a plain nav link, only that it's possible to do so.
- **Accept the gap as acceptable given the platform's low external-attack-surface (internal, single-origin app).** Rejected: two of the five found violations (`?next=` UX bugs) are real, user-facing defects independent of any security posture — they'd have shipped regardless of threat model.

## Consequences

**Positive:**
- Every future `/mdd-reverse` run produces a discoverable, per-pattern compliance verdict table, not a hopeful citation list.
- The two costliest judgment-call mistakes found this session (ADR-001 gate-vs-button, ADR-106 write-vs-read severity) are now encoded directly in the skill, not left for the next investigator to rediscover.
- Empirically validated before being marked Accepted — this ADR does not assert the fix works, it cites the specific blind-run evidence that it does.

**Negative / Trade-offs:**
- ~35-40% more time per MDD generation, confirmed by the validation run. Accepted as the cost of the checklist actually doing something.
- The checklist is 7 items sized to what this platform's actual mandatory-pattern ADRs turned out to be (2026-07-03 audit). If new mandatory-pattern ADRs are added later (e.g. a future dark-mode or bilingual requirement becomes universal), this skill file needs a matching update — there's no auto-sync between `docs/adr/README.md` and this checklist.

**Risks and mitigations:**

| Risk | Mitigation |
|---|---|
| Checklist goes stale as new mandatory-pattern ADRs are added | No automated check yet; treat as a known gap — revisit this ADR if the mandatory-pattern set grows materially |
| A future edit re-summarizes the checklist back into a short instruction (repeating the original failure mode) | The skill file itself now states the causal history inline ("was the reason a prior batch run under-cited"), so a future editor sees why the verbosity is load-bearing before trimming it |
| Subagent delegation still drops the checklist despite the new note | No automated enforcement; the note is advisory. If this recurs, consider a template/schema-validated agent output format instead of prose instructions |

## Related Decisions

- **ADR-099** — DevGuide Is an Index + Skill + Topic Files, Not a Monolith. The closest precedent for treating skill/tooling architecture as ADR-worthy, not just PWA-code architecture.
- **ADR-001, ADR-081, ADR-106** — the specific house-standard ADRs whose compliance-checking method is now encoded in this skill's checklist.
- **ADR-105** — the JWT ADR drafted the same day this skill fix was validated; unrelated in content, same session's broader compliance-hardening arc.

## References

- `/root/.claude/skills/mdd-reverse/SKILL.md` — the fixed skill file (this ADR documents its rationale; the file itself is the artifact)
- `/root/.claude/projects/-root-360lm-web/memory/mdd_reverse_skill_fix.md` — full root-cause narrative and validation transcript summary
- `docs/audit_mdd_adr_compliance_2026-07-03.md` — the audit that surfaced the original gap
- `hr/MDD_hr.md`, `rentveh/MDD_rentveh.md` — the new exemplars
