Spec Studio

Validation re-runs while an author edits carriers

spec:consumers.validate-watchUse Case / Behavior · storyready floor ready

Packs: pack:adopter-speed-v1, pack:design-management-v1, pack:self-hosting-v1

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

Findings: no errors, no warnings

specs/consumers/validate-watch.sdp.md

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

Intent
problem
An author editing a Spec re-runs sdp validate by hand after every save.
outcome
Let sdp validate --watch re-run the one validation path on every carrier change and stay alive after findings, as a loop for authoring and never a second validation path.
Behavior
rule line 19 · specs/consumers/validate-watch.sdp.md:19
sdp validate --watch [root] installs its watcher first, then runs the same validate path sdp validate runs, from scratch, once at start and again after every carrier create, change, delete or rename under the root.
rule line 20 · specs/consumers/validate-watch.sdp.md:20
A carrier ends in .sdp.md, .sdp.gherkin or .sdp.ts. The watcher ignores the directories discovery skips, the configured exclusion prefixes and every non-carrier path other than the rules files and parameter files --rules names, which it watches wherever they live, as spec:validation.corpus-rules#rule.watchReruns and spec:validation.corpus-rules#rule.watchedParams state, and the symbolic links discovery warns about, as spec:extraction.excludes#rule.canonicalDiscovery states, because creating, removing or replacing one changes the warning list. The watcher never follows a link. A watched directory removed or replaced by a link, a file or another directory, and an event with no filename, each schedule a run because their affected carriers cannot be named. So does a watched directory's own watch reporting a change to the directory itself, because a directory deleted and recreated can keep its identity while that watch has died; on a platform that reports a change to the directory's attributes the same way, that change schedules a run too. An event for an entry that has the directory's own name can look the same and then schedules a run too, as where the filesystem reports no birth time for the directory. A directory that replaces a watched one, the root included, is watched in its place, and a root that no longer resolves to a directory ends the watch with exit 1.
rule line 21 · specs/consumers/validate-watch.sdp.md:21
Events that arrive while a run is in progress coalesce into one pending run.
rule.operatorStop line 22 · specs/consumers/validate-watch.sdp.md:22
Findings print as sdp validate prints them and the process stays alive; operator SIGINT terminates the process with exit 0 even while a rules body is active, without waiting for it. No further rules file runs or output is written after the stop.

no example exercises it

rule line 23 · specs/consumers/validate-watch.sdp.md:23
For sdp validate, --watch cannot combine with --check-clean, and it re-runs on carrier edits and on edits to the files --rules names, and never on source edits, so an author re-runs validation after editing an anchor. This rule restricts no other verb's --watch, which its own Spec states.

4 unkeyed rules.

Verification

Verifier bindings

  • test:protocol.validate-watch · watch-loop checks verify the validate --watch authoring loop · anchored · test anchor binding present · test/cli.test.ts:1692

    External run evidence from test/cli.test.ts

    Test anchors: test:protocol.engine-provenance, test:protocol.extraction-determinism, test:protocol.projections-model.publication, test:protocol.regenerability, test:protocol.validate-watch. Specs verified by those bindings: spec:consumers.engine-provenance, spec:consumers.projections-model, spec:consumers.validate-watch, spec:extraction.determinism, spec:extraction.regenerability.

    Run 1: external run evidence from vitest 4.1.10

    Build: CI 439 · Branch: docs/articles-refresh-1 · Commit: 61576184ea9f39b7f91c51fef5ff991b0bf2d0e6 · Start: 2026-11-04T08:03:40.500Z · Stop: 2026-11-04T08:04:09.917Z

    NameSuiteResultDuration
    prints the exact help text for no argssdp clipassed2.5 ms
    points operators to the shipped on-ramps and Protocol corpussdp clipassed2.6 ms
    describes both anchor forms and non-failing warnings in helpsdp clipassed0.61 ms
    prints the exact help text for --helpsdp clipassed0.29 ms
    builds the checkout-v1 example: writes graph, contracts, and registrar manifest atomicallysdp clipassed183.58 ms
    invalidates an existing Design Review when build replaces its source graphsdp clipassed102.06 ms
    views the self-hosting corpus from the default repository rootsdp clipassed14803.46 ms
    renders contracts warnings through the one formatter and counts them in the summarysdp clipassed11.76 ms
    withholds case-colliding contract paths with a warning: graph kept, nothing gatessdp clipassed7.14 ms
    passes --check-clean on the example (determinism self-check through the CLI)sdp clipassed63.79 ms
    end-to-end determinism self-check: delete generated/, rebuild, byte-identicalsdp clipassed239.81 ms
    fails clean on a root that is not a directory: one line, exit 1, never a stack tracesdp clipassed0.44 ms
    rejects an unknown option: one line, exit 1, nothing runssdp clipassed0.2 ms
    accepts repeatable --exclude paths for buildsdp clipassed7.89 ms
    accepts repeatable --exclude paths for validatesdp clipassed9.26 ms
    accepts repeatable --exclude paths for viewsdp clipassed8.56 ms
    uses the identical normalized exclusions in both --check-clean extractionssdp clipassed11.76 ms
    refuses invalid --exclude path "" before build writessdp clipassed1.23 ms
    refuses invalid --exclude path "." before build writessdp clipassed0.67 ms
    refuses invalid --exclude path "./explorations" before build writessdp clipassed0.46 ms
    refuses invalid --exclude path "explorations/" before build writessdp clipassed0.41 ms
    refuses invalid --exclude path "/explorations" before build writessdp clipassed0.42 ms
    refuses invalid --exclude path "../x" before build writessdp clipassed0.41 ms
    refuses invalid --exclude path "a/../b" before build writessdp clipassed0.34 ms
    refuses invalid --exclude path "a//b" before build writessdp clipassed0.33 ms
    refuses invalid --exclude path "a\\b" before build writessdp clipassed0.49 ms
    refuses a missing --exclude operand before build writessdp clipassed0.51 ms
    names a flag supplied as an --exclude operand before build writessdp clipassed0.35 ms
    documents repeatable --exclude paths in helpsdp clipassed0.13 ms
    rejects a second root argument: one line, exit 1, nothing runssdp clipassed0.3 ms
    notes an empty authored model: zero spec files still builds and exits 0, but says where it lookedsdp clipassed2.84 ms
    renders a finding's location exactly once, from the structured fields: file:line — [severity]sdp clipassed5.53 ms
    renders a Gherkin parser failure through the public CLIsdp clipassed3.78 ms
    exits 1, writes nothing, and removes a stale graph.json on a hard-error corpussdp clipassed6.4 ms
    fails build on an integer-like design key holding a static valuesdp clipassed10.07 ms
    fails build on an integer-like design key holding a non-static valuesdp clipassed3.54 ms
    fails build on an integer-like design key holding a methodsdp clipassed3.59 ms
    fails build on an integer-like design key holding an accessorsdp clipassed3.72 ms
    fails --check-clean on a diverging second extraction: exit 1, the stale graph.json removedsdp clipassed11.32 ms
    fails --check-clean on a diverging second contract generation: exit 1, no artifact survivessdp clipassed40.44 ms
    owns the contracts tree wholesale: with nothing to generate, a stale contracts dir is removedsdp clipassed8.01 ms
    refuses a swapped registrar ancestor before creating outside parent directoriessdp clipassed23.4 ms
    reconciles a registrar sibling that a later generation no longer owessdp clipassed44.01 ms
    fails --check-clean on registrar-byte drift and removes the uncertified known setsdp clipassed54.69 ms
    passes --check-clean without a prior manifest when no registrars are owedsdp clipassed8.5 ms
    fails --check-clean on registrar manifest whitespace driftsdp clipassed53.03 ms
    fails --check-clean on registrar manifest ignored property driftsdp clipassed55.98 ms
    removes graph, contracts, manifest, and registrar siblings after a staged write failuresdp clipassed46.62 ms
    fails clean when extraction throws past discovery: one line, exit 1, the stale graph.json removedsdp clipassed1.74 ms
    fails clean when generated exists as a file: one line each for build and view, never a stack tracesdp clipassed1.59 ms
    names the survivor when a recovery-path removal is denied: a stale artifact never silently reads as currentsdp clipassed1.58 ms
    stops a build when an existing Design Review cannot be invalidatedsdp clipassed6.18 ms
    fails clean when the checks throw: one line, exit 1, the built graph.json stayssdp clipassed7.39 ms
    suppresses the empty-model note when spec files were found but none reified — a failed file is not an absent onesdp clipassed4.51 ms
    treats a root of only ordinary .feature files as an empty authored model, not a missing-identity errorsdp clipassed3.08 ms
    suppresses the empty-model note when a failed .sdp.gherkin finding.file matches the carrier suffix predicatesdp clipassed3.35 ms
    builds a mixed root with one .sdp.gherkin carrier and ignores the ordinary .feature siblingsdp clipassed3.64 ms
    removes the temp twin on a failed build and a failed view — no partial .tmp artifact survivessdp clipassed21.76 ms
    recognizes the published-bin path: a .bin-style symlink resolves to the entry modulesdp clipassed0.79 ms
    exits 0 quietly on a stdout EPIPE and stays fatal for any other stream errorsdp clipassed0.92 ms
    validates the example: exit 0, the artifact written, and no warningsdp clipassed58.4 ms
    gates on the checks, not the build: a clean-building broken link validates to exit 1 with the artifact keptsdp clipassed8.03 ms
    short-circuits the checks on extraction hard errors: validate keeps build semanticssdp clipassed4.99 ms
    prints help plus an unknown-command errorsdp clipassed0.23 ms
    views the example: validate + the Design Review written, with no warningsdp clipassed84.09 ms
    owns the view directory wholesale: a stale page does not survive a re-rendersdp clipassed35.98 ms
    regenerates the view byte-identically: delete generated/, re-view, same bytessdp clipassed58.04 ms
    writes the view even when checks fail: findings render in it, the exit code is validate'ssdp clipassed9.51 ms
    keeps build semantics on extraction hard errors: no graph, no view, stale view removedsdp clipassed4.54 ms
    fails view --check-clean on a diverging second render: exit 1, the stale view removedsdp clipassed10.34 ms
    fails clean when the render throws: one line on stderr, exit 1, the stale view removedsdp clipassed6.38 ms
    closes the compiled watch process with exit 0 after operator SIGINTsdp validate --watchpassed490.08 ms
    documents --watch as a validate-only authoring loopsdp validate --watchpassed0.32 ms
    rejects --watch on build with a named error and no watchersdp validate --watchpassed0.23 ms
    rejects --watch on view with a named error and no watchersdp validate --watchpassed0.13 ms
    rejects --watch on census with a named error and no watchersdp validate --watchpassed0.13 ms
    rejects --watch on mermaid with a named error and no watchersdp validate --watchpassed0.13 ms
    rejects --watch on gherkin with a named error and no watchersdp validate --watchpassed0.13 ms
    rejects --watch on import with a named error and no watchersdp validate --watchpassed0.31 ms
    rejects --watch on new with a named error and no watchersdp validate --watchpassed0.4 ms
    rejects --watch on q with a named error and no watchersdp validate --watchpassed0.35 ms
    rejects --watch --check-clean with a named error and no watchersdp validate --watchpassed0.21 ms
    installs the watcher before the first validation cyclesdp validate --watchpassed8.85 ms
    catches an edit during the first cycle with exactly one coalesced rerunsdp validate --watchpassed12.09 ms
    coalesces a burst during an active cycle into exactly one rerunsdp validate --watchpassed11.97 ms
    prints validation findings and keeps watching until abort exits 0sdp validate --watchpassed11.72 ms
    ignores generated, dist, node_modules, coverage, dot directories, and configured excludessdp validate --watchpassed13.37 ms
    coalesces production-shaped events from later turns into one pending rerunsdp validate --watchpassed11.99 ms
    does not natively subscribe to excluded or generated subtreessdp validate --watchpassed31.81 ms
    routes a native watcher error through a typed channel and closes oncesdp validate --watchpassed7.71 ms
    clean-repo determinism: the full pipeline at a different absolute path is byte-identicalnot recordedpassed152.57 ms
    clean-repo determinism: an untouched Protocol copy has the same graph with external and local enginesnot recordedpassed9629.74 ms
    prints one line naming the package version and the recorded commit, and exits 0sdp --versionpassed0.67 ms
    names the commit unknown when the build recorded none or recorded something elsesdp --versionpassed1.12 ms
    reads the version from the package manifest two directories above the CLI modulesdp --versionpassed0.46 ms
    documents --version and --params in the usage textsdp --versionpassed0.2 ms
    records the checked-out commit at build time, or unknown when git cannot name onesdp --versionpassed16.95 ms
    publishes the commit the build step reads from git beside the CLIsdp --versionpassed1.94 ms
    builds commit metadata from a substituted git archive extracted without .gitsdp --versionpassed60.71 ms
    uses only a full archive commit when git gives none, keeping git firstsdp --versionpassed1.82 ms
    answers from the compiled CLI with the commit its build recorded beside itsdp --versionpassed475.14 ms
    runs recipe 4 as shipped, its changed files passed with --params @PATHa shipped recipe file through the compiled CLIpassed588.2 ms
  • test:protocol.validate-watch-rules · process checks verify operator stop during active corpus rules · anchored · test anchor binding present · test/corpus-rules.test.ts:351

    External run evidence from test/corpus-rules.test.ts

    Test anchors: test:protocol.validate-watch-rules. Specs verified by those bindings: spec:consumers.validate-watch.

    Run 2: external run evidence from vitest 4.1.10

    Build: CI 439 · Branch: docs/articles-refresh-1 · Commit: 61576184ea9f39b7f91c51fef5ff991b0bf2d0e6 · Start: 2026-11-04T07:59:39.962Z · Stop: 2026-11-04T08:03:39.928Z

    NameSuiteResultDuration
    documents repeatable rules, per-file parameters and check-cleancorpus rule argumentspassed3.18 ms
    refuses "--params" before derivingcorpus rule argumentspassed2.02 ms
    refuses "--params" before derivingcorpus rule argumentspassed0.53 ms
    refuses "--rules" before derivingcorpus rule argumentspassed0.36 ms
    refuses "--rules" before derivingcorpus rule argumentspassed0.86 ms
    refuses "--rules" before derivingcorpus rule argumentspassed1.19 ms
    refuses "--rules" before derivingcorpus rule argumentspassed0.57 ms
    refuses "--rules" before derivingcorpus rule argumentspassed0.6 ms
    refuses "--rules" before derivingcorpus rule argumentspassed0.52 ms
    binds parameters to the preceding file across other optionscorpus rule argumentspassed2.92 ms
    refuses rules on buildcorpus rule argumentspassed0.81 ms
    refuses rules on viewcorpus rule argumentspassed0.3 ms
    refuses rules on censuscorpus rule argumentspassed0.31 ms
    refuses rules on mermaidcorpus rule argumentspassed0.5 ms
    refuses rules on gherkincorpus rule argumentspassed0.41 ms
    refuses rules on qcorpus rule argumentspassed0.49 ms
    refuses the same rules file through a symlink before derivingcorpus rules on validatepassed2.57 ms
    refuses a finding file outside root-relative POSIX paths: /etc/passwdcorpus rules on validatepassed31.38 ms
    refuses a finding file outside root-relative POSIX paths: ../outside.tscorpus rules on validatepassed8.95 ms
    refuses a finding file outside root-relative POSIX paths: src/../../outside.tscorpus rules on validatepassed11.3 ms
    refuses a finding file outside root-relative POSIX paths: src\\probe.tscorpus rules on validatepassed14.57 ms
    refuses a finding file outside root-relative POSIX paths: C:/outside.tscorpus rules on validatepassed16.94 ms
    reports a root-relative finding path: src/probe.tscorpus rules on validatepassed18.38 ms
    reports a root-relative finding path: src/../probe.tscorpus rules on validatepassed13.86 ms
    reports a error finding apart from Protocol findingscorpus rules on validatepassed18.35 ms
    reports a warning finding apart from Protocol findingscorpus rules on validatepassed21.36 ms
    fails a broken file and continues: throw new Error('two\nlines')corpus rules on validatepassed15.12 ms
    fails a broken file and continues: return {corpus rules on validatepassed37.68 ms
    fails a broken file and continues: return { findings: [] }; /* open commentcorpus rules on validatepassed20.15 ms
    fails a broken file and continues: return { findings: [] }; }) ;(function(){corpus rules on validatepassed17.1 ms
    fails a broken file and continues: return { diagnostics: ['bad'] }corpus rules on validatepassed6 ms
    fails a broken file and continues: return { unknownParams: ['typo'], accepts: [] }corpus rules on validatepassed7.06 ms
    fails a broken file and continues: return { findings: [{ validatorId: 'a', severity: 'warning', message: 'x' }] }corpus rules on validatepassed8.88 ms
    fails a broken file and continues: return { findings: [{ ...({ validatorId: "probe-rule", subjectId: "probe-subject", severity: "error", message: "probe finding" }), severity: 'info' }] }corpus rules on validatepassed16.32 ms
    fails a broken file and continues: return { findings: [{ ...({ validatorId: "probe-rule", subjectId: "probe-subject", severity: "error", message: "probe finding" }), validatorId: 'a/b' }] }corpus rules on validatepassed8.46 ms
    fails a broken file and continues: return { findings: [{ ...({ validatorId: "probe-rule", subjectId: "probe-subject", severity: "error", message: "probe finding" }), line: 1 }] }corpus rules on validatepassed7.21 ms
    fails a broken file and continues: return { findings: [{ ...({ validatorId: "probe-rule", subjectId: "probe-subject", severity: "error", message: "probe finding" }), relatedId: 1 }] }corpus rules on validatepassed8.99 ms
    fails a broken file and continues: return { findings: [{ ...({ validatorId: "probe-rule", subjectId: "probe-subject", severity: "error", message: "probe finding" }), path: 1 }] }corpus rules on validatepassed6.75 ms
    fails a broken file and continues: return { findings: [{ ...({ validatorId: "probe-rule", subjectId: "probe-subject", severity: "error", message: "probe finding" }), file: '' }] }corpus rules on validatepassed7.84 ms
    fails an unreadable filecorpus rules on validatepassed8.66 ms
    discards every finding of a malformed answercorpus rules on validatepassed7.8 ms
    clones the graph and report separately for each file and leaves written bytes wholecorpus rules on validatepassed8.7 ms
    gives each file only its own parameters, including JSON files and keyed valuescorpus rules on validatepassed8 ms
    keeps the ordinary validate output unchanged and q report free of corpus datacorpus rules on validatepassed9.15 ms
    does not run rules when the graph does not derivecorpus rules on validatepassed9.11 ms
    exposes corpus data only on the aggregate validate outcomenot recordedpassed7.31 ms
    awaits bodies in file order and keeps a Protocol error fatalnot recordedpassed12.4 ms
    SIGINT exits 0 during a live rules body, with no later output or rules, even if it can settle: falsenot recordedpassed819.64 ms
    SIGINT exits 0 during a live rules body, with no later output or rules, even if it can settle: truenot recordedpassed820.15 ms
    rereads rules when its file changesnot recordedpassed24.28 ms
    gives each watch cycle fresh parameters after a body mutates themnot recordedpassed14.56 ms
Design view

Requirement drawing

  • Declared verifying examples: no declared verifying example.
Requirement drawing for spec:consumers.validate-watch
The diagram as text
  • spec:consumers.validate-watch: Validation re-runs while an author edits carriers · declared Spec
  • spec:consumers.authoring-on-ramp: Authors move one Spec from intent to reviewed evidence · declared Spec
  • impl:protocol.validate-watch: watches carrier directories and coalesces events into a pending validation rerun · anchored code · src/cli/validate-watch.ts:924
  • test:protocol.validate-watch: watch-loop checks verify the validate --watch authoring loop · anchored test binding · binding present · test/cli.test.ts:1692
  • test:protocol.validate-watch-rules: process checks verify operator stop during active corpus rules · anchored test binding · binding present · test/corpus-rules.test.ts:351
  • spec:consumers.validate-watch refines spec:consumers.authoring-on-ramp · declared
  • impl:protocol.validate-watch satisfies spec:consumers.validate-watch · anchored
  • test:protocol.validate-watch verifies spec:consumers.validate-watch · anchored
  • test:protocol.validate-watch-rules verifies spec:consumers.validate-watch · anchored
Mermaid source

Copyable source; the Studio draws static SVG.

Preferred and chosen syntax: requirementDiagram; exact refines, satisfies and verifies, with claim words in nodes and per-edge comments.

Decisions

No decision record named.

Runtime
  • component:protocol.cli · entry points, shared build and publication · src/cli/build-command.ts:31 · layer edge · context protocol

    Uses

    • component:protocol.adapters · external runtime and source adapters · src/adapters/vitest.ts:23 · layer adapter · context protocol
    • component:protocol.codegen · contracts and registrar output · src/codegen/contracts.ts:671 · layer application · context protocol
    • component:protocol.extract · the carrier and source pipeline · src/extract/index.ts:197 · 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.import · canonical conversion with a fidelity boundary · src/import/import.ts:45 · layer application · context protocol
    • component:protocol.model · the authored contracts and stable ids · src/model/anchors.ts:100 · layer domain · context protocol
    • component:protocol.projections · read-only output, layout and owned publication · src/projections/design-review.ts:29 · layer edge · context protocol
    • component:protocol.reader · the typed graph contract and body evaluator · src/reader/reader.ts:697 · layer application · context protocol
    • component:protocol.validate · one finding currency and ordered checks · src/validate/validators.ts:76 · layer domain · context protocol
  • impl:protocol.validate-watch · watches carrier directories and coalesces events into a pending validation rerun · src/cli/validate-watch.ts:924

    Component: component:protocol.cli · entry points, shared build and publication · src/cli/build-command.ts:31 · 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.validate-watch
The diagram as text
  • spec:consumers.authoring-on-ramp: Authors move one Spec from intent to reviewed evidence
  • spec:consumers.obsidian-vault.iteration: A design pass is followed and answered from the vault
  • spec:consumers.spec-studio.publisher.watch: sdp studio --watch rebuilds the page set on each carrier change
  • spec:consumers.validate-watch: Validation re-runs while an author edits carriers
  • spec:decisions.one-validation-path: Validation follows one graph
  • spec:extraction.excludes: Extraction exclusions are strict consumer input
  • spec:validation.corpus-rules: Corpus-authored rules run on the one validation path
  • spec:consumers.validate-watch dependsOn spec:decisions.one-validation-path · declared
  • spec:consumers.validate-watch dependsOn spec:extraction.excludes · declared
  • spec:consumers.validate-watch refines spec:consumers.authoring-on-ramp · declared
  • spec:consumers.obsidian-vault.iteration dependsOn spec:consumers.validate-watch · declared — the vault's watch runs the same loop over carriers and anchored source files
  • spec:consumers.spec-studio.publisher.watch dependsOn spec:consumers.validate-watch · declared — the watch reruns on the carrier events validate's watch follows
  • spec:validation.corpus-rules dependsOn spec:consumers.validate-watch · declared — the watch loop reruns the named rules in each cycle
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
dependsOn · outgoingValidation follows one graph
spec:decisions.one-validation-path · resolves
declaredNoneNone
dependsOn · outgoingExtraction exclusions are strict consumer input
spec:extraction.excludes · resolves
declaredNoneNone
refines · outgoingAuthors move one Spec from intent to reviewed evidence
spec:consumers.authoring-on-ramp · resolves
declaredNoneNone
dependsOn · incomingA design pass is followed and answered from the vault
spec:consumers.obsidian-vault.iteration · resolves
declaredthe vault's watch runs the same loop over carriers and anchored source filesNone
dependsOn · incomingsdp studio --watch rebuilds the page set on each carrier change
spec:consumers.spec-studio.publisher.watch · resolves
declaredthe watch reruns on the carrier events validate's watch followsNone
dependsOn · incomingCorpus-authored rules run on the one validation path
spec:validation.corpus-rules · resolves
declaredthe watch loop reruns the named rules in each cycleNone

Bindings

Implementation binding: present

  • impl:protocol.validate-watch · watches carrier directories and coalesces events into a pending validation rerun · src/cli/validate-watch.ts:924 · role service · component component:protocol.cli · layer edge · context protocol

Design reference: none

Verifier binding: present

  • test:protocol.validate-watch · watch-loop checks verify the validate --watch authoring loop · anchored · test/cli.test.ts:1692 · test anchor
  • test:protocol.validate-watch-rules · process checks verify operator stop during active corpus rules · anchored · test/corpus-rules.test.ts:351 · 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.