WORK-705
ID:WORK-705Status:done

Generate a per-rune intro record from each reference page and the rune's resolution

SPEC-187 D5: the rune intro renders from data. One record per rune, beside the attribute records scripts/generate-rune-attributes.mjs already writes.

Priority:mediumComplexity:moderateMilestone:v0.48.0Source:SPEC-187
claude/composition-usage-rune-pages-c87ar6 View source

Criteria completion

Criteria completion: 6 of 6 (100%) checked; history from Nov 3 to Nov 30%25%50%75%100%Nov 3Nov 3
Branches 2
claude/composition-usage-rune-pages-c87ar6 current done
main donechangeset-release/main ready
History 3
  1. d0f3f9b
    • ☑ Each rune with a reference page has one record with `title`, `description`, `package`, `composed`, `status`, `schemaType` and `source`, and no `install` field (D8)
    • ☑ `title`, `description` and `status` are read from the reference page's frontmatter, not repeated anywhere else
    • ☑ `composed` and `source` come from how the rune resolves on the `main` site: a composition's `.md` definition, or a native rune's schema file, as a repo-relative path
    • ☑ `schemaType` is the type the rune's resolved schema row publishes with its defaults, the row `refrakt inspect <rune> --site main` prints; it is the default when an attribute changes the type or can switch it off, and empty when the rune publishes nothing (D9)
    • ☑ The drift check fails when the committed data differs from a fresh run, as it does for the attribute data
    • ☑ A test covers one core rune, one native plugin rune, one composed rune, and one rune that publishes no structured data
    by bjornolofandersson
  2. 506a927
    Content editedby bjornolofandersson
  3. f91f637
    Created (ready)by bjornolofandersson

Acceptance Criteria

  • Each rune with a reference page has one record with title, description, package, composed, status, schemaType and source, and no install field (D8)
  • title, description and status are read from the reference page's frontmatter, not repeated anywhere else
  • composed and source come from how the rune resolves on the main site: a composition's .md definition, or a native rune's schema file, as a repo-relative path
  • schemaType is the type the rune's resolved schema row publishes with its defaults, the row refrakt inspect <rune> --site main prints; it is the default when an attribute changes the type or can switch it off, and empty when the rune publishes nothing (D9)
  • The drift check fails when the committed data differs from a fresh run, as it does for the attribute data
  • A test covers one core rune, one native plugin rune, one composed rune, and one rune that publishes no structured data

Approach

Extend generate-rune-attributes.mjs or add a sibling; SPEC-187 leaves the choice open. Reading resolution from the loaded plugins, not a list, means WORK-702 to WORK-704 flip composed with no edit here.

References

  • SPEC-187: D4, D5, D8, D9.
  • SPEC-128: the generated attribute data.
  • SPEC-130: D5, visibility in place of validation.

Resolution

Completed: 2026-11-03

Branch: claude/composition-usage-rune-pages-c87ar6 PR: refrakt-md/refrakt#770

What was done

  • scripts/rune-intro.mjs: builds one record per rune reference page and writes site/content/_data/rune-intro.json (99 records). Wired into scripts/generate-rune-attributes.mjs, so npm run runes:attributes writes it and --check covers both files.
  • Fields: rune, title, description, status, unstable, package, packageLabel, packageUrl, plugin, composed, source, publishes, schemaType, schemaUrl. No install (D8).
  • scripts/rune-intro.test.mjs: synthetic core / native plugin / composed / no-schema runes; against the repo, every rune page has a record, every source exists, the composed set is cta, hero, testimonial, and the committed file is fresh.

Notes

  • A separate file rather than a sixth partition of rune-attributes.json: that artifact's partition list is pinned by its tests and its query shape.
  • composed/source rest on SPEC-153 D3: a plugin cannot define a rune in both Plugin.runes and its runeDir, so a <runeDir>/<rune>.md in the owning package is the definition. Each plugin's runeDir is read from the plugin module, not assumed. A record whose source names no file fails the build.
  • schemaType is reference dump's schemaOrg.type, the row's default (playlist: MusicAlbum, its fallback).
  • Booleans (composed, unstable, plugin, publishes) exist because Markdoc's {% if %} treats "" as true.