Acceptance Criteria
RuneConfig exposes a self-declared requiresParent (formalizing parent); there is no container-side allowedParents/forbiddenParents.- The pipeline detects a rune that declares
requiresParent: X appearing without an X ancestor and reports it with the rune name and location. - Severity: warning by default; error for the structurally-meaningless set (accordion-item, tab, tab-panel, breadcrumb-item, juxtapose-panel, bento-cell, definition, step, tier, map-pin, itinerary-day, itinerary-stop).
- A rune that declares no constraint is never flagged (open composition is unrestricted).
- Tests cover: a valid nesting, an error case (strict child stranded), a warning case, a third-party-style child requiring a known parent, and an unconstrained rune nested freely (no diagnostic).
Approach
The engine already threads parentRune through the recursive walk (packages/transform/src/engine.ts), so the immediate-ancestor chain is available. Either check during that walk or in a dedicated validation pass over the transformed tree. The check is purely "does this rune's self-declared required parent appear among its ancestors" — no cross-rune knowledge, no allow-list. Default non-breaking; gate the strict set as errors.
References
packages/transform/src/engine.ts (parentRune propagation)packages/content/src/pipeline.ts- Contract: SPEC-084