Part of the learning paths for issue #79. This page explains how the implementation is actually layered, what the proof layer proves (and what it deliberately does not), and how to add a language feature end-to-end.
Every .obl program flows through one OCaml pipeline. Read the files in this
order once and the whole compiler stops being mysterious:
| Stage | File | What to notice |
|---|---|---|
Lexing |
|
Token stream; rejects |
Parsing |
|
menhir grammar; builds |
Types |
|
i64/bool/string/structs, plus the |
Evaluation |
|
The audit trace is produced here — every operation appends. |
Constrained-form validation |
|
The gate that makes the four guarantees checkable: bounded loops, acyclic call graph, affinity/linearity for non-copyable echoes. |
Static analysis |
|
Resource and reversibility analysis; call analysis and struct-size accounting are partial (see the honest table in |
Supporting cast |
|
Debugger/profiler are scaffold/partial — their README status rows say exactly what is real and what is placeholder. |
Entry points: bin/main.ml (the oblibeny CLI — --check, --dump-trace)
and bin/oblibeny_lsp.ml (the LSP server; diagnostics/hover/completion live in
the lib/lsp_*.ml modules).
Idris2 proofs about the package ABI: installReversible preserves
reversibility, installation is idempotent (doubleInstallIdempotent), and the
echo residue is non-trivial (echoResidueNonTrivial). History matters here:
PR #51 found these were non-compiling stubs with a believe_me-masked theorem
that was false as written. They are now genuine total proofs, and CI
type-checks them (just proofs) and greps for escape hatches on every push.
A faithful Idris2 model of lib/ast.ml / lib/eval.ml /
lib/constrained_check.ml, with the constrained form’s four guarantees proved
over that model, %default total, zero escape hatches:
| Module | Proves | Mechanism |
|---|---|---|
|
The evaluator is total (termination) |
Call-free slice, then rank-stratified |
|
Checker soundness |
A |
|
|
|
|
Static resource budget = accountability-trace length |
Both sides total; ties the resource story to the audit story. |
The model-fidelity caveat, stated plainly: these theorems are about the model. The model was written to be faithful and CI keeps the escape hatches out, but "the Idris2 model of the checker is sound" and "the OCaml checker is sound" are different claims. Closing that gap (translation validation / verified extraction) is the open endpoint of issue #78. When you write or read claims, keep the two layers separate.
Follow-on slices are enumerated in
#78: checker
completeness (existence of a ranking from acceptance), general semantic
reversibility over a DecEq-keyed store, and a trace-producing evaluator
faithful to staticTrace.
ffi/zig/ carries the post-quantum crypto seam:
-
ffi/zig/build.zig— Zig 0.13 build (0.14 renamedcallconv(.C); do not "modernise" past 0.13 without a migration plan —.tool-versionspins it). -
ffi/zig/src/crypto.zig— liboqs (Dilithium5, SPHINCS+) + libsodium (Ed25519) bindings. -
ffi/zig/src/obli-pkg.zig— the.zpkgsigner/verifier; canonical payload = package bytes minusSIGNATURE:envelope; keyring handling is fail-closed. -
CI runs
zig ast-checkover every FFI source (maintainers.adoc has the gate inventory); full linking needs system liboqs and is handled by the CI liboqs job, not assumed locally.
-
Define the AST node in
lib/ast.ml(and its echo/affinity properties if any). -
Lex it (
lib/lexer.ml), parse it (lib/parser.mly). -
Type it (
lib/typecheck.ml) — decide how it interacts withecho[A,B]linearity before writing code; that decision is the design. -
Evaluate it (
lib/eval.ml) — it must append to the trace or have a stated reason not to. -
Gate it (
lib/constrained_check.ml) — can it loop? can it recurse? is it reversible? If it is destructive, it should produce an echo. -
Mirror it in the Idris2 model (
src/abi/Lang/Syntax.idr→Eval.idr) — a feature the model does not know about silently widens the fidelity gap. -
Extend the conformance suite (
tests/conformance_test.ml) — a behaviour change without a conformance test is a regression lottery. -
Update the honest tables (
README.adocstatus rows,descriptiles/STATE.a2ml) in the same PR.
just build # dune build
just test # 27-test conformance suite
just ci # lint + test + zig-ffi-check + escape-hatch guard
just proofs # Idris2 ABI + Lang.* type-check (needs idris2 0.7.0)
just demo # golden path with --dump-traceidris2, zig, and liboqs are not required to build the OCaml core —
the justfile recipes degrade gracefully and tell you what was skipped. Do not
report a gate green that you did not run (see CLAUDE.md, guardrail 2).
-
End-user path — the language from the outside.
-
Maintainer path — the gates that protect all this.
-
docs/academic/ — the research foundations (type theory, ORAM, formal verification).