Spec Studio

The Studio renders from the reader's values and embeds only what its script reads

spec:consumers.spec-studio.dataContract · storyready floor ready

Packs: pack:self-hosting-v1, pack:spec-studio-v1

Design: 5 design entries · 5 pinned declarations · no decisions

Findings: no errors, no warnings

specs/consumers/spec-studio.data.sdp.md

No open questions and no blocking questions; implementation binding present, verifier binding present, and expected-outcome oracle none.

The build writes each value into the page's markup, so a page reads in full as HTML. Search is the exception: a browser refuses a fetch from a page opened through file://, so the search page carries its index inside it. On the first adopter's corpus that index is too large to repeat on every page, which is why search runs on a page of its own.

Intent
outcome
Render every Studio page from the values the reader returns for the graph the agent surface reads, so a page derives nothing of its own and carries only the data its script needs.
Contract
rule.readerValues line 24 · specs/consumers/spec-studio.data.sdp.md:24
The build renders the index from specs(), packs(), findings(), each Spec's design columns and the epic memberships recipe 52 answers, a Pack page from packContext and the Pack totals, a Spec page from specContext, and the search page from the search index; every page's rail renders the rail values. A page states no value the reader did not return or a named recipe did not answer, apart from counts the build takes of those values.

no example exercises it

rule.embeddedData line 25 · specs/consumers/spec-studio.data.sdp.md:25
A page whose script reads data embeds it in one script element of type application/json with the id sdp-data, serialized as JSON with every < then written as the six characters \u003c, so no text can close the element. The search page embeds the search index there; every other page embeds no data, because its values are in its markup.

no example exercises it

rule.noDataFiles line 26 · specs/consumers/spec-studio.data.sdp.md:26
The page set writes no data file of its own: an agent reads the graph through sdp q, and sdp build writes the serialized graph.

no example exercises it

rule.noSlices line 27 · specs/consumers/spec-studio.data.sdp.md:27
The Studio's data holds no context bundle or other AI slice: the context bundle is composed on each invocation and never saved, and a design pass composes one with its recipe when it needs it. A slice page renders the design slice's answer into its markup, as every page renders its values, and embeds no slice data.

no example exercises it

0 unkeyed rules.

Design
packTotals line 30 · specs/consumers/spec-studio.data.sdp.md:30
{ members: number; unresolved: number; heldBelowNextRung: number; waitingForAuthor: number; entries: number; declarations: number; openQuestions: number; blockingQuestions: number; withImplementations: number; withReferences: number; restsOn: number; restedOnBy: number; verifiedBy: number; supersededBy: number }, the totals recipe 29 returns for the Pack, each counted as that recipe counts it.

no citation recorded

railValues line 31 · specs/consumers/spec-studio.data.sdp.md:31
{ packs: { id: string; title?: string; members: { id: string; title?: string; statedReadiness?: string; ownsExampleSpace: boolean }[] }[]; findings: { errors: number; warnings: number } }, the values every page's rail renders: each Pack in id order with its members in authored order, a member owning an example space when its Spec context carries one, and the validation report's findings counted by severity.

no citation recorded

searchIndex line 32 · specs/consumers/spec-studio.data.sdp.md:32
{ records: SearchRecord[] }, one record per graph node, in id order.

no citation recorded

searchRecord line 33 · specs/consumers/spec-studio.data.sdp.md:33
{ id: string; nodeType: "Primitive" | "Pack" | "Anchor" | "CodeNode"; page: string | null; title?: string; label?: string; framing?: string; narrative?: string; sections?: Record<string, unknown>; file?: string; line?: number; specKind?: string; statedReadiness?: string; floorReached?: string | null; bindings: { edge: string; specId: string }[]; entries: SearchEntry[] }: title, label, framing, narrative and sections exactly as the graph node holds them, the fields findByConcept reads; page the node's page path in the page set, null for an Anchor or a CodeNode; file and line as recorded; the kind and the two rungs on a Spec only, floorReached null when no rung derives; bindings the Specs an Anchor's or CodeNode's outgoing edges reach, with the edge type, and empty for any other node.

no citation recorded

searchEntry line 34 · specs/consumers/spec-studio.data.sdp.md:34
{ section: string; entry: string | null; key: string | null; address: string | null; line: number | null; text: string }, one per value recipe 23's walk reaches in a Spec's narrative and sections, taken with no term: each string, and each value that is not a string under a key the author coins, as its JSON text; in that walk's order, with that recipe's entry path, coined key, address and line. A term matches an entry as that recipe matches it, a string by its key or text and any other value by its key only, so the entries a term matches are the rows recipe 23 returns for it.

no citation recorded

Verification

Verifier bindings

  • test:protocol.studio-data · anchored · test anchor binding present · test/studio-data.test.ts:26

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

    Test anchors: test:protocol.studio-data. Specs verified by those bindings: spec:consumers.spec-studio.data, spec:consumers.spec-studio.publisher.

    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
    counts every Pack exactly as recipe 29Studio data over 'Protocol'passed516.47 ms
    keeps one search record per node, fields unchanged and bindings decodedStudio data over 'Protocol'passed443.96 ms
    matches recipe 23's exact rows for suffixStudio data over 'Protocol'passed429.99 ms
    matches recipe 23's exact rows for ruleStudio data over 'Protocol'passed438.74 ms
    matches recipe 23's exact rows for typeStudio data over 'Protocol'passed374.75 ms
    matches recipe 23's exact rows for outcomeStudio data over 'Protocol'passed438.99 ms
    matches recipe 23's exact rows for orderStudio data over 'Protocol'passed362.31 ms
    matches recipe 23's exact rows for decisionStudio data over 'Protocol'passed302.81 ms
    matches recipe 23's exact rows for graphOnlyStudio data over 'Protocol'passed430.63 ms
    keeps rails in Pack-id and authored-member order, with severity and space ownershipStudio data over 'Protocol'passed356.57 ms
    counts every Pack exactly as recipe 29Studio data over 'checkout'passed3.92 ms
    keeps one search record per node, fields unchanged and bindings decodedStudio data over 'checkout'passed3.37 ms
    matches recipe 23's exact rows for suffixStudio data over 'checkout'passed4.05 ms
    matches recipe 23's exact rows for ruleStudio data over 'checkout'passed8.03 ms
    matches recipe 23's exact rows for typeStudio data over 'checkout'passed9.6 ms
    matches recipe 23's exact rows for outcomeStudio data over 'checkout'passed5.91 ms
    matches recipe 23's exact rows for orderStudio data over 'checkout'passed5.11 ms
    matches recipe 23's exact rows for decisionStudio data over 'checkout'passed2.74 ms
    matches recipe 23's exact rows for graphOnlyStudio data over 'checkout'passed3.89 ms
    keeps rails in Pack-id and authored-member order, with severity and space ownershipStudio data over 'checkout'passed3.39 ms
    serializes embedded JSON with no literal less-than characternot recordedpassed0.34 ms
    encodes uppercase ids without case-insensitive page collisionsnot recordedpassed0.31 ms
    preserves coined non-string entries, question and rule addresses and their linesnot recordedpassed0.83 ms
    keeps term addresses, keys and physical lines aligned with recipe 23not recordedpassed4.8 ms
    shares only parameterless recipe answers within one Studio evaluationnot recordedpassed1.52 ms
Design view

Requirement drawing

Requirement drawing for spec:consumers.spec-studio.data
The diagram as text
  • spec:consumers.spec-studio.data: The Studio renders from the reader's values and embeds only what its script reads · declared Spec
  • spec:consumers.spec-studio.data.inputs: The Studio reads two named inputs beside the graph, a base graph and run records · declared Spec
  • spec:consumers.spec-studio.data.recipe-answers: A page takes each recipe answer from the recipe's shipped body · declared Spec
  • spec:consumers.spec-studio.data.inputs.both-given: Both inputs add their pages, named, and the same inputs write the same bytes · declared Spec
  • spec:consumers.spec-studio.data.inputs.graph-only: Without inputs the page set is the graph's alone · declared Spec
  • spec:consumers.spec-studio: The Spec Studio is a static HTML workbench over the one graph · declared Spec
  • impl:protocol.studio-base-input: reads named Studio base graphs and run inputs · anchored code · src/cli/studio-inputs.ts:9
  • impl:protocol.studio-command: validates and renders the Studio with independent byte checks and diagnostic exit codes · anchored code · src/cli/studio-command.ts:106
  • impl:protocol.studio-data: assembles reader contexts, Pack totals, rails and search records for static pages · anchored code · src/projections/studio/data.ts:279
  • impl:protocol.studio-inputs: named base graph and run input contract · anchored code · src/projections/studio/inputs.ts:1
  • impl:protocol.studio-recipes: evaluates shipped recipe bodies once and shares answers between Studio pages · anchored code · src/projections/studio/recipes.ts:34
  • impl:protocol.studio-register-contracts: shared recipe answer shapes for Studio registers · anchored code · src/projections/studio/pages/register-answers.ts:4
  • oracle:protocol.studio-inputs: oracle:protocol.studio-inputs · anchored oracle binding · test/studio-s4.test.ts:417
  • test:protocol.studio-data: test:protocol.studio-data · anchored test binding · binding present · test/studio-data.test.ts:26
  • test:protocol.studio-graph-only: test:protocol.studio-graph-only · anchored test binding · binding present · test/studio-s4.test.ts:434
  • test:protocol.studio-inputs-both-given: test:protocol.studio-inputs-both-given · anchored test binding · binding present · test/studio-s4.test.ts:464
  • test:protocol.studio-lenses: test:protocol.studio-lenses · anchored test binding · binding present · test/studio-s1.test.ts:273
  • spec:consumers.spec-studio.data refines spec:consumers.spec-studio · declared
  • spec:consumers.spec-studio.data.inputs refines spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.data.inputs.both-given refines spec:consumers.spec-studio.data.inputs · declared
  • spec:consumers.spec-studio.data.inputs.both-given verifies spec:consumers.spec-studio.data.inputs · declared
  • spec:consumers.spec-studio.data.inputs.graph-only refines spec:consumers.spec-studio.data.inputs · declared
  • spec:consumers.spec-studio.data.inputs.graph-only verifies spec:consumers.spec-studio.data.inputs · declared
  • spec:consumers.spec-studio.data.recipe-answers refines spec:consumers.spec-studio.data · declared
  • impl:protocol.studio-base-input satisfies spec:consumers.spec-studio.data.inputs · anchored
  • impl:protocol.studio-command satisfies spec:consumers.spec-studio.data.inputs · anchored
  • impl:protocol.studio-data satisfies spec:consumers.spec-studio.data · anchored
  • impl:protocol.studio-inputs satisfies spec:consumers.spec-studio.data.inputs · anchored
  • impl:protocol.studio-recipes satisfies spec:consumers.spec-studio.data.recipe-answers · anchored
  • impl:protocol.studio-register-contracts references spec:consumers.spec-studio.data.recipe-answers · anchored
  • oracle:protocol.studio-inputs models spec:consumers.spec-studio.data.inputs · anchored
  • test:protocol.studio-data verifies spec:consumers.spec-studio.data · anchored
  • test:protocol.studio-graph-only verifies spec:consumers.spec-studio.data.inputs.graph-only · anchored
  • test:protocol.studio-inputs-both-given verifies spec:consumers.spec-studio.data.inputs.both-given · anchored
  • test:protocol.studio-lenses verifies spec:consumers.spec-studio.data.recipe-answers · anchored
Mermaid source

Copyable source; the Studio draws static SVG.

Preferred syntax: requirementDiagram. Chosen syntax: flowchart TB because models, references, folds require exact labels unavailable in requirement syntax.

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
  • impl:protocol.studio-data · assembles reader contexts, Pack totals, rails and search records for static pages · src/projections/studio/data.ts:279

    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.data
The diagram as text
  • spec:consumers.pack-design: The Pack context carries the Pack's design
  • spec:consumers.reader: The reader bridges agent entry points to composable graph context
  • spec:consumers.spec-studio: The Spec Studio is a static HTML workbench over the one graph
  • spec:consumers.spec-studio.components: The Studio's custom elements each hold one view the build renders
  • spec:consumers.spec-studio.data: The Studio renders from the reader's values and embeds only what its script reads
  • spec:consumers.spec-studio.data.inputs: The Studio reads two named inputs beside the graph, a base graph and run records
  • spec:consumers.spec-studio.data.recipe-answers: A page takes each recipe answer from the recipe's shipped body
  • spec:consumers.spec-studio.diagram-kinds.requirement-trace: A requirement drawing separates intent from realization and verification
  • spec:consumers.spec-studio.diagrams: A diagram is laid out from graph values into SVG with a text equivalent
  • spec:consumers.spec-studio.glossary-page: The glossary page lists every term the corpus's Specs define
  • 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.owner-queue: The owner queue page orders the statements and questions only a person can settle
  • spec:consumers.spec-studio.pack-page: A Pack page shows the Pack's design as one card per member
  • spec:consumers.spec-studio.publisher: sdp studio publishes the Studio as one page set
  • spec:consumers.spec-studio.registers: The corpus's registers are pages a reviewer opens from a link
  • spec:consumers.spec-studio.roadmap-page: The roadmap page shows the upcoming work in priority order, split by what it needs
  • spec:consumers.spec-studio.search: Search finds a Spec, a Pack, an entry or a bound file by a word
  • spec:consumers.spec-studio.shell: The Studio's shell frames every page with navigation, a rail and a canvas
  • spec:consumers.spec-studio.spec-page: A Spec page shows one Spec in collapsible panels, in a fixed order
  • spec:consumers.spec-studio.spec-page.core: A Spec page's core shows the whole Spec, with an anchor for every entry
  • spec:extraction.determinism: Committed source derives byte-identical output
  • spec:extraction.entry-locations: The graph records where each addressable entry is written
  • spec:extraction.pack-member-order: A Pack node keeps its members in authored order
  • spec:validation.next-rung-floor: The floor names what blocks the floor's next rung
  • spec:consumers.spec-studio.data constrainedBy spec:extraction.determinism · declared
  • spec:consumers.spec-studio.data dependsOn spec:consumers.pack-design · declared
  • spec:consumers.spec-studio.data dependsOn spec:consumers.reader · declared
  • spec:consumers.spec-studio.data dependsOn spec:extraction.entry-locations · declared
  • spec:consumers.spec-studio.data dependsOn spec:extraction.pack-member-order · declared
  • spec:consumers.spec-studio.data dependsOn spec:validation.next-rung-floor · declared
  • spec:consumers.spec-studio.data refines spec:consumers.spec-studio · declared
  • spec:consumers.spec-studio.components dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.diagram-kinds.requirement-trace dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.diagrams dependsOn spec:consumers.spec-studio.data · declared — a diagram is laid out from the values and recipe answers its page renders
  • spec:consumers.spec-studio.glossary-page dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.index-page dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.lenses dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.owner-queue dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.pack-page dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.publisher dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.registers dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.roadmap-page dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.search dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.shell dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.spec-page dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.spec-page.core dependsOn spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.data.inputs refines spec:consumers.spec-studio.data · declared
  • spec:consumers.spec-studio.data.recipe-answers refines spec:consumers.spec-studio.data · declared
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

Distance 1

Distance 2

Distance 3

Relations

Relation and directionOther endClaimReasonExercised keys
constrainedBy · outgoingCommitted source derives byte-identical output
spec:extraction.determinism · resolves
declaredNoneNone
dependsOn · outgoingThe Pack context carries the Pack's design
spec:consumers.pack-design · resolves
declaredNoneNone
dependsOn · outgoingThe reader bridges agent entry points to composable graph context
spec:consumers.reader · resolves
declaredNoneNone
dependsOn · outgoingThe graph records where each addressable entry is written
spec:extraction.entry-locations · resolves
declaredNoneNone
dependsOn · outgoingA Pack node keeps its members in authored order
spec:extraction.pack-member-order · resolves
declaredNoneNone
dependsOn · outgoingThe floor names what blocks the floor's next rung
spec:validation.next-rung-floor · resolves
declaredNoneNone
refines · outgoingThe Spec Studio is a static HTML workbench over the one graph
spec:consumers.spec-studio · resolves
declaredNoneNone
dependsOn · incomingThe Studio's custom elements each hold one view the build renders
spec:consumers.spec-studio.components · resolves
declaredNoneNone
dependsOn · incomingA requirement drawing separates intent from realization and verification
spec:consumers.spec-studio.diagram-kinds.requirement-trace · resolves
declaredNoneNone
dependsOn · incomingA diagram is laid out from graph values into SVG with a text equivalent
spec:consumers.spec-studio.diagrams · resolves
declareda diagram is laid out from the values and recipe answers its page rendersNone
dependsOn · incomingThe glossary page lists every term the corpus's Specs define
spec:consumers.spec-studio.glossary-page · resolves
declaredNoneNone
dependsOn · incomingThe index says where the corpus stands and narrows every Spec
spec:consumers.spec-studio.index-page · resolves
declaredNoneNone
dependsOn · incomingFive lenses read the graph as Packs, capabilities, architecture, tests and evidence
spec:consumers.spec-studio.lenses · resolves
declaredNoneNone
dependsOn · incomingThe owner queue page orders the statements and questions only a person can settle
spec:consumers.spec-studio.owner-queue · resolves
declaredNoneNone
dependsOn · incomingA Pack page shows the Pack's design as one card per member
spec:consumers.spec-studio.pack-page · resolves
declaredNoneNone
dependsOn · incomingsdp studio publishes the Studio as one page set
spec:consumers.spec-studio.publisher · resolves
declaredNoneNone
dependsOn · incomingThe corpus's registers are pages a reviewer opens from a link
spec:consumers.spec-studio.registers · resolves
declaredNoneNone
dependsOn · incomingThe roadmap page shows the upcoming work in priority order, split by what it needs
spec:consumers.spec-studio.roadmap-page · resolves
declaredNoneNone
dependsOn · incomingSearch finds a Spec, a Pack, an entry or a bound file by a word
spec:consumers.spec-studio.search · resolves
declaredNoneNone
dependsOn · incomingThe Studio's shell frames every page with navigation, a rail and a canvas
spec:consumers.spec-studio.shell · resolves
declaredNoneNone
dependsOn · incomingA Spec page shows one Spec in collapsible panels, in a fixed order
spec:consumers.spec-studio.spec-page · resolves
declaredNoneNone
dependsOn · incomingA Spec page's core shows the whole Spec, with an anchor for every entry
spec:consumers.spec-studio.spec-page.core · resolves
declaredNoneNone
refines · incomingThe Studio reads two named inputs beside the graph, a base graph and run records
spec:consumers.spec-studio.data.inputs · resolves
declaredNoneNone
refines · incomingA page takes each recipe answer from the recipe's shipped body
spec:consumers.spec-studio.data.recipe-answers · resolves
declaredNoneNone

Bindings

Implementation binding: present

  • impl:protocol.studio-data · assembles reader contexts, Pack totals, rails and search records for static pages · src/projections/studio/data.ts:279 · role contract · component component:protocol.projections · layer edge · context protocol

Design reference: none

Verifier binding: present

  • test:protocol.studio-data · anchored · test/studio-data.test.ts:26 · 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.