WORK-537
ID:WORK-537Status:ready

Separate the prose capability from the body role

body carries two meanings that were merged by accident of timing:

Priority:mediumComplexity:moderateMilestone:v0.32.0Source:SPEC-125
changeset-release/main View source

Criteria completion

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

Tracking started Sep 8 — check back for trends.

Branches 3
History 1
  1. 87cf634
    Created (ready)by github-actions[bot]

Shape

Declare the gate rather than inferring it, per SPEC-125's governing rule:

readingAxis.requires = 'prose'
TextBlock: { provides: ['prose'] }

Only one axis needs it initially, so this is close to a bespoke field in cost. It is worth the general shape because SPEC-124 already gave every facet a declaration point — requires sits beside contract and describeForRune, and flows into the structure contract for free. A bespoke proseSection on RuneConfig solves the same case and leaves the next axis to invent its own.

Acceptance Criteria

  • reading and dropcap gate on a declared prose capability, not on the body role
  • The capability is declared by the facet and provided by the rune, so the next axis needing one does not invent a bespoke field
  • The structural body role and every stylesheet keying on [data-section="body"] are unchanged
  • The 32 body-role runes are audited for whether they bear authored prose
  • DataTable, Showcase, Form, Api and Symbol no longer offer reading/dropcap; Blog, TextBlock, PullQuote, Sidenote and Lore still do
  • The structure contract's unavailable reasons reflect the new gate rather than still citing the body role
  • A breaking changeset records the runes that lose the attributes
  • npm run build, the full repo suite, and refrakt contracts --check pass

Scope grew in v0.31.0 — the audit list, not the answer

The criteria above said "~21" when this item was written. Phase 1 added a body role to twelve more runes, so the audit covers 32:

AccordionItem, Annotate, Api, BentoCell, Blog, Bond, Bug, Card, Character, CharacterSection, DataTable, Decision, Drawer, Event, Faction, FactionSection, Form, ItineraryStop, Lore, MediaText, Milestone, Organization, Playlist, PullQuote, Realm, RealmSection, Showcase, Sidenote, Spec, Symbol, TextBlock, Work.

The expected non-provider list is unchanged. All twelve additions are prose-bearing regions — a card's body, a bento cell's body, an accordion answer, a storytelling entity's or section's prose, an itinerary stop's note, the prose after a playlist's track list — so DataTable, Showcase, Form, Api and Symbol remain the five expected to lose reading/dropcap. The larger number is more runes to confirm, not more exceptions to find.

One caveat on Character: its body role is correct but its slot is always empty — prose written directly inside {% character %} is dropped by its content model (BUG-003). It provides prose in principle and none in practice until that is fixed; audit it on the intent, not on the current output.

Approach

Sequenced after WORK-534, and the order is load-bearing. The design question is the default:

  • Default-on (a body role implies prose unless a rune opts out) keeps the migration tiny, but preserves the lossy proxy as the default — so this same bug recurs for the next non-prose rune.
  • Default-off (a rune must declare that it bears prose) is honest, but a forgotten declaration silently disables reading — today's failure mode returning.

Default-off is right only once schemas have narrowed: with WORK-534 in place a forgotten declaration is no longer silent — the attribute is not offered and refrakt reference says so. Running this first would forfeit that, so take default-off and rely on the narrowing to make omissions discoverable.

Note Playlist may arrive here from WORK-531 with a newly-added structural body role and no prose — that is the intended interaction between the two items, not a conflict.

Blocked by

  • WORK-534

References

  • SPEC-125 — Phase 4, and The governing rule
  • SPEC-108 — where the proxy was introduced
  • SPEC-124 — the facet declaration point this reuses