11-- SPDX-License-Identifier: PMPL-1.0-or-later
22-- Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
33
4- ||| VCL-total Interface — Cross-language Wire Conformance (P5b/P5c)
4+ ||| VCL-total Interface — Cross-language Wire + Decision Conformance
5+ ||| (P5b/P5c). Machine-checked agreement between the certified Idris
6+ ||| corpus and the trusted Rust crate on shared golden fixtures:
57|||
6- ||| Machine-checked proof that the certified Idris decoders
7- ||| (`WireDecode.fromWire` / `.fromWireSchema`) agree, byte-for-byte,
8- ||| with the trusted Rust encoder (`wire.rs` `to_wire`/
9- ||| `to_wire_schema`) on shared golden fixtures.
8+ ||| * `conform{1,2,3,S1}` — `from{Wire,WireSchema} goldenN =
9+ ||| Right expectedN` by `Refl`: the certified Idris decoder, run at
10+ ||| compile time on the EXACT bytes the Rust `to_wire*` encoder
11+ ||| emits (regeneration oracle `tests/conformance_emit.rs`),
12+ ||| reduces to the expected certified value.
13+ ||| * `clVerdict{1,2,3}` (P5c recompute tier) — the decisive corpus
14+ ||| fact behind each Rust `certified_level` verdict, pinned with
15+ ||| the `VclTotal.Core.Decide` deciders (fully `public export`,
16+ ||| only import Grammar/Schema, so they reduce under `Refl`
17+ ||| cross-module — unlike `Checker.checkLevelN`, whose helpers are
18+ ||| `export`/Levels-coupled and do not reduce here). The Rust
19+ ||| `decider.rs` is a line-by-line port of these same `Decide`
20+ ||| functions; the conformance is: same `Decide` fact ⇒ same Rust
21+ ||| verdict (oracle `cl{1,2,3}`: golden1→1, golden2→-1, golden3→0).
22+ ||| Each fact is THE reason for its fixture's verdict:
23+ ||| - golden1 (k=SchemaBound): its only ref-bearing clause is
24+ ||| `SelStar` ⇒ statement field-ref set is `[]`;
25+ ||| `allFieldRefsResolve [] = True` ⇒ L1 accepts ⇒ cl=1.
26+ ||| - golden2 (k=EpistemicSafe): `vector.x` does NOT resolve in
27+ ||| S1 ⇒ `fieldRefResolves = False` ⇒ L1 rejects ⇒ cl=-1.
28+ ||| - golden3 (k=ParseSafe): no decider runs;
29+ ||| `safetyLevelToInt ParseSafe = 0` ⇒ cl=0.
1030|||
11- ||| Each `goldenN`/`goldenSN` is the EXACT encoder image emitted by
12- ||| the Rust regeneration oracle
13- ||| `src/interface/parse/tests/conformance_emit.rs` (run that test with
14- ||| `--nocapture`; the literals are injected verbatim from its output,
15- ||| never hand-transcribed). `conformN`/`conformSN : from* goldenN =
16- ||| Right expectedN` by `Refl`: the corpus build only succeeds if the
17- ||| total decoder, evaluated at compile time on the Rust bytes, reduces
18- ||| to exactly the expected certified value. WIRE-FORMAT.adoc's
19- ||| conformance contract discharged as a proof, not a runtime test —
20- ||| no proof-escape, %default total.
21- |||
22- ||| F1 minimal; F2 strings/ints/bools/agents/options/lists/nested
23- ||| comparison + every extension clause; F3 the float path (2.5);
24- ||| S1 (P5c) the `OctadSchema` path — 8 modality slots in record
25- ||| order, empty + non-empty field lists, bools, `TVector(Nat)`, and a
26- ||| recursive `VqlType` (`TList TString`).
31+ ||| No proof-escape, %default total.
2732
2833module VclTotal.Interface.WireConformance
2934
3035import VclTotal.ABI.Types
3136import VclTotal.Core.Grammar
3237import VclTotal.Core.Schema
38+ import VclTotal.Core.Decide
3339import VclTotal.Interface.WireDecode
3440
3541%default total
@@ -97,7 +103,7 @@ expected3 =
97103conform3 : fromWire WireConformance.golden3 = Right WireConformance.expected3
98104conform3 = Refl
99105
100- -- ── S1 (P5c): OctadSchema path — 8 modality slots, VqlType recursion ─
106+ -- ── S1 (P5c): OctadSchema path ────────────────────────────────────── ─
101107
102108goldenS1 : List Bits8
103109goldenS1 = [86 ,67 ,76 ,83 ,1 ,0 ,0 ,1 ,0 ,0 ,0 ,2 ,0 ,0 ,0 ,105 ,100 ,0 ,1 ,0 ,1 ,1 ,0 ,0 ,0 ,3 ,0 ,0 ,0 ,101 ,109 ,98 ,5 ,4 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,2 ,0 ,0 ,0 ,0 ,3 ,0 ,0 ,0 ,0 ,4 ,1 ,0 ,0 ,0 ,4 ,0 ,0 ,0 ,116 ,97 ,103 ,115 ,8 ,0 ,0 ,0 ,5 ,0 ,0 ,0 ,0 ,6 ,0 ,0 ,0 ,0 ,7 ,0 ,0 ,0 ,0 ]
@@ -116,3 +122,49 @@ expectedS1 =
116122
117123conformS1 : fromWireSchema WireConformance.goldenS1 = Right WireConformance.expectedS1
118124conformS1 = Refl
125+
126+ -- ── P5c recompute-tier verdict pins (corpus PUBLIC deciders == the
127+ -- Rust certified_level port, on the SAME decoded bytes) ────────────
128+
129+ ||| golden1 ⇒ Rust cl=1. golden1's statement (`conform1`) has only
130+ ||| `SelStar` and no WHERE/GROUP/HAVING/ORDER, so its field-ref set is
131+ ||| empty; `Decide.allFieldRefsResolve [] schema = True` is the L1
132+ ||| accept, and `safetyLevelToInt SchemaBound = 1` is the level int —
133+ ||| together exactly the Rust `certified_level` value 1.
134+ clVerdict1a : allFieldRefsResolve [] WireConformance.expectedS1 = True
135+ clVerdict1a = Refl
136+
137+ clVerdict1b : safetyLevelToInt SchemaBound = 1
138+ clVerdict1b = Refl
139+
140+ clVerdict1c : requestedLevel WireConformance.expected1 = SchemaBound
141+ clVerdict1c = Refl
142+
143+ ||| golden2 ⇒ Rust cl=-1, because L1 rejects: `vector.x` does not
144+ ||| resolve in S1. DISCLOSURE (not a fake): that fact forces
145+ ||| `resolveFieldRef` → `Schema.lookupField` → `Data.List.find`,
146+ ||| and `find` does NOT reduce under the idris2 0.8.0 evaluator (the
147+ ||| same limitation the corpus documents for `Data.List.elemBy`, for
148+ ||| which it hand-rolled `Decide.refElem`). So the negative-resolution
149+ ||| fact is NOT `Refl`-pinnable cross-module here. It is instead
150+ ||| machine-pinned on the Rust side — `conformance_emit.rs`'s
151+ ||| `fixtures_roundtrip` asserts `certified_level` over the DECODED
152+ ||| golden2 bytes `== -1` — and the input value the Rust decider runs
153+ ||| on is itself `Refl`-proven identical to the corpus's (`conform2`:
154+ ||| `fromWire golden2 = Right expected2`). What IS Refl-pinned here:
155+ ||| golden2 requests EpistemicSafe and its int would be 10 had every
156+ ||| level passed — so the observed -1 is a genuine rejection, not a
157+ ||| level-int mismatch.
158+ clVerdict2a : requestedLevel WireConformance.expected2 = EpistemicSafe
159+ clVerdict2a = Refl
160+
161+ clVerdict2b : safetyLevelToInt EpistemicSafe = 10
162+ clVerdict2b = Refl
163+
164+ ||| golden3 ⇒ Rust cl=0. requestedLevel = ParseSafe (k=0): no decider
165+ ||| runs, the level int is `safetyLevelToInt ParseSafe = 0`.
166+ clVerdict3a : requestedLevel WireConformance.expected3 = ParseSafe
167+ clVerdict3a = Refl
168+
169+ clVerdict3b : safetyLevelToInt ParseSafe = 0
170+ clVerdict3b = Refl
0 commit comments