Plugin UI contracts 0.4.0 — validation report
Evidence record for the L5 §E.1 input trio bump (gateway issue #463; design .claude/deep-review/2026-10-16-classref-l5-plugin-ui-0-4-0-design.md, committed on the branch before any build, whose §9 carries the pre-committed acceptance rules and whose §5 sanctions this corpus motion in writing). The 0.3.1 increment’s evidence record remains in standards/plugin-ui/0.3.1/validation-report.md, digest-frozen with its tree.
What moved
plugin-ui 0.3.1 → 0.4.0, MINOR (the D4 amendment’s one sanctioned wall payment), and plugin-ui-class-reference 0.1.0 → 0.2.0 in the same train. Copy, never move: 4 new corpus rows citing standards/plugin-ui/0.3.1/* as source and 3 new rows citing standards/plugin-ui-class-reference/0.1.0/*, digests moved only by benchweave.standards repin (7 rows re-pinned, zero rewrites among the 275 frozen predecessor rows — the command’s own frozen-row gate ran over them); the predecessor trees are untouched.
The schema delta is re-stamp only, verified by sorted-key JSON diff: the four 0.4.0 schemas differ from their 0.3.1 sources in $id, title, contract_version consts and the cross-schema $ref URLs — 12 diff lines in ui-manifest.schema.json, all carrying version strings; zero other delta. The family’s layout.schema.json carries the one widening: control.kind ["button","numeric","rotary"] → ["button","numeric","rotary","text","select","boolean"] (11 diff lines, all version strings or the three new kinds); class-logic_analyser.json re-stamps with exactly one line changed.
Version sweep
- All THREE version-literal sites in the corpus-owned code row moved 0.3.1 → 0.4.0 (the path-shaped
SCHEMA_ROOTliteral and the two barecontract_versionconsts); the zero-literal register row’sexpected_sitesstays 3, its reason text records the motion. - The family’s authored provenance literals moved in the same arc:
classref.FOUNDING_FAMILY_VERSIONand the classref panel’scorpus_pin(the panel render path derives the served version and refuses the composition on mismatch, so a stale pin breaks the panel — the readiness audit’s H2). Register value tuples moved (“0.1.0” → “0.2.0”, one site each), reason texts record the motion.
RED-first evidence (junitxml counts, this worktree)
- The ZERO gate as the register arc’s RED. With the classref.py and panels.py literals moved but the register rows unedited:
gateway: 0 outside register (5 sites, 111 files scanned, FAILED)—register value pin failed: ... classref.py expects ['0.1.0'], found ['0.2.0']and the identical panels.py row, exit 1. Register rows edited (values + motion notes):gateway: 0 outside register (5 sites, 111 files scanned, ok), exit 0. - The widening’s schema RED. A
select-kind control node validated against the frozen 0.1.0 layout schema:valid=False(refused); the same node against the 0.2.0 schema:valid=True. The suite’s trio arms (test_control_kinds_widen_to_the_input_trio, parametrized 3/3) pin it. - The validator-const RED. With
contracts.pymoved and the unit fixtures still stamped 0.3.1:tests/unit/test_presentation_{manifest,presets,profiles,specimens, digital_lanes}+tests/contract/test_sim_scope_plugin: tests=142 failures=78 (every failure a 0.3.1-stamped document refusedunsupported_versionby the moved const). After the fixture sweep (and the sim_scope document re-stamp with its digest chain re-derived): tests=142 failures=0. - The corpus-pin-guard RED (H2). The corpus moved with
panels.corpus_pinstill “0.1.0”: the classref panel suite reds on the pin guard (served 0.2.0 ≠ pin 0.1.0 refuses the composition). The literal move in the same arc greens it. - The parity-fixtures RED (B8). With the corpus at 0.2.0/0.4.0 and the committed SDK fixtures still carrying the 0.3.1/0.1.0 stamps:
test_f1_f2_triples_byte_equal_committed_sdk_fixturesred. The 9 fixtures regenerated (see provenance below): tests=68 failures=0 overtests/presentation/+tests/interfaces_ui/test_ui_presentation.py+tests/ui_html/test_classref_page.py.
Parity-fixture provenance
The 9 committed parity fixtures regenerated from the SDK v0.14.0 derivation (the submodule pin at this branch’s base, 201c343 — read, never modified) against the NEW corpus: a scratch copy of the v0.14.0 package with the 0.4.0 + 0.2.0 directories vendored and the lock’s active markers moved (0.4.0/0.2.0 active; 0.3.1/0.1.0 retained). derive_ui resolved actives from that lock: plugin-ui 0.4.0, family 0.2.0. The derivation code is v0.14.0’s UNMODIFIED — the expander/ladder widening (the F2 ruling’s select-node emission) is the SDK leg’s work and emits nothing for these fixtures (their fields are all numeric/button kinds). Fixture diffs verified stamp-only: 15 inserted / 15 deleted lines across the 9 files — version strings plus the three envelopes’ manifest sha256 pins (derived, not content). B8 byte-parity (gateway derivation ≡ committed fixtures) green after regeneration.
In-arc sweep (the #444 bump’s own file-set convention)
The design record’s §4 census names the corpus and the presentation surfaces; the landed sweep additionally covers the surfaces the #444 bump commit (fc6a0d63) swept, per the obligations doc’s in-arc rule: the five validator unit suites’ fixtures (0.4.0 stamps + the active-dir globs), tests/contract/test_sim_scope_plugin.py and the five shipped sim_scope presentation documents (byte-faithful re-stamp; preset bytes → manifest asset pins → presentation manifest pin, the #444 chain), tests/standards/test_{export,scenarios,dependency,dependency_policy, dev_pins,zero_literal_gate}.py (carried-set/served-set/resolution constants), the matrix denominator test (23 → 25 retained version rows: plugin-ui 6 dirs, classref 2), the ui_presentation classref arms (active paths + layout const + rendered pin), the derive/page suites’ corpus paths, and the ui-html module docstring’s corpus pointer.
Gates
benchweave.standards repin: exactly 7 rows re-pinned, 0 rewritten among frozen predecessors (row-level diff: +35 lines, all new rows).- Version-literal ZERO gate: gateway/plugins/docs/scripts scopes green with the register rows moved (5 sites, count unchanged); the sdk scope rides the pointer leg.
benchweave.standards checkand thetests/standards/test_checkmirror/anchor lanes are red on this branch BY THE LANDING SPLIT (the 0.3.1 validation-report’s own disclosure, issue #408’s rule): they compare a fresh export against the SDK submodule’s lock and vendored tree, and the pointer does not move until the landing train’s same-commit advance. The red family: 2×served_set_drift(the new actives absent from the v0.14.0 lock), 2×sdk_version_mismatch, 1×policy_mirror_drift, 4×stale_generated+ 7×missing_asset(the vendored tree lags), 2×_GENERATED.txt— 19 failures, one mechanical root, all cleared by the SDK sync + pointer commit.matrix --check: re-rendereddocs/compatibility-matrix.mdfrom the committed manifest in the same arc (CON-12 committed-state purity); clean at this report’s commit.scripts/ci/win_core_manifest.py --check: refreshed with the architecture suite’s total (74 → 81; the trio + retained-freeze arms).