Problem
The current parse-embedded.ts implementation accumulates state in an ad-hoc way as it walks the mdast tree. Signals that determine node creation (heading level, inheritance from parent context, anchors, relationship matchers) are handled piecemeal, making the algorithm hard to reason about, extend, and debug.
Known failure cases:
- A heading that matches a relationship matcher may or may not become a node depending on what follows it — this "pending" state logic is interleaved with other concerns
- Sibling entity groups under a single parent aren't clearly modelled — e.g. an
Application page with both an embedded Tools list and an embedded Capabilities list under separate headings, alongside regular body content, lacks a clean traversal pattern
- New embedded node context (a heading that starts a new entity, not just a structural grouping) and a relationship grouping heading (e.g.
### Applications) need different handling, but the distinction isn't explicit in the walk
What needs to happen
Redesign the traversal to make signal tracking first-class:
-
Explicit signal accumulator — as the walker descends into headings, it should clearly track:
- Current heading depth and inferred type from depth
- Anchor-derived type signal
- Relationship match (which relationship definition is active, if any)
- Whether we're in a new embedded node context vs. a relationship grouping context
-
Clean state transitions — transitioning from "relationship grouping heading" → "embedded node content" → "sibling relationship group" should be explicit, not implicit from content-type lookahead
-
Sibling relationship groups — when a parent type has multiple relationships (e.g. both Tools and Capabilities embedded), each grouping heading should clearly switch the active relationship context without disturbing the parent node or other sibling groups
-
Inheritance — when a heading doesn't resolve to a new node, its content should be inherited into the parent context, not silently dropped
Likely scope
Related
- Companion issue: Reconcile overlap between relationships and hierarchy
- Test:
tests/relationship-embedded-nodes.test.ts is a failing test demonstrating one of the broken cases
Problem
The current
parse-embedded.tsimplementation accumulates state in an ad-hoc way as it walks the mdast tree. Signals that determine node creation (heading level, inheritance from parent context, anchors, relationship matchers) are handled piecemeal, making the algorithm hard to reason about, extend, and debug.Known failure cases:
Applicationpage with both an embeddedToolslist and an embeddedCapabilitieslist under separate headings, alongside regular body content, lacks a clean traversal pattern### Applications) need different handling, but the distinction isn't explicit in the walkWhat needs to happen
Redesign the traversal to make signal tracking first-class:
Explicit signal accumulator — as the walker descends into headings, it should clearly track:
Clean state transitions — transitioning from "relationship grouping heading" → "embedded node content" → "sibling relationship group" should be explicit, not implicit from content-type lookahead
Sibling relationship groups — when a parent type has multiple relationships (e.g. both
ToolsandCapabilitiesembedded), each grouping heading should clearly switch the active relationship context without disturbing the parent node or other sibling groupsInheritance — when a heading doesn't resolve to a new node, its content should be inherited into the parent context, not silently dropped
Likely scope
extractEmbeddedNodesRelated
tests/relationship-embedded-nodes.test.tsis a failing test demonstrating one of the broken cases