Skip to content

Commit 40bafa0

Browse files
docs: record AffineScript migration decision + session handoff (#25)
Resolves ADR-001 and adds ADR-006: AffineScript-first, but build the Rust↔AffineScript bridge FIRST (in the affinescript repo, runtime/) before migrating git-reticulator's core. No migration code yet — this is the pick-up-locally handoff after the 2026-06-04 readiness assessment. - docs/MIGRATION-PLAN.adoc — full handoff: readiness findings, bridge scope, host+core plan, verisim DB mapping, tests/benches/CI, RESUME HERE. - META.a2ml: ADR-001 resolved (IO host-side via extern fn, not crate calls) + ADR-006. - STATE.a2ml: [migration-decision] + refreshed critical-next-actions. - debt.a2ml: core item updated to the bridge-first blocker. https://claude.ai/code/session_01JNCDaWMB8NV6nAPrvmTg4w
1 parent 3dae78b commit 40bafa0

4 files changed

Lines changed: 140 additions & 10 deletions

File tree

.machine_readable/6a2/META.a2ml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,19 @@ package-manager = "cargo" # guix.scm / flake.nix also present for reproducib
2626
[[adr]]
2727
id = "ADR-001"
2828
title = "Rust host, AffineScript core"
29-
status = "accepted-but-under-review"
29+
status = "accepted"
3030
date = "2026-04"
31-
decision = "CLI/REST/IO in Rust; lattice algorithms in AffineScript (.affine) for affine-typed safe traversal."
32-
consequence = "Today the core cannot compile (no AffineScript compiler) and is written against Rust crates AffineScript cannot bind. STATE.honest-status flags this; ADR may be superseded by a Rust-native core."
31+
resolved = "2026-06-04"
32+
decision = "CLI/REST/IO in Rust; the PURE lattice algorithm in AffineScript (.affine) compiled to Wasm. IO is host-side, exposed to the core as `extern fn` host imports — NOT direct Rust-crate calls (AffineScript is Wasm-sandboxed)."
33+
consequence = "The old src/lattice/affine/*.affine (which called git2/postgres directly) is invalid and must be rewritten pure. AffineScript-first is confirmed as the target; sequencing is governed by ADR-006."
34+
35+
[[adr]]
36+
id = "ADR-006"
37+
title = "Build the Rust↔AffineScript bridge before migrating the core"
38+
status = "accepted"
39+
date = "2026-06-04"
40+
decision = "Do NOT migrate git-reticulator's core to .affine yet. First build the missing Rust loader/marshalling for compiled AffineScript (the affine-js equivalent for Rust) in the affinescript repo's runtime/. Then migrate git-reticulator onto it behind a `trait LatticeCore` seam."
41+
rationale = "AffineScript's compiler works (→Wasm) but the Rust host bridge does not exist: affinescript-runtime is ~80% Phase-6 stubs, no Rust loader/marshalling, alpha + CORE-01 soundness gap. The bridge is an affinescript-repo deliverable; git-reticulator is its first consumer. Full handoff in docs/MIGRATION-PLAN.adoc."
3342

3443
[[adr]]
3544
id = "ADR-002"

.machine_readable/6a2/STATE.a2ml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@
88
[metadata]
99
project = "git-reticulator"
1010
version = "0.1.0"
11-
last-updated = "2026-06-03"
12-
status = "paused-resumed" # was on backburner; resumed 2026-06-03 for a tidy-up pass
11+
last-updated = "2026-06-04"
12+
status = "active" # tidy-up merged (PR #23); migration direction decided 2026-06-04
13+
14+
[migration-decision]
15+
date = "2026-06-04"
16+
decision = "AffineScript-first, build the Rust↔AffineScript bridge FIRST (ADR-006)"
17+
bridge-lives-in = "hyperpolymath/affinescript (runtime/) — NOT this repo"
18+
handoff-doc = "docs/MIGRATION-PLAN.adoc"
19+
db = "verisim standalone (HTTP client; octad store); no federation unless needed"
1320

1421
[project-context]
1522
name = "git-reticulator"
@@ -60,11 +67,12 @@ template-debt = [
6067
]
6168

6269
[critical-next-actions]
70+
# Core-language question DECIDED 2026-06-04 (ADR-006): AffineScript-first, bridge-first.
6371
actions = [
64-
"DECIDE the core-language question: either (a) make the lattice core real in Rust (wire git2, drop the un-compilable .affine), or (b) wait for AffineScript and rewrite the .affine to compile to Wasm without Rust-crate calls",
65-
"Earn the 'lattice' word: implement SCC-condensation + a partial order, then discharge PROOF-NEEDS.md P1-P2 (Idris2)",
66-
"Wire git2 behind the default feature so reticulate actually reads a repo",
67-
"Replace println stubs with a real (even in-memory) lattice build + a test that asserts a lattice PROPERTY, not just no-panic",
72+
"DELIVERABLE 1 (in affinescript repo, runtime/): build the Rust loader + marshalling for compiled AffineScript — the affine-js equivalent for Rust. Acceptance: a Rust test loads a compiled .affine fn, calls it, round-trips a string via a host extern fn. See docs/MIGRATION-PLAN.adoc.",
73+
"DELIVERABLE 2 (here, once 1 lands): thin Rust host (git2 + verisim HTTP DB + actix) + pure .affine lattice core over Wasm, behind a `trait LatticeCore` seam.",
74+
"Earn the 'lattice' word: SCC-condensation + partial order in the core, then discharge PROOF-NEEDS.md P1-P2 (Idris2).",
75+
"Tests/benches: replace smoke-over-stubs with property tests (partial-order laws, zoom soundness/completeness) + criterion benches; strict-but-passable CI with an AffineScript compile gate.",
6876
]
6977

7078
[ecosystem]

.machine_readable/agent_instructions/debt.a2ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ last-updated = "2026-06-03"
5252

5353
[[debt.should]]
5454
component = "src/lattice/affine"
55-
issue = "Core .affine cannot compile and calls Rust crates AffineScript can't bind — decide Rust-native core vs wait-for-AffineScript (META ADR-001)."
55+
issue = "DECIDED 2026-06-04 (ADR-006): AffineScript-first, bridge-first. Blocked on Deliverable 1 — the Rust↔AffineScript loader/marshalling bridge in the affinescript repo (runtime/), which does not exist yet (Phase-6 stubs, no Rust loader). The old .affine (calls git2/postgres directly) is invalid and will be rewritten pure once the bridge lands. Full plan: docs/MIGRATION-PLAN.adoc."
5656
effort = "hard"
5757
impact = "high"
5858
discovered = "2026-06-03"
59+
updated = "2026-06-04"
5960

6061
[[debt.should]]
6162
component = "contractiles"

docs/MIGRATION-PLAN.adoc

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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

Comments
 (0)