Skip to main content
Governance

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 (pinned 5.0.16) served from jsDelivr; falls back to Helvetica if registration throws.
  • Migrated the Fairness Transparency Report (QuickActionToolbar.tsx) off jspdf to the shared @react-pdf/renderer pipeline. New document lives at src/lib/pdf/TransparencyPdf.tsx and reuses pdfTheme + ensureFontsRegistered.
  • Removed jspdf and html2canvas from package.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 .md file into src/content/manual/chapters/, it appears in nav, on-screen ToC, and the PDF. No registration file.
  • Added docs/CHECKLIST.md Definition of Done.
  • Expanded src/content/manual/README.md with the frontmatter contract.

1.1.0 — 2026-06-08 — Authentication hardening wired into auth flow

  • auth.tsx now calls login-rate-limit pre- and post-sign-in.
  • app.tsx beforeLoad enforces mandatory AAL2 (un-enrolled users → /mfa-setup enrol; 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 /docs route 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

#ItemSeverityOwnerNext step
1No automated end-to-end (Playwright) suiteMedPlatformScaffold auth + MFA + access-gov flows
2Coverage metrics not enforced in CIMedPlatformAdd Vitest coverage gate after item 1
3Old jspdf / html2canvas still in package.jsonPlatformResolved in 1.3.0 — single PDF engine (@react-pdf/renderer)
4Manual is bundled at build time (no live edit)LowPlatformAcceptable — keeps diff-reviewable. Revisit if non-engineers must author
5ASCII diagrams instead of SVGLowDesignMermaid / SVG render once a renderer is added
6No search across docsLowPlatformAdd 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.