No open questions and no blocking questions; implementation binding present, verifier binding present, and expected-outcome oracle present.
A corpus written against an earlier design cites that design's numbered things by token: its decisions, laws, scenarios, and the extensions the corpus itself adds. The first adopter keeps such a register as a table in its design README and checks the tokens its Specs cite against it with a script that reads the carriers a second way (libar-platform/design/tools/check.py). A register is the corpus's own data and never the Protocol's. A token stays prose: the carrier gains no grammar for it and the graph mints no node for it. Recipe 50 reads the tokens the Specs already hold as text, finds them by a pattern the corpus gives, checks them against a register file the corpus passes, and answers with findings, so the check runs as a rules file on the one validation path. Which registers a corpus may cite, and so which files it passes, is its owner's ruling.
Intent
problem
A corpus that cites the tokens of an outside register checks them with a script that reads its carriers a second way, or does not check them at all.
outcome
Check the tokens a corpus cites from an outside register against a register file it supplies, as a rules file, with no new grammar and no graph node.
External registers, recipe 50, takes the register as data, a file the corpus passes with --params register=@PATH, and the pattern that finds the register's tokens in text, and reads the graph and nothing else.
It reads every string entry search walks in each Spec, the narrative and every section value with the keys an author coins, open questions and their fields and example steps included, plus each Spec's title and the reason of each relation it declares; it reads no id, fixed field name, Pack manifest, file or source.
The answer carries its findings, so the shipped file runs unchanged as a rules file at the severity the corpus passes; a corpus that checks several registers calls the recipe once per register through recipes from a rules file of its own, because one rules file is named once.
Given a probe corpus whose Spec cites the tokens {cited: "E-1"}
Given a register file that holds {held: "E-1 E-2"} and retires {retired: ""}
When the shipped external-registers file runs as a rules file with the pattern for E-numbers and uncited {uncited: true}
Then the command exits {exitCode: 1}
Then the corpus findings carry the rule ids {ruleIds: "uncited-token"}
Given
a probe corpus whose Spec cites the tokens {cited: "E-1"}
a register file that holds {held: "E-1 E-2"} and retires {retired: ""}
When
the shipped external-registers file runs as a rules file with the pattern for E-numbers and uncited {uncited: true}
Then
the command exits {exitCode: 1}
the corpus findings carry the rule ids {ruleIds: "uncited-token"}
Given a probe corpus whose Spec cites the tokens {cited: "E-1 E-7 E-9"}
Given a register file that holds {held: "E-1 E-2"} and retires {retired: "E-7"}
When the shipped external-registers file runs as a rules file with the pattern for E-numbers and uncited {uncited: false}
Then the command exits {exitCode: 1}
Then the corpus findings carry the rule ids {ruleIds: "retired-token, unknown-token"}
Given
a probe corpus whose Spec cites the tokens {cited: "E-1 E-7 E-9"}
a register file that holds {held: "E-1 E-2"} and retires {retired: "E-7"}
When
the shipped external-registers file runs as a rules file with the pattern for E-numbers and uncited {uncited: false}
Then
the command exits {exitCode: 1}
the corpus findings carry the rule ids {ruleIds: "retired-token, unknown-token"}
Given a probe corpus whose Spec cites the tokens {cited:string}
Given a register file that holds {held:string} and retires {retired:string}
When the shipped external-registers file runs as a rules file with the pattern for E-numbers and uncited {uncited:boolean}
Then the command exits {exitCode:number}
Then the corpus findings carry the rule ids {ruleIds:string}
{ "tokens": [token] }, where each token is a non-empty string the register holds, or { "token": "<string>", "retired": <boolean> }, retired when retired is true and held otherwise; other keys of the file and of a token object are the corpus's own and ignored, so a register may carry its own columns.
recipe 50 takes params.register, the register file's object, params.pattern, params.severity, "error" by default or "warning", and params.uncited, false by default; register and pattern have no sample, and a missing or malformed parameter returns { diagnostics: [{ parameter, problem }] } and no findings, which fails the file as a rules file.
params.pattern is the source of a JavaScript regular expression compiled with the flags gu, whose whole match is the token; a pattern that does not compile, that matches the empty string, or that fails to match each of the register's tokens whole is a diagnostic, as is a token the register lists twice.
{ input: { pattern, severity, uncited }, totals: { specs, citations, tokens, unknown, retired, uncited }, tokens, findings }, where specs counts the Specs read, citations the matches, tokens the distinct cited tokens, and the last three the findings of each rule id.
{ token, held, retired, citations, specs } for each distinct cited token in code-unit order, where specs lists the citing Specs by id and an unknown token has held and retired false.
{ validatorId, subjectId, relatedId, severity, message, file, path, line } for unknown-token and retired-token, where subjectId is the citing Spec, relatedId the token, file the Spec's carrier, path the first citing text, in the order the title, the narrative and sections as entry search walks them, then relation reasons as authored, written title, a text path in the form the prose-mention check writes, such as narrative, behavior.rules[2] or design.<key>, or relation.<type>.<target>, and line that text's recorded line, left out when not located; findings sort by Spec id, then token.
<spec> cites <token>, which the register does not list for unknown-token, <spec> cites <token>, which the register retires for retired-token, and <token> is held by the register and no Spec cites it for uncited-token.
{ validatorId: "uncited-token", subjectId, severity, message }, where subjectId is the token; these findings follow the others, in the register's order.
no citation recorded
Verification
Verifier bindings
spec:validation.external-registers.uncited-on-request · A held token no Spec cites fails a rules run only when the caller asks · declared · example enabled · specs/validation/external-registers.uncited-on-request.sdp.md
External run evidence from test/self-hosting-external-registers.test.ts
spec:consumers.spec-studio.register-input: An outside register is a named Studio input, so a cited token links to its entry
spec:validation.corpus-rules: Corpus-authored rules run on the one validation path
spec:validation.external-registers: A corpus checks the register tokens its prose cites
spec:validation.external-registers.uncited-on-request: A held token no Spec cites fails a rules run only when the caller asks
spec:validation.external-registers.unknown-and-retired: A cited token the register lacks or retires fails a rules run
spec:validation.external-registers dependsOn spec:consumers.agent-surface.recipe-parameters · declared — the register arrives as data through `--params register=@PATH`
spec:validation.external-registers dependsOn spec:consumers.agent-surface.register-recipes · declared — the recipe reads the strings entry search walks, with its entry paths and lines
spec:validation.external-registers dependsOn spec:validation.corpus-rules · declared — the recipe answers with findings and runs as a rules file
spec:validation.external-registers refines spec:validation.corpus-rules · declared — external-register checks run as corpus-selected rules
spec:consumers.spec-studio.register-input dependsOn spec:validation.external-registers · declared — the input is the register file and pattern the external-registers recipe already reads
impl:protocol.external-registers-recipe · asserts realization of the shipped external-registers recipe · test/external-registers.test.ts:9
Design reference: none
Verifier binding: present
spec:validation.external-registers.uncited-on-request · A held token no Spec cites fails a rules run only when the caller asks · declared · specs/validation/external-registers.uncited-on-request.sdp.md · example enabled