# ADR Rules for Coding Work
# Source: rvdbreemen/adr-kit instructions/adr.coding.md (adapted for 360lm)

When about to implement or change code, run through these rules **before** writing.

## Before implementing

- **Check for existing ADRs**: scan `docs/adr/README.md` index for an ADR that governs the area you are about to touch, then open relevant ADRs.
- **Assess architectural significance**: does the change affect any of the following?
  - Architecture: PWA boundaries, hub integration, proxy routing, shared infra
  - Non-functional: security (PIN/session), availability, performance
  - Interfaces: hub session format, SW cache contract, PostgREST grants, proxy endpoints
  - Dependencies: new library, new MCP, new service
  - Build and tooling: SW versioning, docker-compose, Traefik rules

  If yes → ADR in scope. If clearly no (bug fix, refactor preserving contract, doc fix) → skip.

## Creating a new ADR

If no ADR exists and the change is architecturally significant:

1. **Run the adr-generator agent** (`.claude/agents/adr-generator.md`). Provide: title, decision, alternatives, constraints, related ADRs.
2. **Review the generated ADR** before coding: confirm all 4 gates pass.
3. **Reference the ADR in your commit message**: `ADR: docs/adr/ADR-NNN-title.md`
4. **Add inline code comment** at non-obvious enforcement sites: `// See ADR-NNN`

## Superseding an existing ADR

If your change reverses or replaces an `Accepted` ADR:

1. **Do not modify** the accepted ADR's decision text or reasoning.
2. **Write a new superseding ADR** explaining: what is changing, why the original no longer fits, the new choice, migration path.
3. **Update old ADR status line only**: `Superseded by ADR-YYY, YYYY-MM-DD`. Append matching status_history entry.
4. **Cross-link** in both ADRs' Related Decisions sections.

## Implementation checklist

For every commit that lands an architecturally significant change:

- [ ] ADR exists or has been created via adr-generator
- [ ] ADR follows structure in `docs/adr/README.md`
- [ ] ≥2 alternatives documented with rejection reasoning
- [ ] Consequences include both positive and negative; risks have mitigations
- [ ] **Revisit If section present** — invalidation triggers stated, plus what the ADR does NOT govern
- [ ] All 4 verification gates pass
- [ ] Commit message links to ADR
- [ ] If superseding: old ADR status line + status_history updated, cross-references in place

## When ADR rules do NOT apply

Skip for:
- Bug fixes that do not change a contract
- Refactors that preserve external behaviour
- Documentation updates (unless the doc IS an ADR)
- Configuration tweaks within an existing range
- Minor feature additions that fit an established pattern

**If unsure: default to creating an ADR.** Cost of writing one = 15 min. Cost of re-deriving rationale 6 months later = hours.

---

## The WHY rule (mandatory, added 2026-08-09 by hkl)

**Every ADR must record WHY, not just WHAT — and must state what would make it wrong.**

An ADR captures a decision made under a specific set of forces. When those forces change, an ADR
that recorded only the decision becomes a **hurdle**: nobody can tell whether the reasoning still
holds, so the rule gets obeyed past its own expiry — or over-applied to cases it never considered.

Three fields carry this, and all three are required:

| Field | Carries | Gate |
|---|---|---|
| **Context** | The actual force driving the decision — cite the incident, constraint, or measurement. Never "best practice" or "scalability". | 2 (Evidence) |
| **Alternatives Considered** | Why each rejected option was rejected — the reasoning, not just the verdict. | 1 (Completeness) |
| **Revisit If** | The invalidation triggers, **and** what the ADR does NOT govern. | **5 (Revisitability)** |

**Worked example of the failure this prevents.** A rule recorded as *"designer machines are
zero-token"* reads as an absolute ban. Its real basis was narrower: *don't provision a second
Claude CLI seat on a designer machine* — a login/seat/quota concern about the bridge, not about
whether any AI call may originate there. Without a Revisit If, the narrow rationale is invisible
and the broad reading wins, blocking work the decision never intended to block.

**Scope discipline is half the value.** "Does NOT govern" prevents an ADR being cited against
cases outside its reasoning — the most common way a good decision turns into an obstacle.

**Applies to new and Proposed ADRs.** Do **not** retrofit an `Accepted` ADR — that violates the
immutability rule. If an Accepted ADR is blocking work because its rationale is unrecoverable,
that is itself the signal to write a superseding ADR.
