WORK-686
ID:WORK-686Status:done

A paragraph field takes an item model, and fills the rune's own attributes

The content model reads structured values out of a list item (itemModel) and a heading (headingExtract), but not out of a paragraph, and what it extracts can only reach an emitted child or $each (SPEC-182). This item adds both missing pieces, reusing the list-item vocabulary.

Priority:highComplexity:moderateMilestone:v0.44.0Source:SPEC-182

Criteria completion

Criteria completion: 7 of 7 (100%) checked; tracking started on Oct 30, no incremental history yet0%25%50%75%100%Oct 30Nov 4

Tracking started Oct 30 — check back for trends.

Branches 1
History 3
  1. 99771c3
    Created (done)by bjornolofandersson
  2. a23b676
    Content editedby Claude
    WORK-686, WORK-687: done, PR #738
  3. 7370042
    Content editedby Claude
    v0.44.0: a paragraph fills a rune's own values; testimonial keeps its by

Acceptance Criteria

  • A sequence field matching paragraph accepts itemModel and resolves to one record, with the list-item vocabulary unchanged (D1)
  • A field with an item model matches only a paragraph in which its required fields match; any other paragraph is left for the next field or reported unmatched (D3)
  • fills maps the rune's declared attributes to extracted fields; an undeclared attribute or an unknown $ field is rejected at definition load, naming it (D2)
  • The author's attribute wins over a filled value, and the filled value reaches the field bag, so meta blocks, the schema table and registration read it as they read the attribute (D2, D4)
  • Writing both forms keeps the attribute, consumes the paragraph and reports a fill-overridden warning naming the attribute and line (D4)
  • A filling field counts as placed for SPEC-145 D11, and placing it with a slot as well is rejected (D5)
  • The composed-runes guide documents paragraph item models and fills, and every new error code has an entry in its Errors table

References

  • SPEC-182: D1–D5.
  • SPEC-145: D4a, D11.

Resolution

Completed: 2026-10-30

Branch: claude/milestone-v0-44-0-ism7ni

What was done

  • packages/runes/src/lib/resolver.ts: a paragraph field with an itemModel resolves to one record (<field>Data) and matches only when its required item fields match (resolveParagraphItem, hasRequiredItemFields).
  • packages/types/src/content-model.ts: fills on ContentFieldDefinition.
  • packages/runes/src/lib/composition.ts: fills is validated at load (fills-invalid); a filling field counts as placed for D11, and slotting it as well is fill-placed. The transform merges filled values into the attributes before the template and schema table see them, with the author's attribute winning.
  • packages/runes/src/lib/index.ts: auditCompositionFills reports fill-overridden as a warning.
  • packages/runes/test/composition-fills.test.ts: covers D1–D5.
  • site/content/extend/rune-authoring/composed-runes.md: a section on paragraph item models and fills, plus Errors table rows.

Notes

  • Only an attribute the author wrote overrides a fill. A default does not, because defaults are applied after the fill.
  • The precedence applies per attribute: author= written with a paragraph still fills role from it.