REL2 plan: interval primitive → Bridge → K7 cubical encoding
Some checks failed
Lean Action CI / build (push) Has been cancelled

Detailed three-phase plan for the next stratum past REL1:

  1. CType.interval primitive (1-2d) — the river-bed under every
     dim-flowing computation.  Promotes .dimExpr from .univ
     placeholder to .interval typing.

  2. Bridge.lean (Eq ↔ Path interop, 3-5d) — the ferry between
     Lean's discrete equality and the embedded cubical Path.
     Default CubicalEmbed instances for Bool, Nat, List, Prod;
     forward bridge always available, backward restricted to
     neutral-free paths in REL2.0 (full Glue NbE deferred to
     REL2.1).

  3. paideia K7 literal cubical encoding (5-10d) — the carrying
     load.  Replaces MathPath p₀ p₁ with a CTerm-typed
     Path between two embedded MasteryProvenance traces.
     Closes engine issue #1 with the originating use case.

Covers acceptance criteria, risk register, sequencing graph
(engine → topolei → paideia, no cycle), Rust ABI bump 2→3,
post-REL2 deferral list (REL2.1 Glue NbE / pointwise dist,
REL3 numerical layer, REL3+ higher cells, REL4 GPU/interaction).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maximus Gorog 2026-04-30 18:36:58 -06:00
parent 50bb6660d6
commit 915b7b3b68

411
docs/REL2_PLAN.md Normal file
View file

@ -0,0 +1,411 @@
# REL2_PLAN.md — Interval, Bridge, K7 Cubical Encoding
*Drafted 2026-04-30, on `Dev_REL1`. The detailed engineering plan
for advancing both the implementation and the project's Eulerian
abstractions one stratum past REL1. Three coordinated phases across
three repos (`cubical-transport-hott-lean4`, `topolei`, `paideia`),
sequenced to land in a single merge train.*
---
## 0. Eulerian framing (why this trio)
Three poetic-and-applicable abstractions converge on this work:
- **River bed** — the **interval** `𝕀` as a first-class type. Today
`.dimExpr r` types as the placeholder `.univ`; promoting interval to
a CType primitive gives every dim-flowing computation real semantic
ground. Without a river bed, paths flow over an unspecified medium.
- **Ferry** — the **`Eq ↔ Path` bridge**. Lean's discrete-equality
river and the embedded cubical-path river run in parallel. The
ferry lets payload (Mathlib lemmas, decidable-equality witnesses)
cross between them in either direction.
- **Carrying load****paideia K7** as a literal cubical `Path`
between two `MasteryProvenance` traces. The originating issue (#1)
filed against this repo. REL1 gave us inductive types in the
cubical universe; REL2 makes K7 an actual passenger on the ferry.
Each phase advances both registers simultaneously: the metaphor lands
*because* the implementation lands.
---
## 1. Phase 1 — `CType.interval` primitive
**Repo:** `cubical-transport-hott-lean4` (+ topolei follow-up).
**Estimated effort:** 12 days.
**Branch:** continue on `Dev_REL1`.
### 1.1 Goal
Promote the cubical interval to a first-class CType. After this
phase, `.dimExpr r : .interval` is a real typing judgement, not a
`.univ` placeholder.
### 1.2 Engine changes
| File | Change |
|------|--------|
| `CubicalTransport/Syntax.lean` | Add `\| interval : CType` to the mutual block (tag 6, after `.ind`). Bump tag-layout doc in §6 of `INDUCTIVE_TYPES.md`. |
| `CubicalTransport/Subst.lean` | `.interval` arms in `CType.substDim` / `substDimExpr` (no recursion). Reduction lemmas `substDim_interval`, `substDimExpr_interval` (both `rfl`). |
| `CubicalTransport/DimLine.lean` | `.interval` arms in `CType.dimAbsent` (always `true`); `CType.substDim_absent_aux`; `CType.substDimExpr_absent_aux`; `CType.dimAbsent_after_substDim_aux`; `CType.substDim_comm_aux`. All trivial. |
| `CubicalTransport/Typing.lean` | Replace `HasType.dimExpr : HasType Γ (.dimExpr r) .univ` with `… .interval`. Update `HasType.weaken_core`'s `\| dimExpr` arm. |
| `CubicalTransport/Inductive.lean` | Add ergonomic alias `CType.intervalC : CType := .interval`. |
| `CubicalTransport/TransportLaws.lean` | Optional: `eval_transp_interval_const : eval env (.transp i .interval φ t) = eval env t` — derived corollary of `eval_transp_const` since `.interval` is dim-absent. |
### 1.3 Rust kernel changes (`native/cubical/src/`)
| File | Change |
|------|--------|
| `tags.rs` | `pub const TY_INTERVAL: u32 = 6;` |
| `subst.rs` | `TY_INTERVAL` arm in `ctype_subst_dim` and `ctype_subst_dim_expr` — return self with `retain`. |
| `dim_absent.rs` | `TY_INTERVAL` arm in `ctype_absent` — return `true`. |
| `include/topolei_cubical.h` | Bump `TOPOLEI_FFI_ABI_VERSION` 2 → 3. |
### 1.4 Topolei follow-up
`Topolei/Cubical/DecEq.lean`'s `CType.beq` is exhaustive — add an
`.interval` arm:
```lean
\| .interval, .interval => true
```
Plus `\| .interval => by simp [CType.beq]` in `CType.beq_refl`.
Commit on topolei `Dev_REL1`.
### 1.5 Tests
- `CubicalTransport/FFITest.lean`: smoke test `cvalSummary (eval .nil (.dimExpr (.var ⟨"i"⟩)))``"vdimExpr ..."` (existing test, still passes).
- New `EvalTest.lean` arm: `HasType.dimExpr` constructs a witness at `.interval`.
- All existing 74/74 tests must still pass.
### 1.6 Acceptance criteria
- `lake build` clean across all 30+ jobs.
- `./.lake/build/bin/cubical-test` reports 74/74 + new arm = 75/75.
- Engine builds on its own; topolei `Dev_REL1` rebuilds with the
one-line `DecEq.lean` patch.
- `INDUCTIVE_TYPES.md` §6 tag table updated; doc note in §11.4 marks
the dimExpr-typing approximation as resolved.
---
## 2. Phase 2 — `Bridge.lean` (`Eq ↔ Path` interop)
**Repo:** `cubical-transport-hott-lean4`.
**Estimated effort:** 35 days.
**Branch:** `Dev_REL1` (continues from Phase 1).
**Blocked by:** Phase 1 (instances need interval-typed dim args for path constructors).
### 2.1 Goal
Provide a typeclass-mediated bridge between Lean's `Eq` and embedded
cubical `Path`, with default instances for canonical types (`Bool`,
`Nat`, `List`, products), plus the two principal bridge directions.
### 2.2 The `CubicalEmbed` typeclass
```lean
class CubicalEmbed (α : Type) where
ctype : CType
toCTerm : α → CTerm
fromCTerm : CTerm → Option α
roundtrip : ∀ a, fromCTerm (toCTerm a) = some a
toCTerm_typed : ∀ a, HasType .nil (toCTerm a) ctype
```
Per-instance bookkeeping: `roundtrip` is by structural recursion;
`toCTerm_typed` follows from `HasType.ctor`'s minimal-viable rule
(REL1) — no per-arg coherence needed at this level.
### 2.3 Default instances
| Type | Schema | Notes |
|------|--------|-------|
| `Bool` | `boolSchema` | `toCTerm true = trueC`, `false = falseC`. |
| `Nat` | `natSchema` | `toCTerm n = natLit n` (tower of `succC`s). |
| `List α [CubicalEmbed α]` | `listSchema [α.ctype]` | folds via `consC`/`nilC`. |
| `α × β [CubicalEmbed α] [CubicalEmbed β]` | (uses Σ via `CType.sigma`) | `toCTerm (a,b) = .pair (toCTerm a) (toCTerm b)`. |
| `Option α [CubicalEmbed α]` | (encode as `α + Unit` schema, REL2.1) | deferred. |
### 2.4 Bridge directions
**Forward (always available):**
```lean
def Eq.toPath {α} [CubicalEmbed α] {a b : α} (h : a = b) : CTerm :=
.plam (DimVar.mk "$eq2path") (CubicalEmbed.toCTerm a)
-- Constant path; b reduces to a by h, so endpoints match.
theorem Eq.toPath_typed {α} [CubicalEmbed α] {a b : α} (h : a = b) :
HasType .nil (Eq.toPath h)
(.path (CubicalEmbed.ctype α)
(CubicalEmbed.toCTerm a)
(CubicalEmbed.toCTerm b))
```
**Backward (decidable types):**
```lean
theorem Path.toEq {α} [CubicalEmbed α] [DecidableEq α]
{a b : α} (p : CTerm)
(hp : HasType .nil p
(.path (CubicalEmbed.ctype α)
(CubicalEmbed.toCTerm a)
(CubicalEmbed.toCTerm b))) :
a = b
```
**Proof sketch:** by `decEq a b` case analysis. In the negative
case, derive `False` from path-endpoint coherence: a path between two
`toCTerm`-distinct constructor values cannot exist, by readback +
`CTerm.noConfusion`.
**Restriction in REL2.0:** Backward bridge is restricted to *neutral-
free* paths in the first cut. A non-canonical path produced by Glue
or transport may not directly close `Path.toEq`; defer to REL2.1
once the Glue NbE story is fully discharged (sibling open work).
Document the restriction in the docstring.
**Prop-level coincidence:**
```lean
theorem Path_iff_Eq_of_Prop {P : Prop} (a b : P) :
a = b ↔ True := ⟨fun _ => trivial, fun _ => proof_irrel a b⟩
-- Trivial bijection via proof irrelevance.
```
### 2.5 Module layout
`CubicalTransport/Bridge.lean` (new):
- §1 `CubicalEmbed` class + universe-polymorphic instances skeleton.
- §2 Default instances (`Bool`, `Nat`, `List`, `Prod`).
- §3 Forward bridge (`Eq.toPath` + typing).
- §4 Backward bridge (`Path.toEq` for decidable types).
- §5 Prop-level coincidence.
- §6 Round-trip lemmas + composition theorems.
Re-export from `CubicalTransport.lean`.
### 2.6 Tests
`BridgeTest.lean` (new):
- `Eq.toPath rfl |> readback` round-trips through a constant `.plam`.
- `Path.toEq` on the constant path returns `rfl`.
- `roundtrip` per-instance for Bool/Nat/List Bool/(Nat × Bool).
- A property-style test: 100 random `Bool`/`Nat` values, all
round-trips succeed.
### 2.7 Doc updates
- `KERNEL_BOUNDARY.md §2.6` from "planned" to "landed in
`Bridge.lean`".
- New `docs/EULERIAN.md` (optional but recommended): the river-bed /
ferry / carrying-load metaphor with concrete Lean counterparts.
Keep under 200 lines; this is the project's poetic record.
### 2.8 Acceptance criteria
- All instances compile and `roundtrip`/`toCTerm_typed` proofs go
through.
- `Path.toEq` proven for `Bool`, `Nat`, `List Bool`, `Nat × Bool`.
- `BridgeTest.lean` reports new arms passing alongside the existing
smoke + property suites.
- `KERNEL_BOUNDARY.md` updated.
---
## 3. Phase 3 — paideia K7 literal cubical encoding
**Repo:** `paideia` (separate repo; depends on engine + topolei).
**Estimated effort:** 510 days.
**Branch:** new `Dev_REL1` on paideia.
**Blocked by:** Phase 1 (interval), Phase 2 (Bridge), engine
`Dev_REL1` merged or available as a path-require.
### 3.1 Goal
Replace the discrete-shadow `MathPath p₀ p₁` with a `CTerm`-typed
`Path (embed MasteryProvenance) (embed p₀) (embed p₁)`. Closes
issue #1 in `max/cubical-transport-hott-lean4`.
### 3.2 Survey day (1 day)
Read paideia's existing `Foundation/K7Cubical.lean`, the locations
of `KnowledgeNode` and `MasteryProvenance`, and every consumer of
`MathPath`. Catalogue:
- `KnowledgeNode`'s record fields (CubicalEmbed instance shape).
- `MasteryProvenance`'s exact definition (likely `Trace
KnowledgeNode` ≡ list).
- All `MathPath` call sites (the migration surface).
- K7's external API (`init`, `step`, `lift`, anything else).
### 3.3 New module: `Paideia/Foundation/MasteryEncoding.lean`
```lean
import CubicalTransport.Bridge
import CubicalTransport.Inductive
instance : CubicalEmbed KnowledgeNode := { ... }
-- via a paideia-local schema for the record (or via composition
-- of more primitive instances if KnowledgeNode is structured).
instance : CubicalEmbed MasteryProvenance :=
{ ctype := .ind listSchema [CubicalEmbed.ctype KnowledgeNode]
toCTerm := fun mp => mp.foldr
(fun n acc => consC _ (CubicalEmbed.toCTerm n) acc)
(nilC _)
fromCTerm := …
roundtrip := by structural induction on the trace
toCTerm_typed := by structural induction + HasType.ctor }
```
If `KnowledgeNode` carries `Float` fields, encode `Float` opaquely as
`.var <nominal>` for the first cut; flag it in a TODO; revisit if
numerical reasoning at the cubical level becomes necessary (REL3+).
### 3.4 K7 rewrite: `Paideia/Foundation/K7Cubical.lean`
```lean
def CubicalGradient (p₀ p₁ : MasteryProvenance) : Type :=
{ p : CTerm //
HasType .nil p
(.path (CubicalEmbed.ctype MasteryProvenance)
(CubicalEmbed.toCTerm p₀)
(CubicalEmbed.toCTerm p₁)) }
namespace K7
/-- Constant gradient — the "do nothing" learning trajectory. -/
def init (p : MasteryProvenance) : CubicalGradient p p :=
⟨Eq.toPath rfl, Eq.toPath_typed rfl⟩
/-- Compose two adjacent learning trajectories. Implementation
uses cubical `.comp`. REL2.0 produces a stuck `ncomp` neutral
that reads back as a syntactic `.comp` term — semantically
correct (the path exists, paideia's downstream uses are
type-driven). REL2.1 polishes to genuine reduction once
pointwise-distribution-over-`.ind` lands in the engine. -/
def step
{p₀ p₁ p₂ : MasteryProvenance}
(γ : CubicalGradient p₀ p₁) (δ : CubicalGradient p₁ p₂) :
CubicalGradient p₀ p₂ := …
def lift {…} : … := … -- depends on what lift currently does
end K7
```
### 3.5 Migration
Per the user's "no compat shims" mandate, retire `MathPath` outright.
Update every call site to use `CubicalGradient`. Keep the external
API of `K7.init` / `step` / `lift` *type-identical*; only the
underlying representation changes.
### 3.6 Tests
Port any existing K7 tests to the new representation. Add:
- `K7.init p`'s readback equals a constant `.plam` of `(toCTerm p)`.
- `K7.step` of two distinct gradients produces a `Path`-typed
CTerm (even if its readback is a syntactic `.comp` for now).
- Round-trip: `MasteryProvenance.toCTerm ∘ fromCTerm = some` on
a populated trace.
### 3.7 Acceptance criteria
- paideia builds clean.
- All previously-passing K7 tests pass with the new encoding.
- New round-trip and type-coherence tests pass.
- `MathPath` is fully retired (no remaining references).
- A short note in `Paideia/README.md` records "K7 now ships on the
cubical engine; see `Foundation/K7Cubical.lean` and `Bridge.lean`
in the engine repo."
- Engine issue #1 is commented with the closing reference.
---
## 4. Sequencing graph
```
cubical-engine `Dev_REL1` (already pushed)
Phase 1 — interval (12d)
(cubical engine + topolei follow-up)
Phase 2 — Bridge.lean (35d)
(cubical engine only)
Phase 3 — paideia K7 cubical encoding (510d)
(paideia, depends on engine + topolei)
Coordinated merge train: engine `Dev_REL1` → main,
topolei `Dev_REL1` → main, paideia `Dev_REL1` → main.
Engine issue #1 closes with the K7 commit reference.
```
**Total: 917 working days.** Three repos. One coordinated merge.
---
## 5. Risks & mitigations
| Risk | Likelihood | Mitigation |
|------|-----------|------------|
| Interval's introduction surfaces a hidden axiom that pattern-matches `CType` exhaustively. | Low | Build cleanly already after each phase 1 commit; existing topolei `DecEq.lean` is the only known consumer (already covered in 1.4). |
| `Path.toEq` proof needs Glue NbE that isn't yet discharged. | Medium | Restrict REL2.0 backward bridge to neutral-free paths; document; defer full Glue interop to REL2.1. |
| `KnowledgeNode`'s record shape requires a custom paideia schema (more work than expected). | Medium | Survey day in 3.2 catches this; budget contingency in 510d window. |
| paideia has many `MathPath` call sites scattered across modules. | LowMedium | Survey day catalogues them; migration is mechanical once the new type is in place. |
| Rust ABI bump 2→3 breaks any out-of-tree consumers. | Low | Only `cubical-test` and `cubical-bench` link the .a; both are in-tree. Forgejo CI catches any drift. |
| Coordinated merge train: paideia depends on engine which depends on topolei (cyclically via `Trace.lean` modifications). | Low | Engine has no topolei dep; the dependency is paideia → engine and paideia → topolei. No cycle. Land engine first, topolei second, paideia third. |
---
## 6. Definition of done (whole arc)
- `eval .nil (CubicalEmbed.toCTerm mp)` round-trips to `mp` for
every paideia-relevant `MasteryProvenance`.
- `K7.init p` and `K7.step γ δ` produce well-typed CubicalGradients.
- Issue #1 in `max/cubical-transport-hott-lean4` closes with a
comment "K7 now ships as a literal cubical Path; see paideia
`Dev_REL1` commit `<hash>`."
- `KERNEL_BOUNDARY.md §2.6` records the bridge as landed.
- `INDUCTIVE_TYPES.md` §11.4 records `dimExpr` typing as resolved
(interval is the answer).
- *(Optional, recommended)*: `docs/EULERIAN.md` writes up the
river-bed / ferry / carrying-load metaphors next to their concrete
Lean counterparts. The project's poetic record.
---
## 7. After REL2 — what comes next
Items still deferred at end-of-arc, in rough priority:
- **REL2.1 — Glue NbE completion + full backward bridge.** Removes
the neutral-free restriction on `Path.toEq`.
- **REL2.2 — Pointwise transport / composition distribution over
`.ind`.** Makes `K7.step` reduce definitionally instead of
staying as a stuck neutral.
- **REL3 — Numerical layer.** `docs/NUMERICAL.md`'s vision lands;
`Float`-CType primitive; `KnowledgeNode`'s float fields encode
natively rather than opaquely.
- **REL3+ — Higher cells (cells-spec §8).** 2-cells / n-cells
build atop the HIT layer. Mostly Lean-native; small amount of
engine support.
- **REL4 — Cell layer / GPU shaders / interaction (cells-spec
§6§10).** Application surface; depends on most of the above.
Each future item gets its own `docs/RELn_PLAN.md` when scoped.
---
*End of REL2_PLAN.md. Companion to `INDUCTIVE_TYPES.md` (REL1 design)
and `KERNEL_BOUNDARY.md` (long-horizon scope contract). Update as the
arc progresses or as the user redirects.*