|
| 1 | +//// |
| 2 | + PARKED DRAFT — no SPDX/owner header yet. |
| 3 | + The strict pre-commit hook requires: |
| 4 | + SPDX-License-Identifier: MPL-2.0 |
| 5 | + SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> |
| 6 | + Owner adds that header MANUALLY (no automated licence edits), then commits |
| 7 | + SIGNED (-S id_ed25519_signing). Do NOT --no-verify. Until then this file |
| 8 | + lives in the working tree only. |
| 9 | +//// |
| 10 | += AFFIRMATION — AffineScript, as of 2026-06-16 |
| 11 | +:toc: macro |
| 12 | +:toclevels: 2 |
| 13 | +
|
| 14 | +_the No-Bullshit file: what we affirm was true and checkable at this moment_ |
| 15 | +
|
| 16 | +[NOTE] |
| 17 | +==== |
| 18 | +*Genre.* An *affirmation* is a solemn declaration of the truth of a statement, |
| 19 | +made by someone who _declines to swear an oath_. That is exactly what this is: |
| 20 | +our truth-as-best-believed at a stamped instant — binding on our honesty, not a |
| 21 | +claim of infallibility. It is not the README and not the EXPLAINME: |
| 22 | +
|
| 23 | +[cols="1,3,2",options="header"] |
| 24 | +|=== |
| 25 | +| File | Answers | Tense |
| 26 | +| `README` | _Where is this going, and why?_ — state of thinking, steering, intent | future / aspirational |
| 27 | +| `EXPLAINME` | _How is it built, and what's the evidence?_ — engineering underpinnings | descriptive / mechanism |
| 28 | +| *`AFFIRMATION`* (this file) | _What can we honestly affirm was *true and checkable* at a stamped moment?_ | a frozen instant, falsifiable |
| 29 | +|=== |
| 30 | +
|
| 31 | +Every repo in the estate may carry one (`AFFIRMATION.adoc`). It is deliberately |
| 32 | +small, dated, and signed, so a reader can hold us to exactly what we affirmed, |
| 33 | +when we affirmed it. |
| 34 | +==== |
| 35 | +
|
| 36 | +toc::[] |
| 37 | +
|
| 38 | +== What this is, and how it is designed to work |
| 39 | +
|
| 40 | +*What it is.* A short, dated, jointly-signed snapshot of what we can _honestly |
| 41 | +and verifiably_ claim about this repo at one exact commit. Nothing here is |
| 42 | +marketing and nothing is a promise about the future — both of those live in the |
| 43 | +README. This file is the receipt. |
| 44 | +
|
| 45 | +*How it is designed to work.* Three moving parts make it trustworthy: |
| 46 | +
|
| 47 | +. *Ground truth, not memory.* Every claim below was produced by _running the |
| 48 | + tool in the session that wrote this file_ (build, tests, proof checkers). If a |
| 49 | + status doc or a memory said otherwise, the live run wins and we flag the |
| 50 | + contradiction. |
| 51 | +. *A frozen anchor.* The file names the exact commit SHA, branch, UTC timestamp, |
| 52 | + and toolchain (see <<Verifiable anchor>>), so "true" always means "true _at |
| 53 | + this point_". Move the SHA and the file becomes a draft until re-run. |
| 54 | +. *A real signature.* It is landed by a *signed git commit*; that signature over |
| 55 | + this content at the anchored SHA is what makes the affirmation tamper-evident |
| 56 | + and attributable — not the prose alone. |
| 57 | +
|
| 58 | +*We are fallible.* We can be wrong, stale, or simply mistaken about our own |
| 59 | +work. This file is our best honest belief, not a proof of its own correctness. |
| 60 | +Treat it as a falsifiable claim, not gospel. |
| 61 | +
|
| 62 | +== The epistemic contract (read this before you trust _or_ attack) |
| 63 | +
|
| 64 | +This document records our *best joint belief* at the timestamp below. It is |
| 65 | +*not a guarantee of correctness.* We may be wrong. We may be deluded. We may |
| 66 | +have missed something — a hole, a stale doc, a proof that checks a calculus we |
| 67 | +then fail to match in the implementation. |
| 68 | +
|
| 69 | +*No intentional overclaim.* That is the only guarantee here: we have not |
| 70 | +_knowingly_ inflated anything. Where something is tested-but-not-proved, we say |
| 71 | +so. Where a proof covers an idealised core and _not_ the production code, we say |
| 72 | +so. Where something is refuted or vacuous, we say so. If you find an honest |
| 73 | +claim here that turns out false, that is an error to be fixed — not a lie. |
| 74 | +
|
| 75 | +*Standing invitation to refute.* You are _invited_ to bulldoze any claim in this |
| 76 | +file. We want that. But the fair form of the attack is: |
| 77 | +
|
| 78 | +. Read this file at the stamped commit. |
| 79 | +. Reproduce (or fail to reproduce) the checks in <<reproduce,Reproduce it yourself>>. |
| 80 | +. _Then_ tell us where the discrepancy is, against the artefact as it stood at |
| 81 | + this moment — so we can either justify it or concede it on the record. |
| 82 | +
|
| 83 | +An attack that skips steps 1–2 is attacking a strawman of a different date. |
| 84 | +
|
| 85 | +*No fights before the facts are cleared up.* We are not interested in a dispute |
| 86 | +over a claim until the discrepancy has actually been checked against the |
| 87 | +artefact at this commit and we have had the chance to either justify it or |
| 88 | +concede it on the record. Good faith both ways: bring a reproducible |
| 89 | +discrepancy and we will fix the claim, the doc, or the code — promptly and |
| 90 | +without defensiveness. The goal is a corrected record, not a won argument. |
| 91 | +
|
| 92 | +== Verifiable anchor |
| 93 | +
|
| 94 | +[cols="1,3"] |
| 95 | +|=== |
| 96 | +| *Repo* | `hyperpolymath/affinescript` (the OCaml compiler — *not* ephapax) |
| 97 | +| *Branch* | `feat/solo-core-metatheory-proofs` |
| 98 | +| *Commit (HEAD)* | `4ed413f4ded5d83813f303854f4b28823847a7b1` |
| 99 | +| *Permalink* | https://github.com/hyperpolymath/affinescript/tree/4ed413f4ded5d83813f303854f4b28823847a7b1 |
| 100 | +| *Verified (UTC)* | 2026-06-16T12:17:10Z |
| 101 | +| *Working-tree delta at verification* | `docs/PROOF-NEEDS.md` modified; untracked `issues-drafts/08-conditional-origin-borrow-escape.md`, `stdlib/SafeHex.affine`, this file. None affect the build/test/proof results below; the green results are HEAD + this delta. |
| 102 | +| *Toolchain* | OCaml 4.14.2 · dune 3.22.2 · Idris2 0.8.0 · Lean 4.13.0 |
| 103 | +|=== |
| 104 | +
|
| 105 | +[IMPORTANT] |
| 106 | +If you are reading this at a _later_ commit, the claims may have drifted. |
| 107 | +Re-run <<reproduce>> and write a fresh affirmation; do not trust a stale one. |
| 108 | +
|
| 109 | +== Companion documents and repo metadata (cross-check) |
| 110 | +
|
| 111 | +This affirmation should be read against the repo's own public claims. Where they |
| 112 | +drift from what we verified, we say so here rather than quietly leave the reader |
| 113 | +to find out. |
| 114 | +
|
| 115 | +* *`README.adoc`* — link:README.adoc[_"AffineScript: A Practical Language for |
| 116 | + Resource-Safe Systems"_]. The README sells the vision; this file is its |
| 117 | + receipt for one moment. (A legacy `README.md` also exists; `README.adoc` is |
| 118 | + canonical per the estate DOC-FORMAT rule.) |
| 119 | +* *`EXPLAINME.adoc`* — *currently absent.* The estate trio |
| 120 | + (README / EXPLAINME / AFFIRMATION) is therefore incomplete for this repo: |
| 121 | + there is no dedicated "prove every README claim with code paths" document yet. |
| 122 | + Noted as a gap, not glossed. |
| 123 | +* *GitHub repo description* — _"The effect row is the abstraction; the backend |
| 124 | + picks the mechanism. An affine-typed language compiling to verifiable typed |
| 125 | + WebAssembly and Deno."_ Honest caveat: "_verifiable_ typed WebAssembly" is |
| 126 | + aspirational at the typed-wasm boundary today — the `own` → ownership mapping |
| 127 | + is known-wrong (no `Affine` kind upstream, mis-mapped to Linear), so the |
| 128 | + emitted ownership section is not yet faithful. |
| 129 | +* *GitHub topics* — `affine-types`, `algebraic-effects`, `borrow-checker`, |
| 130 | + `compiler`, `effect-system`, `formal-verification`, `linear-types`, `ocaml`, |
| 131 | + `programming-language`. Cross-check: `formal-verification` is now _earned_ |
| 132 | + (Idris2 Solo-core progress+preservation + Lean tropical, green — see below); |
| 133 | + `linear-types` is loose — the language is *affine* (≤1 use), not strictly |
| 134 | + linear (exactly-once), and the `own` kind is affine. |
| 135 | +
|
| 136 | +== The honest state (one breath) |
| 137 | +
|
| 138 | +*AffineScript is a working research compiler for an affine / quantitative-typed |
| 139 | +language that compiles to WebAssembly — real, runnable, and now backed by a |
| 140 | +small but genuinely machine-checked metatheory core — yet still pre-1.0, with |
| 141 | +the implementation _not_ proved to match that core, and with effects, async, and |
| 142 | +refinements still partial or unenforced.* |
| 143 | +
|
| 144 | +=== What is solid (and how we checked) |
| 145 | +
|
| 146 | +* *Front-to-back pipeline runs.* parse → typecheck → borrow-check → elaborate → |
| 147 | + codegen → wasm, plus a tree-walking interpreter. `just build` exits 0; |
| 148 | + `just test` (`dune runtest`) exits 0 — *483 tests*; 114+ `.affine` fixtures |
| 149 | + under `test/`. |
| 150 | +* *There IS mechanised metatheory — verified green this moment.* |
| 151 | + `just proof-check-all` → *4 passed, 0 failed, 1 skipped*: |
| 152 | +** *Idris2 — Solo-core QTT metatheory: progress + preservation, fully proved, |
| 153 | + `%default total`, no holes, no `believe_me`/`assert_total`/postulates.* The |
| 154 | + crux is the QTT substitution lemma (`SubstLemma.substLemma0`); the affine |
| 155 | + SPLIT product rule means preservation lands in a `Weaker` sub-context. |
| 156 | + (`docs/academic/formal-verification/solo-core/`.) |
| 157 | +** *Lean 4 — tropical session types proof: passes, no dangerous tactics.* |
| 158 | +** Agda echo-boundary certificates: *SKIPPED* — environment only (needs |
| 159 | + `AFFINESCRIPT_ECHO_TYPES_DIR`); not a failure, but not evidence either. |
| 160 | +* *Canonical borrow hole #554 is closed and tested* (return-borrow summary + |
| 161 | + call-graph fixpoint), including transitive + hardening variants. |
| 162 | +* *The conditional-origin borrow-escape hole is closed and tested* (commit |
| 163 | + `4ed413f`): a use-after-move via a borrow bound through an `if`/`match`/block |
| 164 | + value is now caught. 14 unsound forms reject; 7 safe forms (NLL |
| 165 | + use-before-move, unrelated move) pass; 6 hardening fixtures |
| 166 | + (`test/e2e/fixtures/borrow_cond_origin_*`). |
| 167 | +* *Float-through-heap is durably fixed for all heap aggregates* (arrays, tuples |
| 168 | + uniform/mixed, closed records), wasmtime round-trip verified. |
| 169 | +* *Compile-time complexity is back to linear* (the O(n²) codegen residuals are |
| 170 | + gone, bench-evidenced). |
| 171 | +
|
| 172 | +=== The honest nuance you must not lose |
| 173 | +
|
| 174 | +The Idris2 proof establishes soundness of an *idealised Solo core calculus*. It |
| 175 | +does *not* prove that the OCaml implementation (`lib/borrow.ml`, |
| 176 | +`lib/codegen.ml`, …) _refines_ that calculus. "Proved core" + "tested |
| 177 | +implementation" is exactly that — two things, with an unverified bridge between |
| 178 | +them. Anyone claiming "AffineScript is proven sound" full-stop is overclaiming. |
| 179 | +
|
| 180 | +=== Known-incomplete but honestly fenced (loud failure, never silent miscompile) |
| 181 | +
|
| 182 | +* f64 in closures (calling-convention gap), float array compound-assign, and |
| 183 | + open/polymorphic record rows — these *refuse to compile*, they do not produce |
| 184 | + wrong code. |
| 185 | +
|
| 186 | +=== Outstanding / weak / refuted (no spin) |
| 187 | +
|
| 188 | +* *No silent soundness hole is currently known.* The conditional-origin |
| 189 | + borrow escape found by adversarial probing this session was *fixed and tested* |
| 190 | + (see Solid, above; commit `4ed413f`). This is an absence-of-evidence claim, |
| 191 | + not evidence-of-absence: more probing may surface others — exactly what the |
| 192 | + epistemic contract invites. |
| 193 | +* *Effect-handler lowering (#555) and async CPS (#556): Refuted* — backends |
| 194 | + silently drop handler arms / lower async synchronously. |
| 195 | +* *Refinement types: vacuous* (parse but unenforced). *Trait coherence: |
| 196 | + unchecked.* *typed-wasm `own` mapping: known-wrong* (no `Affine` kind upstream |
| 197 | + → mis-mapped to Linear). |
| 198 | +* *`docs/PROOF-NEEDS.md` and `.claude/CLAUDE.md` are themselves partly stale* at |
| 199 | + this commit: both still say there are no mechanised proofs, which the proof |
| 200 | + run above *refutes*. Correcting those is owner-gated (SPDX header) and pending. |
| 201 | +
|
| 202 | +[#reproduce] |
| 203 | +== Reproduce it yourself |
| 204 | +
|
| 205 | +From the repo root, at the commit above: |
| 206 | +
|
| 207 | +[source,sh] |
| 208 | +---- |
| 209 | +just build # expect exit 0 |
| 210 | +just test # expect exit 0 (dune runtest) |
| 211 | +just proof-check-all # expect: 4 passed, 0 failed, 1 skipped |
| 212 | +---- |
| 213 | +
|
| 214 | +For the proofs individually: |
| 215 | +
|
| 216 | +[source,sh] |
| 217 | +---- |
| 218 | +just proof-check-idris2 # Solo-core progress + preservation (no holes) |
| 219 | +just proof-check-lean # tropical session types |
| 220 | +# Agda is skipped unless AFFINESCRIPT_ECHO_TYPES_DIR points at echo-types/proofs/agda |
| 221 | +---- |
| 222 | +
|
| 223 | +To see the open hole bite (it is _currently accepted_ — that's the bug): see the |
| 224 | +reproducer table in `issues-drafts/08-conditional-origin-borrow-escape.md`. |
| 225 | +
|
| 226 | +== One-line characterisation (quote this) |
| 227 | +
|
| 228 | +[quote] |
| 229 | +____ |
| 230 | +"A real, runnable affine-typed → WASM research compiler with a *machine-checked |
| 231 | +Solo core* (Idris2 progress+preservation, no holes) and a tested — _not yet |
| 232 | +proved-to-match_ — implementation; conservative loud-failures at the edges; one |
| 233 | +known open borrow hole on the fix queue; effects/async/refinements still |
| 234 | +partial. Serious research artifact, not a production language. No intentional |
| 235 | +overclaim." |
| 236 | +____ |
| 237 | +
|
| 238 | +== Joint attestation |
| 239 | +
|
| 240 | +We, the undersigned, assert that *to the best of our joint belief at the |
| 241 | +timestamp above, every claim in this file is true and was checked as described* |
| 242 | +— with no intentional overclaim, and with the open gaps stated rather than |
| 243 | +hidden. |
| 244 | +
|
| 245 | +* *Engineering party (AI):* Claude Opus 4.8 (`claude-opus-4-8[1m]`) — ran the |
| 246 | + build, test, and proof checks recorded here on 2026-06-16T11:41:06Z and stands |
| 247 | + behind the wording above as a faithful report of those runs. |
| 248 | +* *Owner / maintainer:* Jonathan D.A. Jewell — _signs by committing this file |
| 249 | + with `-S` (`id_ed25519_signing`); the git commit signature over this content, |
| 250 | + at the commit SHA recorded above, is the cryptographic form of this |
| 251 | + affirmation._ |
| 252 | ++ |
| 253 | +Signed-off-date: ____________________ (fill on signing) |
| 254 | +
|
| 255 | +[TIP] |
| 256 | +The authoritative, tamper-evident signature is the *signed git commit* that |
| 257 | +lands this file. If the SHA in <<Verifiable anchor>> matches the parent of that |
| 258 | +commit and the commit verifies, this affirmation is anchored. If they don't |
| 259 | +match, treat the file as a draft. |
0 commit comments