Skip to content

ARC-ADR-045 — Unified untool.ai Documentation Site (hub-aggregated, docs.untool.ai)

Field Value
ID ARC-ADR-045
Status Accepted
Date 2026-05-30
Deciders Hub owner (Nicky Clarke)

Context

The fleet's documentation was fragmented:

  • The AgentArmy hub publishes a MkDocs + Material site (deploy-docs.yml → GitHub Pages) covering the template, agents, and ADRs.
  • Each spoke (frontend-core, backend-core, middle-core) carries its own docs/ (~30 markdown files total — design system, agent runtime, knowledge loop, ontology & data objects, charters, research) but published nowhere — orphaned.

The spokes are dual-natured: they are spokes generated by the AgentArmy template factory and the building system for the untool.ai platform. Their documentation is therefore mostly a platform story, not template scaffolding. We want one site that reads as the untool.ai platform, aggregating every layer, without each spoke standing up its own site.

Decision

  1. Aggregate into the hub, single build. Spoke docs/ are synced into the hub at docs/platform/<spoke>/ at build time by scripts/sync-spoke-docs.sh (invoked from deploy-docs.yml). Each spoke remains the single source of truth for its own docs; the hub holds no committed copies (the synced subdirs are gitignored).
  2. Auto-nav via awesome-pages. The Platform Layers nav entry points at the platform/ directory; mkdocs-awesome-pages-plugin expands it from the file tree, so newly-synced spoke pages appear with no hand-editing of nav: (the drift that hid the untool docs + ~20 ADRs — see #379 — cannot recur for synced content).
  3. Graceful sync. A missing token or an unavailable spoke is skipped with a ::warning::; the docs build never fails because one layer is briefly unreachable.
  4. Host at docs.untool.ai. docs/CNAME sets the GitHub Pages custom domain; a Cloudflare CNAME docs.untool.ai → nickpclarke.github.io completes it (Cloudflare is an operator-owned step).
  5. Content split. Hub docs describe the layers at the template level (how a spoke is generated, routed, synced); the per-layer pages under platform/ are the platform story.

Consequences

  • + One canonical untool.ai docs site; orphaned spoke docs become discoverable.
  • + Reuses the working hub pipeline; no per-spoke Pages infra to maintain.
  • + Sync + awesome-pages remove the manual-nav drift class of bug for layer docs.
  • Synced snapshots are only as fresh as the last hub docs build (acceptable: the build runs on every hub docs/**/mkdocs.yml change and can be workflow_dispatch-triggered). A future enhancement is a spoke→hub callback that triggers the hub build on spoke docs/ changes (the claude/mkdocs-pipeline-repos-* trigger already scaffolds this direction).
  • Cross-tree relative links in spoke docs may warn at build (non-fatal); curating each spoke's docs/ toward platform-only content is a follow-up.

Alternatives considered

  • mkdocs multirepo/monorepo plugin (build-time include without copying): cleaner in theory but adds a plugin + cross-repo checkout coupling at build; the sync step is simpler and reuses the same actions/checkout-free flow. Revisit if copy latency becomes an issue.
  • Federated per-spoke sites: rejected — counter to a single unified untool.ai site.
  • 379 (mkdocs nav drift fix — untool docs + all ADRs published)

  • 376 (ADR-number collision guard) · ARC-ADR-039 (foundations as perspectives)