Repository navigation
0.1b — Add the lab.toml schema and validate it on extension load with field-precise errors #16
Description
Phase: 0-prime — Contracts/foundation · Plan task: 0.1 (SchemaPackage, lab.toml slice) · Implementing repo: amicode
Blocked by: 0.1a (SchemaPackage scaffold + shared validator + schema_version convention)
Important
Problem
A partner lab's lab.toml is the only place hardware params (frequencies, anharmonicities, couplings, drive cap) enter a solve. Today nothing validates it: β supports one lab via interview-baked constants or a raw lab.toml path with no validation layer (β.3's template reads params "from the interview or from a lab.toml path"), so a malformed or mistyped config either silently solves against the wrong hardware or fails opaquely mid-solve. A lab partner cannot fix their own config without reading source.
Approach
Add a versioned JSON Schema for lab.toml to the shared SchemaPackage (built on 0.1a's scaffold + shared validator), plus the validator entry point the extension calls when a lab.toml is loaded, emitting a field-precise error that names the offending key and its dotted path on malformed input.
Approaches Considered
- Schema + shared-validator field-precise error path (chosen) — one source of truth, reused by CLI/CI/Julia round-trip from 0.1a.
- Hand-rolled per-field checks in the extension — duplicates logic, drifts from the schema, no CI/Julia reuse.
- Defer validation, parse-and-pray at solve time — the β.3 status quo; reproduces the silent-wrong-hardware failure this slice exists to kill.
Scope
In: the lab.toml JSON Schema (schema_version-bearing); the load-time validator surface the extension invokes; field-precise error reporting (offending key + dotted path); fixture-driven negative cases.
Out:
- Value-range / sanitization / injection guards (huge
N, path-traversal, shell/eval flow) — schema-valid ≠ safe; deferred hygiene (Q110/Q111), not a 0-prime gate. - Active-lab discovery / precedence (workspace vs user) and multi-lab generalization — Phase 2 (Q134).
- Lab-injection-correctness (values land in the emitted SolveSpec) — that is the merge path, not this schema (Q44).
- Editor inline diagnostics UI surfacing — the validator returns the field-precise error; wiring it into a diagnostics panel is a separate UI concern.
Assumptions
- 0.1a has landed the shared validator harness and
schema_versionconvention this schema plugs into. - The
lab.tomlfield set (which params are required vs optional) is taken from the Schuster hardware profile the β template already consumes; this slice formalizes it, it does not negotiate it.
Acceptance Criteria
- A schema-valid
lab.toml(Schuster profile) validates clean with no error. (S17) - A
lab.tomlwith a wrong-typed value yields a single error naming the offending key and its dotted path (e.g. the key and where it sits), not a barevalid===false. (S17) - A missing required key yields a field-precise error naming the absent key + its path. (S17)
- An unknown / misspelled key is rejected with a field-precise error naming that key. (S17)
- The schema carries a
schema_versionand validation rejects an unsupported version with a version-specific error. (S14) - The extension's load-time validation accepts/rejects exactly the same
lab.tomlinputs as the CLI/CI validator over the shared negative-fixture corpus (no input is valid in one and invalid in the other). (S14) - A negative matrix (missing / wrong-type / unknown-key / bad-version) over the lab.toml fields each asserts the error points at the right field. (S17)
Key Decisions
- JSON Schema is the single source of truth; the lab.toml schema lives in the shared SchemaPackage and is consumed by extension + CLI + CI + the Julia round-trip (per 0.1a).
- The lab-partner promise is field-precise errors: the test asserts the error names the offending field, not merely that validation failed.
Constraints & Invariants
schema_versionis carried by the schema; an unknown newer version is a typed, recoverable rejection, never a silent pass.- This slice supersedes β.3's no-validation
lab.tomlhandling — both the rawlab.tomlpath and the interview-baked-constants path the template reads: once landed, a loadedlab.tomlis validated before it can reach a solve.
Prior Art / Patterns
- SchemaPackage — the shared JSON-Schema source of truth +
validate()surface consumed by extension, CLI, CI, and the Julia round-trip (0.1a scaffolds it; this slice adds thelab.tomlmember). - The β.3 solve-script template + AGENTS.md — already read lab params from a
lab.tomlpath or interview-baked constants; this schema formalizes the shape they assume. - The negative-matrix schema-validation pattern (per-field × per-constraint) asserting the error points at the offending field.
Testing
Extend the CI fast-tier schema-validation suite (table-driven lab.toml negative matrix asserting field-precise errors), alongside the extension fast tier for the load-time validator entry point. Semi-TDD: phrase each negative case as a failing assertion on the named offending field/path; the extension/CLI parity case is a failing assertion that both reach the same accept/reject verdict over the shared fixture corpus.
Source
Phase 0-prime plan task 0.1 (SchemaPackage, lab.toml slice; DoD: "a malformed lab.toml yields a field-precise error (S17)"). Realizes S17; S29/S30 provenance (lab.toml is the config a partner drops in and the source of injected hardware params). PRD §"Schema package" + §Interfaces (SchemaPackage); PRD testing-decisions ("We do not pin internals"). Decisions: schema home / shared-package (Q86), schema_version carrier (Q54/Q87), field-precise-error test bar (Q32). Out-of-scope rationale: Q110/Q111 (sanitization), Q134 (discovery/precedence), Q44 (injection correctness). Depends on 0.1a (SchemaPackage scaffold + shared validator). Supersedes β.3's unvalidated lab.toml handling (raw path + interview-baked constants; plan §2 β.3 + S30 note "β supports one lab via a single lab.toml path or interview-baked constants").
Notes
This is the lab.toml schema β explicitly deferred from its flat one-lab starter — β.3 proved a single hardcoded/raw config works; 0-prime makes any lab's config machine-checkable so additional labs compose without hand-edits. Catalog-entry SCHEMA shape is a sibling 0.1 slice; the catalog STORE/consumer is Phase 3. Correctly sliced as a bite-sized vertical slice (schema + validator + error path); do not merge with 0.1a or further decompose.
Activity
jack-champagne commentedon Jun 18, 2026
Depends on #15.
feat(extension): 0.1b — validate lab.toml on load with field-precise …
fix(extension): 0.1b review — corpus-wide parity + lab range/minLengt…
Merge pull request #29 from harmoniqs/rchari/0.1b-lab-validation