Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/proof-safety.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,55 @@ jobs:
ECHIDNA_BIN: ${{ github.workspace }}/_echidna/target/debug/echidna
run: |
bash tests/e2e.sh
agda:
name: Agda proofs (PROOF-POLICY §2.1 canonical invocation)
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- name: Install pinned, digest-checked Agda and standard library
run: |
set -euo pipefail
tc="$RUNNER_TEMP/agda"
mkdir -p "$tc"
curl --proto '=https' --proto-redir '=https' --fail --location --retry 3 -o "$tc/agda.tar.xz" \
https://github.com/agda/agda/releases/download/v2.7.0.1/Agda-v2.7.0.1-linux.tar.xz
echo "975b515a14877ab6bce5bfc641e16c4a3ee52ca5d7f846577dee80aa2145db8a $tc/agda.tar.xz" | sha256sum --check
curl --proto '=https' --proto-redir '=https' --fail --location --retry 3 -o "$tc/stdlib.tar.gz" \
https://github.com/agda/agda-stdlib/archive/refs/tags/v2.1.tar.gz
echo "72ca3ea25094efa0439e106f0d949330414232ec4cc5c3c3316e7e70dd06d431 $tc/stdlib.tar.gz" | sha256sum --check
tar --no-same-owner -xJf "$tc/agda.tar.xz" -C "$tc"
tar --no-same-owner -xzf "$tc/stdlib.tar.gz" -C "$tc"
printf '%s\n' "$tc/agda-stdlib-2.1/standard-library.agda-lib" \
"$GITHUB_WORKSPACE/verification/proofs/agda/burrow.agda-lib" > "$tc/libraries"
{
echo "Agda_datadir=$tc/Agda-v2.7.0.1/data"
echo "AGDA_LIBRARIES_FILE=$tc/libraries"
echo "LC_ALL=C.UTF-8"
} >> "$GITHUB_ENV"
echo "$tc/Agda-v2.7.0.1/bin" >> "$GITHUB_PATH"
- name: Type-check DOM-1 and DOM-2 and print the receipt
working-directory: verification/proofs/agda
run: |
set -euo pipefail
agda --version
echo "commit: $GITHUB_SHA"
echo "flags: --safe --without-K --cubical-compatible"
echo "stdlib: agda-stdlib v2.1, archive sha256 72ca3ea25094efa0439e106f0d949330414232ec4cc5c3c3316e7e70dd06d431"
echo "first-party sources:"
sha256sum Burrow/Trust.agda Burrow/Ledger.agda burrow.agda-lib
stdlib="$RUNNER_TEMP/agda/agda-stdlib-2.1"
find . "$stdlib" -name '*.agdai' -delete
for m in Burrow/Trust.agda Burrow/Ledger.agda; do
agda --no-default-libraries --library-file "$AGDA_LIBRARIES_FILE" \
--safe --without-K --cubical-compatible "$m"
done
# The transitive import cone is exactly the set of interfaces this
# check wrote. --safe is coinfective, so every module in it was
# itself checked under --safe: no postulate, no unsafe pragma.
echo "import cone (standard-library modules, sources pinned by the archive digest):"
find "$stdlib" -name '*.agdai' | sed "s|.*/agda/||; s|^src/||; s|\.agdai$||; s|/|.|g" | LC_ALL=C sort
echo "import cone (first-party modules):"
find . -name '*.agdai' | sed "s|.*/agda/||; s|^src/||; s|\.agdai$||; s|/|.|g" | LC_ALL=C sort
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,10 @@ dist/
/exports/*.lgt
composer/*.beam
composer/build/

# Coq/Rocq build artefacts (written by `just proof-check-coq`)
*.vo
*.vok
*.vos
*.glob
.*.aux
22 changes: 15 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,34 @@ file, not this summary.

| Obligation | Verifier |
|------------|----------|
| First-party Rust (`burrower-core`, `-cli`, `-wasm`) | Creusot |
| First-party Rust (`burrower-core`, `-cli`, `-wasm`) | Creusot with Pearlite contracts, and Verus (PROOF-POLICY §1.2) |
| APIs, ABIs, wire formats, engineering properties | Idris2 |
| Theory (anything true of any implementation) | Agda, rechecked in Rocq and Lean |

- Canonical Agda invocation, in recipes and CI alike:
`agda --safe --without-K --cubical-compatible <module.agda>`.
`--cubical-compatible` is not full `--cubical`. Pin and record the Agda
version and standard library with each source commit and proof result.
- Grade ladder (Mathesis §5): Grade 3 = type-checks locally in Agda,
untranslated; 2i = one independent system; 2ii = two, the second
non-DTT (e.g. Isabelle/HOL); 1 = machine-checked via a verified checker
API in headless CI. Never flatten this into a confidence percentage.
- Proof Witness Grades (PROOF-POLICY §8, normative; always write the `PWG-`
prefix): `PWG-3` = the Agda source is checked under the §2.1 invocation
with a receipt (Agda version, stdlib pin, flags, import cone);
`PWG-2i` = plus one counted Rocq or Lean recheck (kernel-accepted and
§2.2 `RECONCILED`); `PWG-2ii` = plus both; `PWG-1` = every counted
witness has a current per-commit receipt from a headless, pinned run.
Engineering proofs (Creusot, Verus, SPARK, Idris2) carry no PWG (§8.1).
Grades are derived from receipts, never asserted, and never flattened
into a percentage.
- Missing tools, incompatible dependencies or failed theorems are open
obligations. Do not skip proofs or weaken flags to make a check green.
- Escape hatches follow `docs/TRUSTED-BASE-REDUCTION-POLICY.adoc` and are
recorded in `docs/proof-debt.adoc`.
- An ECHIDNA result is *evidence about someone else's proof*. Burrower
records the grade it was told and never asserts one it derived.

Status for this repo: 0 of 7 obligations proven; no first-party Agda
theorem yet, so nothing here is at Grade 3. See
Status for this repo: 2 of 14 tracked obligations proven (DOM-1, DOM-2,
first-party Agda). Both are `ungraded` until the `agda` job in
`.github/workflows/proof-safety.yml` has produced a receipt for the current
`main` commit; `PWG-3` follows from that receipt, not from this sentence, and
lapses if a later run on `main` fails or cannot be reproduced. See
`docs/status/PROOF-STATUS.adoc` and
`docs/reports/audit/2026-11-01-echidna-topology-audit.adoc`.
31 changes: 21 additions & 10 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -1342,17 +1342,28 @@ help-me:
# ═══════════════════════════════════════════════════════════════════════════════

# Check all formal proofs (Idris2 + Lean4 + Agda + Coq)
proof-check-all: proof-check-idris2 proof-check-lean4 proof-check-agda proof-check-coq proof-scan-dangerous
@echo "=== All proof checks complete ==="
# Runs every checker even when an earlier one fails, then fails if any did.
proof-check-all:
#!/usr/bin/env bash
set -uo pipefail
failed=()
for r in proof-check-idris2 proof-check-lean4 proof-check-agda proof-check-coq proof-scan-dangerous; do
just "$r" || failed+=("$r")
done
if [ ${#failed[@]} -gt 0 ]; then
echo "=== Proof checks FAILED or NOT RUN: ${failed[*]} ===" >&2
exit 1
fi
echo "=== All proof checks complete ==="

# Check Idris2 proofs (ABI, types, dependent type proofs)
proof-check-idris2:
#!/usr/bin/env bash
set -euo pipefail
echo "=== Checking Idris2 proofs ==="
if ! command -v idris2 &>/dev/null; then
echo "SKIP: idris2 not installed"
exit 0
echo "NOT RUN: idris2 not installed — a missing prover is an open obligation, not a pass (PROOF-POLICY §2.1)" >&2
exit 1
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
fi
ERRORS=0
for f in $(find verification/proofs/idris2 -name '*.idr' 2>/dev/null); do
Expand All @@ -1376,8 +1387,8 @@ proof-check-lean4:
set -euo pipefail
echo "=== Checking Lean4 proofs ==="
if ! command -v lean &>/dev/null; then
echo "SKIP: lean not installed"
exit 0
echo "NOT RUN: lean not installed — a missing prover is an open obligation, not a pass (PROOF-POLICY §2.1)" >&2
exit 1
fi
ERRORS=0
for f in $(find verification/proofs/lean4 -name '*.lean' 2>/dev/null); do
Expand All @@ -1401,8 +1412,8 @@ proof-check-agda:
set -euo pipefail
echo "=== Checking Agda proofs ==="
if ! command -v agda &>/dev/null; then
echo "SKIP: agda not installed"
exit 0
echo "NOT RUN: agda not installed — a missing prover is an open obligation, not a pass (PROOF-POLICY §2.1)" >&2
exit 1
fi
# Estate canonical invocation (standards 3-practice/PROOF-POLICY.adoc
# §2.1). `--cubical-compatible` implies `--without-K`; both are named
Expand Down Expand Up @@ -1441,8 +1452,8 @@ proof-check-coq:
set -euo pipefail
echo "=== Checking Coq proofs ==="
if ! command -v coqc &>/dev/null; then
echo "SKIP: coqc not installed"
exit 0
echo "NOT RUN: coqc not installed — a missing prover is an open obligation, not a pass (PROOF-POLICY §2.1)" >&2
exit 1
fi
ERRORS=0
for f in $(find verification/proofs/coq -name '*.v' 2>/dev/null); do
Expand Down
23 changes: 17 additions & 6 deletions docs/proof-debt.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ reading of the situation.
== (a) Discharged in this repo

- `verification/proofs/agda/Burrow/Trust.agda` — the receipt/warrant
semantics (DOM-1). Grade 3: type-checks under
semantics (DOM-1). Mathesis Grade 3 on a historical local run: type-checks under
`agda --safe --without-K --cubical-compatible`, 0 warnings, also clean
under full `--cubical`. Agda 2.7.0.1, agda-stdlib 2.4, 2026-11-01.
under full `--cubical`. Agda 2.7.0.1, agda-stdlib 2.4, 2026-11-01. Under
PROOF-POLICY §8 it is `ungraded` until the CI `agda` job (stdlib 2.1)
records a receipt for the current commit.
- `verification/proofs/agda/Burrow/Ledger.agda` — the ledger read path and
`no-launder` (DOM-2). Same toolchain, same flags, same date.

Expand All @@ -44,7 +46,9 @@ would be exactly the unfalsifiable "covered by tests" the policy rejects.

- (none)

No first-party proof exists, so no first-party axiom exists.
The first-party proofs (DOM-1 `Burrow/Trust.agda`, DOM-2
`Burrow/Ledger.agda`) check under `--safe`, which rejects `postulate`, so
no first-party axiom exists.

== 1. Debt

Expand Down Expand Up @@ -142,12 +146,19 @@ already retired for `TODO` markers — "grepping prose … measures the prose,
not the proofs" — and it should be reported upstream rather than triaged
here.

The absence of markers is not a clean bill of health. It reflects an empty
proof set: there is nothing to have escaped from.
The absence of markers is not a clean bill of health. The only proofs are
DOM-1 and DOM-2 in §(a). Their CI check runs under `--safe`, which rejects
`postulate` and the unsafe pragmas and options (`TERMINATING`,
`NON_TERMINATING`, `--type-in-type` and the like) in the whole import cone.
That check and the marker scan are different things: the scan is textual and
covers other languages' markers (`sorry`, `Admitted`, `believe_me`), which
`--safe` neither knows nor replaces. Neither says anything about the twelve
obligations that have no proof at all.

== 3. What a Grade 3 result would look like here

Mathesis §5: "A proof is Grade 3 if it type-checks locally in Agda but has
This section uses the Mathesis grade, not the Proof Witness Grade of
PROOF-POLICY §8 (`PWG-3`), which needs a CI receipt as well. Mathesis §5: "A proof is Grade 3 if it type-checks locally in Agda but has
not been translated to an independent foundational system." For this
repository the shortest honest path is one theorem about Burrower's own
contract handling, checked with:
Expand Down
23 changes: 16 additions & 7 deletions docs/status/PROOF-STATUS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@

*Overall*: 2 of 14 tracked obligations proven.

Estate grade (`hyperpolymath/mathesis` §5): the two Domain proofs are
*Grade 3* — constructed in Agda and type-checked locally, not yet
translated to an independent foundational system. Nothing else in this
repository has a grade.
Proof Witness Grade (`PROOF-POLICY` §8, normative): the two Domain proofs
are `ungraded` until a receipt exists. A grade is derived from a receipt
that records the Agda version, the standard-library pin, the flags in
force and the import cone; the 2026-11-01 local run recorded the first
three but no source commit or digests. The `agda` job in
Comment thread
hyperpolymath marked this conversation as resolved.
Resolved
`.github/workflows/proof-safety.yml` (Agda 2.7.0.1 and agda-stdlib 2.1,
both digest-pinned; canonical §2.1 flags; prints the commit and the
SHA-256 of each first-party source) produces that receipt. The first green
run on `main` makes them `PWG-3`, for as long as the receipt is current:
a later failing or unreproducible run on `main` withdraws the grade. No Rocq or Lean recheck exists, so
nothing can be higher. Nothing else in this repository is a theory
theorem, so nothing else carries a PWG.

=== Proofs Done

Expand All @@ -34,8 +42,9 @@ repository has a grade.
|Agda 2.7.0.1
|`verification/proofs/agda/Burrow/Trust.agda`
|2026-11-01
|`just proof-check-agda`, `agda --safe --without-K --cubical-compatible`,
0 warnings; also clean under full `--cubical`
|Historical local run only (no commit or digests recorded):
`agda --safe --without-K --cubical-compatible`, 0 warnings; also clean
under full `--cubical`. Current verification is the CI receipt.

|DOM-2
|Ledger read path: no function from a stored record to the fact exists
Expand Down Expand Up @@ -122,7 +131,7 @@ panic-attack assail --proofs-only
|===
|Date |Change |By
|2026-04-04 |Initial proof status tracking |Template
|2026-11-01 |DOM-1 and DOM-2 proved in Agda (Grade 3); DOM-3..7 added;
|2026-11-01 |DOM-1 and DOM-2 proved in Agda (receipt pending; see above); DOM-3..7 added;
`just proof-check-agda` moved to the estate canonical flags with an
include path |Audit 2026-11-01
|===
5 changes: 5 additions & 0 deletions verification/proofs/agda/burrow.agda-lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- SPDX-License-Identifier: MPL-2.0
-- Agda library for proof-burrower's first-party proofs (DOM-1, DOM-2).
name: burrow
depend: standard-library
include: .
Loading