WORK-695
ID:WORK-695Status:done

Section's header grammar is declared, and the hand-written reader goes

SPEC-186 D5: section's header is read from a declared header group (eyebrow, headline, blurb), and sectionHeaderParts and its header-role reader are removed.

Priority:mediumComplexity:moderateMilestone:v0.47.0Source:SPEC-186

Criteria completion

Criteria completion: 5 of 5 (100%) checked; history from Nov 1 to Nov 30%25%50%75%100%Nov 1Nov 3
Branches 1
History 3
  1. 06ec403
    • ☑ `section`'s content model declares its header as an optional group, and its transform reads the header from the resolved model
    • ☑ The `header` attribute's `headline` and `none` modes are conditional models
    • ☑ The media and footer zones split as before, through a delimited model
    • ☑ `sectionHeaderParts` and the reader registered in `schemaHeaderRoles` are removed; the composition audit reads the declared model
    • ☑ Every existing section, hero, cta and testimonial test passes unchanged
    by bjornolofandersson
  2. 6e4cec3
    Created (ready)by bjornolofandersson
  3. f315698
    Content editedby Claude
    Withdraw pullquote variant="plain"; v0.47.0 planned for SPEC-185 and SPE

Acceptance Criteria

  • section's content model declares its header as an optional group, and its transform reads the header from the resolved model
  • The header attribute's headline and none modes are conditional models
  • The media and footer zones split as before, through a delimited model
  • sectionHeaderParts and the reader registered in schemaHeaderRoles are removed; the composition audit reads the declared model
  • Every existing section, hero, cta and testimonial test passes unchanged

Blocked by

  • WORK-692

References

  • SPEC-186: D5.
  • ADR-046

Resolution

Completed: 2026-11-03

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

What was done

  • packages/runes/src/tags/section.ts:
    • sectionContentModel(attrs): a header group by mode, then body; delimited media/content/footer zones when split;
    • the transform reads the resolved model;
    • sectionHeaderParts, SectionHeaderParts and sectionZones are removed.
  • packages/runes/src/lib/header-roles.ts:
    • HeaderRoleHost holds { roles, model };
    • readHeaderRoles resolves the declared model, searching zones one level down;
    • auditSlotHeaderRoles uses it.
  • section registers { roles: eyebrow/headline/blurb, model: sectionContentModel }.
  • packages/runes/test/section-declared-model.test.ts.

Notes

  • Output unchanged: section, hero, cta and testimonial tests, the SEO baseline and contracts are untouched, and validate is clean on every site.
  • Behaviour change only in theory: a split with 4+ --- zones now reports the extras as content-unmatched instead of folding them into the body. None exist.