This is the record of an abcd-managed repository

abcdBetav0.16.2 · 2026-11-06

Development record

abcdev.app is rendered from this repository alone

adracceptedadr-47

Context

abcdev.app serves the MkDocs Material rendering of docs/ at the root; the repository behind it holds a rich, machine-readable development record nobody can see without reading frontmatter on GitHub. The 2026-08-21 investigation and the ideate verdict (survives) establish the shape: / becomes a landing page for product thinkers, the docs move to /docs/, and a record explorer renders the record. Two ecosystem facts constrain the architecture: Material for MkDocs is in maintenance mode (announced November 2025) with MkDocs 2.0 removing plugins, and the unauthenticated GitHub API allows 60 requests/hour per IP — so the build can depend on neither MkDocs extension points nor runtime API calls.

Decision

  1. The website is a surface of this repository and of nothing else. It is generated by an abcd site verb family in the binary (abcd site build, abcd site check), a sibling of the surfaces .abcd/positioning.json already re-renders from the Identity block; the site hero becomes the fourth registered surface. One repository; there is no abcd-web.
  2. The single-source rule: no text is written for the website. Every sentence the site renders is a span of a repository file selected by path and heading through .abcd/site.json; the only words the generator may add are the interface strings in site-src/ui.json, plus numbers, dates, file names and asset names. Every picture is a committed asset under docs/assets/img/, referenced from a docs page; the build inlines SVGs (var(--token, fallback) colours) and optimises rasters, and never draws. A sentence that would improve the site is written into docs/ or the record, where it must also read true on GitHub.
  3. The build fails loudly on unsourced or drifted content: on a rendered text node without a source, on composed text that breaks the docs-lint banned-token rules, on an abcd … snippet that differs from the generated CLI reference, and on an unresolved cross-reference outside the committed baseline (.abcd/site-baseline.json — a ratchet seeded with the dangling references known today; fixing one shrinks it, growing it fails). The banned-token gate's scope is explicit so its coverage is auditable: it covers the composed surfaces — / and every span selected through .abcd/site.json — whichever tree the span came from; the verbatim record rendering at /record/** is exempt (the record legitimately contains change-narration and tool names, and rewriting it to look better on the site is exactly what this ADR forbids), and the contributors page prints model names under the declared attribution escape. The naming of human authors on that page, which itd-136 delivered under this decision, is superseded by ADR-2610291037481588 (2026-10-29): the page counts people and names none, and the escape for model names stands.
  4. SSG-agnostic by construction. MkDocs Material keeps rendering /docs/ for now; the generator writes plain files and depends on no MkDocs plugin or hook, so the SSG is replaceable by a later ADR (due before Material's maintenance window closes, ~November 2026).
  5. Amendment to adr-30: the record stays out of the launch payload, but the site renders it at /record/ as a third publication surface, distinct from both trees — the boundary is never bundled, rendered read-only. The record is rendered into site/record/** by the site build, never copied into docs/; the adr-28 launch boundary is unchanged.
  6. The record explorer has a repo-agnostic input contract; genericity is demonstrated, never claimed. The explorer pages (/record/…, /contributors/, /references/) consume only the record format, git history and CHANGELOG.md — the generalisation gauntlet (verdict: reframed) verified that no abcd-only input appears in them — but abcd site build may not describe itself as repo-agnostic until a second, sparse managed instance (a committed fixture repo at minimum, driven through the same CLI surface in CI with golden-file output) exercises every graceful-absence and graceful-sparsity path. The zero-configuration default renders the durable record (.abcd/development/**) only; publication of the working-tier issue ledger is an explicit per-repo opt-in in .abcd/site.json, per adr-32's tiering. The references page ships only when a renderer compatible with the no-Node and no-committed-HTML constraints exists, and the generic claim inherits itd-9's schema-migration obligation the moment schema_version moves. The landing page is opt-in composition declared in the repo's .abcd/site.json; deployment stays with the repo (at most a scaffolded, itd-93-style parity-tested workflow); abcd never becomes a static-site generator for arbitrary content.

Alternatives Considered

  • A second repository (abcd-web): cleanest reproducibility story (abcd-web@sha builds abcd@tag) and the shape Kubernetes, Go, Rust and Atuin use — rejected because the single-source rule is a property of one tree at one commit (the manifest, the allowlist, docs-lint, the record and the docs must be reviewable in one PR and checkable by one CI job on one commit), because the generator is product code (the binary rendering its own record), because a split re-creates the dev→public mirror adr-28 abolished, and because the peer group that actually resembles abcd (GoReleaser, golangci-lint, Task, mise, chezmoi, uv) keeps its site in-repo. Evidence that would reopen this: localisation, a second product on the same site, or documentation contributors who are not CLI contributors.
  • A Node-based SSG (Starlight, VitePress, Docusaurus) for the whole site: rejected — brings a Node toolchain into a repo that has none, against the single-binary ethos and the new-dependency gate.
  • MkDocs plugins/hooks as the generation mechanism: rejected — MkDocs 1.x is unmaintained, Material is in maintenance mode, MkDocs 2.0 removes plugins; generation stays outside the SSG.
  • Copy written for the site (taglines, invented testimonials, logo walls): rejected — the site selects and arranges repository text; the only testimonial is the newest shipped intent with a MET audit, quoted verbatim.
  • "Repo-agnostic by construction, from day one, zero configuration": the generalisation gauntlet's adversarial leg killed the wording — abcd's own record is written by the format's designers, so nothing in the rollout exercises sparse, malformed or absent inputs, and a genericity claim without a demonstrated second instance is exactly what evaluate-at-the-user-surface and enforcement-claims-are-facts refuse. Rejected in favour of the demonstrated-genericity gate in decision 6.
  • Keep the generator abcd-specific, structured for later extraction: rejected — the research leg verified the explorer consumes no abcd-only input, so specificity would be a choice rather than a constraint; the demonstrated-genericity gate captures the honest middle without foreclosing the adoption story (itd-139).

Consequences

  • The site intents are itd-135 (landing page, umbrella), itd-136 (record explorer pages), itd-137 (relationship chart and genealogy) and itd-138 (install.sh); the README→docs migration and the generator itself are plumbing, recorded in the brief.
  • README's product narrative moves verbatim into docs/explanation/{rationale,roles,artefacts,process}.md and docs/how-to/install.md; README becomes a contributor page whose universal one-liner must agree with the per-OS forms by test.
  • .abcd/site.json, site-src/ui.json and .abcd/site-baseline.json join the committed configuration; the site build gains CI gates (provenance, docs-lint over rendered text, snippet drift, the baseline ratchet, the 390 px mobile audit).
  • The deploy trigger and cadence are adr-48's.

Frontmatter

idadr-47
typeadr
statusaccepted
date2026-08-22

References12

Referenced by6

mentions21