ADR 0021 — Maintenance harness
Context
Section titled “Context”Restura ships one React renderer to three backends (Cloudflare Worker, Node/Docker, Electron) over a security-critical shared protocol core, with six independent TypeScript projects, two codegen drift gates, a capability matrix, a large documentation surface, and a desktop-only feature set. Keeping all of that consistent is the bulk of the maintenance cost, and several gaps were only known as folklore:
npm run type-checkonly type-checks the renderer. The roottsconfig.jsonruns baretsc --noEmitand excludesworker,electron/main, andcli. CI ran six separatetscinvocations, but there was no single local command equivalent — so a green localvalidatedid not mean the Electron main process, Worker, or CLI compiled. The pre-commit hook skipstscentirely, so type errors landed in commits.- No content-parity gate for docs.
npm run docs:checkis onlyastro check(links/types).CLAUDE.mdanddocs/ARCHITECTURE.mdhad both drifted from the actual type-check behaviour; the ADR timeline on this page is hand-maintained. - The existing build-side skill covers adding features, not verifying or maintaining them, and the built-in
/code-review//security-reviewlack Restura-specific knowledge (the single-source SSRF guard, the DNS-rebind residual window, broker-discovery bypass, the IPC validate + rate-limit + sender triad, SecretRef isolation).
We wanted the assistant (Claude Code) to build and maintain Restura at production grade — skills that encode gotchas and organisational knowledge (not the obvious), use progressive disclosure, prefer scripts for deterministic work, and accrete over time.
Decision
Section titled “Decision”Add a maintenance harness under .claude/, paired with a source-level fix for the type-check gap.
- Source fix (closes the root cause) — add
npm run type-check:all, which runs all sixtscprojects CI uses, and chain it intonpm run validate. Localvalidatenow matches CI. Correct the stale type-check claims inCLAUDE.mdanddocs/ARCHITECTURE.md. - Verify/maintain skill — the counterpart to the build-side feature skill. It carries the top gotchas (type-check gap, pre-commit skips tsc, codegen drift gates, capability parity, coverage thresholds, commit scope-enum) with progressive-disclosure references (verification gates, security checklist, release readiness, docs parity).
- Subagents — a security auditor (SSRF single-source, DNS-rebind residual window, broker-discovery bypass, IPC guard triad, SecretRef isolation, wire-level signing), a parity checker (web/desktop wiring + capability matrix), and a docs steward (doc-ownership map + a “does this need an ADR?” rubric). Each encodes knowledge the built-in reviewers lack.
- Commands —
/ship-check(run the full gatevalidateskips, triage failures tofile:line),/new-protocol(drive the feature runbook), and/docs-sync(walk the doc-ownership map and update every stale surface). - Measurement hook — a
PreToolUsehook logs skill invocations so under/over-triggering is observable, shipped via the committed.claude/settings.json.
Consequences
Section titled “Consequences”Positive
- Local
validateis now type-complete; the most common “passed locally, failed CI” class is closed at the source. - The verify/maintain knowledge that was folklore is now discoverable and triggers itself.
- Reviews of the security and wiring surfaces carry Restura-specific invariants instead of generic advice.
- Docs gain a parity gate (the steward + ownership map) where CI has none.
Negative
type-check:allmakesvalidateslower locally (sixtscruns); the renderer-onlytype-checkremains for fast inner-loop checks.- The harness is prompt/skill content, not executable gates — it guides the assistant but does not block a human running raw
git/npm. The hard gates remain CI. - More artifacts to keep current; this ADR and the doc-ownership map are themselves maintenance surface.
Related
Section titled “Related”- Contract tests & CI — the
validategate this harness’s source-level fix (type-check:all) closes a gap in. - ADR 0004 — Security Hardening — the SSRF/security invariants the security-auditor subagent encodes.
- ADR 0006 — Electron Connection Cleanup + Pre-flight DNS Guard — the DNS-rebind residual window it carries as knowledge.
- ADR 0007 — SecretRef Pattern — the isolation invariant it checks for.
- ADR 0012 — Capability Matrix Source of Truth — what the parity checker subagent verifies.