Development record
abcdev.app is rendered from this repository alone
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
- The website is a surface of this repository and of nothing else. It is
generated by an
abcd siteverb family in the binary (abcd site build,abcd site check), a sibling of the surfaces.abcd/positioning.jsonalready re-renders from the Identity block; the site hero becomes the fourth registered surface. One repository; there is noabcd-web. - 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 insite-src/ui.json, plus numbers, dates, file names and asset names. Every picture is a committed asset underdocs/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 intodocs/or the record, where it must also read true on GitHub. - 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. - 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). - 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 intosite/record/**by the site build, never copied intodocs/; the adr-28 launch boundary is unchanged. - 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 andCHANGELOG.md— the generalisation gauntlet (verdict: reframed) verified that no abcd-only input appears in them — butabcd site buildmay 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 momentschema_versionmoves. 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@shabuildsabcd@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}.mdanddocs/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.jsonand.abcd/site-baseline.jsonjoin 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
| id | adr-47 |
|---|---|
| type | adr |
| status | accepted |
| date | 2026-08-22 |
.abcd/development/decisions/adrs/0047-abcdev-app-rendered-from-this-repository.md
open on GitHub ↗ · commit history ↗
References12
- adr-28One repository, a curated release artifact — no dev→public mirrorrelated
- adr-30Design-record information architecture — flat artefact-type foldersrelated
- adr-32The issue ledger is working-tier data, not authored recordrelated
- adr-37Releases are changelog-driven — rolling `[Unreleased]` is the release decision, and automation tags exactly that commitrelated
- adr-48The website deploys on release, not on mergerelated
- adr-2610291037481588The contributors page counts people and names nonerelated
- itd-135Iris opens abcdev.app and understands who abcd is for, what they and their facilitator own, and how to install it — from one page rendered from the repositoryrelated
- itd-136Alice opens the record explorer and reads the whole development record — every decision, intent, spec and issue as a page, with contributors and references — without reading YAML on GitHubrelated
- itd-137Maya sees how every decision connects — one relationship chart with a date coil and a links-only layout, and a five-lane genealogy of the record over timerelated
- itd-138Bob installs abcd with one checksum-verified command served from the project's own domainrelated
- itd-139Carol's team adopts abcd and gets a readable record the next day, without writing a line of site coderelated
- itd-140The Generic/Specific Boundary of the Site Generator Is a Gate, Not a Hoperelated
Referenced by6
- adr-2609301720596683abcd adds a missing site label to an existing ui.json and never rewrites onerelated
- adr-2610091010387033abcdev.app may render public abcd-managed repositories other than abcdrelated
- adr-2610141949110653The brief session's browser editor ships as a vendored bundle the binary embedsrelated
- adr-2610142147242544abcd's record is built onto its own GitHub Pages, and abcdev.app becomes abcd's documentation siterelated
- itd-2610091010348892An opted-in project's record is built at each release onto its own GitHub Pagesrelated
- itd-2610142145236613abcd's own record is built onto its GitHub Pages like any project'srelated
mentions21
- dcn-26082200000000042026-08-22 — The abcdev.app website enters the record: adr-47 (rendered from
- dcn-26082300000000042026-08-23 — Manual-test triage rulings (maintainer): (1) spc-38's "every
- dcn-26093000000000212026-09-30 — An older site interface-string file keeps building: `abcd site setup` and `abcd site build` add to `site-src/ui.json` each label the allowlist declares and the file does not carry, with abcd's default words, name each on stderr, and change nothing else in it (the product thinker's ruling TG1 of 2026-09-30, relayed verbatim: "(b) ABCD ADDS THE MISSING LABELS: on the next site setup or site build, abcd adds only the missing required labels (with the default words); the project's own wording elsewhere in ui.json is never changed. No failure, no manual step; both intents stay impact: additive."). It is the one exception to "a file the repository owns once it exists is kept", recorded as adr-2609301720596683, which refines adr-47 and leaves decision 2's closed allowlist untouched: a blank declared label and an unknown key are still refused, and the site gate's own render never completes the file. itd-2609212103568351 and itd-2609212103572513 keep `impact: additive` (lane tgLabels of autonomous run A).
- iss-2608220150157503The docs toolchain is on a closing maintenance window: MkDocs 1.x has had no release since August 2024, Material for MkDocs announced maintenance mode in November 2025 (critical bug fixes and security updates for 12 months at least, no new features), and MkDocs 2.0 removes plugins entirely. An SSG decision (Zensical, Hugo/Hextra, or other) is due as an ADR before the window closes, around November 2026; adr-47 keeps generation outside the SSG so the migration touches only mkdocs.yml, overrides and the build command
- iss-2608220750024263adr-47 decision 2 says the site build optimises rasters, but the stdlib-only generator copies rasters verbatim; optimisation needs either an image-codec dependency (sign-off gate) or pre-optimised committed assets
- iss-2608220750024303adr-47 decision 2's allowlist of generator-added words does not name image alt text, yet the migrated docs pages carry alt text the site inherits; the carve-out wants an explicit ADR amendment
- iss-2608220750029986adrs/README.md index omits the accepted adr-47 and adr-48 rows (site-build session) — fourth recurrence of the unindexed-ADR class after adr-45 (iss-38 wants these indexes gated); rows added in the same change that records this
- iss-2608221342508040seven check-config JSON files sit flat in the abcd directory; the maintainer suggests a config sub-tree, which needs one convention decision covering all of them plus an adr-47 amendment for the site pair
- iss-2608230752354925Contributor author rows should link to forge profiles, derived deterministically (no API per adr-47) from the forge noreply email pattern, graceful absence otherwise. Includes the repo-side .mailmap fix: the old-format noreply <login>@users.noreply.github.com (39 commits) is not folded into the product thinker's canonical name; maintainer authorised the one-line unification 2026-08-23 (report 19).
- iss-2608231001035445A dedicated print layout for the record, and a downloadable PDF report of the whole Record section (future intent seed). The 2026-08-23 print pass is a stylesheet that stops the worst faults — blank sheets, sliced cards, printed chrome — and it stops there: a closed disclosure still prints as its summary alone outside Chromium, the relationship chart's list is deliberately left collapsed, and nothing composes a document a reader would want to keep. This intent is the designed thing: a print/PDF surface for /record/** with its own page furniture (running heads, page numbers, a contents page, record ids as cross-references rather than links), and a single 'download the record' artefact a visitor can take away. Generic-side under itd-140 — inputs stay the record format, git history and CHANGELOG.md — and adr-47's single-source rule applies unchanged: the document selects spans, it never writes prose. Open questions for the interview: is the PDF built at site-build time (deterministic, attestable, adds a renderer dependency) or printed by the reader's browser from a print stylesheet (no dependency, no attestation, engine-dependent); and does it cover the record only or the whole site.
- iss-2608271711535817the brief's canonical docs tree drifted from the shipped tree: .abcd/development/brief/05-internals/03-configuration.md line 441 names the task-oriented home guides/ while the shipped directory, docs/README.md and every other reference say how-to/, and the tree block lacks an assets/ line although adr-47 decision 2 sanctions that directory. Correct the tree block — rename guides/ to how-to/ keeping the comment, add the assets/ line citing adr-47. No file moves; the shipped tree is the truth.
- iss-2609231010077584itd-157 ac-3 narrowed: the intent promised that the overlap gate 'flags the by-links overlap as a red result', and the delivery (PR #555, 64ac809c) widens the count to both arrangements and prints it (internal/surface/cli/site.go:201 'N overlapping bubbles across both arrangements'), but nothing outside the test suite goes red on a non-zero count — 'site build' exits 0 with the number in its summary, and 'site check' (internal/core/site/check.go) never reads Layout.Overlaps, so the make site-render gate passes a record whose by-links picture overlaps. The only red is TestBuildLayoutDoesNotOverlap over the test fixture and TestByLinksNeverOverlaps over synthetic corpora, neither of which sees a user's record. Either 'site check' should refuse on a non-zero published count or the intent's criterion should say the gate is the test suite
- iss-2610091010558682The research the routing of itd-2610091010348892 owes before planning has not been done: how abcdev.app can build pages from other public GitHub repositories within the GitHub API's limits (60 unauthenticated requests an hour, adr-47) and its terms, whether to fetch on a schedule, on an owner's request or from the owner's own release, and how comparable hosted documentation services handle opt-in, rebuilds and takedown.
- iss-2610262035542834The site internals page puts a second-instance demonstration ahead of any repo-agnostic claim; the site chapter already ships site setup for any repository abcd manages
- iss-2610262042028384The site chapter says no repo-agnostic explorer claim is made until a second instance proves it; shipped itd-2609061543533170 claims the pages render for every managed repository.
- itd-9Old Lifeboats Still Unpack
- itd-93abcd Scaffolds a Release Gate That Works on the First Try
- spc-37iris-opens-abcdev-app-and-understands-who-abcd-is-for-what-t
- spc-38alice-opens-the-record-explorer-and-reads-the-whole-developm
- spc-40bob-installs-abcd-with-one-checksum-verified-command-served
- spc-2610141709430146the-product-thinker-and-the-technical