Extending Musewoods
Extending Musewoods should make the system more expressive without making its authoring grammar less coherent. The first question is therefore not “where do I add a component?” but “what new responsibility is the platform being asked to carry?” Once that responsibility is clear, the implementation should enter at the narrowest existing boundary and preserve the same expectations around validation, accessibility, Ground behavior, field ownership, tests, and Guide coverage.
The default posture is reuse. If an existing motif, analytical primitive, resolver, or field adapter already expresses the semantics, extend through that contract rather than creating a parallel path. New vocabulary earns its place only when the system would otherwise be forced to misrepresent the authored meaning.
The Governing Instinct
Do not add an abstraction when a responsibility already exists
If a
ledger,field,evidence, or another registered motif already carries the intended structure, use it. A new motif should represent a distinct editorial or analytical responsibility, not a preference for a slightly different arrangement.The registry is the contract
Public vocabulary belongs in the registry or field model that owns it. A new capability may require only registration and treatment when an existing renderer already understands the shape; a genuinely new structure or behavior may also require validation, a renderer, interaction logic, and accessibility work. The extension should be explicit at the contract boundary rather than hidden in route- or title-specific conditionals.
Authors express meaning; renderers own mechanics
Authored content should not specify pixel coordinates, D3 callbacks, ad hoc CSS, or the physical location of remote data. Authors declare semantics and bounded treatments; renderers and infrastructure translate those declarations into geometry, interaction, and data resolution.
Ground is consumed, never forked
A Story- or Grove-aware component consumes semantic Ground tokens and should preserve the same structure across Grounds. If a feature needs a separate Forest Floor implementation merely to change its appearance, the presentation abstraction has leaked into behavior.
Shared behavior has one home
Shared editorial motifs live in the common motif layer, shared analytical primitives in the analytical layer, and charts in the chart engine. A field adapter can decide whether and how a capability is hosted, but it should not create a second implementation of the same behavior.
Context is not a publishing field
Clearing extends meaning across canonical objects; it does not become another field adapter or a destination for copied editorial content. New semantic capability should enter through the relationship registry, context resolver, provenance model, or Clearing projection boundary rather than by adding
clearingto field-wide switches. Until those contracts exist in code, use the normative Clearing System design and do not invent route-local implementations.The same boundary applies to book vocabulary such as Allures, Roots, Connections, Canopy, and Arrival. A specialized v9 behavior may exist under a particular subsystem, but the concept does not become a general authoring or runtime primitive until a release deliberately defines its schema, validator, renderer, compatibility policy, and tests.
Navigation is not a publishing field
Trailheads and Trailmaps cross canonical work without becoming additional publishing fields. A Trailhead extension should enter through the v2 semantic journey model or the v1 compatibility boundary it actually changes. A Trailmap extension should enter through graph model, validation, projection, or Explorer interaction. Do not add
trailheadortrailmapbranches to Story, Journal, Viewgraph, or Grove field switches merely to reuse layout or routing behavior.Circulation is not a publishing field
Resonance extends audience relationship across canonical objects; it does not become another field adapter or a destination for copied editorial content. A Trailhead extension should enter through Trailhead source/model/projection, a relationship extension through Follow, and a journey-measurement extension through the bounded signal grammar rather than by adding
resonanceto every field switch statement.
Recipe — Add A Story Motif
01 Shape
Write down the semantic job first, then the smallest authoring shape that can express it: fields, item cardinality, child grammar, optionality, and any meaningful treatment values. If the shape is already representable through an existing motif, stop here and reuse it.
02 Register
Add the public name and summary to the Story vocabulary owned by the render layer. Registration should make the capability discoverable to normalization, documentation generation, and coverage checks rather than relying on a renderer that only happens to recognize a special case.
03 Validate
Add validation only for structural conditions that a renderer cannot safely or meaningfully recover from: missing required fields, impossible counts, invalid references, or unsupported enumerated values. Do not turn aesthetic preference into a build failure.
04 Render
Reuse the generic block path whenever the shape is ordinary. Add a dedicated component only when real structure or interaction requires one, and style it through stable motif/treatment hooks rather than a content title, route slug, or one-off page selector.
05 Cover
Add a minimal fixture, a live Field Manual specimen or canonical gallery example, and the appropriate coverage entry. Coverage should prove that the registered capability is both documented and actually renderable through the production path.
06 Prove
Regenerate derived vocabulary when applicable, then run the full content, test, type, and build chain. An extension is not complete because the new page looks right locally; it is complete when the registries, validators, renderers, documentation, fixtures, and build all agree on the new contract.
Recipe — Add A Chart Family
A chart family crosses more boundaries than a visual motif because type semantics, validation, geometry, interaction, field permission, canonical data, and gallery coverage must stay aligned. The sequence below is therefore a useful dependency order rather than a suggestion to scatter chart behavior across unrelated modules.
Figure 1
Rendering diagram…
| Step | Responsibility |
|---|---|
| Register the family | declare the chart type and type-specific authored fields in the chart model |
| Validate semantics | enforce required dimensions, numeric expectations, accessibility, and density guidance |
| Draw the family | implement geometry in the shared D3 chart layer rather than in a field-specific renderer |
| Declare interaction | state which interaction modes the family can support without distortion |
| Gate by field | narrow interaction or treatment where a host field's editorial contract requires it |
| Cover it | add the family to the canonical gallery and its exhaustiveness/regression tests |
Extension Recipes, In Full
Answer every question before adding anything
A new motif in the Grove field's own registry — only when no existing Grove motif already expresses the structure.
- When to add this:
ledger,field,evidence, or another existing native motif cannot represent the semantic job without distortion. - Responsibility added: one new registered Grove authoring pattern.
- Files touched: the Grove motif model/validator and, only if necessary, the Grove motif component registry.
- Minimum authoring fixture: the smallest valid
**Render:**section that proves the new responsibility. - Model / registry change: add the public name to the Grove registry; reserve internal vocabulary for build-time Guide/runtime machinery, not author-facing features.
- Validation: enforce structure and bounded enumerations, not editorial taste.
- Renderer / geometry: reuse common Markdown block rendering where possible and keep geometry out of authored fields.
- Field adapter: none when the motif is Grove-native; shared behavior belongs in the shared layer instead.
- Ground awareness: consume semantic Ground tokens and avoid component branches whose only purpose is recoloring.
- Accessibility: semantic headings, visible focus, and no color-only state.
- Tests: model/validator tests plus the smallest render fixture needed to prove the contract.
- Field Manual coverage: add the appropriate live Guide or specimen coverage reference.
- Done when: content validation, tests, typecheck, and build all pass with the new capability covered.
A Story- or Grove-rendered surface that must remain legible and semantically identical on both supported Grounds.
- When to add this: a new or shared component renders inside a Story or Grove Ground boundary and needs to consume Ground-aware presentation tokens.
- Responsibility added: normally none; this is implementation correctness, not new authoring vocabulary.
- Files touched: shared styles/tokens unless behavior itself changes.
- Minimum authoring fixture: a laboratory or Guide specimen that can be inspected on both Grounds.
- Model / registry change: none unless the feature introduces new authored semantics.
- Validation: usually none; visual token misuse is better caught by tests/review than by inventing a content rule.
- Renderer / geometry: consume semantic Ground roles and keep component structure stable.
- Field adapter: use a scoped host treatment only when a shared component genuinely needs Story- or Grove-specific surface adaptation.
- Ground awareness: never globally re-tone unrelated Musewoods surfaces from inside a Story or Grove boundary; embedded Viewgraph frames retain their canonical surface.
- Accessibility: verify contrast, focus, and non-color state on every supported Ground.
- Tests: Ground/token regression tests plus Story Ground coverage and visual inspection in the Grove laboratories.
- Field Manual coverage: required only if author-facing capability changed.
- Done when: the same composition remains structurally identical and readable on both Grounds.
A new structural check for an existing motif, field, or shared model.
- When to add this: malformed source can currently reach a renderer that cannot honor it safely or deterministically.
- Responsibility added: a source-oriented failure at the correct model boundary.
- Files touched: the validator owned by the relevant field or shared subsystem.
- Minimum authoring fixture: one valid case and one deliberately invalid case kept in tests rather than shipped content.
- Model / registry change: only if the validation rule depends on new declared vocabulary.
- Validation: report the authored file/section context and the violated contract; avoid leaking irrelevant renderer internals.
- Renderer / geometry: unchanged; validation should fail before the renderer is forced to guess.
- Field adapter: none unless the rule is specifically a host permission constraint.
- Ground awareness: not applicable unless the rule itself governs authored Ground values.
- Accessibility: apply when the validator is protecting an accessibility requirement such as required
Alttext. - Tests: one passing and one failing fixture with assertions on the meaningful failure condition.
- Field Manual coverage: update Architecture & Validation when the public structural contract changes.
- Done when: invalid source fails predictably and valid source continues through the production pipeline.
A new frame render, layout, primitive, or presentation behavior in the Viewgraph vocabulary.
- When to add this: the fixed logical frame needs a visual responsibility not representable by the existing vocabulary.
- Responsibility added: one explicit Viewgraph contract, including layout compatibility where relevant.
- Files touched: Viewgraph vocabulary/model, renderer, and tests; shared chart/media engines remain separate when reused.
- Minimum authoring fixture: the smallest valid frame that proves the new capability at the canonical logical size.
- Model / registry change: add the vocabulary entry and its accepted child structure/treatments.
- Validation: reject layout-incompatible children or impossible frame structures before geometry is attempted.
- Renderer / geometry: preserve the fixed-frame contract and solve density through authored composition, not microscopic type or frame expansion.
- Field adapter: none; Viewgraphs is already the host field.
- Ground awareness: Viewgraph surface choice is distinct from the Grove Ground system.
- Accessibility: keyboard-operable controls, visible focus, and meaningful
Alttext for authored visual media. - Tests: model/layout tests plus the canonical Viewgraph presentation fixture.
- Field Manual coverage: update this Guide when the capability changes public authoring or architecture.
- Done when: the frame works at the canonical logical size and degrades into the intended reading reflow on smaller screens.
A new infrastructure strategy for resolving a logical dataset reference into rows for the shared chart engine.
- When to add this: the existing resolver chain cannot reach a required data source without pushing physical location details into authored content.
- Responsibility added: one bounded resolution strategy with explicit failure behavior.
- Files touched: the chart data-resolution layer and its tests.
- Minimum authoring fixture: a logical
**Data:**reference that resolves through the new strategy. - Model / registry change: add the resolver to the ordered resolution chain only where its precedence is unambiguous.
- Validation: reject unsafe, malformed, or unresolved references before chart rendering.
- Renderer / geometry: unaffected; the resolver returns rows and metadata, not presentation decisions.
- Field adapter: none; data resolution is field-agnostic unless a host explicitly restricts allowable sources.
- Ground awareness: not applicable.
- Accessibility: not applicable directly, though resolved data must still support the chart's first-frame accessibility contract.
- Tests: resolver-specific tests plus the existing shared chart-spec/data tests.
- Field Manual coverage: update only when the author-facing data contract changes.
- Done when: authored source keeps logical identity while infrastructure owns physical retrieval.
A change to v2 Encounter roles, cardinality, transitions, routes, relationships, target semantics, Trailmap bridge, or compatible rendering hints; v1 changes remain isolated to their circulation compatibility lane.
- When to add this: the journey needs a genuinely new semantic responsibility rather than a cosmetic change to one Trailhead.
- Responsibility added: one explicit semantic rule in the source/model boundary, with projection behavior consuming the normalized result rather than inventing private meaning.
- Files touched: the v2 Trailhead schema/model/validation/discovery and journey projection boundaries; touch v1 Resonance files only when the legacy circulation grammar itself changes.
- Minimum authoring fixture: the smallest v2 Trailhead that proves the new semantic rule, including an invalid counterpart when validation is part of the change.
- Model / registry change: preserve stable Encounter ids, semantic roles, route semantics, and the BEGIN Trailmap bridge; do not make a React component the source of a new role.
- Validation: reject unsupported roles, invalid cardinality, broken transitions/routes, incompatible motifs, malformed relationships, or unresolved canonical references before projection.
- Renderer / geometry: the journey renderer owns geometry; author source never owns node coordinates, connector mechanics, or responsive placement.
- Field adapter: none; Trailheads are Navigation System instruments rather than a fifth publishing field.
- Accessibility: preserve server-rendered reading order, keyboard traversal, and reduced-motion behavior for progressive enhancement.
- Tests: v2 parser/model/validation/projection tests plus representative long-form journey fixtures; v1 regression tests remain separate.
- Field Manual coverage: update Trailheads and Architecture & Validation when the public contributor contract changes.
- Done when: the new meaning is expressible in source, validated before render, survives production build, and does not alter unrelated publishing-field or v1 Resonance contracts.
A change to Trailmap regions, node ontology, edge kinds/relations, Trails, Horizons, provenance, projection hints, Waymarker interaction, or Trailhead bridge semantics.
- When to add this: the innovation field needs a new graph responsibility that cannot be represented faithfully through the current v9 model.
- Responsibility added: one bounded semantic or interaction rule that remains independent of hand-authored geometry.
- Files touched:
content/trailmaps/fixtures and the relevantlib/trailmaps/{model,parse,normalize,validate,load,library,graph,projection}boundary; projection/UI work may also touch the Trailmap shared components and/trailmapsroutes. - Minimum authoring fixture: the smallest canonical
trailmap.yamlthat proves the new graph structure, plus a malformed source proving the validator rejects the corresponding failure. - Model / registry change: extend the bounded vocabulary centrally; do not mint node types, edge kinds, or relation semantics inside one renderer or one map.
- Validation: preserve unique ids, valid regions/endpoints/routes/Horizons, provenance basis, reachability, and canonical refs.
- Renderer / geometry: projection owns deterministic layout, region gravity, active-Trail emphasis, Glimpse, Encounter Lens, and responsive geometry. Authors do not place Waymarkers with pixel coordinates.
- Field adapter: none; a Venture Trailmap is a Navigation System field representation, not another publishing field.
- Accessibility: Waymarkers, Glimpse, Encounter Lens, Trail selection, and deeper-source actions remain keyboard reachable; hover-only meaning is invalid.
- Tests: graph normalization/validation, registry discovery, route reachability, interaction state, keyboard/focus behavior, and production
/trailmapsrendering. - Field Manual coverage: update Venture Trailmaps, Architecture & Validation, and System Health when the public contract changes.
- Done when: the same semantic graph can be projected without authored node geometry, selection deepens the field before optional source exit, and Trailhead bindings continue to resolve.
A different AsciiMath implementation, a wider MathML allowlist, or a new content surface adopting `{{math: ...}}` / `:::math`.
- When to add this: the current adapter cannot express a needed AsciiMath construct, the sanitizer's allowlist rejects MathML the adapter can legitimately produce, or a new content surface already parses through the shared parser and renders through
ContentBlocks.tsx/InlineContent.tsxand simply needs to be proven. - Responsibility added: none, in the common case — Math is registered once in the shared parser (
lib/storyboard-parser.mjs) and is therefore already available to Story, Journal, Grove, Viewgraph, and Trailhead. Extending it usually means widening one existing boundary, not adding a new one. - Files touched:
lib/math/ascii-math-to-mathml.mjsfor a different adapter;lib/math/sanitize-mathml.mjsfor a wider allowlist; a positive block-type allowlist in a new surface's own model (the fix Trailhead v2'sRENDERABLE_BLOCK_TYPESneeded) for a new surface. - Minimum authoring fixture: the smallest
{{math: ...}}/:::mathexpression that exercises the new construct or surface. - Model / registry change: none for the Math node itself —
MathBlock/ the"math"InlineTokenalready carrysource,normalizedSource,mathml,status, anddiagnostics(lib/storyboard.ts). - Validation: an unsupported construct must fail into the existing safe-source fallback, never a page-breaking error; a sanitizer change must be proven against both the new legitimate output and a hostile-input regression case.
- Renderer / geometry:
MathInline/MathBlockpresent only; they must never gain AsciiMath-parsing logic of their own. - Field adapter: none, unless the new surface's own content model filters block types with a positive allowlist rather than reusing
ContentBlockdirectly. - Ground awareness: Math inherits
colorfrom its surrounding text; it should not need its own per-Ground styling. - Accessibility: semantic MathML, not an image or canvas rendering, remains the non-negotiable output.
- Tests: adapter/conversion tests for the new construct, a sanitizer allowlist/rejection pair, and a cross-surface test proving the new surface's real loader (not only the shared component).
- Field Manual coverage: update Architecture & Validation's Math Expressions section when the adapter, sanitizer boundary, or surface list changes.
- Done when: the expression renders as sanitized, semantic MathML in server-rendered HTML, and a malformed expression still degrades to its own safe source text.
A new bounded journey event, or a versioned change to what engagement or Return means.
- When to add this: the existing eight-event grammar cannot represent a materially new journey fact without overloading an existing event.
- Responsibility added: one bounded semantic event or one new version of an interpretation policy.
- Files touched: the signal registry/validator and, for interpreted events, the versioned engagement or return-policy module.
- Minimum fixture: a valid event using an opaque actor id plus a deliberately invalid payload proving identity and vocabulary boundaries.
- Model / registry change: register semantics centrally; routes must not mint event names or threshold rules locally.
- Validation: reject unregistered names and email addresses in event payloads.
- Renderer / geometry: none.
- Field adapter: none; field crossing is event data, not a field-specific event engine.
- Accessibility: not applicable directly.
- Tests: event validation, policy versioning, rollup consequences where applicable, and identity-separation regression coverage.
- Field Manual coverage: update Resonance System when the bounded public grammar changes.
- Done when: raw history remains stable while changed interpretation is expressed through explicit versioned policy.
A transport adapter behind Musewoods-owned consent, Follow, Trailhead, suppression, and send semantics.
- When to add this: production delivery requires a transport beyond the development outbox.
- Responsibility added: provider
send,sendTest, delivery-event normalization, and provider message identifiers only. - Files touched: provider adapter/registration plus provider-specific tests and configuration.
- Minimum fixture: a rendered test edition passed through the provider boundary without re-modeling followers or Trailheads.
- Model / registry change: register the provider and select it with
RESONANCE_MAIL_PROVIDER; do not add provider vocabulary to authored Trailhead source. - Validation: preserve bearer boundaries, suppression/eligibility checks, and idempotent production sends before transport is invoked.
- Renderer / geometry: none; provider receives rendered artifacts rather than owning projection.
- Field adapter: none.
- Accessibility: preserve the canonical email projection output.
- Tests: transport normalization, test send, failure handling, duplicate production-key behavior, and zero-send behavior on repeated idempotent calls.
- Field Manual coverage: update Resonance System's provider boundary if the public operational contract changes.
- Done when: changing transport does not change Trailhead, Follow, event, or canonical content semantics.
Anti-Patterns
Parallel field engines
A shared semantic responsibility should not grow one behavior engine per field. Fields can adapt presentation and permission, but copied logic creates drift in validation, interaction, accessibility, and future maintenance.
Authored pixel geometry
Margins, coordinates, callback code, and chart geometry belong to renderers. Authors may choose bounded semantic treatments such as
wide; they should not become layout programmers inside Markdown.Hard-coded field color
Shared components should consume semantic Palette or host tokens. A route name or literal field color embedded in component logic is a coupling defect.
Direct chart fetches
Charts ask the data-resolution layer for rows through a logical reference. Authored analytical content should not couple itself to infrastructure topology or duplicate data-fetch policy.
Global Ground leakage
Story and Grove Ground belong at their bounded page/shell roots. Embedded Viewgraph frames and unrelated Musewoods surfaces should retain their own canonical token contracts rather than inheriting a local Ground accidentally.
Separate dark-mode components
Forest Floor is a governed re-toning of one semantic surface contract, not a second component tree. Forking component structure for appearance guarantees behavior drift later.
Parser bypass
Every public authored shape should enter through a registered model and validation boundary. Silent acceptance is especially dangerous because it turns implementation accidents into undocumented authoring contracts.
Clearing as field number five
Do not add Clearing to publishing-field navigation, field manifests, or field-wide switches. Do not create a parallel canonical content model merely to host context that belongs to Stories, Journals, Viewgraphs, or Groves. Clearing is a semantic system layer; when it needs a durable human-facing place, project it through a Grove rather than redefining the field architecture.
Trailmap as a visual sitemap
Do not create a graph whose only semantic content is page titles connected by lines, and do not make a Waymarker click an automatic exit to another page. A Venture Trailmap must represent innovation topology and should first deepen a selected Waymarker inside the field through Glimpse/Encounter Lens context.
Resonance as field number five
Do not add Resonance to publishing-field navigation, field manifests, motif adapters, or field-wide switches simply to reuse field infrastructure. It is a cross-field system layer whose content plane references canonical objects.
Provider-owned audience semantics
A mail vendor may transport a rendered edition and normalize delivery feedback; it must not become the source of truth for Follow, consent, attribution, Trailhead structure, or suppression policy. Those remain Musewoods semantics.
Generic analytics event sprawl
Do not turn
/api/resonance/eventsinto an open collection endpoint or invent route-local event names. The bounded event grammar and versioned engagement / Return policies exist specifically to keep journey signals interpretable and identity-separated.
