Skip to content

ADR 0021 — Maintenance harness

Accepted · 2026-06-10

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:

  1. npm run type-check only type-checks the renderer. The root tsconfig.json runs bare tsc --noEmit and excludes worker, electron/main, and cli. CI ran six separate tsc invocations, but there was no single local command equivalent — so a green local validate did not mean the Electron main process, Worker, or CLI compiled. The pre-commit hook skips tsc entirely, so type errors landed in commits.
  2. No content-parity gate for docs. npm run docs:check is only astro check (links/types). CLAUDE.md and docs/ARCHITECTURE.md had both drifted from the actual type-check behaviour; the ADR timeline on this page is hand-maintained.
  3. The existing build-side skill covers adding features, not verifying or maintaining them, and the built-in /code-review / /security-review lack 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.

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 six tsc projects CI uses, and chain it into npm run validate. Local validate now matches CI. Correct the stale type-check claims in CLAUDE.md and docs/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 gate validate skips, triage failures to file:line), /new-protocol (drive the feature runbook), and /docs-sync (walk the doc-ownership map and update every stale surface).
  • Measurement hook — a PreToolUse hook logs skill invocations so under/over-triggering is observable, shipped via the committed .claude/settings.json.

Positive

  • Local validate is 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:all makes validate slower locally (six tsc runs); the renderer-only type-check remains 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.