Read this before you conclude the repo is broken or abandoned. It is neither. It is a research language part-way through a deliberate second draft, and the second draft exists because the first one was honest about its own limits.
|
Important
|
Why this document exists
Several of this repo’s status surfaces (the README warning, That conclusion is wrong, and this document is the correction. The honest facts are unchanged (they are restated below, in full, under "What is genuinely settled"). What changes is the framing: those facts are the receipts of a language learning from its first attempt, not an obituary. Ephapax is gestating. The first draft taught us exactly what the second draft needed to be. |
Ephapax is a research language for compile-time-memory-safe WebAssembly with first-class irreversible boundaries (region exits, drops, key erasure, audit trails). It is mid-way through two parallel second drafts, and both are going well:
-
The grammar. v1 was a flat surface fed straight to the parser. It worked for the core calculus but had no room to grow into modules, generics, effects, traits, or a compile-time meta plane. v2 introduces a surface → desugar → core architecture: a rich surface that lowers into the same small, well-understood core. v2 is landing incrementally and passing its phase tests — "so far, so good."
-
The soundness proof. v1 was a single typing judgment that tried to track regions, structural discipline, echo residue and dyadic mode all at once. That conflation was unsound, and — unusually — we proved it unsound with a machine-checked counterexample rather than shipping the bug. v2 splits those four concerns into four orthogonal layers (L1–L4) and re-derives preservation per layer from explicit invariants. Three of the four layers already carry
Qedtheorems.
Discovering your own unsoundness before anyone depends on it, with a proof, and then redesigning around the lesson, is not failure. It is the rare, expensive, correct thing. Most languages never find out. Ephapax did, and the second draft is sharper for it.
|
Note
|
Machine-readable orientation
|
The prohibitions you will find in CLAUDE.md and STATUS.adoc are
narrow: they fence off exactly two v1 artefacts (the falsified
Semantics.v preservation theorem and the superseded v1 surface
grammar). They are not a statement about the project’s health. Treat
them as "mind the wet paint on this one wall," not "the building is
condemned."
-
Proof, L1: close the residual L1 structural admits in
formal/Semantics_L1.v(list/multiset bridge;TFuneffect typing). These are v2 design follow-ups, not legacy patching. SeePROOF-NEEDS.md §4. -
Proof, L3: state and prove the unconditional
preservation_l3(currently conditional on an L1 admit). -
Grammar, v2: continue the phase work in
spec/ephapax-v2-grammar.ebnf+ thev2_grammar_phase_*CLI tests. -
Proof, L4: Phase A scaffold has landed; the dyadic mother–child semantics in
PRESERVATION-DESIGN.md §7is the next design step.
Two transitions are in flight at once. They are independent (you can work either without touching the other), but they rhyme — each follows the same three-beat arc:
| Beat | Grammar track | Proof track |
|---|---|---|
1. An honest v1 |
A real, working surface grammar for the core calculus. |
A real, complete typing judgment with progress + preservation stated. |
2. A rigorously-diagnosed wall |
The flat surface cannot grow into modules / generics / effects / comptime without becoming a tangle — a square peg forced through a round hole. |
The conflated judgment is unsound. Not suspected — proven, by
|
3. A better v2, shaped by the lesson |
Surface → desugar → core: a rich surface that lowers into the unchanged small core. Two planes (data / meta). Landing in phases. |
Four orthogonal layers (L1 regions, L2 modality, L3 echo, L4 dyadic mode), each with its own invariants and its own per-layer preservation theorem. |
The v1 artefacts are not garbage to be hidden. They are the evidence of beat 2 — the precise record of what went wrong and why — which is what made beat 3 designable. Keep them readable; just do not build on them.
The v1 surface was parsed directly (PEG parser in
src/ephapax-parser/, with the discipline-focused EBNFs in
ephapax-linear/grammar/{linear,affine}.ebnf). For the core
calculus — binary sums, case, inl/inr, let/let!, regions —
this is correct and still describes what the checker accepts.
The wall: a real systems language needs modules, generics, algebraic effects, traits, contracts, FFI capabilities, and a compile-time meta plane. Bolting all of that onto a flat surface that is parsed straight into the core means every new feature fights every other feature in one undifferentiated grammar. That is the square peg in the round hole — not because the grammar was bad work, but because the approach had no layer in which richness could live without contaminating the core.
v2 (spec/ephapax-v2-grammar.ebnf) introduces the missing layer:
SURFACE GRAMMAR → desugar → CORE CALCULUS (unchanged)The core calculus stays small and well-understood. Everything rich — modules, generics, the comptime meta plane, traits, effects, contracts — lives in the surface and desugars down. Two planes are kept apart: a data plane (runtime, linear/affine, regions, effects) and a meta plane (compile-time, total, pure, unrestricted) that can observe types and generate code but cannot touch runtime values or break linearity.
Status: active and landing. The grammar is specified end-to-end and
implemented in phases, each gated by its own v2_grammar_phase_* CLI
test. This is the "v2 so far okay" — the phases that have landed pass;
the ones that have not are scheduled, not stuck.
formal/Semantics.v carried a single typing judgment that tracked region
capabilities, structural discipline, echo residue, and dyadic mode all in
one rule set. Theorem preservation was stated against it.
It is false — and we did not merely suspect it, we proved it:
formal/Counterexample.v (5 Qed lemmas) exhibits a concrete
configuration that type-checks, takes a legal step, and lands in a state
the judgment cannot type. The bug is that a region exit invalidates a
sibling’s assumptions without the conflated judgment tracking the
dependency.
|
Tip
|
The counterexample is an achievement, not a tombstone
A machine-checked counterexample to your own soundness theorem is a
good day in language design. It converts "we think this is sound" into
"we know exactly where and why it is not," which is the only solid ground
to redesign from. The |
The redesign (formal/PRESERVATION-DESIGN.md) splits the four conflated
concerns into four first-class, orthogonal layers. Each has its own
judgment, its own invariants, and its own preservation theorem — so a fix
in one layer cannot silently break another.
| Layer | Concern | v2 status |
|---|---|---|
L1 |
Region capabilities |
Judgment complete; semantics carries a small set of named structural admits (the live work). |
L2 |
Structural modality (Linear vs Affine) |
Core landed,
|
L3 |
Echo / residue — what was lost at an irreversible step |
Calculus
+ wiring landed; |
L4 |
Dyadic mode (mother–child) |
Phase A scaffold landed; semantics design is the next step. |
The counterexample named the missing invariant precisely: a step that exits a region must not leave a sibling’s typing assumptions standing. v1 had no place to state that. v2’s L1 makes region-capability threading first-class, which is exactly the place that invariant lives. The bug became the blueprint.
This is the part that is no less transparent than before. Two things are closed, and closed for good reasons:
-
Legacy preservation (
formal/Semantics.v) is false. Keep theAdmitted.. Do not attempt to close it, strengthen lemmas toward it, add side conditions for it, or follow any pre-2026-05-26 "closure plan."formal/Counterexample.vdepends on its falsity. This wall is load-bearing. -
The v1 flat surface grammar is superseded. New surface work goes through the v2 surface → desugar → core architecture, not by extending the flat v1 surface. The v1 EBNFs remain accurate for the core and stay in-tree as reference; they are not the growth surface.
Everything else — all of L1/L2/L3/L4’s open theorems, every v2 grammar phase not yet landed — is live, tractable work. The fence is two posts wide. The field behind it is open.
Ephapax is not a failed language. It is a careful one, caught in the middle of its second draft, having done the rare thing of proving its own first draft’s limits before building the better second. Read the warnings as guardrails around two fenced-off v1 artefacts, then go work on v2 — the grammar phases and the per-layer proofs are open and waiting.
-
STATUS.adoc— the operational past / present / future map. -
formal/PRESERVATION-DESIGN.md— the four-layer architecture in full. -
PROOF-NEEDS.md— per-sublanguage proof debt, with the explicit do-not-do list. -
spec/ephapax-v2-grammar.ebnf— the v2 surface grammar specification. -
CLAUDE.md— agent guidance; its prohibitions are the two fence posts named above, nothing wider.