Workbench Island
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
The grading workbench keeps its working files in a directory that is deliberately walled off from the shipped repositories. This chapter explains why that separation exists, how the internal naming scheme earns its verbosity, and how data crosses the boundary in both directions without ever overwriting a source. The result is a non-destructive round-trip — import, grade, improve, export — whose internal complexity never reaches the public artifacts.
The Island Principle
Section titled “The Island Principle”The grading data directory (grading-data/) is a workbench island: an internal working area where schemas and selections are hammered on day after day. It is deliberately separate from the public, shipped repositories. Treating it as an island is what makes the verbose internal naming scheme defensible — it is not over-engineering, it is the price of predictability.
Two properties define the island:
-
Internally verbose. Inside the island, file names carry a logical name plus a timestamp plus a content hash (
‹logical-name›--‹YYYY-MM-DDTHH-MM-SSZ›--‹hash8›.‹ext›; see15-versioning-axes.md). Each primitive gets its own folder. This verbosity guarantees predictability, linkability, and version tracking: every snapshot is addressable, every grading binds to a concrete hash, and a naivesort().at(-1)always yields the newest version. -
Stripped on the way out. When data leaves the island toward the real repositories (the mirror-out step), names are stripped to clean spec names. The outside world never sees the internal timestamps and hashes; it sees the resolved, current artifact under its plain logical name.
The island argument beats the “isn’t this overkill?” argument: the verbosity lives only on the workbench, never in the shipped product.
Outside View is the Namespace
Section titled “Outside View is the Namespace”From the outside, the unit of interest is the namespace — does it work, what can it do. Individual schemas are an internal complexity split inside a namespace (one namespace, several schemas; see the namespace special case in 19-folder-layout.md). The outside consumer asks “is this namespace operational and what grade does it carry”, not “which timestamped snapshot of which schema produced it”. The island keeps the fine-grained internal structure; the outside view collapses it to the namespace (and, for Task B, to the selection).
The source files that travel — the schema .mjs and the selection.json — are kept neutral: they carry only logical names, no inner hashes or snapshot-version keys (see 06-determinism-and-tier.md and 19-folder-layout.md). Versioning lives in the file name; the hash bindings live in the derived index.json. The source stays clean, yet every binding remains traceable.
The IN/OUT Round-Trip
Section titled “The IN/OUT Round-Trip”The island is connected to the real repositories by a two-way round-trip. Both directions are non-destructive: the island never overwrites a source, and an export never overwrites the destination.
IN — grading import <provider-path>
Section titled “IN — grading import <provider-path>”Source (a provider folder or a selection) flows into the workbench:
- Scan the
.mjsfiles. - Run
flowmcp schema-check. On failure, do NOT abort the run — emit ablockednode withreason: "validation-failed"intoindex.json, snapshot the unparseable source if it is readable, and CONTINUE with the remaining files in the folder. This is the emit-on-failure contract (the3.0.0break, see Emit-on-Failure Import Contract). - The single-namespace expectation is retained as a normative invariant (one folder = one namespace), but its violation is now an emitted record, not an abort: a folder whose schemas cannot be parsed to a single namespace emits a
blockednode rather than aborting. (A genuine disagreement between two declared namespaces remains a hard configuration error — see the emit-on-failure section below.) - Existence check: missing → create; changed (new hash) → write a new snapshot alongside the old one; identical hash → skip. The import never overwrites an existing snapshot.
- Convert into the island structure (resources to
resources/about/, skills toskills/, inline skills normalised into files). - Rebuild
index.json.
Emit-on-Failure Import Contract
Section titled “Emit-on-Failure Import Contract”Up to and including gradingSpec/2.0.x, the import gate was a hard gate: a flowmcp schema-check failure or a folder that resolved to anything other than a single namespace aborted the whole import. 3.0.0 flips this to emit-a-blocked-node-and-continue:
- Validate failure →
blockednode. When a schema fails the validate gate, the import does NOT abort. It emits ablockednode withreason: "validation-failed"(the pinned reason, matching the closedblockedReasonset in the grading module — see23-index-json.md), snapshots the unparseable source if readable, and continues with the remaining files. - All-unparseable folder → namespace-folder fallback. When all schemas in a folder are unparseable (no readable
main.namespace), the folder name is the fallback namespace identifier for the emittedblockedrollup. The fallback name MUST itself be a valid namespace (/^[a-z][a-z0-9-]*$/); a folder name that is not a valid namespace is a hard error (no silent normalisation). See19-folder-layout.mdfor the folder↔namespace consistency rule and the rename-on-parse lifecycle. - Single-namespace invariant retained, violation emitted. The one-folder-one-namespace expectation is still normative. A folder that simply could not be parsed to a namespace emits a
blockednode (it does not abort). A folder whose parsed schemas disagree on a declared namespace (≥2 distinct usable namespaces) is a genuine misconfiguration, not a fallback case, and is reported as a hard error.
Non-destructive guarantee restated. Emit-on-failure changes only the control flow (continue instead of abort); it does not weaken the non-destructive guarantees. The island still never overwrites a source snapshot (Step 4), the export never overwrites the destination (OUT), and
index.jsonremains the only overwritable artifact. No source snapshot is written for an unparseable/blocked schema — only theindex.jsonstatus record is emitted.
OUT — grading export <namespace|selection>
Section titled “OUT — grading export <namespace|selection>”Workbench flows back toward the source:
- The primary hand-off is the
index.json— the complete graded state (status, grade, member resolution, lock snapshot). - The export lands the per-namespace rollup as the committed, CI-visible provider-proof
providers/<ns>/grade.jsoninside the provider folder of the source schemas repository; CI reads that repo-resident copy, never the island-localindex.json. The data flow is specified in26-monitoring-track.md. - Optionally, the clean schema
.mjsfiles (resolved viaresolveLatest, names stripped) MAY accompany the export. - The export MUST NOT overwrite the source; it writes into a fresh export folder.
The round-trip is the concrete shape of the flywheel loop described in 18-flywheel-loop.md: import → grade → improve → export, then around again.
Related
Section titled “Related”- ./00-overview.md — see chapter 00.
- ./15-versioning-axes.md — see chapter 15.
- ./18-flywheel-loop.md — see chapter 18.
- ./19-folder-layout.md — see chapter 19.
- ./23-index-json.md — see chapter 23.
- ./26-monitoring-track.md — see chapter 26.