|
| 1 | +// SPDX-License-Identifier: MPL-2.0 |
| 2 | +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> |
| 3 | += git-reticulator — AffineScript Migration Plan & Session Handoff |
| 4 | +:revdate: 2026-06-04 |
| 5 | +:status: planning |
| 6 | + |
| 7 | +== TL;DR (RESUME HERE) |
| 8 | + |
| 9 | +Decision (2026-06-04): **AffineScript-first, but build the Rust↔AffineScript |
| 10 | +bridge FIRST** (resolves META `ADR-001`; chosen over an immediate full migrate |
| 11 | +and over a Rust-native core). No migration code has been written yet — this |
| 12 | +document is the handoff so the work can be picked up locally. |
| 13 | + |
| 14 | +The bridge is **not** a git-reticulator deliverable — it lives in the |
| 15 | +**`hyperpolymath/affinescript`** repo (`runtime/`). git-reticulator is its |
| 16 | +*first consumer*, not its home. |
| 17 | + |
| 18 | +== Why "bridge first" (AffineScript readiness findings) |
| 19 | + |
| 20 | +Assessed 2026-06-04 against `/affinescript` (authoritative: |
| 21 | +`affinescript/docs/CAPABILITY-MATRIX.adoc`). Honest state: |
| 22 | + |
| 23 | +* The compiler **works**: `.affine` → Wasm / Deno-ESM / Node-CJS, ~278 tests green. |
| 24 | +* AffineScript is **alpha (0.1.1)** with a known base-language soundness gap |
| 25 | + (CORE-01 / affinescript#177). The repo runs a CI ratchet that *fails* any |
| 26 | + "production-ready" claim — so do not write one. |
| 27 | +* It is **Wasm-sandboxed**: a `.affine` core **cannot** call `git2`/`postgres` |
| 28 | + crates directly (the old `src/lattice/affine/*.affine` is invalid on this |
| 29 | + count). All IO is host-side, declared as `extern fn` host imports. |
| 30 | +* The Rust integration story is **the blocker**: `affinescript/runtime` (crate |
| 31 | + `affinescript-runtime`) is ~80% "TODO Phase 6" stubs (`ffi.rs` marshalling |
| 32 | + returns 0/null), and there is **no Rust loader/marshalling library** — JS has |
| 33 | + `packages/affine-js`; Rust has nothing equivalent. The only proven host+core |
| 34 | + pattern (the VS Code extension) is JS-side only. |
| 35 | + |
| 36 | +Conclusion: a pure AffineScript lattice core is the right *target*, but it |
| 37 | +cannot load into a Rust host until the bridge exists. |
| 38 | + |
| 39 | +== Deliverable 1 — the bridge (in `hyperpolymath/affinescript`) |
| 40 | + |
| 41 | +A Rust loader + marshalling layer: the `affine-js` equivalent for Rust. |
| 42 | + |
| 43 | +* Location: `affinescript/runtime/` (extend the crate) or a new |
| 44 | + `affinescript/packages/affine-rs/`. |
| 45 | +* Scope: |
| 46 | +** A `wasmtime`- (or `wasmi`-) based loader: `AffineModule::from_bytes(&[u8])`, |
| 47 | + instantiate, call exports (`main`, named `pub fn`s). |
| 48 | +** Memory marshalling: read/write AffineScript strings (`[u32 len][utf-8]`), |
| 49 | + ints, records, `Vec`, across the Wasm linear-memory boundary (the part |
| 50 | + `affine-js/mod.js` does in JS; `runtime/src/ffi.rs` Phase-6 stubs need |
| 51 | + completing). |
| 52 | +** An `extern fn` host-import registry so the host supplies implementations |
| 53 | + (mirror the `Vscode` import object in `affine-vscode/mod.js`). |
| 54 | +* Acceptance: a Rust test loads a trivial compiled `.affine` (`fn add(a,b)`), |
| 55 | + calls it, and round-trips a string through a host `extern fn`. |
| 56 | + |
| 57 | +== Deliverable 2 — git-reticulator migration (once the bridge exists) |
| 58 | + |
| 59 | +Architecture: **thin Rust host + pure AffineScript lattice core over Wasm.** |
| 60 | + |
| 61 | +* Rust host (IO, provided to the core as `extern fn`s): |
| 62 | +** `git2` ingestion (real repo parsing — currently not wired). |
| 63 | +** verisim as the database (see below). |
| 64 | +** embeddings (feature-gated), actix REST surface. |
| 65 | +** loads + drives the AffineScript-Wasm core via Deliverable 1. |
| 66 | +* AffineScript core (pure, `.affine` → Wasm): the lattice algorithm only — |
| 67 | + SCC-condensation, partial order, meet/join, LOD `zoom_to_node` selection. |
| 68 | + This is the slice that earns the "lattice" word (see `PROOF-NEEDS.md` P1–P4). |
| 69 | +* Seam: define a Rust `trait LatticeCore` so the host runs against a Rust impl |
| 70 | + today and swaps to the Wasm-backed impl with no host rewrite. |
| 71 | + |
| 72 | +=== Database: verisim (standalone; federate only if needed) |
| 73 | + |
| 74 | +git-reticulator is an HTTP client of `verisim-api` (default `:8080`). No |
| 75 | +federation — a single octad store suffices. A thin `reqwest` client (own module, |
| 76 | +no cross-repo path-dep that would break CI): |
| 77 | + |
| 78 | +[cols="1,2"] |
| 79 | +|=== |
| 80 | +| Lattice concept | verisim mapping |
| 81 | + |
| 82 | +| node (Keyword) | one octad — `POST /api/v1/octads` |
| 83 | +| edges | Graph modality |
| 84 | +| embedding | Vector modality |
| 85 | +| source text | Document modality |
| 86 | +| authorship | Provenance modality |
| 87 | +| commit history | Temporal modality |
| 88 | +| retrieval | VQL via `/queries` |
| 89 | +| staleness sentinel | `/drift` |
| 90 | +|=== |
| 91 | + |
| 92 | +(A Rust client SDK exists at `verisimdb/connectors/clients/rust` for reference, |
| 93 | +but copying its shapes into a local `reqwest` module keeps CI self-contained.) |
| 94 | + |
| 95 | +=== Tests, benches, CI (per the CRG taxonomy already in `TEST-NEEDS.md`) |
| 96 | + |
| 97 | +* Replace the smoke-over-`println` tests with behavioural tests that assert |
| 98 | + lattice **properties** (proptest): partial-order laws, `zoom` soundness + |
| 99 | + completeness, SCC-condensation acyclicity. |
| 100 | +* Benches: criterion over ingest / build / zoom on fixture repos (baseline). |
| 101 | +* Strict-but-passable CI: keep the `standards` reusable wrappers; add an |
| 102 | + AffineScript compile gate for the `.affine` core (CI is the verification |
| 103 | + surface — there is no AffineScript toolchain in the web sandbox); keep |
| 104 | + governance/scorecard/secret-scanner green. Gate on real failures only. |
| 105 | + |
| 106 | +== Status ledger |
| 107 | + |
| 108 | +* PR #23 (docs/metadata de-template + 6a2 + PROOF-NEEDS + CI hardening): **merged**. |
| 109 | +* This plan: the agreed next-steps record. Migration code: **not started** |
| 110 | + (blocked on Deliverable 1). |
| 111 | +* Cross-refs: `META.a2ml` ADR-001/ADR-006; `STATE.a2ml` critical-next-actions; |
| 112 | + `PROOF-NEEDS.md`; `NEUROSYM.a2ml` (the four-layer stack this realises). |
0 commit comments