Skip to content

Documentation Strategy — Design Spec

Date: 2026-04-27 Status: Draft for review Author: Jim Holmes (with brainstorming session) Tracking issue / PR: TBD


1. Purpose & scope

Build the documentation surface for the clinical-data-model platform across multiple audiences (SMT, internal tech team, auditors, regulators, integrators, procurement) so that the platform is presentable, audit-ready, and discoverable without a forcing event.

Mode: general readiness — no specific deadline (e.g. an audit, regulatory filing, or named customer) is driving this work. Scope decisions optimise for breadth-first scaffolding so structure is in place even if individual artifacts are filled in over time.

Approach: stay in CLI / git-versioned text for ~80% of the work — markdown narratives, Mermaid/D2 diagrams, generated artifacts (SBOM, license inventory, OpenAPI). Switch to graphical tooling only for one-off polished hero visuals (board / SMT decks).


2. Audience priorities (v1)

2.1 v1 content (real narratives + content)

  • SMT / leadership — exec-level capability and direction overview; ≤10 pages total
  • Tech team (internal) — architecture, service catalogue, cross-service flows, runbook templates; mostly aggregation of existing specs/plans
  • Compliance pack (auditors + regulatory) — combined because the artifact set overlaps heavily for a medical device platform; security model + data model + audit + retention narratives, plus auto-generated SBOM, licenses, SOUP

2.2 v1 scaffold-only (placeholder + auto-generated)

  • Integrators — placeholder index + auto-generated OpenAPI per service; getting-started guides deferred until a real integration partner needs them
  • Procurement / commercial — auto-generated license inventory; sub-processor list deferred (manual artifact)

2.3 Deferred from v1 (no v1 ship)

  • Risk management file (ISO 14971-style) — large, medical-device-specific, needs clinical input
  • Threat model (STRIDE-style) — valuable but a separate engagement
  • Traceability matrix (req → design → code → tests) — useful only when a regulator asks specifically
  • Pen test summary — external work
  • Reviewer-facing UI — separate frontend track (out of doc scope)

3. Audience-specific v1 deliverables

3.1 SMT — 4 documents + 1 hero diagram

File Purpose
audiences/smt/overview.md Executive narrative: what the platform is, who it serves, current state
audiences/smt/capability-map.md Plain-English description of each module (clinical-api, ai-review, orchestrator, human-review, etc.)
audiences/smt/architecture-glance.md Single architecture diagram + 1-paragraph intro
audiences/smt/roadmap.md Shipped / next / deferred snapshot

3.2 Tech team — service catalogue + per-service deep-dives + flows + runbooks

File / folder Purpose
audiences/tech/README.md Service catalogue index — 8 services + 3 packages, one-liner each
audiences/tech/services/{service}.md Per-service summary: purpose, key endpoints, key DB tables, dependencies, link to spec
audiences/tech/packages.md Shared package overview (@sa-platform/{events,common,auth-client,...})
audiences/tech/flows/ai-review-flow.md Sequence diagram + narrative
audiences/tech/flows/orchestrator-flow.md Orchestrator-driven workflow flow
audiences/tech/runbooks/service-down-triage.md Starter runbook: incident triage
audiences/tech/runbooks/deployment-rollback.md Starter runbook: deploy rollback
audiences/tech/runbooks/database-migration.md Starter runbook: Prisma migration ops
audiences/tech/adrs/README.md Index pointing at docs/superpowers/specs/ (ADR-style design records already exist)

3.3 Compliance pack — 5 narratives + 4 generated artifacts

File / artifact Type Purpose
audiences/compliance/README.md HW Pack overview + entry point
audiences/compliance/security-model.md HW Auth (OAuth2, JWT, scopes), encryption (at rest + in transit), tenancy isolation, secrets handling
audiences/compliance/data-model-phi.md HW PHI classification table + data flow + storage
audiences/compliance/audit-trail.md HW What's logged, by which service, retention semantics
audiences/compliance/retention-erasure.md HW Retention policy mechanism, GDPR Article 17 erasure flow, crypto-shredding
audiences/compliance/architecture.md HW Network topology, service map, data-flow diagram (D2 / Mermaid)
audiences/compliance/generated/sbom.cdx.json AG CycloneDX SBOM
audiences/compliance/generated/sbom.spdx.json AG SPDX SBOM (FDA-preferred format)
audiences/compliance/generated/licenses.{json,md} AG Dependency license inventory
audiences/compliance/generated/soup.md AG + HW SOUP (Software of Unknown Provenance) classification

3.4 Integrators — scaffold + auto-generated

File Purpose
audiences/integrators/README.md "Coming soon" + pointer to current state
audiences/integrators/generated/openapi/{service}.json Per-service OpenAPI specs (from NestJS Swagger module)

3.5 Procurement — scaffold + auto-generated

File Purpose
audiences/procurement/README.md Scaffold
audiences/procurement/generated/licenses.md Same source as compliance/generated
audiences/procurement/sub-processors.md Hand-written; auto-list in v2

4. Repository structure

docs/
├── README.md                        # Top-level discovery: "I'm an X, take me to Y"
├── CONTRIBUTING.md                  # How to add a doc, frontmatter, owner conventions
├── audiences/
│   ├── smt/
│   │   ├── overview.md
│   │   ├── capability-map.md
│   │   ├── architecture-glance.md
│   │   └── roadmap.md
│   ├── tech/
│   │   ├── README.md
│   │   ├── services/{ai-review,orchestrator,human-review,clinical-api,consent,auth,notifications,user-management}.md
│   │   ├── packages.md
│   │   ├── flows/{ai-review-flow,orchestrator-flow}.md
│   │   ├── runbooks/{service-down-triage,deployment-rollback,database-migration}.md
│   │   └── adrs/README.md
│   ├── compliance/
│   │   ├── README.md
│   │   ├── security-model.md
│   │   ├── data-model-phi.md
│   │   ├── audit-trail.md
│   │   ├── retention-erasure.md
│   │   ├── architecture.md
│   │   └── generated/
│   │       ├── sbom.cdx.json
│   │       ├── sbom.spdx.json
│   │       ├── licenses.{json,md}
│   │       ├── soup.md
│   │       └── README.md           # "Generated by scripts/generate-docs.sh — do not edit"
│   ├── integrators/
│   │   ├── README.md
│   │   └── generated/openapi/{service}.json
│   └── procurement/
│       ├── README.md
│       └── generated/licenses.md
├── superpowers/                     # EXISTING — not moved
│   ├── specs/
│   └── plans/
└── diagrams/                        # Single source of truth for diagram source
    ├── architecture-glance.mmd
    ├── ai-review-sequence.mmd
    ├── orchestrator-sequence.mmd
    ├── network-topology.d2
    └── data-model-erd.mmd

Key choices:

  1. Audience-segmented top-level discovery. Top-level docs/README.md routes readers ("If you're an auditor, start at audiences/compliance/; if you're a developer onboarding, start at audiences/tech/"). Lower friction than a single flat index.
  2. Generated subdirectories per audience. Auto-emitted artifacts live next to the audience that consumes them, marked do-not-edit. Same SBOM may be referenced from multiple audiences — easiest is to generate to one location and symlink, or simply re-emit (generation is cheap).
  3. diagrams/ as single source of truth. All Mermaid .mmd and D2 .d2 source files in one place; markdown docs reference rendered SVG output. Updates flow source → all consumers.
  4. superpowers/ stays intact. Design specs and plans are engineering history, not audience-facing. Tech ADR index links to them; structure doesn't move.

Alternatives considered and rejected:

  • By artifact type (docs/diagrams/, docs/runbooks/, docs/policies/) — clean for editors, hostile for readers. Less friendly for "I'm an auditor, where do I start?".
  • Single flat docs/ with naming conventions — simplest, but quickly noisy at this many artifact types.

5. Generation toolchain

All tools CLI-driven, scripted, and CI-runnable. Added to root devDependencies or installed in CI only.

Artifact Tool Source Output
SBOM (CycloneDX) @cyclonedx/cdxgen pnpm-lock.yaml sbom.cdx.json
SBOM (SPDX) cdxgen --output-format spdx-json same sbom.spdx.json
License inventory pnpm licenses list --json runtime deps licenses.json + licenses.md
SOUP classification custom script merges CycloneDX + manual soup-classification.yaml soup.md
OpenAPI per service NestJS Swagger module + @nestjs/swagger CLI controllers openapi/{service}.json
Mermaid → SVG @mermaid-js/mermaid-cli (mmdc) .mmd source .svg
D2 → SVG d2 CLI .d2 source .svg
Markdown → PDF pandoc + custom template per-audience folder compliance-pack.pdf etc.

Scripts:

  • scripts/generate-docs.sh — orchestrator script, runs all sub-scripts
  • scripts/docs/sbom.sh — SBOM generation (both formats)
  • scripts/docs/licenses.sh — license inventory
  • scripts/docs/soup.sh — SOUP classification (merges generated + manual classifications)
  • scripts/docs/openapi.sh — per-service OpenAPI export (one Swagger CLI invocation per service)
  • scripts/docs/diagrams.sh — render Mermaid + D2 sources to SVG
  • scripts/docs/pdf.sh — Pandoc-driven per-audience PDF bundles

6. Cadence & freshness

On every commit to main (CI): regenerate SBOM, licenses, OpenAPI, Mermaid SVGs. Recommend keeping generated files out of git (built artifacts only); served via GitHub Pages or attached to CI runs. Reduces diff noise; eliminates stale-generated-file failure mode.

On every release tag (CI): full doc bundle build — SBOMs cryptographically signed (e.g. via cosign), per-audience PDFs generated via Pandoc, attached to the GitHub release. This is what auditors get a link to.

Manual / on-demand: hand-written narratives. Each document has a last_reviewed frontmatter field; scripts/docs/check-staleness.sh runs in CI and warns if any doc hasn't been reviewed in 90 days. Soft warning, not failing.

Per-PR: a path-based mapping (.github/docs-codeowners.yml) flags affected docs in PR descriptions. If a PR touches services/clinical-api/src/auth/..., the PR description gets a comment: "Consider reviewing docs/audiences/compliance/security-model.md for accuracy."


7. Export formats

  • Markdown source — primary format, lives in repo, rendered by GitHub
  • HTML site — generated via mkdocs material or docusaurus, deployed to GitHub Pages on every commit to main. Single discovery URL for all audiences. Worth doing in v1 because auditors prefer a portal link, not a tarball.
  • PDF — per-audience PDF generated via Pandoc on release tag; specifically:
  • compliance-pack.pdf (everything in audiences/compliance/ + audiences/compliance/generated/*)
  • tech-pack.pdf (selective tech-audience content; less critical but useful for onboarding new engineers offline)
  • smt-summary.pdf (4 docs + hero diagram, for board/exec)
  • SBOM — CycloneDX JSON + SPDX JSON, both formats. Different consumers prefer different ones (FDA leans SPDX; most tooling speaks CycloneDX).

8. Update governance

Each markdown file gets a frontmatter block:

---
title: Security Model
audience: compliance
owner: tech-lead
last_reviewed: 2026-04-27
review_cycle_days: 90
---

scripts/docs/check-staleness.sh reads the frontmatter, warns on stale docs in CI (non-blocking on PR; daily summary as a separate workflow).

docs/CONTRIBUTING.md documents:

  • How to add a new doc to a given audience
  • Where to put diagrams (docs/diagrams/) — and the source-then-render pipeline
  • Naming + frontmatter convention
  • How generated artifacts work (don't manually edit; how to regenerate locally)
  • Review cycle expectations per audience
  • How the per-PR doc-impact mapping works

Each audiences/*/README.md lists the audience-level owner and review cadence as a whole.


9. v1 ship list (consolidated)

Audience v1 deliverable
SMT 4 markdown docs (overview, capability-map, architecture-glance, roadmap) + 1 architecture Mermaid diagram
Tech Service catalogue + 8 per-service summaries + 1 packages doc + 2 flow diagrams + 3 runbook templates + ADR index
Compliance 5 narrative docs (security-model, data-model-phi, audit-trail, retention-erasure, architecture) + 4 generated artifacts (CycloneDX SBOM, SPDX SBOM, licenses, SOUP)
Integrators Scaffold + auto-generated OpenAPI per service
Procurement Scaffold + auto-generated license inventory

Generation toolchain: 6 scripts in scripts/docs/ + 1 orchestrator script. CI workflow on every commit (artifacts as outputs) and every release tag (full bundle attached).

Static site: MkDocs Material build pointed at docs/, deployed to GitHub Pages on every commit to main.

PDFs: Pandoc + custom template, generated on release tag, attached to GitHub release.

Governance: frontmatter staleness check (90-day default, soft warning) + per-PR diff awareness via path-based docs-codeowners mapping.


10. Out-of-scope / deferred

  • ISO 14971 risk management file (medical-device-specific; large effort)
  • STRIDE-style threat model (valuable; separate engagement)
  • Traceability matrix (req → design → code → tests; only useful when a regulator asks)
  • Pen test summary (external work)
  • Hand-drawn / branded SMT visuals (one-off, may be done in Claude.ai if needed)
  • Reviewer-facing UI documentation (separate frontend track)
  • Customer-specific security review packs (driven by named customers; templated from compliance pack when one arrives)
  • Translated / localised documentation (English only in v1)
  • Live "documentation as code" portal (e.g. Backstage TechDocs) — MkDocs Material is the v1 pragmatic choice
  • Automated linting of doc prose (e.g. Vale, Alex) — could add later, not v1

11. Open questions for implementation plan

  1. MkDocs vs Docusaurus for the static HTML site. MkDocs Material is simpler to bootstrap and renders Mermaid natively; Docusaurus has stronger React-based extensibility. Lean MkDocs for v1; Docusaurus if a richer interactive surface is later needed.
  2. SBOM signing tool — cosign is the most common; consider whether the existing CI has the appropriate secrets infrastructure or if it needs to be set up.
  3. Where to host the static site: GitHub Pages (free, simple) vs. an internal docs domain (e.g. docs.skinanalytics.internal via a separate static-host pipeline). v1 default GitHub Pages on the repo's gh-pages branch.
  4. Diagram source format split — Mermaid for sequence/architecture diagrams is fine; for network topology, D2 vs Graphviz vs Excalidraw text format. Lean D2 for the network diagram only; Mermaid everywhere else.
  5. OpenAPI extraction — NestJS Swagger module needs to be installed and configured per service; some services may already have it (verify ai-review, orchestrator), others may not. Implementation plan should audit.