Rulebearing Playground Coverage Schemas GitHub

ADR-0074: The cookbook's question pages are fixtures beside the guard catalogue, and the site renders them from what the binary produced

Context

Plan 0004 asks for one cookbook page per architecture question, each with the rule in both configuration formats, the edge that breaks it and the fix, with the rules in a fixture that the docs build runs through rulebearing test and config convert, and a playground preloaded with the fixture. It places the pages and fixtures under site/.

Three facts shape where they go and how a page is kept honest:

Decision

One cookbook, two halves. The question pages live in cookbook/questions/<question>/, beside cookbook/guards/. Each is a fixture:

File Holds
README.md the page's prose, with a <!-- cookbook:<part> --> line where each generated part goes
rulebearing.yaml the rules, each with fix, a decision token and examples
repo/ a small repository that breaks the rules at least once
expected.json the violations cruise finds in repo/
converted/ config convert --to dependency-cruiser and its report of what it dropped
imported/ for an import-linter question, what import import-linter writes for repo/.importlinter, and its violations

The binary writes every generated file, and a runner holds them to it. cookbook/questions/run.sh runs rulebearing test (no rule without examples), config lint --require-comment-token --strict-compat, config convert, cruise in repo/ and, for an import-linter question, import import-linter and a cruise with what it wrote, and byte-compares each with the committed file; RB_UPDATE_SNAPSHOTS=1 rewrites them. It also requires at least one violation, and that the imported rules find the same edges as the page's rules unless the import writes slice rules, whose findings name slices rather than modules. It runs in the guards CI job beside the guard runner, and in site/build.sh before the site is generated, so neither a pull request nor a deployment can carry a page that disagrees with the binary.

The site renders a page from the committed files and nothing else. site/src/cookbook.ts replaces each marker with the file it stands for (the YAML, the converted JSON and the dropped report, the violations as a table, the contract and the imported rules) and with a playground whose embedded example is the fixture's repo/ and rulebearing.yaml, loaded as soon as the module is ready. A page that lacks a marker its fixture calls for, or carries one it has no content for, fails the build, as does a question the index cookbook/questions/README.md does not link. The generator needs no binary: it reads the files the runner checked.

Consequences

Alternatives considered

Option Why not
site/cookbook/<question>.md with fixtures under site/cookbook/fixtures/, as the plan's text has it A second cookbook beside cookbook/guards/, with its own layout, its own runner and a source tree that mixes documents with the generator's code.
Run config convert inside the generator and embed its output The generator would need the binary in every test and every build, and the committed fixture would no longer show a reviewer what changed. The runner gives the same guarantee with a diff.
Hand-write the converted form and the violations in the page, with a test that compares them Two copies of the same text, one of them in prose; the generated copy is the one that is right.
A graph per question, as the guard catalogue has The playground could only evaluate a pasted graph. A repository lets a reader see the import that breaks the rule and run the extraction too.