Skip to content

Commit 8a36afb

Browse files
Merge pull request #31 from hyperpolymath/reinforce/vclut-25-phase5c2-aff-decoder
vcl-ut #25 P5c (steps 2-4): faithful Rust recompute-decider + cross-language decision conformance
2 parents c977fca + 4ae5126 commit 8a36afb

4 files changed

Lines changed: 621 additions & 22 deletions

File tree

src/interface/WireConformance.idr

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,41 @@
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

2833
module VclTotal.Interface.WireConformance
2934

3035
import VclTotal.ABI.Types
3136
import VclTotal.Core.Grammar
3237
import VclTotal.Core.Schema
38+
import VclTotal.Core.Decide
3339
import VclTotal.Interface.WireDecode
3440

3541
%default total
@@ -97,7 +103,7 @@ expected3 =
97103
conform3 : fromWire WireConformance.golden3 = Right WireConformance.expected3
98104
conform3 = Refl
99105

100-
-- ── S1 (P5c): OctadSchema path — 8 modality slots, VqlType recursion
106+
-- ── S1 (P5c): OctadSchema path ──────────────────────────────────────
101107

102108
goldenS1 : List Bits8
103109
goldenS1 = [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

117123
conformS1 : fromWireSchema WireConformance.goldenS1 = Right WireConformance.expectedS1
118124
conformS1 = 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

Comments
 (0)