ADR 0001 — Shannon stack: Astro Starlight on Azure Static Web Apps, gated by Entra ID, with federated markdown sources
ADR 0001 — Shannon stack choice
Section titled “ADR 0001 — Shannon stack choice”Context and problem statement
Section titled “Context and problem statement”PWG has accreted technical documentation across wikis, SharePoint folders, OneNote notebooks, Slack/Teams threads, and a handful of README files. Finding anything requires knowing where to look, and most of what’s there is either stale, uncited, or duplicated across surfaces. A non-trivial amount of “institutional knowledge” lives only in senior engineers’ heads.
We want a single durable knowledge base for PWG technology that:
- Is the source of truth for system architecture, cross-cutting decisions, runbooks, and reference content.
- Can be regenerated — per-system pages are mostly authored by AI against the live system’s API (Salesforce describe calls, MYOB schema, PWG_DATA metadata, etc.), not hand-written drift.
- Supports review workflow — proposed changes are pull requests, not edits in a rich-text UI where nobody sees the diff.
- Renders diagrams inline without a separate tool (Lucidchart, draw.io SVG exports, etc.), because those age out of sync with the text.
- Authenticates against Entra ID so access is managed by the same group memberships as the rest of PWG’s internal systems.
- Hosts somewhere we already operate and trust.
Decision drivers
Section titled “Decision drivers”- Source-controlled markdown. Diff-reviewable. AI-regeneratable. Grep-able. Survives vendor churn.
- Per-system content stays in per-system repos. Shannon should not become the thing all documentation PRs funnel through — that’s a bottleneck and it couples system owners to a repo they don’t otherwise touch.
- Search must work out of the box. A KB nobody can search is just a filesystem.
- Server-rendered diagrams. No runtime JS tax for Mermaid.
- Entra ID auth, same pattern as the Sydney meeting rooms landing page. Operationally familiar.
- Low ongoing cost. We can justify hours; we cannot justify a five-figure platform licence for a 100-seat KB.
- Low vendor lock-in. If we decide to move in two years, the content is markdown and the history is in git. That’s it.
Considered options
Section titled “Considered options”Option A — Notion
Section titled “Option A — Notion”Pros: excellent editing UX, familiar to most staff, good search.
Cons: content is stored in Notion’s proprietary blocks, not markdown. AI regeneration against live system APIs would have to push into Notion’s API — painful and lossy. Review workflow is comments on blocks, not diffs. No Entra ID SSO on the tier we’d be willing to pay for (enterprise SSO is a significant cost jump). Long-term portability is poor.
Option B — SharePoint / M365 wiki
Section titled “Option B — SharePoint / M365 wiki”Pros: already paid for, Entra auth is native, staff already have access.
Cons: terrible as a technical KB — pages are not version-controlled in a way engineers use (version history exists but is not diff-first), markdown is a second-class citizen, no Mermaid, no Pagefind-quality search, and cross-page linking between SharePoint and markdown-in-git is brittle. We’ve tried this and it degrades into a stale folder of .docx files within 12 months.
Option C — Docusaurus on Azure Static Web Apps
Section titled “Option C — Docusaurus on Azure Static Web Apps”Pros: mature, React-based, widely used, MDX-rich.
Cons: client-rendered by default, heavier JS bundle, Mermaid integration involves a client-side library. Theme customisation needs React knowledge. Slightly over-engineered for a technical KB where we don’t want custom components — we want markdown.
Option D — GitBook
Section titled “Option D — GitBook”Pros: purpose-built for technical docs, has a git-sync mode.
Cons: per-seat pricing for the tier with SSO. Git sync is bidirectional and has historically produced merge conflicts that confuse non-engineer contributors. Vendor lock-in on the rendering side.
Option E — MkDocs Material on Azure Static Web Apps
Section titled “Option E — MkDocs Material on Azure Static Web Apps”Pros: excellent, lightweight, Python-based, extremely mature.
Cons: Python toolchain is slightly out of step with the rest of PWG’s technology stack (Node / .NET / Python-for-data). Sidebar config is more hand-curation than autogeneration. Search is good but not as good as Pagefind on prose content.
Option F — Astro Starlight on Azure Static Web Apps (chosen)
Section titled “Option F — Astro Starlight on Azure Static Web Apps (chosen)”Pros:
- Markdown-first. The
src/content/docs/tree is the content. No proprietary block format. - Starlight ships Pagefind — static, client-side search index built at deploy. Excellent quality, no server.
- Sidebar autogeneration from folder structure — important for a federated site where folders are materialised at build time by the assembler.
- Zod frontmatter schema — invalid frontmatter fails the build. Schema enforcement is free.
rehype-mermaidwithstrategy: 'img-svg'renders diagrams to SVG at build time. No client JS cost.- Astro 5’s content collections are the right abstraction for “every .md in the tree must satisfy a schema”.
- Deploys cleanly to Azure Static Web Apps. Free tier comfortably covers a read-mostly KB. Entra ID auth is a built-in feature.
Cons:
- Astro is still evolving faster than, say, MkDocs — major version bumps need planning.
- Starlight’s theme is opinionated; deep visual customisation means poking at Starlight internals.
- rehype-mermaid SSR requires Playwright in CI — an extra ~150MB install per build.
Decision outcome
Section titled “Decision outcome”Chosen: Option F — Astro Starlight on Azure Static Web Apps, gated by Entra ID, with per-system documentation federated into Shannon at build time.
The federation model is a first-class part of the decision. Per-system docs (Salesforce, MYOB, XPLAN, Hex, PWG_DATA, Workato, Azure, M365) live in their own source repos so the teams and AI regeneration processes that own each system can iterate without touching Shannon. Shannon owns only:
- The site shell, theme, and sidebar config.
- Cross-cutting ADRs, runbooks, and reference content.
- The frontmatter schema and CI lint.
- The
sources.ymlmanifest that declares which source repos to fetch.
CI in Shannon fetches each source repo (using SHANNON_FETCH_TOKEN), assembles declared from → to paths into src/content/docs/, validates frontmatter against the Zod schema, runs astro build, and deploys to Azure Static Web Apps. Source repos can fire a repository_dispatch event (event_type: source-updated) to trigger a rebuild when they merge to main.
Consequences
Section titled “Consequences”Positive
- Every per-system doc change ships through a standard PR review in a repo the system owner already works in.
- AI regeneration of per-system content is decoupled from Shannon — the generating process only needs write access to the source repo.
- Content is portable:
git cloneeach source repo and you have the raw markdown. - Site is fast, fully static, JS-light, and costs effectively nothing to host.
- Entra ID auth reuses operational patterns we already have (matches the Sydney meeting rooms Bookings landing page).
Negative
- Two-step authoring story for someone who doesn’t know the model (“where do I edit the Salesforce page?”). Mitigated by making the edit-link on every page point to the correct source repo, and by the contribution table in the site landing page.
- Build requires a token with read access to all source repos (
SHANNON_FETCH_TOKEN). If the token expires, the build fails — we need to rotate deliberately, not reactively. - A stale source repo silently leaves stale content in Shannon. Partial mitigation: the weekly
stale-docs-checkworkflow scanslast_reviewedfrontmatter and opens an issue grouped by source repo. - Mermaid SSR pulls in Playwright — not free in CI time or runner disk space. Acceptable tradeoff for zero client JS.