Skip to content

Commit 78d7ec7

Browse files
docs: authoritative ledger — CAPABILITY-MATRIX/ECOSYSTEM/TECH-DEBT (Refs #175 #176) (#239)
* docs: authoritative ledger — CAPABILITY-MATRIX/ECOSYSTEM/TECH-DEBT (Refs #175 #176) The "first PR" #175 claims landed (docs/CAPABILITY-MATRIX.adoc, docs/ECOSYSTEM.adoc, docs/TECH-DEBT.adoc) never existed in git history; every sub-issue (#176-183, #228, #177) cites docs/TECH-DEBT.adoc as its coordination index. This materialises that ledger authoritatively, reconstructed 2026-05-19 from the issues + the compiler-as-oracle audit + the hyperpolymath/typed-wasm LEVEL-STATUS (v1.5). - docs/CAPABILITY-MATRIX.adoc: single authoritative readiness source (overrides README/BACKEND-IMPLEMENTATION/COMPILER-CAPABILITIES/ ALPHA-1-RELEASE-NOTES/STATE.a2ml). Truthed: alpha; CORE-01 borrow soundness gap named; backend breadth real but uneven; typed-wasm is a separate language-agnostic target, AffineScript is one producer. - docs/ECOSYSTEM.adoc: the implementation spine + the macro-stage spine (Stage A–E definitions, established here — never committed before), the actual AS↔typed-wasm contract (narrow: L7+L10 on emitted wasm; affinescript.ownership section; multi-producer w/ ephapax), the truthed satellite registry, and the INT-01..12 integration roadmap. - docs/TECH-DEBT.adoc: the coordination ledger (DOC/CORE/STDLIB/INT/SAT), critical path, update protocol. DOC-01/02/03/07 done here. - Authoritative banners: README.adoc, BACKEND-IMPLEMENTATION.md, COMPILER-CAPABILITIES.md, ALPHA-1-RELEASE-NOTES.md (DOC-04). - STATE.a2ml drift-flagged (DOC-05); ROADMAP.adoc cross-links (DOC-06). Docs-only; gate unaffected (dune runtest --force = 260/260, 2026-05-19). Front-loaded ahead of CORE-01 (#177) so that work unit cites a real ledger. Refs #175 #176 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: truth CORE-01 part 1 (PR #240) in the ledger (Refs #175 #176 #177) CORE-01 borrow-graph validation part 1 landed via PR #240. Keep the authoritative docs in lockstep (DOC-01..09 / #176 — "docs current as you go"): - CAPABILITY-MATRIX.adoc borrow row: graph validation landed; remaining NLL/flow-sensitive deferred to part 2+. - TECH-DEBT.adoc CORE-01: part 1 LANDED (PR #240); part 2+ scoped. - STATE.a2ml borrow-checker feature line updated (it mirrors). Each file stays single-owner: the compiler change is PR #240 off main; these doc/ledger files are owned by this branch (#239). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: truth CORE-03 / ADR-014 grammar landed (PR #241) (Refs #175 #176 #228) Module-qualified type/effect paths landed via PR #241 (zero Menhir conflict delta, gate 267/267). Keep the authoritative docs in lockstep: - TECH-DEBT.adoc CORE-03: grammar LANDED (PR #241), supersedes #231; estate re-audit + #229 follow. - CAPABILITY-MATRIX.adoc parser row: qualified paths now parse; dominant estate parse blocker cleared. - STATE.a2ml parser feature line updated (it mirrors). ADR-014 itself is recorded in META.a2ml + SETTLED-DECISIONS.adoc on the #241 branch (those ADR registries are owned by the implementation PR; these ledger/status docs are owned by #239 — single-owner discipline). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: hyperpolymath <hyperpolymath@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent dc5b817 commit 78d7ec7

9 files changed

Lines changed: 618 additions & 7 deletions

File tree

.machine_readable/6a2/STATE.a2ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ project = "affinescript"
66
version = "0.1.0"
77
last-updated = "2026-05-03"
88
status = "active"
9+
authoritative-status-doc = "docs/CAPABILITY-MATRIX.adoc"
10+
drift-flag = "STALE as of 2026-05-19: this file's [components]/[features]/[project-context] predate origin/main@dc5b817. It MIRRORS, it does not LEAD. For live readiness use docs/CAPABILITY-MATRIX.adoc; for the spine/contract/ledger use docs/ECOSYSTEM.adoc + docs/TECH-DEBT.adoc (DOC-05, issue #176). Gate baseline now 260/260, not 257."
911
session-note-2026-05-03-c = "EXTERN/VSCODE/ARRAY/PATCON BATCH. (1) `extern fn name(...) -> Ret;` and `extern type Name;` now parse — added EXTERN keyword to lexer/token/parse_driver, FnExtern to fn_body and TyExtern to type_body in AST, extern_fn_decl + extern_type_decl rules in parser.mly. Resolve registers the symbol; Typecheck.check_fn_decl special-cases FnExtern to register the polymorphic scheme without body checking; Codegen.gen_decl emits a real `(import \"env\" \"<name>\" (func ...))` for each extern fn, mirroring gen_imports's cross-module shape. Borrow + Quantity skip extern fns. lib/dune now demotes warning 8/9 from error to warning so the new variants don't require lock-step updates across all 27 codegens (any non-Wasm codegen that doesn't handle FnExtern raises Match_failure with file:line at runtime — correct signal for 'this target has no story for host-supplied implementations'). 192 tests; 0 regressions. (2) Issue #35 Phase 2: stdlib/Vscode.affine and stdlib/VscodeLanguageClient.affine ship the ~12 + 3 binding declarations from the issue's API inventory (registerCommand, getConfiguration, showInformationMessage, createTerminal, ...). packages/affine-vscode/mod.js is the JS-side adapter that translates each `extern fn` invocation into the corresponding vscode/lc API call, with a JS-side handle table for opaque host objects and a string-marshal helper that reads `[u32 length][utf-8 bytes]` out of the wasm memory. Adapter returns a namespaced object `{ Vscode: {...}, VscodeLanguageClient: {...} }` matching the WASM cross-module imports' module names. examples/vscode_extension_minimal.affine demonstrates an end-to-end VS Code extension authored in AffineScript using `use Vscode::{registerCommand, showInformationMessage, pushSubscription}` — compiles to .cjs via the Node-CJS path. (3) issues-drafts/02 closed: `[T]` array type now parses via `LBRACKET type_expr RBRACKET → TyApp (Array, [TyArg elem])` in lib/parser.mly's type_expr_primary rule. Verified for fn params, return types, struct fields, and nested `[[T]]`. Other stdlib files (Option/math/io/string) still fail with distinct issues (`fn() -> T` type syntax, `Option<T>` angle brackets) — the array fix advanced math.affine's failure point from line 349 to 354 etc. (4) PatCon sub-pattern destructuring under WasmGC: `match Mk(7, 99) { Mk(a, b) => a }` now lowers to RefCast + StructGet for the tag check + per-field RefCast HtI31 + I31GetS unboxing for each PatVar sub-pattern. Validated end-to-end: emitted .wasm instantiates in Deno and `main()` returns 7. The mixed-arity case (zero-arg + with-args in same enum, e.g. Option) errors loudly with the workaround documented (split into two matches, or use Wasm 1.0). Unifying variant rep — uniform `struct {tag, payload}` so Some+None can share — is the next destructuring milestone. 195 → 198 → 200 tests; 0 regressions throughout."
1012
session-note-2026-05-03-b = "FOLLOW-ON BATCH AFTER TYPED-WASM CLOSURE: variant-with-args under WasmGC, Node-target codegen Phase 1 (issue #35), stdlib Core.affine fix, cross-module for other codegens. (1) lib/codegen_gc.ml — added gen_variant_with_args helper that lowers ExprApp(ExprVariant(_), args) and bare-name `Some(42)` (via variant_tags lookup in ExprApp ExprVar) to a tagged anon-struct allocation [tag: i32, payload: anyref, ...] with i32 args boxed via ref.i31. ExprVar gained variant_tags fallback so `return Happy` works. gen_gc_function now post-processes body_code: when result_vt ≠ I32 the trailing `push_i32 0` fallback (emitted by gen_gc_block when blk_expr=None) is swapped for RefNull HtAny, which fixes 'end[0] expected type anyref, found i32' validator errors on functions that explicitly return a struct. Validated: emitted .wasm instantiates in Node 18 / V8 14, main() returns the GC struct. f64 args remain UnsupportedFeature (no i31 boxing path). (2) lib/codegen_node.ml — new module implementing issue #35 Phase 1 (Node-CJS emit). Wraps Codegen.generate_module output in a CJS shim with: inline base64-encoded wasm constant, lazy WebAssembly.instantiate on first activate/deactivate call, JS-side opaque-handle table (_registerHandle / _getHandle / _freeHandle exported for Phase 2 vscode bindings), minimal WASI fd_write so println-style codegen works, exports.activate/exports.deactivate re-exports of the wasm module's same-named exports. .cjs output extension dispatches in bin/main.ml (both JSON and non-JSON paths). Smoke-tested: real Node 18 require()s a generated .cjs and successfully calls activate(fakeContext) → 0, deactivate() → 0. Issue #35 Phases 2-4 (stdlib/Vscode.affine bindings, extension.ts → extension.affine migration, rattlescript-face sweep) remain as separate work. (3) stdlib/Core.affine — three parser-collision fixes: `pub fn const[A,B]` → `always` (const is a reserved keyword for compile-time bindings); `fn(x: A) -> C { ... }` lambdas → `|x: A|` form (the parser's actual lambda syntax); `flip` rewritten from `(A, B) -> C` to curried `A -> B -> C` to dodge tuple-arrow ambiguity. The originally-blocked tests/modules/test_simple_import.affine (use Core::{min}; min(10,20)) now compiles end-to-end. Other stdlib files (Option/math/io/string/...) still don't parse — each has distinct issues (fn() type syntax, `[T]` array type per issues-drafts/02, `Option<T>` angle brackets) that need their own passes or compiler-level fixes. (4) lib/module_loader.ml — new flatten_imports : t -> program -> program that prepends imported public TopFns into the importer's prog_decls (deduplicating against local fn names). bin/main.ml now binds [let flat_prog = Module_loader.flatten_imports loader prog in] in both compile_file paths and threads flat_prog through all 22 non-Wasm codegens (Julia, JS, C, WGSL, Faust, ONNX, OCaml, Lua, Bash, Nickel, ReScript, Rust, LLVM, Verilog, Gleam, CUDA, Metal, OpenCL, MLIR, Why3, Lean, SPIR-V) — Wasm and Wasm-GC keep the original prog because Codegen.gen_imports handles their cross-module needs natively. Smoke-tested: caller_ok.affine (use CrossCallee::{consume}) now compiles to JS / Julia / Rust / Lua with consume's body inlined. The non-JSON compile_file path also gained ~loader on its previously-loaderless Codegen.generate_module call (latent bug for cross-module wasm via this path). 188 → 190 tests; 0 regressions."
1113
session-note-2026-05-03 = "TYPED-WASM CROSS-MODULE CLOSURE + MCP CARTRIDGE REWIRE + WASMGC LOUD-FAIL HARDENING. (1) lib/codegen.ml — generate_module gained ?loader and a new gen_imports pass that walks prog.prog_imports, loads each referenced module via Module_loader, and emits one (import \"<modpath>\" \"<fn>\" (func ...)) entry per imported function plus a (local_alias_name → import_func_idx) entry in func_indices. ImportSimple is namespace-only (no emit), ImportList emits per item, ImportGlob enumerates public TopFns. Closes the cross-module WASM import emission gap called out in session-note-2026-04-19-a — `verify-boundary CALLEE.affine CALLER.affine` now works on user-authored AffineScript pairs, not just hand-assembled bridges. (2) lib/resolve.ml — import_resolved_symbols / import_specific_items / ImportGlob inline path now also write to dest type_ctx.name_types (not just var_types), with a new lookup_source_scheme helper that falls back from sym_id-keyed source_types to name-keyed source_name_types because resolve_and_typecheck_module's per-decl Typecheck.check_decl populates name_types but never var_types. lib/typecheck.ml — Typecheck.check_program gained ?import_types : (string, scheme) Hashtbl.t that seeds name_types after register_builtins, supplied by the resolver. bin/main.ml compile_file (JSON + non-JSON paths), compile_to_wasm_module, verify_file all updated to thread import_type_ctx.name_types through and pass ~loader to Codegen.generate_module. (3) test/e2e/fixtures/ — CrossCallee.affine + cross_caller_{ok,dup,drop}.affine, plus 3 new alcotest cases under E2E Boundary Verify exercising the full pipeline (parse → resolve_with_loader → typecheck-with-import-types → codegen-with-loader → Tw_interface.verify_cross_module). All three boundary outcomes (clean / LinearImportCalledMultiple / LinearImportDroppedOnSomePath) confirmed end-to-end. (4) boj-server/cartridges/typed-wasm-mcp — mod.js rewritten to call `affinescript` (was: nonexistent `typed-wasm` binary), with cwd set to the source's directory so Module_loader resolves relative imports correctly. cartridge.json bumped to v0.2.0 with corrected input descriptions (.affine source paths) and a new typed_wasm_verify_boundary tool exposing the cross-module verifier. README.adoc updated to match. (5) lib/codegen_gc.ml — eliminated three silent-bad-codegen fallbacks (same class as BUG-005): wildcard ExprLambda/ExprUnsafe → RefNull replaced with explicit UnsupportedFeature errors; match-arm wildcard PatTuple/PatRecord → fall-to-default replaced with UnsupportedFeature; PatLit fallback for LitFloat/LitString replaced with explicit errors. test/test_e2e.ml gained E2E WasmGC Loud-Fail suite with 2 regression markers. Bumps wasm-gc-codegen from 70% to 85% (silent-fallback gap is gone; effects/try-catch/lambda/call_ref remain genuinely deferred to upstream EH proposal or whole-program CPS). 180 → 182 tests; 0 regressions."
@@ -31,7 +33,7 @@ note = "Session 2026-04-11 final checkpoint. DONE THIS SESSION: (1) JS-face (lib
3133

3234
[components]
3335
lexer = "complete-minus-affine-tokens (ZERO/ONE tokens for quantity literals NOT emitted; blocks QTT surface syntax). float_exponent now correctly named sub-regexp — scientific notation crash fixed 2026-04-11."
34-
parser = "conformance-complete (ADR-009 achieved 2026-04-11). 12/12 valid tests parse. Added: optional SEMICOLON on type aliases/enums, enum leading-pipe syntax, effect op type params, ROW_VAR type params, ty_record_body/expr_record_body recursive rules for row-polymorphic records, field_name contextual keyword rule, struct literal expressions."
36+
parser = "conformance-complete (ADR-009 achieved 2026-04-11). 12/12 valid tests parse. Added: optional SEMICOLON on type aliases/enums, enum leading-pipe syntax, effect op type params, ROW_VAR type params, ty_record_body/expr_record_body recursive rules for row-polymorphic records, field_name contextual keyword rule, struct literal expressions. CORE-03 / ADR-014 (PR #241, Refs #228, 2026-05-19, gate 267/267, ZERO Menhir conflict delta — 21 S/R + 1 R/R unchanged): module-qualified type/effect paths Pkg.Type / Pkg::Type (mixed, deep) parse — folded to one canonical ::-joined ident so resolve/typecheck/codegen/fmt unchanged. Cleared the estate's dominant parse blocker (was 525/1177). Authoritative: docs/CAPABILITY-MATRIX.adoc + docs/TECH-DEBT.adoc CORE-03."
3537
type-checker-rules = "99% (bidirectional inference, Never/bottom, block divergence, variant/constructor/record-spread/mutable bindings all implemented in lib/typecheck.ml)"
3638
type-checker-enforcement-wiring = "wired (Typecheck.check_program is invoked from bin/main.ml on every check/compile/eval path; Quantity.check_program_quantities runs after typecheck at lib/typecheck.ml:1206; the gating IS live for the rules and quantity annotations that exist today)"
3739
borrow-checker = "live-gate (2026-04-11): Borrow.check_program wired into check/compile pipeline at all 4 Typecheck success sites. Emits E0501-E0506 diagnostics. PlaceVar carries variable name for readable errors (file:line:col at both use and move sites). ExprMatch arm state merging fixed. Lexical borrow lifetime clearing in check_block. BUG-004 (lambda capture tracking) still deferred — requires type info propagation. lib/borrow.ml 669 LOC."
@@ -64,7 +66,7 @@ test-files = 54
6466
# the feature is not enforced on user programs through the CLI pipeline.
6567
affine-types = "wired-and-reachable (Track A Manhattan plan complete 2026-04-10. Quantity semiring in lib/quantity.ml; invoked from typecheck.ml:1206 inside the standard CLI pipeline. Surface syntax per ADR-007 hybrid: @linear/@erased/@unrestricted attributes (Option C primary) on let/stmt-let/param/lambda-param, AND :1/:0/:ω numeric sugar (Option B) on let/stmt-let. Scaled Let rule per ADR-002 implemented in lib/quantity.ml ExprLet/StmtLet — closes BUG-001 (ω-let smuggles linear values) and BUG-002 (zero-let erasure). Four regression fixtures in test/e2e/fixtures/ exercise both surface forms. Behavioural enforcement verified via E2E Quantity test suite — 4 new passing tests, 0 regressions.)"
6668
linear-arrows = "enforced (2026-04-11): Three-part fix landed. (1) typecheck.ml lambda synth: |@linear x: T| e now synthesises T -[1]-> U (was always QOmega). (2) typecheck.ml lambda check mode: explicit param quantity annotation validated against expected TArrow quantity; unannotated params inherit context quantity. (3) quantity.ml ExprLambda: added env.errors accumulator; annotated lambda params declared via env_declare so env_use tracks them; usage verified with check_quantity after body walk; violations pushed to env.errors and drained at end of check_function_quantities (step 4). Saved/restored env.quantities entries to prevent scope leakage. Two E2E fixtures + 2 passing tests. 75 tests total, 0 regressions. Commit d2f9b7b pushed."
67-
borrow-checker = "phase-3-in-progress (see lib/borrow.ml [IMPL-DEP: Phase 3])"
69+
borrow-checker = "phase-3-part-1-landed (CORE-01, PR #240 Refs #177, 2026-05-19, gate 263/263): borrow-graph validation wired — BorrowOutlivesOwner emitted (&local escaping its block), shared-XOR-exclusive enforced at use sites (UseWhileExclusivelyBorrowed), ownership derived from param type TyOwn/TyRef/TyMut (owned/ref/mut discipline now enforced from real parsed source — closed a latent hole), call-arg borrows temporary, ref-binding graph tracked. Part 2+ deferred: NLL/region inference, flow-sensitive escape via `outer = &x`, tighter quantity integration. Authoritative: docs/CAPABILITY-MATRIX.adoc + docs/TECH-DEBT.adoc CORE-01."
6870
row-polymorphism = "60% (records + effects rows implemented in typecheck/unify; not fully exercised end-to-end)"
6971
effects = "interpreter-complete (handler dispatch, PerformEffect propagation, ExprResume, multi-arg ops all wired in interp.ml 2026-04-11). WasmGC: ops registered as unreachable stubs; ExprHandle/ExprResume reject with UnsupportedFeature — full WASM dispatch needs EH proposal or CPS transform."
7072
dependent-types = "parse-only (TRefined AST node exists and refinement predicates parse, but predicates do not reduce; no SMT/decision procedure wired in)"

ALPHA-1-RELEASE-NOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# AffineScript Alpha-1 Release Notes
22

3+
> **⚠️ AUTHORITATIVE STATUS:** Historical release notes. Current readiness is
4+
> [`docs/CAPABILITY-MATRIX.adoc`](docs/CAPABILITY-MATRIX.adoc) (overrides this
5+
> file). AffineScript remains alpha with a known soundness gap (CORE-01 /
6+
> issue #177).
7+
38
## 🎮 Game Developer's Edition
49

510
**Release Date:** March 31, 2026

BACKEND-IMPLEMENTATION.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# AffineScript Backend Implementation
22

3+
> **⚠️ AUTHORITATIVE STATUS:** Backend maturity is uneven and is defined by
4+
> [`docs/CAPABILITY-MATRIX.adoc`](docs/CAPABILITY-MATRIX.adoc), which overrides
5+
> this document. "Complete backends" below means *code-generators exist*, not
6+
> *production-ready*. One reference target (WASM); Deno-ESM/Node-CJS solid;
7+
> the rest experimental. Do not cite a backend count.
8+
39
## 🎯 Overview
410

511
**Complete processor backends with kernel stubs** have been implemented for AffineScript.

COMPILER-CAPABILITIES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# AffineScript Compiler Capabilities Analysis
22

3+
> **⚠️ AUTHORITATIVE STATUS:** Superseded by
4+
> [`docs/CAPABILITY-MATRIX.adoc`](docs/CAPABILITY-MATRIX.adoc) for all
5+
> feature-readiness claims. This file is retained as analysis history; where
6+
> it disagrees with the matrix, the matrix wins.
7+
38
## 🎯 Current Compiler Targets
49

510
### Primary Target: WebAssembly

README.adoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@
55
:source-highlighter: rouge
66
:icons: font
77

8+
[IMPORTANT]
9+
====
10+
*Authoritative status lives in link:docs/CAPABILITY-MATRIX.adoc[docs/CAPABILITY-MATRIX.adoc].*
11+
Where this README's prose implies broader maturity than that matrix states,
12+
the matrix wins. AffineScript is *alpha* with one known base-language
13+
soundness gap (CORE-01 / issue #177). typed-wasm is a *separate*
14+
language-agnostic target (`hyperpolymath/typed-wasm`), not an AffineScript
15+
subsystem — see link:docs/ECOSYSTEM.adoc[docs/ECOSYSTEM.adoc].
16+
====
17+
818
License: PMPL-1.0-or-later +
919
Built alongside Gossamer, typed-wasm, and Burble
1020

ROADMAP.adoc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@ Historical development plan from the January 2026 baseline.
88

99
[IMPORTANT]
1010
====
11-
Status sync note (2026-04-12): This file contains historical planning text and
12-
is not the authoritative source for current feature readiness. Use
13-
`.machine_readable/6a2/STATE.a2ml` for live status (including affine/QTT
14-
wiring, borrow-checker gating, effect handling status, row polymorphism, and
15-
dependent/refinement progress).
11+
Status sync note (updated 2026-05-19): This file is historical planning text
12+
and is *not* authoritative for feature readiness. Authoritative sources, in
13+
order:
14+
15+
* `docs/CAPABILITY-MATRIX.adoc` — per-feature readiness (overrides everything).
16+
* `docs/ECOSYSTEM.adoc` — the spine, the Stage A–E definitions, the real
17+
AffineScript↔typed-wasm contract, the satellite registry, and the
18+
*Ecosystem Integration Track* INT-01..12.
19+
* `docs/TECH-DEBT.adoc` — the coordination ledger (DOC/CORE/STDLIB/INT/SAT).
20+
21+
`.machine_readable/6a2/STATE.a2ml` mirrors these; it does not lead, and is
22+
currently flagged stale (DOC-05, issue #176).
1623
====
1724

1825
toc::[]

0 commit comments

Comments
 (0)