actorThe capability map page makes refinement readable by epic
spec:consumers.spec-studio.capability-map-pageNew since the base graph base da4b141. See the diff.
Base input: schema 0.11.0, 405 Specs.
Packs: pack:roadmaps-and-slices-v1, pack:self-hosting-v1
Design: 6 design entries · 1 pinned declaration · no decisions
Findings: no errors, no warnings
specs/consumers/spec-studio.capability-map-page.sdp.md
No open questions and no blocking questions; implementation binding present, verifier binding present, and expected-outcome oracle none.
Intent
- A reviewer looking for a capability before choosing a Spec or Pack.
problem- A flat altitude filter hides how a capability is decomposed, and a large refinement drawing becomes unreadable when shrunk to the page width.
outcome- Read an epic overview, inspect its refinement structure and evidence, and narrow the index's Specs to its descendants.
Behavior
rule.pageline 32 ·specs/consumers/spec-studio.capability-map-page.sdp.md:32- The Studio publishes
capabilities.htmlon every build and links it asCapabilitiesimmediately afterPacksin the top navigation. The Packs lens keeps its membership order and the index remains the landing page.no example exercises it
rule.recipeDataline 33 ·specs/consumers/spec-studio.capability-map-page.sdp.md:33- The page reads recipe 52 with
{ detail: true }and no epic parameter. It renders every epic's own evidence beside its descendant rollup and names the rollup's scope. Examples and decisions have separate counts and expandable rows. There is no combined total obtained by adding epic rows.no example exercises it
rule.drawingline 34 ·specs/consumers/spec-studio.capability-map-page.sdp.md:34- Each epic has a refinement drawing supplied by the shared diagram implementation. It keeps parent-to-child reading order while arrows, if drawn, point child to parent and the legend says
refines. Repeated nodes link to their first occurrence within that epic section. A nested epic remains a labelled epic, not a new altitude.no example exercises it
rule.boundedline 35 ·specs/consumers/spec-studio.capability-map-page.sdp.md:35- A large branch folds at the shared diagram bound and links to its complete refinement text. At desktop width it never scales labels below the shared legibility size to fit an entire tree; below the responsive breakpoint it follows the shared legibility rule's narrow fit. The text includes every node and edge, repeats and cyclic links labelled in words, and stays readable without script.
no example exercises it
rule.linksline 36 ·specs/consumers/spec-studio.capability-map-page.sdp.md:36- Every node title links to that Spec's Studio page. A separate
Show these Specslink goes to the index's Specs section with the epic selected. Keyed questions link to their entry on the Spec page; unkeyed questions link to the Spec page'ssection.intent. Unresolved endpoints are text with their diagnostics, never plausible Spec links.no example exercises it
rule.filterline 37 ·specs/consumers/spec-studio.capability-map-page.sdp.md:37- The index's Specs filter gains
Epic, withAny,No epicand every epic by title and id. An epic selects its own Spec and every Spec whose full-corpus epicIds contains it. It intersects with the existing filters, resets with them, and never changes Pack membership or hides Pack cards.no example exercises it
rule.withoutScriptline 38 ·specs/consumers/spec-studio.capability-map-page.sdp.md:38- Native links, disclosures, complete refinement text and all Spec rows work without script. Index filtering is an enhancement: before script applies a requested epic, the index says filtering needs script and shows all rows. A supplied id that is absent or not epic reports
Unknown epic filterand leaves all rows visible.no example exercises it
rule.emptyAndDamageline 39 ·specs/consumers/spec-studio.capability-map-page.sdp.md:39- The page always has
No epic reaches these Specs, including an explicit empty message. With no epics it explains that authors may organize Specs through refinement and still lists the whole corpus. Cycles and unresolved edges are visible diagnostics beside the complete text, without a new validation rule.no example exercises it
0 unkeyed rules.
Design
routeline 43 ·specs/consumers/spec-studio.capability-map-page.sdp.md:43capabilities.html; an epic's section id is its Spec id. The filtered-index route isindex.html?epic=<percent-encoded Spec id>#specs;epic=noneselects unreached Specs, absence selects Any. An unknown or repeated epic parameter reports the unknown-filter message without applying it.no citation recorded
diagramInputline 44 ·specs/consumers/spec-studio.capability-map-page.sdp.md:44- recipe 52's node, edge, epic and unreached rows supply the drawing and its text; layout derives no reach, floor or delivery fact. The shared drawing implementation owns folding, label metrics and SVG or Mermaid representation. A capability drawing must support same-altitude edges, skipped altitudes, multiple parents, nested epics, and cycles without pretending to be a strict three-level tree.
disclosureOrderline 45 ·specs/consumers/spec-studio.capability-map-page.sdp.md:45- epic overview cards and sections follow recipe order. Each section opens with the epic's own rung, floor, binding evidence and questions, then the rollup labelled
Distinct descendants, excluding this epic. Refinement text expands a depth-first walk with children in id order and renders later visits as references; it follows the recipe's root order and uses per-section visited ids. Examples and decisions fold through native disclosures without pruning their descendants. rowEvidenceline 46 ·specs/consumers/spec-studio.capability-map-page.sdp.md:46- each row names kind and altitude,
stated <rung>,floor <rung>, the implementation binding and the verifier binding aspresentornone, and open and blocking question counts with their text available. Facts that are absent stay absent; a folded branch's counts never become the parent's badges. nestedEpicsline 47 ·specs/consumers/spec-studio.capability-map-page.sdp.md:47- a card for an epic that refines another epic says
Inside <title>, usingparentEpicIds, and a card whose descendants include an epic names it, so overlapping counts read as overlap. responsiveline 48 ·specs/consumers/spec-studio.capability-map-page.sdp.md:48- overview cards reflow to one column on a narrow viewport; refinement text wraps ids and titles, caps visual indentation, and names the parent in words so deep trees remain readable. At desktop width diagram labels use the shared readable size and bounded branches. Below the responsive breakpoint the drawing follows the legibility rule's narrow fit; the complete refinement text is the readable form. Print opens the disclosures and retains the complete text.
Verification · reviewed
criteria- Read the same page on a corpus with one broad epic, several epics, and no epics, with script disabled and at a narrow viewport.
- Follow a shared descendant from both parents and verify that the rollup counts it once and the index filter lists it once.
- Select an epic on the index, combine it with kind and readiness filters, reset it, and open the filtered URL directly; invalid and repeated epic parameters never show a false empty result.
mode- reviewed
Verification
Verifier bindings
- test:protocol.studio-capabilities · anchored · test anchor binding present ·
test/studio-capabilities.test.ts:89External run evidence from
test/studio-capabilities.test.tsTest anchors:
test:protocol.studio-capabilities. Specs verified by those bindings: spec:consumers.spec-studio.capability-map-page, spec:consumers.spec-studio.diagram-kinds.capability-tree.Run 1: external run evidence from vitest 4.1.10
Build: CI 380 · Branch: feature/roadmap-and-slices-v0 · Commit: 34909918bf0be0e849959644401797191cae379f · Start: 2026-10-22T17:40:31.456Z · Stop: 2026-10-22T17:42:16.171Z
Name Suite Result Duration folds whole sibling branches for 30 features with 1 stories Studio capabilities passed 43.76 ms folds whole sibling branches for 45 features with 5 stories Studio capabilities passed 341.22 ms folds whole sibling branches for 40 features with 40 stories Studio capabilities passed 1950.89 ms keeps reached children out of the unreached drawing and complete rows Studio capabilities passed 23.26 ms shows cycle diagnostics outside closed disclosures Studio capabilities passed 13.52 ms exports every cycle member and exact edge with the Mermaid fallback reason Studio capabilities passed 1.79 ms renders code-span titles as plain drawing words and questions as linked prose Studio capabilities passed 5.4 ms initializes epic filtering from the URL, intersects every control and resets native rows Studio capabilities passed 8.57 ms reflows capability cards, caps deep indentation and opens complete text for print Studio capabilities passed 36.15 ms folds only a leaf remainder at the root, preserves first siblings and falls back for too many roots Studio capabilities passed 51.61 ms condenses a cycle into a labelled group and retains its internal relations in words Studio capabilities passed 4.43 ms shares the detailed recipe answer and publishes a lens immediately after Packs Studio capabilities passed 0.75 ms labels nested epics, scopes distinct rollups and separates examples and decisions Studio capabilities passed 0.3 ms keeps depth-first repeats, every relation and question links to real ids Studio capabilities passed 0.5 ms renders a repeat box with its own child-to-parent arrow and groups siblings Studio capabilities passed 1.58 ms uses mindmap only for a strict tree and folds large branches without losing text Studio capabilities passed 36.37 ms keeps cycles finite, labelled and complete, and handles no epics or an empty corpus Studio capabilities passed 10.01 ms records all epic memberships on index rows and preserves Pack disclosures Studio capabilities passed 0.41 ms intersects epic selection with every existing filter and treats no epic explicitly Studio capabilities passed 0.92 ms
Design view
Requirement drawing
- Declared verifying examples: no declared verifying example.
Scroll horizontally to read the whole drawing.
The diagram as text
- spec:consumers.spec-studio.capability-map-page: The capability map page makes refinement readable by epic · declared Spec
- spec:consumers.capability-map: The capability map reads every epic and its refinement descendants · declared Spec
- spec:consumers.spec-studio.lenses: Five lenses read the graph as Packs, capabilities, architecture, tests and evidence · declared Spec
- impl:protocol.studio-capabilities-page: renders epic evidence, refinement and unreached Specs from the capability map · anchored code ·
src/projections/studio/pages/capabilities-page.ts:78 - impl:protocol.studio-filter: filters build-rendered rows through their recorded attributes · anchored code ·
src/studio-elements/filter.ts:25 - impl:protocol.studio-frame: renders Studio navigation, page rails and composing controls · anchored code ·
src/projections/studio/pages/frame.ts:6 - impl:protocol.studio-index-page: renders Pack disclosures and filterable Spec rows · anchored code ·
src/projections/studio/pages/index-page.ts:8 - test:protocol.studio-capabilities: test:protocol.studio-capabilities · anchored test binding · binding present ·
test/studio-capabilities.test.ts:89 - spec:consumers.spec-studio.capability-map-page refines spec:consumers.capability-map · declared — the page is the capability map's reading for a person
- spec:consumers.spec-studio.capability-map-page refines spec:consumers.spec-studio.lenses · declared — the Capabilities page is a lens that reads refinement
- impl:protocol.studio-capabilities-page satisfies spec:consumers.spec-studio.capability-map-page · anchored
- impl:protocol.studio-filter satisfies spec:consumers.spec-studio.capability-map-page · anchored
- impl:protocol.studio-frame satisfies spec:consumers.spec-studio.capability-map-page · anchored
- impl:protocol.studio-index-page satisfies spec:consumers.spec-studio.capability-map-page · anchored
- test:protocol.studio-capabilities verifies spec:consumers.spec-studio.capability-map-page · anchored
Mermaid source
Copyable source; the Studio draws static SVG.
Preferred and chosen syntax: requirementDiagram; exact refines, satisfies and verifies, with claim words in nodes and per-edge comments.
Decisions
No decision record named.
Runtime
component:protocol.projections· read-only output, layout and owned publication ·src/projections/design-review.ts:29· layer edge · context protocol Uses
component:protocol.extract· the carrier and source pipeline ·src/extract/index.ts:192· layer application · context protocol component:protocol.graph· the one graph and its semantic decisions ·src/graph/schema.ts:34· layer domain · context protocol component:protocol.model· the authored contracts and stable ids ·src/model/anchors.ts:100· layer domain · context protocol component:protocol.notation· the leaf step codec ·src/notation/slots.ts:261· layer domain · context protocol component:protocol.reader· the typed graph contract and body evaluator ·src/reader/reader.ts:671· layer application · context protocol component:protocol.validate· one finding currency and ordered checks ·src/validate/validators.ts:72· layer domain · context protocol
component:protocol.studio-elements· optional browser behavior and proposal handoff ·src/studio-elements/index.ts:13· layer edge · context protocol Uses
component:protocol.projections· read-only output, layout and owned publication ·src/projections/design-review.ts:29· layer edge · context protocol component:protocol.reader· the typed graph contract and body evaluator ·src/reader/reader.ts:671· layer application · context protocol
impl:protocol.studio-capabilities-page· renders epic evidence, refinement and unreached Specs from the capability map ·src/projections/studio/pages/capabilities-page.ts:78Component:
component:protocol.projections· read-only output, layout and owned publication ·src/projections/design-review.ts:29· layer edge · context protocol Uses
None.
impl:protocol.studio-filter· filters build-rendered rows through their recorded attributes ·src/studio-elements/filter.ts:25Component:
component:protocol.studio-elements· optional browser behavior and proposal handoff ·src/studio-elements/index.ts:13· layer edge · context protocol Uses
None.
impl:protocol.studio-frame· renders Studio navigation, page rails and composing controls ·src/projections/studio/pages/frame.ts:6Component:
component:protocol.projections· read-only output, layout and owned publication ·src/projections/design-review.ts:29· layer edge · context protocol Uses
None.
impl:protocol.studio-index-page· renders Pack disclosures and filterable Spec rows ·src/projections/studio/pages/index-page.ts:8Component:
component:protocol.projections· read-only output, layout and owned publication ·src/projections/design-review.ts:29· layer edge · context protocol Uses
None.
Runtime observation: not tracked.
Evidence
Runtime observation: not tracked.
Build attestations: not tracked.
Deployments: not tracked.
Bills of materials: not tracked.
Impact
The diagram as text
- spec:consumers.binding-language-views: Views speak binding language, never the internal fact name
- spec:consumers.capability-map: The capability map reads every epic and its refinement descendants
- spec:consumers.spec-studio.capability-map-page: The capability map page makes refinement readable by epic
- spec:consumers.spec-studio.diagram-kinds: The Studio chooses diagram kinds from graph values
- spec:consumers.spec-studio.index-page: The index says where the corpus stands and narrows every Spec
- spec:consumers.spec-studio.lenses: Five lenses read the graph as Packs, capabilities, architecture, tests and evidence
- spec:consumers.spec-studio.capability-map-page dependsOn spec:consumers.binding-language-views · declared — aggregate rows use the same binding labels as Spec pages
- spec:consumers.spec-studio.capability-map-page dependsOn spec:consumers.capability-map · declared — the page and index filter render the capability map's answer
- spec:consumers.spec-studio.capability-map-page dependsOn spec:consumers.spec-studio.diagram-kinds · declared — the refinement drawing shares the Studio's diagram layout and accessible text contract
- spec:consumers.spec-studio.capability-map-page dependsOn spec:consumers.spec-studio.index-page · declared — the Epic filter extends the index's Specs filters
- spec:consumers.spec-studio.capability-map-page refines spec:consumers.capability-map · declared — the page is the capability map's reading for a person
- spec:consumers.spec-studio.capability-map-page refines spec:consumers.spec-studio.lenses · declared — the Capabilities page is a lens that reads refinement
Mermaid source
Copyable source; the Studio draws static SVG.
Preferred syntax: flowchart. Chosen syntax: labelled flowchart, preserving exact relations, claims and folds.
Rests on
- refines · spec:consumers.capability-map · stated ready, floor ready
- refines · spec:consumers.spec-studio.lenses · stated ready, floor ready
- dependsOn · spec:consumers.binding-language-views · stated ready, floor ready
- dependsOn · spec:consumers.capability-map · stated ready, floor ready
- dependsOn · spec:consumers.spec-studio.diagram-kinds · stated ready, floor ready
- dependsOn · spec:consumers.spec-studio.index-page · stated ready, floor ready
Rested on by
No Spec rests on this Spec.
Relations
| Relation and direction | Other end | Claim | Reason | Exercised keys |
|---|---|---|---|---|
| dependsOn · outgoing | Views speak binding language, never the internal fact namespec:consumers.binding-language-views · resolves | declared | aggregate rows use the same binding labels as Spec pages | None |
| dependsOn · outgoing | The capability map reads every epic and its refinement descendantsspec:consumers.capability-map · resolves | declared | the page and index filter render the capability map's answer | None |
| dependsOn · outgoing | The Studio chooses diagram kinds from graph valuesspec:consumers.spec-studio.diagram-kinds · resolves | declared | the refinement drawing shares the Studio's diagram layout and accessible text contract | None |
| dependsOn · outgoing | The index says where the corpus stands and narrows every Specspec:consumers.spec-studio.index-page · resolves | declared | the Epic filter extends the index's Specs filters | None |
| refines · outgoing | The capability map reads every epic and its refinement descendantsspec:consumers.capability-map · resolves | declared | the page is the capability map's reading for a person | None |
| refines · outgoing | Five lenses read the graph as Packs, capabilities, architecture, tests and evidencespec:consumers.spec-studio.lenses · resolves | declared | the Capabilities page is a lens that reads refinement | None |
Bindings
Implementation binding: present
impl:protocol.studio-capabilities-page· renders epic evidence, refinement and unreached Specs from the capability map ·src/projections/studio/pages/capabilities-page.ts:78· role projection · component component:protocol.projections· layer edge · context protocolimpl:protocol.studio-filter· filters build-rendered rows through their recorded attributes ·src/studio-elements/filter.ts:25· role interaction · component component:protocol.studio-elements· layer edge · context protocolimpl:protocol.studio-frame· renders Studio navigation, page rails and composing controls ·src/projections/studio/pages/frame.ts:6· role projection · component component:protocol.projections· layer edge · context protocolimpl:protocol.studio-index-page· renders Pack disclosures and filterable Spec rows ·src/projections/studio/pages/index-page.ts:8· role projection · component component:protocol.projections· layer edge · context protocol
Design reference: none
Verifier binding: present
- test:protocol.studio-capabilities · anchored ·
test/studio-capabilities.test.ts:89· test anchor
Expected-outcome oracle: none
Runtime observation: not tracked.
Run results: not recorded in the graph.
Findings
None.
Composing (0)
Composing needs the script.