Change Management
Standing rule: every major implementation MUST update this chapter in the same change — at minimum a dated changelog entry, plus an ADR if architecturally significant.
Version history
The current manual version is shown on the cover of the exported PDF and in the sidebar header. Bump MANUAL_META.version in src/content/manual/MANUAL_META.ts whenever the manual structure or major content changes.
Release notes (newest first)
1.3.0 — 2026-06-08 — Unified enterprise PDF engine
- Registered Inter (400/500/600/700 + italic) as the default PDF body font via
@fontsource/inter(pinned5.0.16) served from jsDelivr; falls back to Helvetica if registration throws. - Migrated the Fairness Transparency Report (
QuickActionToolbar.tsx) offjspdfto the shared@react-pdf/rendererpipeline. New document lives atsrc/lib/pdf/TransparencyPdf.tsxand reusespdfTheme+ensureFontsRegistered. - Removed
jspdfandhtml2canvasfrompackage.json— the application now has a single PDF engine. - Every PDF the product emits is now selectable, searchable, copy-pasteable, and audit-ready.
1.2.0 — 2026-06-08 — Enterprise Project Manual
- Replaced rasterised PDF export (
html2canvas+jspdf) with@react-pdf/renderer— text is now selectable, searchable, and copyable. - Added cover page, revision history, table of contents with internal links, page numbering, fixed headers/footers, and reader bookmarks for every chapter.
- Reorganised the manual into 12 enterprise sections (Executive, Architecture, Guides, Security & Identity, Reference, Operations, Governance).
- Automatic chapter discovery — drop a
.mdfile intosrc/content/manual/chapters/, it appears in nav, on-screen ToC, and the PDF. No registration file. - Added
docs/CHECKLIST.mdDefinition of Done. - Expanded
src/content/manual/README.mdwith the frontmatter contract.
1.1.0 — 2026-06-08 — Authentication hardening wired into auth flow
auth.tsxnow callslogin-rate-limitpre- and post-sign-in.app.tsxbeforeLoadenforces mandatory AAL2 (un-enrolled users →/mfa-setupenrol; aal1 → step-up).<InactivityGuard />mounted inside the authenticated layout.- Sidebar links to
/app/audit-log-viewer.
1.0.0 — 2026-06-08 — Initial documentation system
- Added
/docsroute with sidebar + chapter pages. - Seeded 8 chapters and a client-side PDF export.
- Introduced the standing "documentation is a first-class deliverable" rule.
Architectural Decision Records (ADRs)
ADR-001 — TanStack Start over Next.js
Status: Accepted. Context: Need typed file-based routing, SSR on Workers, server functions as typed RPC. Decision: Use TanStack Start v1. Consequences: No src/pages/; no Express middleware; learn createServerFn.
ADR-002 — RBAC via separate user_roles table + SECURITY DEFINER function
Status: Accepted. Context: Storing roles on profile rows enables privilege escalation; recursive RLS is a trap. Decision: Dedicated table; has_role() SECURITY DEFINER. Consequences: All policies use has_role; never literal role strings.
ADR-003 — Mandatory AAL2 on /app/*
Status: Accepted. Context: Tier-1 institutions require MFA. Decision: Force MFA enrolment + step-up via app.tsx beforeLoad. Consequences: Google OAuth users on first visit are bounced to /mfa-setup.
ADR-004 — IP-based rate limiting in an edge function (not in a server fn)
Status: Accepted. Context: Need to count attempts even for failed/anonymous sign-ins; need IP visibility. Decision: Dedicated edge function with service-role write to sec_login_attempts. Consequences: One extra round-trip on /auth; clear separation of concerns.
ADR-005 — @react-pdf/renderer for PDF, not server-side puppeteer
Status: Accepted. Context: Worker runtime cannot run puppeteer / sharp. Decision: Render PDF in the browser via @react-pdf/renderer. Consequences: Larger client bundle behind dynamic import; no server-signed PDFs (revisit if regulators require).
ADR-006 — Automatic chapter discovery via import.meta.glob
Status: Accepted. Context: Hand-maintained _index.ts forces double-edits. Decision: Glob chapters/*.md eagerly at build, sort by frontmatter order. Consequences: Frontmatter is now contract; missing frontmatter degrades gracefully but should never ship.
Technical debt register
| # | Item | Severity | Owner | Next step |
|---|---|---|---|---|
| 1 | No automated end-to-end (Playwright) suite | Med | Platform | Scaffold auth + MFA + access-gov flows |
| 2 | Coverage metrics not enforced in CI | Med | Platform | Add Vitest coverage gate after item 1 |
| 3 | jspdf / html2canvas still in package.json | — | Platform | Resolved in 1.3.0 — single PDF engine (@react-pdf/renderer) |
| 4 | Manual is bundled at build time (no live edit) | Low | Platform | Acceptable — keeps diff-reviewable. Revisit if non-engineers must author |
| 5 | ASCII diagrams instead of SVG | Low | Design | Mermaid / SVG render once a renderer is added |
| 6 | No search across docs | Low | Platform | Add pagefind once content stabilises |
Incidents
(none recorded)
When recording an incident, include: date, severity, summary, root cause, remediation, evidence link. Cross-reference any related ADRs.