Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions .machine_readable/6a2/META.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,19 @@ package-manager = "cargo" # guix.scm / flake.nix also present for reproducib
[[adr]]
id = "ADR-001"
title = "Rust host, AffineScript core"
status = "accepted-but-under-review"
status = "accepted"
date = "2026-04"
decision = "CLI/REST/IO in Rust; lattice algorithms in AffineScript (.affine) for affine-typed safe traversal."
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."
resolved = "2026-06-04"
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)."
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."

[[adr]]
id = "ADR-006"
title = "Build the Rust↔AffineScript bridge before migrating the core"
status = "accepted"
date = "2026-06-04"
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."
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."

[[adr]]
id = "ADR-002"
Expand Down
20 changes: 14 additions & 6 deletions .machine_readable/6a2/STATE.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@
[metadata]
project = "git-reticulator"
version = "0.1.0"
last-updated = "2026-06-03"
status = "paused-resumed" # was on backburner; resumed 2026-06-03 for a tidy-up pass
last-updated = "2026-06-04"
status = "active" # tidy-up merged (PR #23); migration direction decided 2026-06-04

[migration-decision]
date = "2026-06-04"
decision = "AffineScript-first, build the Rust↔AffineScript bridge FIRST (ADR-006)"
bridge-lives-in = "hyperpolymath/affinescript (runtime/) — NOT this repo"
handoff-doc = "docs/MIGRATION-PLAN.adoc"
db = "verisim standalone (HTTP client; octad store); no federation unless needed"

[project-context]
name = "git-reticulator"
Expand Down Expand Up @@ -60,11 +67,12 @@ template-debt = [
]

[critical-next-actions]
# Core-language question DECIDED 2026-06-04 (ADR-006): AffineScript-first, bridge-first.
actions = [
"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",
"Earn the 'lattice' word: implement SCC-condensation + a partial order, then discharge PROOF-NEEDS.md P1-P2 (Idris2)",
"Wire git2 behind the default feature so reticulate actually reads a repo",
"Replace println stubs with a real (even in-memory) lattice build + a test that asserts a lattice PROPERTY, not just no-panic",
"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.",
"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.",
"Earn the 'lattice' word: SCC-condensation + partial order in the core, then discharge PROOF-NEEDS.md P1-P2 (Idris2).",
"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.",
]

[ecosystem]
Expand Down
3 changes: 2 additions & 1 deletion .machine_readable/agent_instructions/debt.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ last-updated = "2026-06-03"

[[debt.should]]
component = "src/lattice/affine"
issue = "Core .affine cannot compile and calls Rust crates AffineScript can't bind — decide Rust-native core vs wait-for-AffineScript (META ADR-001)."
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."
effort = "hard"
impact = "high"
discovered = "2026-06-03"
updated = "2026-06-04"

[[debt.should]]
component = "contractiles"
Expand Down
112 changes: 112 additions & 0 deletions docs/MIGRATION-PLAN.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
= git-reticulator — AffineScript Migration Plan & Session Handoff
:revdate: 2026-06-04
:status: planning

== TL;DR (RESUME HERE)

Decision (2026-06-04): **AffineScript-first, but build the Rust↔AffineScript
bridge FIRST** (resolves META `ADR-001`; chosen over an immediate full migrate
and over a Rust-native core). No migration code has been written yet — this
document is the handoff so the work can be picked up locally.

The bridge is **not** a git-reticulator deliverable — it lives in the
**`hyperpolymath/affinescript`** repo (`runtime/`). git-reticulator is its
*first consumer*, not its home.

== Why "bridge first" (AffineScript readiness findings)

Assessed 2026-06-04 against `/affinescript` (authoritative:
`affinescript/docs/CAPABILITY-MATRIX.adoc`). Honest state:

* The compiler **works**: `.affine` → Wasm / Deno-ESM / Node-CJS, ~278 tests green.
* AffineScript is **alpha (0.1.1)** with a known base-language soundness gap
(CORE-01 / affinescript#177). The repo runs a CI ratchet that *fails* any
"production-ready" claim — so do not write one.
* It is **Wasm-sandboxed**: a `.affine` core **cannot** call `git2`/`postgres`
crates directly (the old `src/lattice/affine/*.affine` is invalid on this
count). All IO is host-side, declared as `extern fn` host imports.
* The Rust integration story is **the blocker**: `affinescript/runtime` (crate
`affinescript-runtime`) is ~80% "TODO Phase 6" stubs (`ffi.rs` marshalling
returns 0/null), and there is **no Rust loader/marshalling library** — JS has
`packages/affine-js`; Rust has nothing equivalent. The only proven host+core
pattern (the VS Code extension) is JS-side only.

Conclusion: a pure AffineScript lattice core is the right *target*, but it
cannot load into a Rust host until the bridge exists.

== Deliverable 1 — the bridge (in `hyperpolymath/affinescript`)

A Rust loader + marshalling layer: the `affine-js` equivalent for Rust.

* Location: `affinescript/runtime/` (extend the crate) or a new
`affinescript/packages/affine-rs/`.
* Scope:
** A `wasmtime`- (or `wasmi`-) based loader: `AffineModule::from_bytes(&[u8])`,
instantiate, call exports (`main`, named `pub fn`s).
** Memory marshalling: read/write AffineScript strings (`[u32 len][utf-8]`),
ints, records, `Vec`, across the Wasm linear-memory boundary (the part
`affine-js/mod.js` does in JS; `runtime/src/ffi.rs` Phase-6 stubs need
completing).
** An `extern fn` host-import registry so the host supplies implementations
(mirror the `Vscode` import object in `affine-vscode/mod.js`).
* Acceptance: a Rust test loads a trivial compiled `.affine` (`fn add(a,b)`),
calls it, and round-trips a string through a host `extern fn`.

== Deliverable 2 — git-reticulator migration (once the bridge exists)

Architecture: **thin Rust host + pure AffineScript lattice core over Wasm.**

* Rust host (IO, provided to the core as `extern fn`s):
** `git2` ingestion (real repo parsing — currently not wired).
** verisim as the database (see below).
** embeddings (feature-gated), actix REST surface.
** loads + drives the AffineScript-Wasm core via Deliverable 1.
* AffineScript core (pure, `.affine` → Wasm): the lattice algorithm only —
SCC-condensation, partial order, meet/join, LOD `zoom_to_node` selection.
This is the slice that earns the "lattice" word (see `PROOF-NEEDS.md` P1–P4).
* Seam: define a Rust `trait LatticeCore` so the host runs against a Rust impl
today and swaps to the Wasm-backed impl with no host rewrite.

=== Database: verisim (standalone; federate only if needed)

git-reticulator is an HTTP client of `verisim-api` (default `:8080`). No
federation — a single octad store suffices. A thin `reqwest` client (own module,
no cross-repo path-dep that would break CI):

[cols="1,2"]
|===
| Lattice concept | verisim mapping

| node (Keyword) | one octad — `POST /api/v1/octads`
| edges | Graph modality
| embedding | Vector modality
| source text | Document modality
| authorship | Provenance modality
| commit history | Temporal modality
| retrieval | VQL via `/queries`
| staleness sentinel | `/drift`
|===

(A Rust client SDK exists at `verisimdb/connectors/clients/rust` for reference,
but copying its shapes into a local `reqwest` module keeps CI self-contained.)

=== Tests, benches, CI (per the CRG taxonomy already in `TEST-NEEDS.md`)

* Replace the smoke-over-`println` tests with behavioural tests that assert
lattice **properties** (proptest): partial-order laws, `zoom` soundness +
completeness, SCC-condensation acyclicity.
* Benches: criterion over ingest / build / zoom on fixture repos (baseline).
* Strict-but-passable CI: keep the `standards` reusable wrappers; add an
AffineScript compile gate for the `.affine` core (CI is the verification
surface — there is no AffineScript toolchain in the web sandbox); keep
governance/scorecard/secret-scanner green. Gate on real failures only.

== Status ledger

* PR #23 (docs/metadata de-template + 6a2 + PROOF-NEEDS + CI hardening): **merged**.
* This plan: the agreed next-steps record. Migration code: **not started**
(blocked on Deliverable 1).
* Cross-refs: `META.a2ml` ADR-001/ADR-006; `STATE.a2ml` critical-next-actions;
`PROOF-NEEDS.md`; `NEUROSYM.a2ml` (the four-layer stack this realises).
Loading