Spec Studio

A Pack's members and the standing queries are tables over the reader's values

spec:consumers.obsidian-vault.basesUse Case / Behavior · storyready floor ready

Packs: pack:obsidian-vault-v1, pack:self-hosting-v1

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

Findings: no errors, no warnings

specs/consumers/obsidian-vault.bases.sdp.md

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

A Base is Obsidian's table, card or list view over notes, filtered and sorted by their properties. Each Pack gets a Base of its members and the corpus one Base whose views are standing queries: the build backlog, the design backlog, the Specs whose next rung waits only for their author's statement, the Specs with blocking questions, and the decisions. In Obsidian a Pack's members read as one sortable table with implementation and verifier bindings shown as present or none, where the Design Review's Pack page is a table too wide for its page.

A view is a filter over values the generator wrote from the reader, so it agrees with the query it mirrors only while its predicate stays that simple. A view that would need a join waits until the reader carries the joined value. Keeping every filter inside a small closed grammar lets a test read each view's selection from the written files, without Obsidian, and compare it with its source over the same graph.

Intent
outcome
Give each Pack a Base of its members and the corpus a Base of standing queries, so a person filters and sorts a design by rung, floor, bindings and design columns.
Behavior

The world writes a probe corpus with a Pack whose members put at least one Spec in every standing view, runs the vault command, reads the Bases and the Spec notes' properties from disk, applies each view's clauses to those properties, and runs each view's source over the same graph.

rule.corpusBase line 22 · specs/consumers/obsidian-vault.bases.sdp.md:22
A corpus Base the command writes, sdp/specs.base, is over every Spec note, with the standing views spec:consumers.obsidian-vault.bases#design.standingViews lists; the index embeds it.

spec:consumers.obsidian-vault.bases.views-match-sources · enabled

rule.packBase line 23 · specs/consumers/obsidian-vault.bases.sdp.md:23
A Pack Base the command writes beside its note selects the Spec notes whose packs property links the Pack, with the views spec:consumers.obsidian-vault.bases#design.packViews lists; the Pack's note embeds it.

spec:consumers.obsidian-vault.bases.views-match-sources · enabled

rule.viewsMirrorSources line 24 · specs/consumers/obsidian-vault.bases.sdp.md:24
Each standing view of a Base the command writes selects, over one graph, exactly the Specs its source selects, as spec:consumers.obsidian-vault.bases#design.viewSources pairs them.

spec:consumers.obsidian-vault.bases.views-match-sources · enabled

rule.closedClauses line 25 · specs/consumers/obsidian-vault.bases.sdp.md:25
Every filter is an and list of clauses from the closed grammar spec:consumers.obsidian-vault.bases#design.filterClauses states, over properties the notes hold, so no view computes a join, a fact or a floor.

spec:consumers.obsidian-vault.bases.views-match-sources · enabled

rule.bindingDisplay line 26 · specs/consumers/obsidian-vault.bases.sdp.md:26
A Base shows the two binding properties through formulas as present or none, under the column names Implementation binding and Verifier binding, never under a delivery-fact name.

no example exercises it

rule.memberOrder line 27 · specs/consumers/obsidian-vault.bases.sdp.md:27
A Pack's note lists its members in manifest order beside its embedded Base, since a Base sorts by property and keeps no authored order.

no example exercises it

0 unkeyed rules.

Verifying examples

Each standing view selects what its source selects · spec:consumers.obsidian-vault.bases.views-match-sources · ready floor ready

Executable Spec

Given a corpus holding a Pack of {members: 6} Specs, with a Spec in every standing view
When the vault command writes the vault
Then each standing view of the corpus Base selects the Specs its source selects: {viewsMatch: true}
Then the Pack's Base selects every member and nothing else: {packMatches: true}
Then every filter clause belongs to the closed grammar: {closedClauses: true}

Open example

Example space

Given a corpus holding a Pack of {members:number} Specs, with a Spec in every standing view
When the vault command writes the vault
Then each standing view of the corpus Base selects the Specs its source selects: {viewsMatch:boolean}
Then the Pack's Base selects every member and nothing else: {packMatches:boolean}
Then every filter clause belongs to the closed grammar: {closedClauses:boolean}
Design
filterClauses line 30 · specs/consumers/obsidian-vault.bases.sdp.md:30
a clause is one of <property> == "<text>", <property> != "<text>", <property> == true, <property> == false, <property> > 0, <property>.isEmpty(), !<property>.isEmpty(), <property>.contains(link("<path>.md")) and file.inFolder("<folder>"), each written as one double-quoted YAML string.
corpusFilter line 31 · specs/consumers/obsidian-vault.bases.sdp.md:31
sdp/specs.base filters on file.inFolder("sdp/specs").

no citation recorded

standingViews line 32 · specs/consumers/obsidian-vault.bases.sdp.md:32
table views in this order, All Specs with no further clause; Build backlog with statedReadiness == "ready", specKind != "example", specKind != "decision" and implementationBinding == false; Design backlog with statedReadiness == "defined", specKind != "example", specKind != "decision" and implementationBinding == false; Nothing blocks the next rung with !statedNextRung.isEmpty() and statedNextRungFailures.isEmpty(); Blocking questions with blockingQuestions > 0; Decisions with specKind == "decision".
viewSources line 33 · specs/consumers/obsidian-vault.bases.sdp.md:33
Build backlog the rows of the build backlog recipe; Design backlog the rows of the design backlog recipe; Nothing blocks the next rung the Specs whose reader context has a statedNextRung and an empty statedNextRungFailures; Blocking questions the Specs with a blocking question in the open-question register; Decisions the rows of the decision register; each compared by Spec id over the same graph.

no citation recorded

packFilter line 34 · specs/consumers/obsidian-vault.bases.sdp.md:34
sdp/packs/<note>.base filters on file.inFolder("sdp/specs") and packs.contains(link("sdp/packs/<note>.md")).

no citation recorded

packViews line 35 · specs/consumers/obsidian-vault.bases.sdp.md:35
table views in this order, Members with no further clause and Nothing blocks the next rung with the clauses of the corpus view of that name.
memberColumns line 36 · specs/consumers/obsidian-vault.bases.sdp.md:36
Members and All Specs show file.name, title, specKind, statedReadiness, derivedReadiness, statedNextRung, statedNextRungFailures, formula.implementation, formula.verifier, designEntries, declarations, openQuestions and blockingQuestions; the other views show file.name, title and the properties their clauses read.

no citation recorded

bindingFormulas line 37 · specs/consumers/obsidian-vault.bases.sdp.md:37
implementation: 'if(implementationBinding, "present", "none")' and verifier: 'if(verifierBinding, "present", "none")' under formulas: in every Base.

no citation recorded

columnNames line 38 · specs/consumers/obsidian-vault.bases.sdp.md:38
every Base names its columns under properties: with displayName, keyed note.<property> or formula.<name>: Title, Kind, Stated, Floor reached, Next rung, What holds it, Implementation binding, Verifier binding, Design entries, Declarations, Open questions, Blocking.
Verification

Verifier bindings

  • spec:consumers.obsidian-vault.bases.views-match-sources · Each standing view selects what its source selects · declared · example enabled · specs/consumers/obsidian-vault.bases.views-match-sources.sdp.md

    External run evidence from test/vault-examples.test.ts

    Test anchors: test:protocol.consumers.obsidian-vault.bases.views-match-sources, test:protocol.consumers.obsidian-vault.changed-note-refused, test:protocol.consumers.obsidian-vault.failed-extraction-keeps-notes, test:protocol.consumers.obsidian-vault.failed-extraction-recovered, test:protocol.consumers.obsidian-vault.fresh-vault, test:protocol.consumers.obsidian-vault.hidden-file-refused, test:protocol.consumers.obsidian-vault.interrupted-run-recovered, test:protocol.consumers.obsidian-vault.iteration.watch-rewrites-changed-notes, test:protocol.consumers.obsidian-vault.iteration.watch-source-anchor, test:protocol.consumers.obsidian-vault.notes.case-collision-refused, test:protocol.consumers.obsidian-vault.notes.entry-address-link, test:protocol.consumers.obsidian-vault.notes.term-address-link, test:protocol.consumers.obsidian-vault.notes.unresolved-mention-stays, test:protocol.consumers.obsidian-vault.person-notes-survive, test:protocol.consumers.obsidian-vault.unknown-note-refused, test:protocol.consumers.obsidian-vault.vault-in-build-path-refused. Specs verified by those bindings: spec:consumers.obsidian-vault, spec:consumers.obsidian-vault.bases, spec:consumers.obsidian-vault.bases.views-match-sources, spec:consumers.obsidian-vault.changed-note-refused, spec:consumers.obsidian-vault.failed-extraction-keeps-notes, spec:consumers.obsidian-vault.failed-extraction-recovered, spec:consumers.obsidian-vault.fresh-vault, spec:consumers.obsidian-vault.hidden-file-refused, spec:consumers.obsidian-vault.interrupted-run-recovered, spec:consumers.obsidian-vault.iteration, spec:consumers.obsidian-vault.iteration.watch-rewrites-changed-notes, spec:consumers.obsidian-vault.iteration.watch-source-anchor, spec:consumers.obsidian-vault.notes, spec:consumers.obsidian-vault.notes.case-collision-refused, spec:consumers.obsidian-vault.notes.entry-address-link, spec:consumers.obsidian-vault.notes.term-address-link, spec:consumers.obsidian-vault.notes.unresolved-mention-stays, spec:consumers.obsidian-vault.person-notes-survive, spec:consumers.obsidian-vault.unknown-note-refused, spec:consumers.obsidian-vault.vault-in-build-path-refused.

    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
    keeps incomplete oracle points unspecifiednot recordedpassed1.97 ms
    executes the bound example against a fresh worldA fresh vault is written the same way twice and every link resolves (spec:consumers.obsidian-vault.fresh-vault)passed40.74 ms
    executes the bound example against a fresh worldA regeneration removes a note that left the graph and keeps a person's notes (spec:consumers.obsidian-vault.person-notes-survive)passed21.7 ms
    executes the bound example against a fresh worldA note a person wrote inside the generated folder refuses the regeneration (spec:consumers.obsidian-vault.unknown-note-refused)passed5.97 ms
    executes the bound example against a fresh worldA generated note a person changed refuses the regeneration and keeps the edit (spec:consumers.obsidian-vault.changed-note-refused)passed5.29 ms
    executes the bound example against a fresh worldA person's file under a temporary's name refuses the regeneration (spec:consumers.obsidian-vault.hidden-file-refused)passed6.73 ms
    executes the bound example against a fresh worldA vault directory the build removes refuses the run and keeps a person's notes (spec:consumers.obsidian-vault.vault-in-build-path-refused)passed1.17 ms
    executes the bound example against a fresh worldA run after a stopped synchronization finishes it (spec:consumers.obsidian-vault.interrupted-run-recovered)passed34.66 ms
    executes the bound example against a fresh worldA failed extraction keeps the notes and says so on the index (spec:consumers.obsidian-vault.failed-extraction-keeps-notes)passed12.45 ms
    executes the bound example against a fresh worldThe run after a failed extraction passes the guard and restores the index (spec:consumers.obsidian-vault.failed-extraction-recovered)passed22.28 ms
    executes the bound example against a fresh worldAn entry address in prose opens the entry's block in its Spec's note (spec:consumers.obsidian-vault.notes.entry-address-link)passed14.02 ms
    executes the bound example against a fresh worldA mention of an entry that does not exist stays as written (spec:consumers.obsidian-vault.notes.unresolved-mention-stays)passed9.02 ms
    executes the bound example against a fresh worldA keyed Model term gets a note, and its address in prose opens the term's block (spec:consumers.obsidian-vault.notes.term-address-link)passed11.72 ms
    executes the bound example against a fresh worldTwo Specs whose notes differ only in case refuse the run (spec:consumers.obsidian-vault.notes.case-collision-refused)passed2.38 ms
    executes the bound example against a fresh worldEach standing view selects what its source selects (spec:consumers.obsidian-vault.bases.views-match-sources)passed30.9 ms
    executes the bound example against a fresh worldA carrier edit under watch rewrites only the notes it changes (spec:consumers.obsidian-vault.iteration.watch-rewrites-changed-notes)passed486.87 ms
    executes the bound example against a fresh worldAn anchor added in a source file under watch rewrites the Spec's note (spec:consumers.obsidian-vault.iteration.watch-source-anchor)passed626.34 ms

Example space

  • members · number · declared by a corpus holding a Pack of {members} Specs, with a Spec in every standing view

Bound points

Oracle binding: present · oracle:protocol.vault-bases · test/vault-examples.test.ts:405

Coverage

members: 6 · spec:consumers.obsidian-vault.bases.views-match-sources · not enumerable

Unbound

  • members: None
Design view

Requirement drawing

Requirement drawing for spec:consumers.obsidian-vault.bases
The diagram as text
  • spec:consumers.obsidian-vault.bases: A Pack's members and the standing queries are tables over the reader's values · declared Spec
  • spec:consumers.obsidian-vault.bases.views-match-sources: Each standing view selects what its source selects · declared Spec
  • spec:consumers.obsidian-vault: An Obsidian vault lets a person iterate on designs from the one graph · declared Spec
  • impl:protocol.vault-bases: serializes standing query predicates over reader properties as Obsidian Bases · anchored code · src/projections/vault/bases.ts:43
  • impl:protocol.vault-notes: renders reader contexts, declared relations and keyed terms as linked notes · anchored code · src/projections/vault/notes.ts:45
  • oracle:protocol.vault-bases: oracle:protocol.vault-bases · anchored oracle binding · test/vault-examples.test.ts:405
  • test:protocol.consumers.obsidian-vault.bases.views-match-sources: test:protocol.consumers.obsidian-vault.bases.views-match-sources · anchored test binding · binding present · test/vault-examples.test.ts:747
  • spec:consumers.obsidian-vault.bases refines spec:consumers.obsidian-vault · declared
  • spec:consumers.obsidian-vault.bases.views-match-sources refines spec:consumers.obsidian-vault.bases · declared
  • spec:consumers.obsidian-vault.bases.views-match-sources verifies spec:consumers.obsidian-vault.bases · declared
  • impl:protocol.vault-bases satisfies spec:consumers.obsidian-vault.bases · anchored
  • impl:protocol.vault-notes satisfies spec:consumers.obsidian-vault.bases · anchored
  • oracle:protocol.vault-bases models spec:consumers.obsidian-vault.bases · anchored
  • test:protocol.consumers.obsidian-vault.bases.views-match-sources verifies spec:consumers.obsidian-vault.bases.views-match-sources · anchored
Mermaid source

Copyable source; the Studio draws static SVG.

Preferred syntax: requirementDiagram. Chosen syntax: flowchart TB because models 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.vault-bases · serializes standing query predicates over reader properties as Obsidian Bases · src/projections/vault/bases.ts:43

    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.vault-notes · renders reader contexts, declared relations and keyed terms as linked notes · src/projections/vault/notes.ts:45

    Component: component:protocol.projections · read-only output, layout and owned publication · src/projections/design-review.ts:29 · layer edge · context protocol

    Uses

    • impl:protocol.reader · typed graph queries, entry adapters and context joins · src/reader/reader.ts:687

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.obsidian-vault.bases
  • E4: verifies · declared
The diagram as text
  • spec:consumers.obsidian-vault: An Obsidian vault lets a person iterate on designs from the one graph
  • spec:consumers.obsidian-vault.bases: A Pack's members and the standing queries are tables over the reader's values
  • spec:consumers.obsidian-vault.bases.views-match-sources: Each standing view selects what its source selects
  • spec:consumers.pack-design: The Pack context carries the Pack's design
  • spec:consumers.obsidian-vault.bases dependsOn spec:consumers.pack-design · declared — a Pack's Base shows the members, rungs and design columns the Pack design assembles
  • spec:consumers.obsidian-vault.bases refines spec:consumers.obsidian-vault · declared
  • spec:consumers.obsidian-vault.bases.views-match-sources refines spec:consumers.obsidian-vault.bases · declared
  • spec:consumers.obsidian-vault.bases.views-match-sources verifies spec:consumers.obsidian-vault.bases · 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

Relations

Relation and directionOther endClaimReasonExercised keys
dependsOn · outgoingThe Pack context carries the Pack's design
spec:consumers.pack-design · resolves
declareda Pack's Base shows the members, rungs and design columns the Pack design assemblesNone
refines · outgoingAn Obsidian vault lets a person iterate on designs from the one graph
spec:consumers.obsidian-vault · resolves
declaredNoneNone
refines · incomingEach standing view selects what its source selects
spec:consumers.obsidian-vault.bases.views-match-sources · resolves
declaredNoneNone
verifies · incomingEach standing view selects what its source selects
spec:consumers.obsidian-vault.bases.views-match-sources · resolves
declaredNonecorpusBase, packBase, viewsMirrorSources, closedClauses

Bindings

Implementation binding: present

  • impl:protocol.vault-bases · serializes standing query predicates over reader properties as Obsidian Bases · src/projections/vault/bases.ts:43 · role projection · component component:protocol.projections · layer edge · context protocol
  • impl:protocol.vault-notes · renders reader contexts, declared relations and keyed terms as linked notes · src/projections/vault/notes.ts:45 · role projection · component component:protocol.projections · layer edge · context protocol

Design reference: none

Verifier binding: present

Expected-outcome oracle: present

  • oracle:protocol.vault-bases · test/vault-examples.test.ts:405

Runtime observation: not tracked.

Run results: not recorded in the graph.

Findings

None.

Composing (0)

Composing needs the script.