Skip to content

chore(docs): unbreak just; gate every .adoc on actually rendering#71

Merged
hyperpolymath merged 2 commits into
mainfrom
chore/docs-render-gate
Jul 16, 2026
Merged

chore(docs): unbreak just; gate every .adoc on actually rendering#71
hyperpolymath merged 2 commits into
mainfrom
chore/docs-render-gate

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Found while verifying #70. Two toolchain defects, both pre-existing on main.

1. just is completely broken on main

build/contractile.just:136 writes a literal grep pattern unescaped:

! grep -rl '{{[A-Z_]*}}' --include='*.a2ml' ...

just parses {{ as an interpolation, hits [A-Z_]*, and aborts before running anything. Not just that recipe — every recipe. just --list, just docs, just quality, all 124 of them:

error: expected '&&', '!=', ... but found '*'
   ——▶ build/contractile.just:136:25

{{{{ is just's escape for a literal {{. The file header says it's hand-maintained ("hand-expanded to match Xfile.a2ml checks"), so the fix won't be clobbered by regeneration. After: 124 recipes list and run.

Unbreaking it also revealed that dust-no-placeholder-tokens fails — it was never able to run. Six files carry unfilled {{PLACEHOLDER}} tokens (container/README.adoc, container/0.1-AI-MANIFEST.a2ml, .machine_readable/agent_instructions/methodology.a2ml, docs/status/TEST-NEEDS.adoc; two more — PLACEHOLDERS.adoc, Dustfile.a2ml — contain the pattern legitimately). Not fixed here — pre-existing, needs your judgement on the values. openssf-compliance.yml misses them because it only scans a curated REQUIRED_FILES list.

2. Nothing checked that .adoc files actually parse

check-no-md-in-docs.sh enforces AsciiDoc by extension. CI's docs job only checked files exist. Nothing checked they render — an unterminated block or malformed table produces mangled output and ships silently. That gap is why #69 shipped on my hand-counted delimiters rather than a real check.

Adds scripts/check-docs-render.sh (house style, matching check-no-md-in-docs.sh), renders every .adoc at --failure-level=WARN. Wired into just docs-check, just quality, and CI's docs job. Also just docs-html for local reading.

Verified it fails correctly, not just passes:

result
repo as-is PASS: 125 .adoc render cleanly (6 quarantined) → exit 0
with a deliberately broken file FAIL: unterminated table block → exit 1

The 6 quarantined files — a real finding

They're Markdown wearing an .adoc extension: a = Title line bolted onto a Markdown body (# headings, <!-- --> comments, | pipe tables). They satisfy check-no-md-in-docs.sh by extension while still being Markdown — the estate rule met in letter, not substance.

They're in an ALLOWED list rather than silently skipped, so the list is visible and meant to shrink. All 6 are RSR boilerplate — no game-design doc is affected.

Worth knowing: the render gate only catches the tip. Asciidoctor accepts ##+ as Markdown-compat headings, so a file can be wholly Markdown and still render "clean" — docs/governance/MAINTENANCE-CHECKLIST.adoc has 53 Markdown headings and passes. At least ten files are affected. A proper conversion is a separate job.

CI impact

None beyond the new gate. No workflow invokes just quality or the dust-* recipes, so unbreaking just cannot turn anything red. (Note main is already partly red independently: Governance = failure, Secret Scanner = startup_failure.)

🤖 Generated with Claude Code

hyperpolymath and others added 2 commits July 16, 2026 22:22
Two toolchain defects found while verifying #70.

1. `just` was completely broken. build/contractile.just:136 wrote a literal
   `{{[A-Z_]*}}` grep pattern unescaped, so just parsed it as an interpolation
   and aborted before running anything — `just --list`, `just docs`, `just
   quality`, all 124 recipes. `{{{{` is just's escape for a literal `{{`.
   The file is hand-maintained (see its header), so this fix holds.

2. Nothing checked that .adoc files parse. check-no-md-in-docs.sh enforces the
   AsciiDoc rule by *extension*; CI's docs job only checked that files *exist*.
   An unterminated block or malformed table renders to mangled output and ships
   unnoticed — which is why #69 shipped on hand-counted delimiters.

Adds scripts/check-docs-render.sh (renders every .adoc at --failure-level=WARN),
wires it into `just docs-check`, `just quality`, and CI's docs job. Also adds
`just docs-html` for local reading.

125 of 131 .adoc render clean. The 6 that do not are quarantined in an ALLOWED
list rather than skipped silently: they are half-converted Markdown carrying an
.adoc extension (a `= Title` bolted onto a Markdown body), which passes the
extension check while still being Markdown. All 6 are RSR boilerplate; no
game-design doc is affected.

No CI impact beyond the new gate: no workflow invokes `just quality` or the
dust-* recipes, so unbreaking just cannot turn anything red.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hyperpolymath
hyperpolymath marked this pull request as ready for review July 16, 2026 21:25
@hyperpolymath
hyperpolymath merged commit 8c3c7b6 into main Jul 16, 2026
14 of 27 checks passed
@hyperpolymath
hyperpolymath deleted the chore/docs-render-gate branch July 16, 2026 21:26
@sonarqubecloud

Copy link
Copy Markdown

hyperpolymath added a commit that referenced this pull request Jul 17, 2026
Follow-on to #71. The estate rule "AsciiDoc by default" was satisfied in
**letter, not substance**.

## The problem

Eight files have been a `= Title` line bolted onto an unmodified
Markdown body since the initial commit. They passed
`check-no-md-in-docs.sh` (named `.adoc`) and Asciidoctor's
Markdown-compat mode accepted `##` headings and ``` fences without
complaint — so they read as "clean" while rendering wrong:

- **SPDX headers rendered as visible body text** in five files. `<!--
... -->` is not a comment in AsciiDoc; the licence header was displaying
as page content.
- **21 Markdown pipe-tables rendered as garbage** — 11 of them in
`THREAT-MODEL.adoc`, so the threat model's tables did not render at all.
- **Markdown links rendered as literal `[text](url)`.**
- Every render failure shared **one root cause**: a Markdown `#` H1
parses as a *level-0* section, and a second level-0 section is a hard
error (`level 0 sections can only be used when doctype is book`).

`docs/STATE-VISUALIZER.adoc` also turned out to have its entire body
wrapped in a bogus `[source]` block — the cause of the `unterminated
listing block` warning.

## The change

Converted: **130** ATX headings, **49** code fences, **21** pipe-tables,
**8** HTML comments, **5** links, **121** `- [ ]` task markers.

Markup only — **no prose was reworded, added, or removed**. Verified by
diffing the word multiset of every file before/after: the only deltas
are added AsciiDoc tokens (`source`, `cols`, `options`, `header`,
`link`, `xref`) and the removed duplicate-title words.
`check-docs-render.sh`'s `ALLOWED` quarantine drops from **6 entries to
0**.

## The gate

Adds `scripts/check-adoc-not-markdown.sh` — the missing third leg:

| check | asks |
|---|---|
| `check-no-md-in-docs.sh` | extension: is it named `.adoc`? |
| `check-docs-render.sh` | render: does asciidoctor parse it? |
| `check-adoc-not-markdown.sh` | **dialect: is the body actually
AsciiDoc?** |

The first two *cannot* catch this class of bug — which is precisely how
it survived. The new check is block-aware, so shell `# comments` inside
listing blocks aren't mistaken for headings, and it does not flag valid
AsciiDoc that merely looks Markdown-ish (`**bold**`, `-` bullets, `>`
quotes, `* [ ]` checklists). **Verified failing on a probe file, not
merely passing.**

## Verification

```
PASS: 131 .adoc files render cleanly (0 quarantined in ALLOWED)
PASS: 131 .adoc files are genuine AsciiDoc (no Markdown syntax)
```

## Flagged, not actioned (your call)

`docs/STATE-VISUALIZER.adoc` is **template residue** — titled `= RSR
Template Repo — Project Topology`, its diagram describes "RSR TEMPLATE
HUB" and "NEW REPOSITORY (Consumer of this Template)". It is the RSR
template's own architecture doc, never adapted to this project.
`must-no-template-residue` misses it (that check only greps the
`Justfile` for one string). Rewriting or deleting it is a content
decision, so this PR only fixes its markup.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant