|
1 | | -== PROOF-NEEDS.md — panll |
| 1 | +// SPDX-License-Identifier: CC-BY-SA-4.0 |
| 2 | += Proof needs — PanLL |
| 3 | +:toc: macro |
2 | 4 |
|
3 | | -=== Current State |
| 5 | +What PanLL proves today, what it deliberately does not, and what is still |
| 6 | +owed. Escape hatches and their dispositions are tracked separately in |
| 7 | +link:docs/proof-debt.adoc[`docs/proof-debt.adoc`]. |
4 | 8 |
|
5 | | -* *src/abi/*: YES — contains `+cartridge-schema.json+` and `+README.md+` |
6 | | -(no Idris2 files) |
7 | | -* *Dangerous patterns*: 0 in own code (164 references are all in UI |
8 | | -display code that shows believe_me/Admitted counts from OTHER repos) |
9 | | -* *LOC*: ~138,000 (ReScript + Rust) |
10 | | -* *ABI layer*: Schema-only, no Idris2 proofs |
| 9 | +Last reconciled against the tree: 2026-10-26 (`main` at `1937c6b`). |
11 | 10 |
|
12 | | -=== What Needs Proving |
| 11 | +toc::[] |
13 | 12 |
|
14 | | -[width="100%",cols="51%,27%,22%",options="header",] |
| 13 | +== Current state |
| 14 | + |
| 15 | +The only machine-checked proofs live in the panel-clades ABI, |
| 16 | +`panel-clades/src/abi/PanelClades/ABI/` (Idris2 0.8.0, `%default total`, |
| 17 | +about 1,300 lines). There are no holes, `believe_me`, `assert_total`, |
| 18 | +`assert_smaller`, `idris_crash` or `postulate` in any `.idr` file. |
| 19 | + |
| 20 | +The CI job `panel-clades-abi` in `.github/workflows/build-validation.yml` |
| 21 | +runs `panel-clades/scripts/check-abi.sh`, which: |
| 22 | + |
| 23 | +* builds typed-wasm's grade kernel at the pin in |
| 24 | + `panel-clades/scripts/fetch-siblings.sh` (`117bbf8`); |
| 25 | +* builds `panel-clades/src/abi/panel-clades-grades.ipkg` against it and |
| 26 | + fails on any `Error:` line, even when `idris2` exits 0; |
| 27 | +* fails if any module under `PanelClades/` is missing from the ipkg, or |
| 28 | + uses an escape hatch; |
| 29 | +* fails if `Budgets.idr` is stale against the clade configs |
| 30 | + (`scripts/gen-budgets.sh --check`); |
| 31 | +* requires each of the six fixtures in `panel-clades/tests/reject/` to be |
| 32 | + refused at its `invalid` declaration, with the expected message. |
| 33 | + |
| 34 | +=== What is proved |
| 35 | + |
| 36 | +[cols="1,3",options="header"] |
| 37 | +|=== |
| 38 | +|Module |Proved |
| 39 | + |
| 40 | +|`Types.idr` |
| 41 | +|The C tag encodings of `Result` and `CladeKind` round-trip, so they are |
| 42 | +injective (`resultRoundTrip`, `cladeKindRoundTrip`). Equality on both is |
| 43 | +decidable without a catch-all `absurd` (`decEqViaTag`). `allCladeKinds` |
| 44 | +lists every kind (`cladeKindExhaustive`) and has length `cladeKindCount`. |
| 45 | +A `Handle` is never null and a `CladeId` is never empty, by construction. |
| 46 | + |
| 47 | +|`Layout.idr` |
| 48 | +|Rounding up to an alignment lands on a multiple of it (`alignUpCorrect`). |
| 49 | +Every computed struct size is a multiple of its alignment |
| 50 | +(`calcStructSizeAligned`). Field alignment is decided by an equation on |
| 51 | +`Nat` (`decDivides`, `proveFieldsAligned`), not by a Boolean test. |
| 52 | + |
| 53 | +|`Grades.idr` |
| 54 | +|Clade resource contracts are graded in typed-wasm's kernel (transcribed |
| 55 | +from hyperpolymath/resource-algebra), not re-declared. Occupancy composes |
| 56 | +within a bound (`phasesWithin`). Loss adds across two crossings |
| 57 | +(`crossTwice`), and the better of two alternatives stays within a shared |
| 58 | +bound (`betterOfTwo`). Occupancy and cost are kept apart |
| 59 | +(`panelPhasesOccupancy` vs `panelPhasesCost`). The neurosym-bridge |
| 60 | +contract typechecks against its declared budget |
| 61 | +(`neurosymBridgeContract`). |
| 62 | + |
| 63 | +|`Budgets.idr` |
| 64 | +|Generated from the clades' `config.k9.ncl` resource blocks. It proves |
| 65 | +nothing itself; it is the input `Grades.idr` checks against. Only |
| 66 | +neurosym-bridge declares a budget so far. |
| 67 | + |
| 68 | +|`Foreign.idr` |
| 69 | +|Typechecks only. It declares the Zig FFI surface; it proves nothing. |
15 | 70 | |=== |
16 | | -|Component |What |Why |
17 | | -|Cartridge schema validation |Cartridge loading validates against schema |
18 | | -correctly |Malformed cartridges crash panels or produce wrong output |
19 | 71 |
|
20 | | -|PCC constraint propagator |Constraint propagation is sound and complete |
21 | | -|PanLL Constraint Checker is the build-time safety net |
| 72 | +The reject fixtures pin down what the types refuse: `BudgetTooSmall`, |
| 73 | +`CollapseWithinTolerance`, `MisalignedField`, `NullHandle`, `OverBudget` |
| 74 | +and `WasmPointerIsEightBytes`. |
| 75 | + |
| 76 | +=== What is not proved |
| 77 | + |
| 78 | +These limits are stated in the modules themselves. |
| 79 | + |
| 80 | +* *Struct size covers the last field.* `Layout.idr` does not prove that a |
| 81 | + computed size is at least the end of the last field; `verifyLayout` |
| 82 | + checks it at run time and refuses a layout that fails. |
| 83 | +* *The Zig side matches.* Nothing checks that `panel-clades/ffi/zig/` |
| 84 | + exports the symbols `Foreign.idr` declares, with those types, or uses |
| 85 | + the sizes and tags `Types.idr` proves. `ffi/zig/src/main.zig` restates |
| 86 | + them by hand. |
| 87 | +* *Grades reach the runtime.* The budgets are DESIGNED values from the |
| 88 | + configs, not measurements, and nothing in the panel runtime emits or |
| 89 | + checks these grades yet. |
| 90 | + |
| 91 | +== What needs proving |
| 92 | + |
| 93 | +[cols="2,3,2,1",options="header"] |
| 94 | +|=== |
| 95 | +|Item |What |Status |Tracked |
| 96 | + |
| 97 | +|Struct size lower bound |
| 98 | +|Prove `calcStructSize` is at least the end of the last field, and drop |
| 99 | +the run-time check in `verifyLayout`. |
| 100 | +|Not started. Induction over the field list plus a lemma about rounding |
| 101 | +up. |
| 102 | +|— |
| 103 | + |
| 104 | +|Safe callback registration |
| 105 | +|A safe wrapper for `prim__registerCallback` in `Foreign.idr`, using |
| 106 | +Idris2's FFI callback mechanism (`cast` is banned). |
| 107 | +|Not started. |
| 108 | +|#149 |
| 109 | + |
| 110 | +|Zig/Idris FFI agreement |
| 111 | +|Check that the Zig exports match `Foreign.idr` and the proven sizes and |
| 112 | +tags. This is a CI check, not a proof. |
| 113 | +|Not started. |
| 114 | +|— |
| 115 | + |
| 116 | +|Grade kernel identity |
| 117 | +|Confirm typed-wasm's transcription matches resource-algebra's Agda |
| 118 | +`MaxPlus` kernel, which is now the family instance. |
| 119 | +|Open question; PanLL already imports the kernel through typed-wasm. |
| 120 | +|#143 |
| 121 | + |
| 122 | +|More clade budgets |
| 123 | +|As clade configs declare resource blocks, `gen-budgets.sh` emits them |
| 124 | +and their contracts need to typecheck. |
| 125 | +|One clade so far (neurosym-bridge). |
| 126 | +|— |
| 127 | + |
| 128 | +|IPC dispatch is total |
| 129 | +|Every command the frontend invokes has a registered handler. |
| 130 | +|Partly covered by tests: `src-gossamer/src/ipc.rs` checks every table |
| 131 | +entry and that the table and `main.rs` never register the same name |
| 132 | +twice. Completing it needs the frontend's `invoke` names, which wait on |
| 133 | +the AffineScript port. |
| 134 | +|#148 |
22 | 135 |
|
23 | | -|PCC ReScript scanner |Scanner correctly identifies all constraint |
24 | | -violations |Missed violations bypass safety checks |
| 136 | +|PCC soundness |
| 137 | +|The PanLL Constraint Checker (`tools/pcc`) propagates constraints soundly |
| 138 | +and finds every violation. |
| 139 | +|Blocked: `tools/pcc` still scans ReScript `.res` sources, which #107 |
| 140 | +removed. It must be rebuilt for AffineScript before a proof means |
| 141 | +anything, and it needs a written specification first. |
| 142 | +|#148 |
25 | 143 |
|
26 | | -|Verification Dashboard accuracy |Dashboard accurately reflects actual |
27 | | -proof state |Displaying wrong verification state gives false confidence |
| 144 | +|Verification Dashboard accuracy |
| 145 | +|The dashboard reports the real proof state of the repos it inspects. |
| 146 | +|Better served by fixture tests than by proof. Waits on the frontend |
| 147 | +port. |
| 148 | +|#148 |
28 | 149 |
|
29 | | -|Provenance engine |Provenance tracking is complete and unforgeable |
30 | | -|Provenance gaps break audit trail |
| 150 | +|Provenance engine |
| 151 | +|Provenance tracking is complete (every action is recorded). "Unforgeable" |
| 152 | +is a cryptographic claim and needs a threat model first. |
| 153 | +|Not started; needs a specification. |
| 154 | +|— |
31 | 155 |
|
32 | | -|Gossamer coprocessor commands |Command dispatch is total (no unhandled |
33 | | -commands) |Unhandled commands silently fail |
| 156 | +|Cartridge schema validation |
| 157 | +|Loading a cartridge validates it against `src/abi/cartridge-schema.json`. |
| 158 | +|Schema only; no validator to prove against yet. |
| 159 | +|— |
34 | 160 |
|
35 | | -|Wiring Inspector |Wiring analysis correctly identifies all connections |
36 | | -|Missing wires mean broken panel communication |
| 161 | +|Wiring Inspector |
| 162 | +|Wiring analysis finds every panel connection. |
| 163 | +|Waits on the frontend port. |
| 164 | +|#148 |
37 | 165 | |=== |
38 | 166 |
|
39 | | -=== Recommended Prover |
| 167 | +== Recommended prover |
40 | 168 |
|
41 | | -*Idris2* — Replace schema-only ABI with proper Idris2 types. PCC |
42 | | -constraint propagation is a natural fit for formal verification. The |
43 | | -Rust PCC tool (`+tools/pcc/+`) should have soundness proofs. |
| 169 | +*Idris2 0.8.0* for anything at the ABI or grade level, matching the |
| 170 | +existing modules and the typed-wasm kernel they import. Rust-side |
| 171 | +properties (IPC dispatch, PCC) are better served first by tests with a |
| 172 | +stated budget; a mechanised proof only pays once each has a written |
| 173 | +specification. |
44 | 174 |
|
45 | | -=== Priority |
| 175 | +== Priority |
46 | 176 |
|
47 | | -*MEDIUM* — PanLL is the developer panel system. PCC soundness is the |
48 | | -highest-value proof (it checks constraints across the ecosystem). The |
49 | | -Verification Dashboard must accurately reflect proof state to avoid |
50 | | -false confidence. |
| 177 | +. Struct size lower bound and the safe callback wrapper (#149): small, |
| 178 | + local, and they close the two gaps the modules admit to. |
| 179 | +. Zig/Idris FFI agreement check: cheap, and it removes the largest |
| 180 | + unchecked assumption under the proofs. |
| 181 | +. PCC soundness: the highest-value proof, but only after the AffineScript |
| 182 | + port (#148) gives it something to check. |
0 commit comments