Spec Studio

A Model term may carry a key that addresses it

spec:model.term-addressesBusiness Rule · storyready floor ready

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

Design: 10 design entries · 7 pinned declarations · 2 decisions

Findings: no errors, no warnings

specs/model/term-addresses.sdp.md

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

A Model section defines a Spec's terms, and prose names those terms by word. A word is not a checked entry address, so a view cannot resolve it to one authored definition, and a renamed term leaves every sentence that names it silently stale. Design, UI, question and rule entries already carry keys that a mention addresses and validation checks; a key gives a Model term the same. The key is authored in a marker, as a rule's is, rather than derived from the term: a derived key would change, and break every address, whenever the term is reworded. The address segment is term, because an address names the kind of entry it reaches, as question and rule do, and the Model section's own prose is not an entry. The ratified glossary stays a document, beside the graph and outside it, so its terms gain no address; a term gains one where a Spec defines it.

Intent
problem
Prose that names a concept a Model section defines has no checked way to point at that definition, so a view cannot link it and a renamed term breaks its readers silently.
outcome
Let a Model term carry a key, addressed as spec:<id>#term.<key>, so prose cites a concept as a checked mention and every view links it exactly.
Rule

The world writes two carriers in one extraction root. The first is a story-altitude model Spec stating scoped, with an Intent outcome and a Model section holding the entries the terms slot joins with a semicolon and a space, in the carrier the slot names: in Markdown one line each, as written, and in TypeScript a .sdp.ts carrier whose model.terms object maps each entry's term to its definition, marker included. The second is a Markdown story-altitude rule Spec stating idea, with an Intent outcome and one rule; its narrative names the address, and it declares dependsOn on the first. A finding read is the first extraction finding, and an empty slot value means the extraction reports none; the term keys of every Spec in the graph are joined by a comma and a space. resolved is true when address resolution gives the address a resolving row whose value is the definition without its marker and whose file and line are those of the term's row in the location table. found is true when entry search for the words of the term that carries the address's key returns a row with that address and that line. The audit reason is the reason of the mention audit's unresolved row for the address, and empty when it lists none. The import reads the first carrier as written in TypeScript: the world imports it to Markdown, reads the emitted Model entry of its first term, extracts the imported carrier in a fresh root, and compares its term keys and definitions with the TypeScript graph's.

rule.termMarker line 32 · specs/model/term-addresses.sdp.md:32
A Model term may carry an optional key in a marker that opens its definition, after the bold term and the em dash, as in - **step key** — [#stepKey] the key a step carries; the TypeScript carrier writes the same marker at the start of the definition string. The key follows the entry-address key grammar, and an unkeyed term stays lawful and has no address. Importing a TypeScript carrier to Markdown writes the marker on the term that carries the key.

spec:model.term-addresses.keyed-term-resolves · enabled, spec:model.term-addresses.malformed-term-marker-refused · enabled, spec:model.term-addresses.typescript-term-imports-keyed · enabled

rule.authoredKey line 33 · specs/model/term-addresses.sdp.md:33
The key is authored and never derived from the term, so rewording a term or its definition keeps its address, while renaming or removing the key fails validation in every Spec that addresses it.

spec:model.term-addresses.unknown-term-key-refused · enabled

rule.uniqueTermKeys line 34 · specs/model/term-addresses.sdp.md:34
A term key is unique among the Model terms of one Spec. Term keys and the Spec's Design, UI, question and rule keys sit under different address segments and stay apart.

spec:model.term-addresses.repeated-term-key-refused · enabled

rule.markerRefusals line 35 · specs/model/term-addresses.sdp.md:35
A definition that opens with [# and does not continue as a marker is refused at its term, and a repeated term key is refused at each term that carries it; a refused Markdown carrier is refused whole, as for every structure refusal, and in the TypeScript carrier the key drops at each site and the Spec stays.

spec:model.term-addresses.malformed-term-marker-refused · enabled, spec:model.term-addresses.repeated-term-key-refused · enabled

rule.termAddress line 36 · specs/model/term-addresses.sdp.md:36
A keyed term is addressed as spec:<id>#term.<key>. The address parses, is refused in every id slot as every entry address is, and resolves while the Spec's model.termKeys carries the key; a mention of a term key the Spec does not carry is a prose-mentions error.

spec:model.term-addresses.keyed-term-resolves · enabled, spec:model.term-addresses.typescript-term-imports-keyed · enabled, spec:model.term-addresses.unknown-term-key-refused · enabled

rule line 37 · specs/model/term-addresses.sdp.md:37
The ratified glossary stays a document, so its terms gain no address; a term gains one where a Spec defines it in a Model section.
rule.termLocations line 38 · specs/model/term-addresses.sdp.md:38
The location table records every Model term its carrier locates, keyed or not, as term[<i>], with <i> the term's position among the Spec's terms in authored order and key beside a keyed term.

spec:model.term-addresses.keyed-term-resolves · enabled

rule.termReaders line 39 · specs/model/term-addresses.sdp.md:39
Address resolution resolves a term address to the term's definition with its file and line, entry search gives a keyed term its address and matches term keys as it matches rule keys, and the mention audit reports a term key the Spec does not carry as a missing entry.

spec:model.term-addresses.keyed-term-resolves · enabled, spec:model.term-addresses.unknown-term-key-refused · enabled

rule line 40 · specs/model/term-addresses.sdp.md:40
A term key mints no edge, confers no delivery fact and moves no readiness floor, and exercises names rule keys only. A term promoted to a model Spec of its own leaves its address behind, because promotion moves the content out, and every mention of the address fails until it names the new Spec.

2 unkeyed rules.

Verifying examples

A keyed term is reified and its address resolves · spec:model.term-addresses.keyed-term-resolves · ready floor ready

Executable Spec

Given a {carrier: "Markdown"} Spec carrier {specId: "spec:probe.subject"} whose Model terms read {terms: "- **step key** — [#stepKey] the key a step carries in its marker; - **slot** — one typed placeholder in a step"}
Given a second Spec that names {address: "spec:probe.subject#term.stepKey"} in its narrative and declares dependsOn on the first
When the extractor reifies both carriers and the graph is validated
Then the first carrier is reified: {reified: true}
Then the first extraction finding's message contains {extractMessage: ""}
Then the graph holds the term keys {keys: "stepKey"}
Then the report holds {mentionErrors: 0} prose-mention errors
Then address resolution resolves the address to the marker-free definition at its recorded term location: {resolved: true}
Then entry search for the addressed term's words finds it at that same address and line: {found: true}

Open example

A term marker whose key is off the grammar refuses its carrier · spec:model.term-addresses.malformed-term-marker-refused · ready floor ready

Executable Spec

Given a {carrier: "Markdown"} Spec carrier {specId: "spec:probe.subject"} whose Model terms read {terms: "- **step key** — [#step-key] the key a step carries in its marker"}
Given a second Spec that names {address: "spec:probe.subject#term.stepKey"} in its narrative and declares dependsOn on the first
When the extractor reifies both carriers and the graph is validated
Then the first carrier is reified: {reified: false}
Then the first extraction finding's message contains {extractMessage: "term key markers must be [#<lower-camel ASCII key>] followed by one space and text"}
Then the graph holds the term keys {keys: ""}
Then the report holds {mentionErrors: 1} prose-mention errors

Open example

A term key repeated in one Spec refuses its carrier · spec:model.term-addresses.repeated-term-key-refused · ready floor ready

Executable Spec

Given a {carrier: "Markdown"} Spec carrier {specId: "spec:probe.subject"} whose Model terms read {terms: "- **step key** — [#stepKey] the key a step carries in its marker; - **term key** — [#stepKey] the key a Model term carries in its marker"}
Given a second Spec that names {address: "spec:probe.subject#term.stepKey"} in its narrative and declares dependsOn on the first
When the extractor reifies both carriers and the graph is validated
Then the first carrier is reified: {reified: false}
Then the first extraction finding's message contains {extractMessage: "is repeated; term keys must be unique within a Spec"}
Then the graph holds the term keys {keys: ""}
Then the report holds {mentionErrors: 1} prose-mention errors

Open example

A keyed TypeScript term keeps its address through import to Markdown · spec:model.term-addresses.typescript-term-imports-keyed · ready floor ready

Executable Spec

Given a {carrier: "TypeScript"} Spec carrier {specId: "spec:probe.subject"} whose Model terms read {terms: "- **step key** — [#stepKey] the key a step carries in its marker"}
Given a second Spec that names {address: "spec:probe.subject#term.stepKey"} in its narrative and declares dependsOn on the first
When the extractor reifies both carriers and the graph is validated
Then the first carrier is reified: {reified: true}
Then the first extraction finding's message contains {extractMessage: ""}
Then the graph holds the term keys {keys: "stepKey"}
Then the report holds {mentionErrors: 0} prose-mention errors
Then the first carrier imported to Markdown writes the entry {importedEntry: "- **step key** — [#stepKey] the key a step carries in its marker"} and keeps its term keys and definitions: {keptOnImport: true}

Open example

An address that names a term key no term carries is an error · spec:model.term-addresses.unknown-term-key-refused · ready floor ready

Executable Spec

Given a {carrier: "Markdown"} Spec carrier {specId: "spec:probe.subject"} whose Model terms read {terms: "- **step key** — [#stepLabel] the key a step carries in its marker"}
Given a second Spec that names {address: "spec:probe.subject#term.stepKey"} in its narrative and declares dependsOn on the first
When the extractor reifies both carriers and the graph is validated
Then the first carrier is reified: {reified: true}
Then the first extraction finding's message contains {extractMessage: ""}
Then the graph holds the term keys {keys: "stepLabel"}
Then the report holds {mentionErrors: 1} prose-mention errors
Then the mention audit lists the address as unresolved with reason {auditReason: "entry"}

Open example

Example space

Given a {carrier:"Markdown"|"TypeScript"} Spec carrier {specId:string} whose Model terms read {terms:string}
Given a second Spec that names {address:string} in its narrative and declares dependsOn on the first
When the extractor reifies both carriers and the graph is validated
Then the first carrier is reified: {reified:boolean}
Then the first extraction finding's message contains {extractMessage:string}
Then the graph holds the term keys {keys:string}
Then the report holds {mentionErrors:number} prose-mention errors
Then address resolution resolves the address to the marker-free definition at its recorded term location: {resolved:boolean}
Then entry search for the addressed term's words finds it at that same address and line: {found:boolean}
Then the mention audit lists the address as unresolved with reason {auditReason:string}
Then the first carrier imported to Markdown writes the entry {importedEntry:string} and keeps its term keys and definitions: {keptOnImport:boolean}
Design
termMarker line 60 · specs/model/term-addresses.sdp.md:60
- **<term>** — [#<key>] <definition> is a keyed Model entry in Markdown and terms: { "<term>": "[#<key>] <definition>" } in TypeScript; <key> matches ^[a-z][A-Za-z0-9]*$, and a marker later in the definition is plain text.

no citation recorded

termKeysField line 61 · specs/model/term-addresses.sdp.md:61
model.termKeys maps each key to the term it names, as authored, in authored order; the definitions hold the text with the marker removed; a Spec with no keyed term carries no termKeys, and the serialized graph writes it after terms.

no citation recorded

markerRefusal line 62 · specs/model/term-addresses.sdp.md:62
term key markers must be [#<lower-camel ASCII key>] followed by one space and text is the message, as the finding extract/unrecognized-property at severity error, at path model.terms.<term>.

no citation recorded

repeatedKey line 63 · specs/model/term-addresses.sdp.md:63
term key "<key>" is repeated; term keys must be unique within a Spec is the message, as the same finding, at each term that carries the key.

no citation recorded

addressSections line 64 · specs/model/term-addresses.sdp.md:64
ENTRY_ADDRESS_SECTIONS is ["design", "ui", "question", "rule", "term"], and parseId refuses any other segment with entry address must be <section>.<key> with section design, ui, question, rule, or term.

no citation recorded

missingTerm line 65 · specs/model/term-addresses.sdp.md:65
Mention in "<spec>" at <path> points to missing entry "term.<key>" of "<target>". is the prose-mentions error for a term key the target does not carry.

no citation recorded

termLocation line 66 · specs/model/term-addresses.sdp.md:66
{ spec, file, entry: "term[<i>]", key?, line } is a term's row in the location table; a mention in a definition, at model.terms.<term>, takes that row's line.

no citation recorded

resolutionRow line 67 · specs/model/term-addresses.sdp.md:67
address resolution (recipe 25) reads term through model.termKeys; a resolving row gives the marker-free definition as value and its recorded file and line. A section or entry miss gives the available term keys sorted in code-unit order. The grammar text is spec:<id>#<section>.<key>, section design, ui, question, rule, or term; key lower-camel ASCII.
searchRow line 68 · specs/model/term-addresses.sdp.md:68
entry search (recipe 23) gives a matching keyed term, in section model and entry terms.<term>, the address spec:<id>#term.<key> and the line of its term[<i>] row, matches the term key as it matches a rule key, and never walks termKeys as content.
importEmitter line 69 · specs/model/term-addresses.sdp.md:69
the TypeScript-to-Markdown import writes a keyed term as - **<term>** — [#<key>] <definition>, so a keyed TypeScript term imports keyed.
Verification

Verifier bindings

  • spec:model.term-addresses.keyed-term-resolves · A keyed term is reified and its address resolves · declared · example enabled · specs/model/term-addresses.keyed-term-resolves.sdp.md

    External run evidence from test/self-hosting-term-addresses.test.ts

    Test anchors: test:protocol.term-addresses.keyed-term-resolves, test:protocol.term-addresses.malformed-term-marker-refused, test:protocol.term-addresses.repeated-term-key-refused, test:protocol.term-addresses.typescript-term-imports-keyed, test:protocol.term-addresses.unknown-term-key-refused. Specs verified by those bindings: spec:model.term-addresses, spec:model.term-addresses.keyed-term-resolves, spec:model.term-addresses.malformed-term-marker-refused, spec:model.term-addresses.repeated-term-key-refused, spec:model.term-addresses.typescript-term-imports-keyed, spec:model.term-addresses.unknown-term-key-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
    executes the bound example against a fresh worldA keyed term is reified and its address resolves (spec:model.term-addresses.keyed-term-resolves)passed31.89 ms
    executes the bound example against a fresh worldA term marker whose key is off the grammar refuses its carrier (spec:model.term-addresses.malformed-term-marker-refused)passed7.42 ms
    executes the bound example against a fresh worldA term key repeated in one Spec refuses its carrier (spec:model.term-addresses.repeated-term-key-refused)passed7.57 ms
    executes the bound example against a fresh worldA keyed TypeScript term keeps its address through import to Markdown (spec:model.term-addresses.typescript-term-imports-keyed)passed33.79 ms
    executes the bound example against a fresh worldAn address that names a term key no term carries is an error (spec:model.term-addresses.unknown-term-key-refused)passed2.92 ms
  • spec:model.term-addresses.malformed-term-marker-refused · A term marker whose key is off the grammar refuses its carrier · declared · example enabled · specs/model/term-addresses.malformed-term-marker-refused.sdp.md
  • spec:model.term-addresses.repeated-term-key-refused · A term key repeated in one Spec refuses its carrier · declared · example enabled · specs/model/term-addresses.repeated-term-key-refused.sdp.md
  • spec:model.term-addresses.typescript-term-imports-keyed · A keyed TypeScript term keeps its address through import to Markdown · declared · example enabled · specs/model/term-addresses.typescript-term-imports-keyed.sdp.md
  • spec:model.term-addresses.unknown-term-key-refused · An address that names a term key no term carries is an error · declared · example enabled · specs/model/term-addresses.unknown-term-key-refused.sdp.md
  • test:protocol.keyed-content · anchored · test anchor binding present · test/keyed-content.test.ts:28

    External run evidence from test/keyed-content.test.ts

    Test anchors: test:protocol.keyed-content. Specs verified by those bindings: spec:carrier.step-keys, spec:model.term-addresses.

    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
    records each TypeScript term's own physical line and authored keykeyed carrier contentpassed16.54 ms
    locates a refused TypeScript exampleSpace step below its Spec declarationkeyed carrier contentpassed3.49 ms
    locates a refused TypeScript examples step below its Spec declarationkeyed carrier contentpassed2.23 ms
    rejects unexpected step extraction findings when the example's message slot is emptykeyed carrier contentpassed1236.58 ms
    rejects unexpected term extraction findings when the example's message slot is emptykeyed carrier contentpassed19.08 ms
    reports false when unchanged handlers typecheck but the step reach changeskeyed carrier contentpassed733 ms
    preserves authored key order, strips markers, records terms and never records stepskeyed carrier contentpassed1.79 ms
    refuses malformed markers at their physical step and term: [#bad-key] textkeyed carrier contentpassed0.77 ms
    refuses malformed markers at their physical step and term: [#good] textkeyed carrier contentpassed0.73 ms
    refuses malformed markers at their physical step and term: [#good] textkeyed carrier contentpassed0.53 ms
    refuses malformed markers at their physical step and term: [#good] keyed carrier contentpassed0.51 ms
    keeps later markers as ordinary text and permits a repeated keyed skeletonkeyed carrier contentpassed3.67 ms
    drops each conflicting TypeScript key while preserving its Spec and marker-free textkeyed carrier contentpassed4.07 ms
    refuses a Gherkin carrier whole at every conflicting stepkeyed carrier contentpassed3.64 ms
    keeps keyed fence text and derived key maps out of the prose mention scankeyed carrier contentpassed1 ms
    checks term addresses and refuses them in Spec id slotskeyed carrier contentpassed0.36 ms
    locates mentions inside keyed and unkeyed definitions, even when a term contains dotskeyed carrier contentpassed1.02 ms
    breaks a keyed binding when its parameter or key changes: items -> countkeyed carrier contentpassed676.27 ms
    breaks a keyed binding when its parameter or key changes: [#cartSize] -> keyed carrier contentpassed581.73 ms
    breaks an unchanged typed handler when a still-compatible bound point changes slot typecontract keys and Then outcomespassed598.12 ms
    withholds a child marker where the vocabulary step carries no markercontract keys and Then outcomespassed5.93 ms
    keys a standalone example and a generated Then registrar by the authored keyscontract keys and Then outcomespassed6.62 ms
    uses a keyed Then for the Outcome union and the registrar bindingcontract keys and Then outcomespassed4.15 ms
    withholds a colliding space and its registrars, while naming the space collisioncontract keys and Then outcomespassed6.82 ms
    dispatches keyed steps and renders a failure from their current wordingcontract keys and Then outcomespassed0.88 ms
    compares an oracle by contract key and lists keys when no Then matchescontract keys and Then outcomespassed1.6 ms

Example space

  • carrier · "Markdown" | "TypeScript" · declared by a {carrier} Spec carrier {specId} whose Model terms read {terms}
  • specId · string · declared by a {carrier} Spec carrier {specId} whose Model terms read {terms}
  • terms · string · declared by a {carrier} Spec carrier {specId} whose Model terms read {terms}
  • address · string · declared by a second Spec that names {address} in its narrative and declares dependsOn on the first

Bound points

ExamplecarrierspecIdtermsaddress
spec:model.term-addresses.keyed-term-resolves"Markdown""spec:probe.subject""- **step key** — [#stepKey] the key a step carries in its marker; - **slot** — one typed placeholder in a step""spec:probe.subject#term.stepKey"
spec:model.term-addresses.malformed-term-marker-refused"Markdown""spec:probe.subject""- **step key** — [#step-key] the key a step carries in its marker""spec:probe.subject#term.stepKey"
spec:model.term-addresses.repeated-term-key-refused"Markdown""spec:probe.subject""- **step key** — [#stepKey] the key a step carries in its marker; - **term key** — [#stepKey] the key a Model term carries in its marker""spec:probe.subject#term.stepKey"
spec:model.term-addresses.typescript-term-imports-keyed"TypeScript""spec:probe.subject""- **step key** — [#stepKey] the key a step carries in its marker""spec:probe.subject#term.stepKey"
spec:model.term-addresses.unknown-term-key-refused"Markdown""spec:probe.subject""- **step key** — [#stepLabel] the key a step carries in its marker""spec:probe.subject#term.stepKey"

Oracle binding: none

Coverage

specId: "spec:probe.subject" · spec:model.term-addresses.keyed-term-resolves, spec:model.term-addresses.malformed-term-marker-refused, spec:model.term-addresses.repeated-term-key-refused, spec:model.term-addresses.typescript-term-imports-keyed, spec:model.term-addresses.unknown-term-key-refused · not enumerable

terms: "- **step key** — [#stepKey] the key a step carries in its marker; - **slot** — one typed placeholder in a step" · spec:model.term-addresses.keyed-term-resolves; "- **step key** — [#step-key] the key a step carries in its marker" · spec:model.term-addresses.malformed-term-marker-refused; "- **step key** — [#stepKey] the key a step carries in its marker; - **term key** — [#stepKey] the key a Model term carries in its marker" · spec:model.term-addresses.repeated-term-key-refused; "- **step key** — [#stepKey] the key a step carries in its marker" · spec:model.term-addresses.typescript-term-imports-keyed; "- **step key** — [#stepLabel] the key a step carries in its marker" · spec:model.term-addresses.unknown-term-key-refused · not enumerable

address: "spec:probe.subject#term.stepKey" · spec:model.term-addresses.keyed-term-resolves, spec:model.term-addresses.malformed-term-marker-refused, spec:model.term-addresses.repeated-term-key-refused, spec:model.term-addresses.typescript-term-imports-keyed, spec:model.term-addresses.unknown-term-key-refused · not enumerable

Unbound

  • carrier: None
  • specId: None
  • terms: None
  • address: None
Design view

Requirement drawing

Requirement drawing for spec:model.term-addresses
The diagram as text
  • spec:model.term-addresses: A Model term may carry a key that addresses it · declared Spec
  • spec:model.term-addresses.keyed-term-resolves: A keyed term is reified and its address resolves · declared Spec
  • spec:model.term-addresses.malformed-term-marker-refused: A term marker whose key is off the grammar refuses its carrier · declared Spec
  • spec:model.term-addresses.repeated-term-key-refused: A term key repeated in one Spec refuses its carrier · declared Spec
  • spec:model.term-addresses.typescript-term-imports-keyed: A keyed TypeScript term keeps its address through import to Markdown · declared Spec
  • spec:model.term-addresses.unknown-term-key-refused: An address that names a term key no term carries is an error · declared Spec
  • spec:model.spec-sections: Spec sections carry typed detail and direct verifier semantics · declared Spec
  • impl:protocol.address-and-cycle-recipes: asserts realization of the shipped address resolution and dependency cycle recipes · anchored code · test/recipes.test.ts:3568
  • impl:protocol.entry-locations: builds the carrier entry location table · anchored code · src/extract/derive.ts:78
  • impl:protocol.key-markers: normalizes step and term markers across the three carriers · anchored code · src/extract/key-markers.ts:136
  • impl:protocol.open-section-order: preserves authored open-section and model-term order and Pack field order · anchored code · src/extract/serialize.ts:105
  • impl:protocol.prose-mentions: checks that prose mentions resolve and warns once per unbacked Spec pair · anchored code · src/validate/validators.ts:1370
  • impl:protocol.register-recipes: asserts realization of the shipped register recipes · anchored code · test/recipes.test.ts:2057
  • impl:protocol.sdp-import-markdown-emit: emits the Markdown document twin for an imported Spec · anchored code · src/import/emit-markdown.ts:253
  • impl:protocol.spec-sections: typed Spec section shapes · anchored code · src/model/sections.ts:138
  • impl:protocol.stable-ids: stable ID grammar parser · anchored code · src/ids.ts:173
  • test:protocol.keyed-content: test:protocol.keyed-content · anchored test binding · binding present · test/keyed-content.test.ts:28
  • test:protocol.term-addresses.keyed-term-resolves: test:protocol.term-addresses.keyed-term-resolves · anchored test binding · binding present · test/self-hosting-term-addresses.test.ts:16
  • test:protocol.term-addresses.malformed-term-marker-refused: test:protocol.term-addresses.malformed-term-marker-refused · anchored test binding · binding present · test/self-hosting-term-addresses.test.ts:63
  • test:protocol.term-addresses.repeated-term-key-refused: test:protocol.term-addresses.repeated-term-key-refused · anchored test binding · binding present · test/self-hosting-term-addresses.test.ts:110
  • test:protocol.term-addresses.typescript-term-imports-keyed: test:protocol.term-addresses.typescript-term-imports-keyed · anchored test binding · binding present · test/self-hosting-term-addresses.test.ts:157
  • test:protocol.term-addresses.unknown-term-key-refused: test:protocol.term-addresses.unknown-term-key-refused · anchored test binding · binding present · test/self-hosting-term-addresses.test.ts:204
  • spec:model.term-addresses refines spec:model.spec-sections · declared — extends entry addresses to the terms a Model section defines
  • spec:model.term-addresses.keyed-term-resolves refines spec:model.term-addresses · declared
  • spec:model.term-addresses.keyed-term-resolves verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.malformed-term-marker-refused refines spec:model.term-addresses · declared
  • spec:model.term-addresses.malformed-term-marker-refused verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.repeated-term-key-refused refines spec:model.term-addresses · declared
  • spec:model.term-addresses.repeated-term-key-refused verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.typescript-term-imports-keyed refines spec:model.term-addresses · declared
  • spec:model.term-addresses.typescript-term-imports-keyed verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.unknown-term-key-refused refines spec:model.term-addresses · declared
  • spec:model.term-addresses.unknown-term-key-refused verifies spec:model.term-addresses · declared
  • impl:protocol.address-and-cycle-recipes satisfies spec:model.term-addresses · anchored
  • impl:protocol.entry-locations satisfies spec:model.term-addresses · anchored
  • impl:protocol.key-markers satisfies spec:model.term-addresses · anchored
  • impl:protocol.open-section-order satisfies spec:model.term-addresses · anchored
  • impl:protocol.prose-mentions satisfies spec:model.term-addresses · anchored
  • impl:protocol.register-recipes satisfies spec:model.term-addresses · anchored
  • impl:protocol.sdp-import-markdown-emit satisfies spec:model.term-addresses · anchored
  • impl:protocol.spec-sections satisfies spec:model.term-addresses · anchored
  • impl:protocol.stable-ids satisfies spec:model.term-addresses · anchored
  • test:protocol.keyed-content verifies spec:model.term-addresses · anchored
  • test:protocol.term-addresses.keyed-term-resolves verifies spec:model.term-addresses.keyed-term-resolves · anchored
  • test:protocol.term-addresses.malformed-term-marker-refused verifies spec:model.term-addresses.malformed-term-marker-refused · anchored
  • test:protocol.term-addresses.repeated-term-key-refused verifies spec:model.term-addresses.repeated-term-key-refused · anchored
  • test:protocol.term-addresses.typescript-term-imports-keyed verifies spec:model.term-addresses.typescript-term-imports-keyed · anchored
  • test:protocol.term-addresses.unknown-term-key-refused verifies spec:model.term-addresses.unknown-term-key-refused · anchored
Mermaid source

Copyable source; the Studio draws static SVG.

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

Decisions

  • A Spec id written in prose is a checked mention

    A Spec id in narrative or section text, outside gwt and gwt-vocabulary fences, is a mention. A mention that does not resolve is a conformance error. A mention of another Spec that shares no declared relation with the mentioning Spec, in either direction, is one warning per mentioning Spec and target Spec pair, whatever the number of locations; an address on the mentioning Spec's own id is checked for its entry and never warned. An entry address is a Spec id followed by #, the section name design, ui, question, rule, or term, a dot, and the entry's lower-camel ASCII key, as in spec:<id>#design.<key> or spec:<id>#question.<key>. A design or ui address resolves when the Spec exists and that section holds the key as its own key, other than description; a question address resolves when the Spec exists and one of its open questions carries that key; a term address resolves when the Spec exists and one of its Model terms carries that key. The # sub-part is reserved for the entry address in every namespace: a Spec's own id, a relation target, a Pack member or model reference, an anchor id or target, and the specId and ref builders all refuse it. A mention mints no edge, and the reader gains no join.

  • The shipped projections stay frozen

    Re-specifying the shipped Design Review, census, Mermaid, or Gherkin projection is refused. These four projections are the ruled read surfaces over the one graph. A later decision Spec that supersedes this one replaces the ruling whole; a decision Spec that refines this one narrows it for one projection or one rendering and leaves the rest frozen. Either passes the ADR three-part test.

Runtime
  • component:protocol.extract · the carrier and source pipeline · src/extract/index.ts:192 · layer application · context protocol

    Uses

    • 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.validate · one finding currency and ordered checks · src/validate/validators.ts:72 · layer domain · context protocol
  • component:protocol.import · canonical conversion with a fidelity boundary · src/import/import.ts:45 · layer application · context protocol

    Uses

  • component:protocol.model · the authored contracts and stable ids · src/model/anchors.ts:100 · layer domain · context protocol

    Uses

    None.

  • component:protocol.validate · one finding currency and ordered checks · src/validate/validators.ts:72 · layer domain · context protocol

    Uses

  • impl:protocol.address-and-cycle-recipes · asserts realization of the shipped address resolution and dependency cycle recipes · test/recipes.test.ts:3568

    Uses

    None.

  • impl:protocol.entry-locations · builds the carrier entry location table · src/extract/derive.ts:78

    Component: component:protocol.extract · the carrier and source pipeline · src/extract/index.ts:192 · layer application · context protocol

    Uses

    None.

  • impl:protocol.key-markers · normalizes step and term markers across the three carriers · src/extract/key-markers.ts:136

    Component: component:protocol.extract · the carrier and source pipeline · src/extract/index.ts:192 · layer application · context protocol

    Uses

    None.

  • impl:protocol.open-section-order · preserves authored open-section and model-term order and Pack field order · src/extract/serialize.ts:105

    Component: component:protocol.extract · the carrier and source pipeline · src/extract/index.ts:192 · layer application · context protocol

    Uses

    None.

  • impl:protocol.prose-mentions · checks that prose mentions resolve and warns once per unbacked Spec pair · src/validate/validators.ts:1370

    Component: component:protocol.validate · one finding currency and ordered checks · src/validate/validators.ts:72 · layer domain · context protocol

    Uses

    None.

  • impl:protocol.register-recipes · asserts realization of the shipped register recipes · test/recipes.test.ts:2057

    Uses

    None.

  • impl:protocol.sdp-import-markdown-emit · emits the Markdown document twin for an imported Spec · src/import/emit-markdown.ts:253

    Component: component:protocol.import · canonical conversion with a fidelity boundary · src/import/import.ts:45 · layer application · context protocol

    Uses

    None.

  • impl:protocol.spec-sections · typed Spec section shapes · src/model/sections.ts:138

    Component: component:protocol.model · the authored contracts and stable ids · src/model/anchors.ts:100 · layer domain · context protocol

    Uses

    None.

  • impl:protocol.stable-ids · stable ID grammar parser · src/ids.ts:173

    Component: component:protocol.model · the authored contracts and stable ids · src/model/anchors.ts:100 · layer domain · 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:model.term-addresses
The diagram as text
  • spec:carrier.markdown-body-grammar: The Markdown body accepts one closed form per section
  • spec:consumers.agent-surface.address-and-cycle-recipes: Address resolution and dependency cycles stay executable graph recipes
  • spec:consumers.agent-surface.register-recipes: Register questions stay executable graph recipes
  • spec:consumers.obsidian-vault.notes: Every Spec, Pack, code unit and keyed term is a note, and every relation is a link
  • spec:consumers.spec-studio.glossary-page: The glossary page lists every term the corpus's Specs define
  • spec:consumers.spec-studio.spec-page: A Spec page shows one Spec in collapsible panels, in a fixed order
  • spec:consumers.upgrade-kit.capability-adoption: Capability adoption counts where each capability is used and where it could apply
  • spec:decisions.checked-mentions: A Spec id written in prose is a checked mention
  • spec:decisions.shipped-projections-frozen: The shipped projections stay frozen
  • spec:extraction.entry-locations: The graph records where each addressable entry is written
  • spec:model.rule-keys: A rule or flow entry may carry a key that addresses it
  • spec:model.spec-sections: Spec sections carry typed detail and direct verifier semantics
  • spec:model.stable-ids: Stable IDs are the Protocol's durable join key
  • spec:model.term-addresses: A Model term may carry a key that addresses it
  • spec:model.term-addresses.keyed-term-resolves: A keyed term is reified and its address resolves
  • spec:model.term-addresses.malformed-term-marker-refused: A term marker whose key is off the grammar refuses its carrier
  • spec:model.term-addresses.repeated-term-key-refused: A term key repeated in one Spec refuses its carrier
  • spec:model.term-addresses.typescript-term-imports-keyed: A keyed TypeScript term keeps its address through import to Markdown
  • spec:model.term-addresses.unknown-term-key-refused: An address that names a term key no term carries is an error
  • spec:validation.prose-mentions: Every Spec id written in prose resolves
  • spec:model.term-addresses decidedBy spec:decisions.checked-mentions · declared — a term address joins the address law that decision rules
  • spec:model.term-addresses decidedBy spec:decisions.shipped-projections-frozen · declared — term keys stay off the frozen projections, which read the definition unchanged
  • spec:model.term-addresses dependsOn spec:extraction.entry-locations · declared — adds a row per Model term to the location table
  • spec:model.term-addresses dependsOn spec:model.rule-keys · declared — the term-key design follows the rule-entry address pattern
  • spec:model.term-addresses dependsOn spec:model.stable-ids · declared — a term address extends the Spec entry-address grammar
  • spec:model.term-addresses refines spec:model.spec-sections · declared — extends entry addresses to the terms a Model section defines
  • spec:carrier.markdown-body-grammar dependsOn spec:model.term-addresses · declared — a Model definition may open with a term key marker
  • spec:consumers.agent-surface.address-and-cycle-recipes dependsOn spec:model.term-addresses · declared — a term address resolves through the Spec's term keys
  • spec:consumers.agent-surface.register-recipes dependsOn spec:model.term-addresses · declared — entry search and the mention audit read term addresses
  • spec:consumers.obsidian-vault.notes dependsOn spec:model.term-addresses · declared — a term note exists for a Model term that carries a key and so an address
  • spec:consumers.spec-studio.glossary-page dependsOn spec:model.term-addresses · declared — a keyed term's address links it to its definition
  • spec:consumers.spec-studio.spec-page dependsOn spec:model.term-addresses · declared — a keyed term's address names the element a glossary row links to
  • spec:consumers.upgrade-kit.capability-adoption dependsOn spec:model.term-addresses · declared — term keys are counted where Model terms are
  • spec:validation.prose-mentions dependsOn spec:model.term-addresses · declared — a term address resolves through the Spec's term keys
  • spec:model.term-addresses.keyed-term-resolves refines spec:model.term-addresses · declared
  • spec:model.term-addresses.malformed-term-marker-refused refines spec:model.term-addresses · declared
  • spec:model.term-addresses.repeated-term-key-refused refines spec:model.term-addresses · declared
  • spec:model.term-addresses.typescript-term-imports-keyed refines spec:model.term-addresses · declared
  • spec:model.term-addresses.unknown-term-key-refused refines spec:model.term-addresses · declared
  • spec:model.term-addresses.keyed-term-resolves verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.malformed-term-marker-refused verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.repeated-term-key-refused verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.typescript-term-imports-keyed verifies spec:model.term-addresses · declared
  • spec:model.term-addresses.unknown-term-key-refused verifies spec:model.term-addresses · 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

Distance 4

Distance 5

Distance 6

Distance 7

Distance 8

Distance 9

Relations

Relation and directionOther endClaimReasonExercised keys
decidedBy · outgoingA Spec id written in prose is a checked mention
spec:decisions.checked-mentions · resolves
declareda term address joins the address law that decision rulesNone
decidedBy · outgoingThe shipped projections stay frozen
spec:decisions.shipped-projections-frozen · resolves
declaredterm keys stay off the frozen projections, which read the definition unchangedNone
dependsOn · outgoingThe graph records where each addressable entry is written
spec:extraction.entry-locations · resolves
declaredadds a row per Model term to the location tableNone
dependsOn · outgoingA rule or flow entry may carry a key that addresses it
spec:model.rule-keys · resolves
declaredthe term-key design follows the rule-entry address patternNone
dependsOn · outgoingStable IDs are the Protocol's durable join key
spec:model.stable-ids · resolves
declareda term address extends the Spec entry-address grammarNone
refines · outgoingSpec sections carry typed detail and direct verifier semantics
spec:model.spec-sections · resolves
declaredextends entry addresses to the terms a Model section definesNone
dependsOn · incomingThe Markdown body accepts one closed form per section
spec:carrier.markdown-body-grammar · resolves
declareda Model definition may open with a term key markerNone
dependsOn · incomingAddress resolution and dependency cycles stay executable graph recipes
spec:consumers.agent-surface.address-and-cycle-recipes · resolves
declareda term address resolves through the Spec's term keysNone
dependsOn · incomingRegister questions stay executable graph recipes
spec:consumers.agent-surface.register-recipes · resolves
declaredentry search and the mention audit read term addressesNone
dependsOn · incomingEvery Spec, Pack, code unit and keyed term is a note, and every relation is a link
spec:consumers.obsidian-vault.notes · resolves
declareda term note exists for a Model term that carries a key and so an addressNone
dependsOn · incomingThe glossary page lists every term the corpus's Specs define
spec:consumers.spec-studio.glossary-page · resolves
declareda keyed term's address links it to its definitionNone
dependsOn · incomingA Spec page shows one Spec in collapsible panels, in a fixed order
spec:consumers.spec-studio.spec-page · resolves
declareda keyed term's address names the element a glossary row links toNone
dependsOn · incomingCapability adoption counts where each capability is used and where it could apply
spec:consumers.upgrade-kit.capability-adoption · resolves
declaredterm keys are counted where Model terms areNone
dependsOn · incomingEvery Spec id written in prose resolves
spec:validation.prose-mentions · resolves
declareda term address resolves through the Spec's term keysNone
refines · incomingA keyed term is reified and its address resolves
spec:model.term-addresses.keyed-term-resolves · resolves
declaredNoneNone
refines · incomingA term marker whose key is off the grammar refuses its carrier
spec:model.term-addresses.malformed-term-marker-refused · resolves
declaredNoneNone
refines · incomingA term key repeated in one Spec refuses its carrier
spec:model.term-addresses.repeated-term-key-refused · resolves
declaredNoneNone
refines · incomingA keyed TypeScript term keeps its address through import to Markdown
spec:model.term-addresses.typescript-term-imports-keyed · resolves
declaredNoneNone
refines · incomingAn address that names a term key no term carries is an error
spec:model.term-addresses.unknown-term-key-refused · resolves
declaredNoneNone
verifies · incomingA keyed term is reified and its address resolves
spec:model.term-addresses.keyed-term-resolves · resolves
declaredNonetermMarker, termAddress, termLocations, termReaders
verifies · incomingA term marker whose key is off the grammar refuses its carrier
spec:model.term-addresses.malformed-term-marker-refused · resolves
declaredNonetermMarker, markerRefusals
verifies · incomingA term key repeated in one Spec refuses its carrier
spec:model.term-addresses.repeated-term-key-refused · resolves
declaredNoneuniqueTermKeys, markerRefusals
verifies · incomingA keyed TypeScript term keeps its address through import to Markdown
spec:model.term-addresses.typescript-term-imports-keyed · resolves
declaredNonetermMarker, termAddress
verifies · incomingAn address that names a term key no term carries is an error
spec:model.term-addresses.unknown-term-key-refused · resolves
declaredNoneauthoredKey, termAddress, termReaders

Bindings

Implementation binding: present

  • impl:protocol.address-and-cycle-recipes · asserts realization of the shipped address resolution and dependency cycle recipes · test/recipes.test.ts:3568
  • impl:protocol.entry-locations · builds the carrier entry location table · src/extract/derive.ts:78 · role extractor · component component:protocol.extract · layer application · context protocol
  • impl:protocol.key-markers · normalizes step and term markers across the three carriers · src/extract/key-markers.ts:136 · role codec · component component:protocol.extract · layer application · context protocol
  • impl:protocol.open-section-order · preserves authored open-section and model-term order and Pack field order · src/extract/serialize.ts:105 · role codec · component component:protocol.extract · layer application · context protocol
  • impl:protocol.prose-mentions · checks that prose mentions resolve and warns once per unbacked Spec pair · src/validate/validators.ts:1370 · role validator · component component:protocol.validate · layer domain · context protocol
  • impl:protocol.register-recipes · asserts realization of the shipped register recipes · test/recipes.test.ts:2057
  • impl:protocol.sdp-import-markdown-emit · emits the Markdown document twin for an imported Spec · src/import/emit-markdown.ts:253 · role codec · component component:protocol.import · layer application · context protocol
  • impl:protocol.spec-sections · typed Spec section shapes · src/model/sections.ts:138 · role contract · component component:protocol.model · layer domain · context protocol
  • impl:protocol.stable-ids · stable ID grammar parser · src/ids.ts:173 · role codec · component component:protocol.model · layer domain · context protocol

Design reference: none

Verifier binding: present

Expected-outcome oracle: none

Runtime observation: not tracked.

Run results: not recorded in the graph.

Findings

None.

Composing (0)

Composing needs the script.