Spec Studio

The capability map page makes refinement readable by epic

spec:consumers.spec-studio.capability-map-pageUse Case / Behavior · storyready floor ready

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
actor
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.page line 32 · specs/consumers/spec-studio.capability-map-page.sdp.md:32
The Studio publishes capabilities.html on every build and links it as Capabilities immediately after Packs in the top navigation. The Packs lens keeps its membership order and the index remains the landing page.

no example exercises it

rule.recipeData line 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.drawing line 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.bounded line 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.links line 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 Specs link 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's section.intent. Unresolved endpoints are text with their diagnostics, never plausible Spec links.

no example exercises it

rule.filter line 37 · specs/consumers/spec-studio.capability-map-page.sdp.md:37
The index's Specs filter gains Epic, with Any, No epic and 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.withoutScript line 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 filter and leaves all rows visible.

no example exercises it

rule.emptyAndDamage line 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
route line 43 · specs/consumers/spec-studio.capability-map-page.sdp.md:43
capabilities.html; an epic's section id is its Spec id. The filtered-index route is index.html?epic=<percent-encoded Spec id>#specs; epic=none selects unreached Specs, absence selects Any. An unknown or repeated epic parameter reports the unknown-filter message without applying it.

no citation recorded

diagramInput line 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.
disclosureOrder line 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.
rowEvidence line 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 as present or none, 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.
nestedEpics line 47 · specs/consumers/spec-studio.capability-map-page.sdp.md:47
a card for an epic that refines another epic says Inside <title>, using parentEpicIds, and a card whose descendants include an epic names it, so overlapping counts read as overlap.
responsive line 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:89

    External run evidence from test/studio-capabilities.test.ts

    Test 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 391 · Branch: cursor/media-plan-and-articles-09b1 · Commit: 076cd4f1f85640d8236e5cca1bffffa68ab79a33 · Start: 2026-10-31T15:32:20.471Z · Stop: 2026-10-31T15:34:02.073Z

    NameSuiteResultDuration
    folds whole sibling branches for 30 features with 1 storiesStudio capabilitiespassed49.24 ms
    folds whole sibling branches for 45 features with 5 storiesStudio capabilitiespassed324.65 ms
    folds whole sibling branches for 40 features with 40 storiesStudio capabilitiespassed1924.22 ms
    keeps reached children out of the unreached drawing and complete rowsStudio capabilitiespassed24.85 ms
    shows cycle diagnostics outside closed disclosuresStudio capabilitiespassed16.96 ms
    exports every cycle member and exact edge with the Mermaid fallback reasonStudio capabilitiespassed3.69 ms
    renders code-span titles as plain drawing words and questions as linked proseStudio capabilitiespassed5.35 ms
    initializes epic filtering from the URL, intersects every control and resets native rowsStudio capabilitiespassed9.11 ms
    reflows capability cards, caps deep indentation and opens complete text for printStudio capabilitiespassed39.26 ms
    folds only a leaf remainder at the root, preserves first siblings and falls back for too many rootsStudio capabilitiespassed65.42 ms
    condenses a cycle into a labelled group and retains its internal relations in wordsStudio capabilitiespassed5.58 ms
    shares the detailed recipe answer and publishes a lens immediately after PacksStudio capabilitiespassed0.84 ms
    labels nested epics, scopes distinct rollups and separates examples and decisionsStudio capabilitiespassed0.33 ms
    keeps depth-first repeats, every relation and question links to real idsStudio capabilitiespassed0.52 ms
    renders a repeat box with its own child-to-parent arrow and groups siblingsStudio capabilitiespassed4.31 ms
    uses mindmap only for a strict tree and folds large branches without losing textStudio capabilitiespassed57.15 ms
    keeps cycles finite, labelled and complete, and handles no epics or an empty corpusStudio capabilitiespassed12.08 ms
    records all epic memberships on index rows and preserves Pack disclosuresStudio capabilitiespassed0.48 ms
    intersects epic selection with every existing filter and treats no epic explicitlyStudio capabilitiespassed0.82 ms
Design view

Requirement drawing

  • Declared verifying examples: no declared verifying example.
Requirement drawing for spec:consumers.spec-studio.capability-map-page

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:78

    Component: 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:25

    Component: 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:6

    Component: 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:8

    Component: 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
Relations of spec:consumers.spec-studio.capability-map-page
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

Rested on by

No Spec rests on this Spec.

Relations

Relation and directionOther endClaimReasonExercised keys
dependsOn · outgoingViews speak binding language, never the internal fact name
spec:consumers.binding-language-views · resolves
declaredaggregate rows use the same binding labels as Spec pagesNone
dependsOn · outgoingThe capability map reads every epic and its refinement descendants
spec:consumers.capability-map · resolves
declaredthe page and index filter render the capability map's answerNone
dependsOn · outgoingThe Studio chooses diagram kinds from graph values
spec:consumers.spec-studio.diagram-kinds · resolves
declaredthe refinement drawing shares the Studio's diagram layout and accessible text contractNone
dependsOn · outgoingThe index says where the corpus stands and narrows every Spec
spec:consumers.spec-studio.index-page · resolves
declaredthe Epic filter extends the index's Specs filtersNone
refines · outgoingThe capability map reads every epic and its refinement descendants
spec:consumers.capability-map · resolves
declaredthe page is the capability map's reading for a personNone
refines · outgoingFive lenses read the graph as Packs, capabilities, architecture, tests and evidence
spec:consumers.spec-studio.lenses · resolves
declaredthe Capabilities page is a lens that reads refinementNone

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 protocol
  • impl: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 protocol
  • impl: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 protocol
  • impl: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.