Skip to content

Commit e60a94c

Browse files
hyperpolymathclaude
andcommitted
docs: AFFIRMATION.adoc — ground-truthed honesty snapshot for SNIFs 2
Point-in-time, jointly-signed attestation per the estate AFFIRMATION standard (the README/EXPLAINME/AFFIRMATION trio). Every claim ground-truthed by running the tools this session against the committed anchor a82bb31 (its parent == the anchor SHA): proof-check-all exit 0 (10 gated artifacts), abi-conformance 15/15, mix test 30/30 (OTP 25). Honest gaps stated: Safer-not-Safe (SEC-1-TCB trusted), ABI-7 15/20, GAP-1b scalar-only. Dual-licensed MPL-2.0 OR CC-BY-SA-4.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent a82bb31 commit e60a94c

1 file changed

Lines changed: 300 additions & 0 deletions

File tree

AFFIRMATION.adoc

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
// SPDX-License-Identifier: MPL-2.0 OR CC-BY-SA-4.0
2+
// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
3+
// Author: Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
4+
= AFFIRMATION — SNIFs (Safer NIFs), as of 2026-06-16
5+
:toc: macro
6+
:toclevels: 2
7+
8+
_the No-Bullshit file: what we affirm was true and checkable at this moment_
9+
10+
[NOTE]
11+
====
12+
*Genre.* An *affirmation* is a solemn declaration of the truth of a statement,
13+
made by someone who _declines to swear an oath_. That is exactly what this is:
14+
our truth-as-best-believed at a stamped instant — binding on our honesty, not a
15+
claim of infallibility. It is not the README and not the EXPLAINME:
16+
17+
[cols="1,3,2",options="header"]
18+
|===
19+
| File | Answers | Tense
20+
| `README` | _Where is this going, and why?_ — what SNIF is, why care, quick start | future / aspirational
21+
| `EXPLAINME` | _How is it built, and what's the evidence?_ — claim-to-code mapping | descriptive / mechanism
22+
| *`AFFIRMATION`* (this file) | _What can we honestly affirm was *true and checkable* at a stamped moment?_ | a frozen instant, falsifiable
23+
|===
24+
25+
It is deliberately small, dated, and signed, so a reader can hold us to exactly
26+
what we affirmed, when we affirmed it.
27+
====
28+
29+
toc::[]
30+
31+
== What this is, and how it is designed to work
32+
33+
*What it is.* A short, dated, jointly-signed snapshot of what we can _honestly
34+
and verifiably_ claim about this repo at one exact moment. Nothing here is
35+
marketing and nothing is a promise about the future — both of those live in the
36+
README. This file is the receipt.
37+
38+
*How it is designed to work.* Three moving parts make it trustworthy:
39+
40+
. *Ground truth, not memory.* Every claim below was produced by _running the
41+
tool in the session that wrote this file_ — the proof checkers, the ABI
42+
conformance gate, and the in-BEAM test suite — on 2026-06-16. If a status doc
43+
or a memory said otherwise, the live run wins and we flag the contradiction.
44+
. *A frozen anchor.* The file names the exact commit SHA, branch, UTC timestamp,
45+
working-tree delta, and toolchain (see <<Verifiable anchor>>), so "true"
46+
always means "true _at this point_". Move the SHA and the file becomes a draft
47+
until re-run.
48+
. *A real signature.* It is landed by a *signed git commit*; that signature over
49+
this content at the anchored SHA is what makes the affirmation tamper-evident
50+
and attributable — not the prose alone.
51+
52+
*We are fallible.* We can be wrong, stale, or simply mistaken about our own
53+
work. This file is our best honest belief, not a proof of its own correctness.
54+
Treat it as a falsifiable claim, not gospel.
55+
56+
== The epistemic contract (read this before you trust _or_ attack)
57+
58+
This document records our *best joint belief* at the timestamp below. It is
59+
*not a guarantee of correctness.* We may be wrong. We may have missed something
60+
— a hole, a stale doc, or a proof that checks an idealised _model_ we then fail
61+
to match in the running _runtime_.
62+
63+
*No intentional overclaim.* That is the only guarantee here: we have not
64+
_knowingly_ inflated anything. Where something is tested-but-not-proved, we say
65+
so. Where a proof covers a model and trusts the real runtime, we say so. Where
66+
something is ledgered, weak, or merely-an-interface-check, we say so. An honest
67+
claim here that turns out false is an error to fix — not a lie.
68+
69+
*Standing invitation to refute.* You are _invited_ to bulldoze any claim in this
70+
file. The fair form of the attack is:
71+
72+
. Read this file at the stamped commit.
73+
. Reproduce (or fail to reproduce) the checks in <<reproduce,Reproduce it yourself>>.
74+
. _Then_ tell us where the discrepancy is, against the artefact as it stood at
75+
this moment — so we can either justify it or concede it on the record.
76+
77+
An attack that skips steps 1–2 is attacking a strawman of a different date.
78+
79+
*No fights before the facts are cleared up.* We are not interested in a dispute
80+
over a claim until the discrepancy has actually been checked against the
81+
artefact at this commit and we have had the chance to either justify it or
82+
concede it on the record. Good faith both ways: bring a reproducible
83+
discrepancy and we will fix the claim, the doc, or the code — promptly and
84+
without defensiveness. The goal is a corrected record, not a won argument.
85+
86+
== Verifiable anchor
87+
88+
[cols="1,3"]
89+
|===
90+
| *Repo* | `hyperpolymath/snifs` (Safer NIFs — native compute for the BEAM via a wasmtime sandbox)
91+
| *Branch* | `feat/snifs-2`
92+
| *Commit (HEAD / anchor)* | `a82bb311609a2580f37dbbc7c1b6687ee7a3c0b7` — the signed commit that lands the SNIFs 2 work. This AFFIRMATION is landed by that commit's signed *child*, so **parent == anchor SHA**.
93+
| *Permalink* | https://github.com/hyperpolymath/snifs/tree/a82bb311609a2580f37dbbc7c1b6687ee7a3c0b7
94+
| *Verified (UTC)* | 2026-06-16T12:22:08Z
95+
| *Toolchain* | Idris2 0.8.0 · Lean 4.13.0 · Agda 2.8.0 · Zig 0.15.2 · wasm-tools 1.249.0 · Elixir 1.18.4 / Erlang OTP 25 · wasmex 0.14.0 · Python 3.12.3 · just 1.50.0
96+
|===
97+
98+
[NOTE]
99+
====
100+
*State at this anchor.* Unlike an earlier draft of this file (which described an
101+
uncommitted working tree), the verification affirmed here **is committed** at the
102+
anchor SHA `a82bb31` — `SnifIsolation.agda`, `SnifVerdict.agda`, `BufferAbi.idr`,
103+
the guest-aware conformance tool, the metamorphic gate, the demo, the Rust guests
104+
and the reconciled docs are all in that commit (signed, `id_ed25519_signing`). The
105+
gate results below were re-run against that committed state at the verified UTC
106+
above. Build artifacts (`priv/*.wasm`, `*.agdai`, `zig/buffer_abi_build/`) are
107+
intentionally **not** committed — CI rebuilds them. This AFFIRMATION itself is
108+
landed by the signed child commit; if its parent SHA matches the anchor and the
109+
commit verifies, the affirmation is anchored. Move HEAD past it and re-run
110+
<<reproduce>> before trusting it.
111+
====
112+
113+
== Companion documents and repo metadata (cross-check)
114+
115+
This affirmation should be read against the repo's own public claims. Where they
116+
drift from what we verified, we say so here rather than leave the reader to find out.
117+
118+
* *`README.adoc`* — present. link:README.adoc[_"SNIFs: Safer Native Implemented
119+
Functions for the BEAM via WebAssembly Sandboxing"_]. Sells the vision + the
120+
scope ceiling; this file is its receipt for one moment.
121+
* *`EXPLAINME.adoc`* — present. Maps README claims to code paths and carries the
122+
corrected "SNIF realizes _a_ cleave instance, not _the_ cleave" framing. The
123+
estate trio (README / EXPLAINME / AFFIRMATION) is *complete* for this repo once
124+
this file lands.
125+
* *`PROOF-STATUS.md` / `PROOF-NEEDS.md`* — the living ledgers this snapshot cites,
126+
reconciled to the verified state in the anchor commit: `PROOF-STATUS.md` now counts
127+
10 gated artifacts, marks SEC-1 F1/F2 **RESOLVED** (keeping F3/F4/F5 as standing
128+
precision notes), and records ABI-7 at 15/20 + CI-1 done.
129+
* *GitHub repo description* — corrected this session to _"SNIFs: **Safer** Native
130+
Implemented Functions for the BEAM via WebAssembly Sandboxing"_ (it previously said
131+
"Safe"; the project renamed *"Safe NIFs" → "Safer NIFs"* — see `CHANGELOG` — because
132+
the end-to-end guarantee is _not_ unconditional, see <<nuance>>).
133+
* *GitHub topics* — `beam`, `elixir`, `erlang`, `fault-tolerance`, `nif`,
134+
`research`, `wasmtime`, `webassembly`, `crash-isolation`. *Under-claim:* there
135+
is no `formal-verification` topic, although the repo now carries 10
136+
machine-checked proof artifacts + a machine-checked operational isolation
137+
theorem. The tags undersell the verification rather than oversell it.
138+
139+
== The honest state (one breath)
140+
141+
*SNIFs is a working, machine-verified "safer NIF" for the BEAM: native
142+
compute/buffer functions compiled to WebAssembly and run in a wasmtime sandbox,
143+
so a guest fault becomes a catchable `{:error, _}` and the BEAM survives. The
144+
in-BEAM demo is green, the formal gate is green (including an operational
145+
crash-isolation theorem with deniability and a 6-origin error taxonomy wired in),
146+
and the interface + a slice of behaviour are gated against the real built wasm —
147+
yet it remains "Safer", not "Safe": one explicit runtime-faithfulness assumption
148+
is trusted, not yet machine-discharged, and several coverage items are honestly
149+
ledgered.*
150+
151+
=== What is solid (and how we checked)
152+
153+
* *The formal gate is green — verified this moment.* `just proof-check-all` →
154+
*exit 0*: **7 Idris2** modules (`Types`, `ABI/{Layout,Platform,Pointers,Foreign,Compliance,BufferAbi}`),
155+
**1 Lean4** (`ApiTypes`), **2 Agda** (`SnifVerdict`, `SnifIsolation`, both
156+
`agda --safe --without-K`), plus the dangerous-pattern scan (no
157+
`believe_me`/`postulate`/`sorry`/`Admitted`).
158+
* *SEC-1 — the operational crash-isolation theorem — typechecks.*
159+
`verification/proofs/agda/SnifIsolation.agda` proves, by induction over a
160+
fuelled host↔guest small-step model: verdict ∈ ok ⊕ trap, host survives every
161+
outcome, the trap carries no guest value, and — newly wired into the
162+
operational run — the fault residue is the _redacted_ secret only, so two
163+
faults with equal redaction are host-indistinguishable (`run-deniable`). The
164+
verdict now models the real *6-origin* taxonomy (guest-fault / host-budget /
165+
pre-exec) via a `call` front-end, not a binary trap. It is proven *modulo* an
166+
explicit `FaithfulRuntime` record hypothesis (the TCB) — see <<nuance>>.
167+
* *Interface conformance is gated against the real binaries.*
168+
`just abi-conformance` → *exit 0*: **15 ABI specs** across **2 guests**
169+
(`safe_nif` 8, `buffer_abi` 7) — the built wasm's real export signatures match
170+
the verified Idris2 model exactly, including three void-returning buffer
171+
exports.
172+
* *In-BEAM behaviour runs.* `mix test` (in `demo/`) → *30 tests, 0 failures* on
173+
Erlang/OTP 25, Elixir 1.18.4, with the precompiled `wasmex` 0.14 NIF. This
174+
includes crash isolation across every failure mode (OOB / unreachable / @panic
175+
/ overflow / div-zero → `{:error,_}`, BEAM alive after each) and a new
176+
dependency-free *metamorphic behaviour gate* over the numeric kernels.
177+
178+
[#nuance]
179+
=== The honest nuance you must not lose
180+
181+
. *"Safer", not "Safe" — the runtime TCB is trusted, not proven.* SEC-1 is proven
182+
over a model whose first argument is a `FaithfulRuntime` record bundling
183+
primitive single-step facts (wasmtime never gets stuck; a trapped step is caught
184+
and surfaced as `{:error,_}` with the scheduler preserved). The prose claim that
185+
this record is _faithful to wasmtime/wasmex_ — "wasmtime ⊨ FaithfulRuntime" — is
186+
**assumed, not discharged in a prover** (it is the named open item SEC-1-TCB, a
187+
WasmCert-Coq effort). This residual assumption is exactly _why_ the project is
188+
Safer NIFs.
189+
. *Model ↔ code faithfulness is only partly mechanised.* The proofs verify a
190+
logical model. The ABI conformance gate closes the *interface* slice of
191+
model↔code (signatures match the real wasm); the metamorphic tests close a
192+
*behaviour* slice (the kernels behave as modelled). The general claim "the Agda
193+
model mirrors the Zig/Rust/wasmex code" is argued + tested, not itself
194+
machine-verified.
195+
. *Honest proof labels (not over-claims).* In SEC-1, `okOrTrap` and `noForgery`
196+
are *structural* facts about the `Verdict` datatype (true with no runtime in
197+
scope); the load-bearing, TCB-consuming content is host *preservation*
198+
(`survives`). `noForgery` is the parametric non-existence of a total extractor,
199+
not an instance-level claim. We state these rather than dress them up.
200+
201+
=== Known-incomplete but honestly fenced (loud failure, never silent miscompile)
202+
203+
* The isolation thesis depends on building guests with `-OReleaseSafe`. Under
204+
`-OReleaseFast` the same faults become *silent wrong answers* — this is
205+
demonstrated, on purpose, as the negative control in the demo suite (e.g. an OOB
206+
read returns a plausible adjacent value). The shipped guests are ReleaseSafe;
207+
the ReleaseFast artifact exists only to keep that danger visible and tested.
208+
209+
=== Outstanding / weak / refuted (no spin)
210+
211+
* *SEC-1-TCB — open.* Discharging "wasmtime ⊨ FaithfulRuntime" in-prover
212+
(WASM trap-soundness; trap → `{:error,_}`; scheduler resumed) is the remaining
213+
half of an end-to-end isolation proof. Not started here.
214+
* *ABI-7 — partial.* 15 of ~20 Zig export sites are modelled+gated (`safe_nif` +
215+
`buffer_abi`). `burble_fft` (`fft`/`ifft`/…) is *not* built into any artifact and
216+
uses `(ptr,len)` slice marshalling = the deeper *ABI-6* obligation; it and the
217+
two Rust guests are *ledgered, not gated* (`PROOF-NEEDS.md`).
218+
* *GAP-1b — partial.* The metamorphic behaviour gate covers the *scalar* kernels
219+
(`fibonacci` recurrence/monotonicity/i64-width; `checked_add` as a wrapping i32
220+
ring); the *buffer* kernels (`sum_f32` permutation-invariance, scale-then-sum)
221+
are the next increment.
222+
* *Finding surfaced by the new gate:* the export named `checked_add` is a
223+
**misnomer** — it is two's-complement *wrapping* addition (`a +% b`, intentional
224+
per `zig/src/safe_nif.zig`), *not* a trapping/checked add (the trapping demo is
225+
the separate `crash_overflow`). The gate characterises the real behaviour;
226+
whether to rename the export is the owner's call.
227+
* *CI.* The ABI conformance gate now runs as a CI job (`proofs.yml`), but making it
228+
a *required* status check is an owner-only branch-protection action — not done.
229+
* *Adversarial mutation re-audit — completed, verdict SOLID.* Four independent
230+
skeptics mutation-tested the SEC-1 sharpening (`--safe --without-K`): every targeted
231+
mutation was rejected as expected, so F1 (lossy redaction), F2 (the pre-exec
232+
coverage + the `guestFault` tag) and F5 (the partial `Alive`) are genuinely
233+
load-bearing — not vacuous; `--safe` is enforced (an injected `postulate` is
234+
rejected) and `run`/`drive` totality is real (a non-decreasing-fuel mutation is
235+
rejected). The only weakness it found was *stale prose*, corrected in the anchor commit.
236+
* *Required-check + Zenodo.* Making the conformance gate a **required** status check is
237+
owner-only branch-protection (pending). The paper's Zenodo DOI still carries the old
238+
"Safe" title; the rename should land on the next deposit.
239+
240+
[#reproduce]
241+
== Reproduce it yourself
242+
243+
From the repo root, at the anchor commit above (you need the toolchain in
244+
<<Verifiable anchor>>):
245+
246+
[source,sh]
247+
----
248+
just proof-check-all # expect exit 0:
249+
# 7 Idris2 OK, 1 Lean4 OK, 2 Agda OK (SnifVerdict + SnifIsolation),
250+
# dangerous-pattern scan PASS
251+
just abi-conformance # expect exit 0: builds safe_nif + buffer_abi wasm, then
252+
# "all 2 guest(s) conform (15 ABI specs verified ...)"
253+
cd demo && mix test # expect "30 tests, 0 failures" (OTP 25 / Elixir 1.18.4)
254+
----
255+
256+
For the SEC-1 proof on its own (the exact gate invocation):
257+
258+
[source,sh]
259+
----
260+
agda -i verification/proofs/agda --safe --without-K --no-libraries \
261+
verification/proofs/agda/SnifIsolation.agda # expect exit 0
262+
----
263+
264+
== One-line characterisation (quote this)
265+
266+
[quote]
267+
____
268+
"A working, machine-verified *Safer* NIF for the BEAM: native compute sandboxed
269+
in wasmtime so a guest fault becomes `{:error,_}` and the VM survives — with an
270+
operational crash-isolation theorem (deniability + 6-origin taxonomy, Agda
271+
`--safe`), an interface gate matching 15 export signatures to the real wasm, and
272+
a behaviour gate over the scalar kernels — all green this moment; *Safer not Safe*
273+
because one runtime-faithfulness assumption is trusted, not yet proven, and
274+
`burble_fft`/Rust/buffer-behaviour coverage is honestly ledgered. No intentional
275+
overclaim."
276+
____
277+
278+
== Joint attestation
279+
280+
We, the undersigned, assert that *to the best of our joint belief at the
281+
timestamp above, every claim in this file is true and was checked as described*
282+
— with no intentional overclaim, and with the open gaps stated rather than hidden.
283+
284+
* *Engineering party (AI):* Claude Opus 4.8 (`claude-opus-4-8[1m]`) — ran the
285+
proof gate, the ABI conformance gate, and the in-BEAM test suite recorded here
286+
on 2026-06-16T12:22:08Z (against the committed anchor state) and stands behind the
287+
wording above as a faithful report of those runs.
288+
* *Owner / maintainer:* Jonathan D.A. Jewell — _signs by committing this file with
289+
`-S` (`id_ed25519_signing`); the git commit signature over this content, whose
290+
parent is the anchor SHA recorded above, is the cryptographic form of this
291+
affirmation._
292+
+
293+
Signed-off-date: 2026-06-16
294+
295+
[TIP]
296+
The authoritative, tamper-evident signature is the *signed git commit* that lands
297+
this file; its **parent is the anchor SHA** `a82bb31`. If that parent matches
298+
<<Verifiable anchor>> and the commit verifies (`id_ed25519_signing`), this
299+
affirmation is anchored. If HEAD later moves past it, re-run <<reproduce>> and write
300+
a fresh affirmation rather than trusting a stale one.

0 commit comments

Comments
 (0)