Rune attribute tables document attributes that do not exist, and omit ones that do
Thirteen rune reference pages carry a hand-written ## Attributes table. Two of them disagree with the rune's actual schema.
Thirteen rune reference pages carry a hand-written ## Attributes table. Two of them disagree with the rune's actual schema.
Tracking started Sep 12 — check back for trends.
A rune's attribute table lists the attributes the rune accepts, and nothing else. An author copying an example from the reference gets working Markdoc.
Two failure modes, and the first is the worse one.
collection.md documents an attribute that has never existed. Lines 139–146 carry a ### Reusable templates — item-template section with a worked example:
{% collection type="page" filter="url:/blog/*" sort="date-desc" item-template="cards:post.md" /%}
packages/runes/src/tags/collection.ts declares type, filter, sort, group, limit, show, fields, layout, group-display, empty. There is no item-template. A repo-wide search finds the string in exactly two places, both comments in config.ts; it appears in no schema, no implementation, and no test. git log -S confirms it has never been in the rune source — it entered the docs at c3fe915 and was never implemented.
The attribute was deliberately abandoned, not forgotten: a {% partial %} placed inside the collection's body does the same job, and is the more intuitive and composable pattern — it reuses the partial mechanism authors already know rather than adding a second, collection-specific way to name a template file. The docs simply kept describing the discarded design. So the fix is to document the partial-in-body pattern, not to implement item-template.
aggregate.md omits layout, chart-type, and chart-title. The page's prose covers layout="chart" correctly, and rune-catalog.md uses all three in a live example — so the feature is documented and exercised in this repo, while the table that claims to enumerate the rune's attributes is missing them.
npm run build node packages/cli/dist/bin.js reference collection --format json # → own: type, filter, sort, group, limit, show, fields, layout, group-display, empty grep -n "item-template" site/content/runes/collection.md # → documented as a live attribute with a worked example
scripts/check-rune-docs.mjs guards that every rune has a page and every type: rune page has a rune. Nothing checks what the page says about the rune. Coverage is enforced; content is not.
The tables are hand-copied from schemas that keep moving — and the reference data needed to check them has existed the whole time, as refrakt reference <name> --format json.
collection.md's ### Reusable templates — item-template section is replaced with the partial-in-body pattern, and the item-template table row goes with itaggregate.md documents layout, chart-type, and chart-titlexref.md names its required positional attribute primary, so the page and a generated table agreecollection + partial example is verified against the real content pipeline, not written from the same assumption that produced the original(A fifth criterion — "tint.md documents only preset and mode" — was withdrawn: the page is correct as written. See the correction at the top.)
Fix the pages by hand — it is a small, mechanical diff and it should not wait on tooling.
The collection.md edit is the only one that writes new prose rather than correcting a row. The replacement is a {% partial %} inside the collection body, and it must be verified against a real build before it ships: the section being replaced was itself a plausible-looking example that never worked, and swapping in a second unverified example would repeat the bug rather than fix it.
Two things suggest the pattern is sound, and neither is proof: collection.md:168 already asserts that {% link href=$item.url %} "works in any body template, partial, or table cell where $item is bound", and config.partials is handed to Markdoc's transform config, so a partial's content expands within the transform pass and per-item $item binding applies to it. Confirm with a build, not with either of those.
Preventing recurrence is SPEC-128 — generating these tables rather than checking them. This bug is deliberately independent of it: the pages are wrong today and the fix should not be blocked on a generator.
scripts/check-rune-docs.mjs — the existing guard, which covers page existence but not page contentrefrakt reference reporting; the reason tint.md's "on any parent rune" table is trustworthy is that those axes are now schema-declared per runeCompleted: 2026-09-10
Branch: claude/content-author-docs-org-vps1un
site/content/runes/collection.md — replaced the ### Reusable templates — item-template section with the partial-in-body pattern, and removed the item-template table row. item-template was never implemented; a {% partial %} in the collection body does the job.
site/content/runes/aggregate.md — added the missing layout, chart-type and chart-title rows, with their matches values.
site/content/runes/xref.md — the required positional attribute is now named primary, with a note that it is written positionally. The row existed as (positional); naming it means the page and a generated table will agree.
packages/content/test/collection-partial-template.test.ts — new. Builds a temp site and asserts the partial renders once per entity with $item bound and nothing unresolved. The interaction is not obvious — partials inline at parse time while a collection's per-item template is a deferred body re-parsed per entity (SPEC-070) — so this is pinned rather than trusted.
tint.md is correct (its second table is labelled "On any parent rune" and documents the universal tint axis); xref.md did document its required attribute, as (positional); collection.md does document show, inline in the type row. Real drift was 2 of 13 pages, not 4.