WORK-534
ID:WORK-534Status:ready

Narrow rune schemas to applicable universal attributes

createContentModelSchema merges all ~37 universal attributes unconditionally:

Priority:highComplexity:complexMilestone:v0.32.0Source:SPEC-125

Criteria completion

Criteria completion: 0 of 8 (0%) checked; tracking started on Sep 6, no incremental history yet0%25%50%75%100%Sep 6Sep 6

Tracking started Sep 6 — check back for trends.

The rule must be declared, not inherited from a constructor

Six runes carry hand-written schemas and therefore no universal attributes at all, and the split is mostly principled:

RuneReason
xref, badgeinline: truecorrect — block axes are meaningless on a span
tint, bgconfigurator runes that supply axis values to a parentcorrect — a {% tint %} with its own tint= is circular
iconeffectively an inline glyphprobably correct; confirm
expandblock-level disclosureprobably wrong; reads as legacy

So availability needs at least three inputs — inline-ness, configurator-ness, and rune-structural applicability — expressed as a rule rather than left to which constructor a schema happened to use.

Migrating these six to createContentModelSchema is a non-goal. Four would end up declaring "no universal attributes" anyway.

Acceptance Criteria

  • createContentModelSchema merges only the applicable universal attributes
  • Availability is governed by a declared rule accounting for inline-ness, configurator runes, and structural applicability — not by constructor choice
  • expand and icon are each explicitly assessed and their outcome recorded
  • Language-server completion narrows with no theme-config loading added to the completion path; covered by a test
  • The structure contract's unavailable entries and the narrowed schemas agree — the two derivations must not diverge, and a test enforces it
  • The migration path is decided from real impact and documented; a breaking changeset accompanies it
  • Transform output is unchanged — this changes what may be written, not what is emitted
  • npm run build, the full repo suite, and refrakt contracts --check pass

Approach

This is the breaking change. {% card reading="prose" %} moves from a silent no-op to a Markdoc validation error. Intended — the author gets no feedback at all today — but it will fail builds on existing content.

Exposure is probably low: most of it is content setting an attribute that never did anything, on a rune that never could honour it, so the likely source is copy-paste between runes. And v0.31.0 removed the sharpest cases in advance — the runes an author is most likely to have written reading on are the six whose roles were missing, and those now work rather than erroring.

Before committing to rejection, measure. ADR-028 keeps a transitional alternative open: keep schemas permissive for one minor and have the tooling annotate rather than reject, narrowing in the release after. Decide from the real numbers, not from the estimate above.

The "declared slots for a rune" helper from WORK-532 is likely reusable here.

Blocked by

  • WORK-533

References

  • SPEC-125 — Phase 3
  • ADR-028 — including the annotate-don't-reject alternative