Skip to content

Commit e5b9394

Browse files
docs: bindings + stdlib + alib roadmaps (3 satellites) (#410)
## Summary Adds three satellite roadmap documents under `docs/`, cross-linked from the main `ROADMAP.adoc`: | Doc | Items | Tiers / Tracks | |---|---|---| | `docs/bindings-roadmap.adoc` | 50 | 5 tiers — idaptik blockers → estate → web universals → backend/cloud → tooling | | `docs/stdlib-roadmap.adoc` | 50 | 5 tiers — runtime gaps → RSR rewires → universals → concurrency → conformance | | `docs/alib-roadmap.adoc` | 25 | 3 tracks — T1 conformance impl, T2 runner/CI, T3 affine-aware contributions back upstream | Main `ROADMAP.adoc` gets a new `== Satellite roadmaps` section near the top and three new `See Also` entries. ## Why three satellites Each surface has a different cadence and different consumers: - *Bindings* track host-runtime FFI needs (consumer-driven: idaptik / estate apps). - *Stdlib* tracks `.affine` files in `stdlib/` (compiler-driven: type-system + interp + codegen). - *aLib* tracks conformance vs the `hyperpolymath/aggregate-library` methods repo + spec extensions we contribute back. Bundling these into the main ROADMAP would crowd compiler-progress reporting; splitting into satellites lets each evolve independently with stable item numbers. ## Source / context Compiled 2026-05-28 during planning after the idaptik PR #107 (ReScript → AffineScript pilot, 9 `.res` → 1 `.affine`). That pilot surfaced ~10 concrete stdlib runtime gaps (now Tier 1 of `stdlib-roadmap.adoc`) and ~10 binding-package needs (now Tier 1 of `bindings-roadmap.adoc`). `alib-roadmap.adoc` is informed by a fresh read of `hyperpolymath/aggregate-library` v0.1.0 (20 ops × 6 categories) — including the schema-extension opportunities AffineScript's affine + effect surface suggests (T3 items). ## Out of scope this PR - Implementing any roadmap item. - Opening the umbrella tracker + per-tier child issues — separate PR(s). - Cross-repo PRs to `hyperpolymath/aggregate-library` (T3 items). - `CAPABILITY-MATRIX.adoc` row updates — that's a follow-up alongside each implementation PR. ## Test plan - [ ] AsciiDoc renders cleanly on the docs site (Casket SSG). - [ ] All four `link:` references resolve (bindings-roadmap ↔ stdlib-roadmap ↔ alib-roadmap ↔ ROADMAP). - [ ] No `docs/*.md` files added (DOC-FORMAT rule). - [ ] No "Closes #N" collision (DOC-DEDUP rule). - [ ] Each satellite carries `SPDX-License-Identifier: MPL-2.0`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d39e9b1 commit e5b9394

4 files changed

Lines changed: 1318 additions & 0 deletions

File tree

docs/ROADMAP.adoc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,34 @@ currently flagged stale (DOC-05, issue #176).
2424

2525
toc::[]
2626

27+
== Satellite roadmaps
28+
29+
This main ROADMAP focuses on *compiler / language* progress. Three
30+
satellite roadmaps split out adjacent surfaces so each can evolve at
31+
its own cadence without crowding this document.
32+
33+
[cols="1,3,3"]
34+
|===
35+
|Scope |Doc |Shape
36+
37+
|*Framework bindings* (host-runtime FFI surfaces — Pixi, DOM, Tauri, GitHub, etc.)
38+
|link:bindings-roadmap.adoc[bindings-roadmap.adoc]
39+
|50 items / 5 tiers, idaptik → estate → universal
40+
41+
|*Standard library* (the `.affine` files in `stdlib/`)
42+
|link:stdlib-roadmap.adoc[stdlib-roadmap.adoc]
43+
|50 items / 5 tiers, runtime gaps → RSR rewires → universals
44+
45+
|*aLib conformance & contributions* (`hyperpolymath/aggregate-library` methods)
46+
|link:alib-roadmap.adoc[alib-roadmap.adoc]
47+
|25 items / 3 tracks, implementation → runner/CI → upstream affine extensions
48+
|===
49+
50+
The three satellites + this main ROADMAP + link:ECOSYSTEM.adoc[ECOSYSTEM.adoc]
51+
+ link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] +
52+
link:TECH-DEBT.adoc[TECH-DEBT.adoc] together cover the full surface;
53+
where any two disagree, CAPABILITY-MATRIX wins.
54+
2755
== Current Status (January 2026 Baseline)
2856

2957
**Overall Completion (historical baseline): 85%**
@@ -326,4 +354,7 @@ SPDX-License-Identifier: MPL-2.0
326354
* link:README.adoc[Project Overview]
327355
* link:affinescript-spec.md[Language Specification]
328356
* link:STATE.scm[Current Project State]
357+
* link:bindings-roadmap.adoc[Framework Bindings Roadmap] — host-runtime FFI surfaces
358+
* link:stdlib-roadmap.adoc[Standard Library Roadmap] — `stdlib/` items
359+
* link:alib-roadmap.adoc[aLib Conformance Roadmap] — aggregate-library methods
329360
# AffineScript v2 Grammar Phase 1

docs/alib-roadmap.adoc

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
= AffineScript ↔ aLib Conformance & Contribution Roadmap
2+
:toc: macro
3+
:toclevels: 3
4+
:icons: font
5+
6+
25 items across three tiers, structuring AffineScript's relationship
7+
with `hyperpolymath/aggregate-library` (aLib): conformance
8+
*implementation* (passing aLib's test vectors), conformance
9+
*infrastructure* (runner, reporting, CI), and *contributions* of
10+
affine-aware semantics back to aLib upstream.
11+
12+
[IMPORTANT]
13+
====
14+
This document complements link:ROADMAP.adoc[ROADMAP.adoc] (language /
15+
compiler progress), link:bindings-roadmap.adoc[bindings-roadmap.adoc]
16+
(framework bindings), and link:stdlib-roadmap.adoc[stdlib-roadmap.adoc]
17+
(standard library). Where this file disagrees with
18+
link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] or
19+
link:ECOSYSTEM.adoc[ECOSYSTEM.adoc], those documents win.
20+
21+
Compiled 2026-05-28 from a fresh read of
22+
link:https://github.com/hyperpolymath/aggregate-library[hyperpolymath/aggregate-library]
23+
v0.1.0 + estate-wide use of the aLib methodology.
24+
====
25+
26+
toc::[]
27+
28+
== What aLib is — and is not
29+
30+
`hyperpolymath/aggregate-library` is a *methods repository*, not a
31+
stdlib replacement. It demonstrates how to:
32+
33+
* identify a minimal overlap between systems with very different
34+
constraints,
35+
* express that overlap as a stable spec surface + semantics notes +
36+
conformance test suite,
37+
* enforce reversibility through disciplined boundaries and test
38+
vectors.
39+
40+
The current overlap is intentionally small — 20 operations across 6
41+
categories — chosen to *stress-test the method*, not to be a "shared
42+
stdlib".
43+
44+
[cols="1,3"]
45+
|===
46+
|Category |Operations
47+
48+
|arithmetic |add, subtract, multiply, divide, modulo, negate, absolute, max, min
49+
|comparison |(per `aggregate.json` — 1+ ops; coverage spec)
50+
|logical |(per `aggregate.json`)
51+
|string |concat, length, reverse, substring
52+
|collection |contains, empty, filter, fold, length, map
53+
|conditional |(per `aggregate.json`)
54+
|===
55+
56+
NOTE: Counts above are from `data/aggregate.json` v1.1.0 (generated
57+
2025-12-27, 20 total operations). When aLib publishes a new version,
58+
this table updates here in the same PR that bumps the consumed
59+
version.
60+
61+
== Reading guide
62+
63+
Each entry carries:
64+
65+
* *Status* — `○` nothing built, `◐` scaffold, `◑` partial, `●` usable.
66+
* *Track* — `T1` implementation, `T2` runner/infra, `T3` contributions.
67+
* *Rationale* — what the item delivers, and which downstream consumer
68+
benefits.
69+
70+
Item numbers are stable across revisions.
71+
72+
== Tier 1 — Conformance implementation
73+
74+
Implement the 20 operations in AffineScript such that aLib's test
75+
vectors pass. Most ops *already* exist in `stdlib/` partially; the
76+
work here is alignment with aLib's `signature_string`, semantics, and
77+
edge-case requirements.
78+
79+
[cols="1,3,1,2,5"]
80+
|===
81+
|# |Item |Status |Track |Rationale
82+
83+
|1
84+
|*Arithmetic-9 implementation* — `add`, `subtract`, `multiply`, `divide`, `modulo`, `negate`, `absolute`, `max`, `min` aligned with `specs/arithmetic/*.md`
85+
|`◑` partial
86+
|T1
87+
|`stdlib/math.affine` covers most; verify signatures match aLib + properties (commutative, associative, identity) hold.
88+
89+
|2
90+
|*Comparison ops* — `eq`, `ne`, `lt`, `le`, `gt`, `ge` per `specs/comparison/`
91+
|`◑` partial
92+
|T1
93+
|Trait surface; pairs with `traits.affine` (stdlib #18).
94+
95+
|3
96+
|*Logical ops* — `and`, `or`, `not`, `xor` per `specs/logical/`
97+
|`◑` partial
98+
|T1
99+
|Mostly built-in operators; conformance is verifying short-circuit + truth-table behaviour matches aLib semantics.
100+
101+
|4
102+
|*String-4 implementation* — `concat`, `length`, `reverse`, `substring` per `specs/string/*.md`
103+
|`◑` partial
104+
|T1
105+
|`stdlib/string.affine` exists; runtime gaps (stdlib roadmap #8, #9) are upstream blockers.
106+
107+
|5
108+
|*Collection-6 implementation* — `contains`, `empty`, `filter`, `fold`, `length`, `map` per `specs/collection/*.md`
109+
|`◑` partial
110+
|T1
111+
|`stdlib/collections.affine` exists; runtime gaps (stdlib roadmap #1, #2) are upstream blockers. Generic over list at minimum; ideally generic over `Foldable`.
112+
113+
|6
114+
|*Conditional op* — `if-then-else` as expression per `specs/conditional/`
115+
|`●` usable
116+
|T1
117+
|Language built-in; verify spec semantics match.
118+
119+
|7
120+
|*Edge-case coverage* — implement and test NaN, infinity, overflow, empty-string, empty-list edge cases per each op's `edge_cases` field
121+
|`○`
122+
|T1
123+
|aLib specs intentionally leave overflow / NaN "implementation-defined" but require *documented* behaviour. AffineScript declares its choice here.
124+
125+
|8
126+
|*Properties verification* — `add` is commutative, `multiply` is associative, `abs` is idempotent, etc.
127+
|`○`
128+
|T1
129+
|aLib `semantics.properties` is the contract; AffineScript proves (or property-tests) each.
130+
131+
|9
132+
|*Signature alignment audit* — every AffineScript op's signature matches the aLib `signature_string`
133+
|`○`
134+
|T1
135+
|Mechanical comparison; ensures cross-language portability of code written against the aLib surface.
136+
137+
|10
138+
|*Conformance module* — `stdlib/alib.affine` re-exporting the 20 ops under their aLib names
139+
|`○`
140+
|T1
141+
|Single import point for consumers wanting the *aLib surface* rather than the *AffineScript-idiomatic surface*.
142+
|===
143+
144+
== Tier 2 — Conformance runner & infrastructure
145+
146+
Build the machinery that *runs* aLib's test vectors against
147+
AffineScript implementations and reports results. This is what makes
148+
aLib's "method" actually testable for our language.
149+
150+
[cols="1,3,1,2,5"]
151+
|===
152+
|# |Item |Status |Track |Rationale
153+
154+
|11
155+
|*`aggregate.json` schema loader* — parse aLib's v1.1.0 schema in AffineScript (or via build tool)
156+
|`○`
157+
|T2
158+
|First step; feeds every later runner item.
159+
160+
|12
161+
|*Test-vector executor* — iterate `operations[].test_cases[]`, dispatch to the corresponding `alib.affine` op, compare output
162+
|`○`
163+
|T2
164+
|Core conformance loop.
165+
166+
|13
167+
|*Properties auto-checker* — for each declared property (e.g. commutative), run randomized inputs and assert
168+
|`○`
169+
|T2
170+
|Pairs with item #8; property-based testing under the hood.
171+
172+
|14
173+
|*Conformance report emitter* — JSON + a2ml output: per-op pass/fail, properties verified, edge cases covered
174+
|`○`
175+
|T2
176+
|Estate convention: a2ml machine-readable; JSON for human / CI.
177+
178+
|15
179+
|*CI workflow* — `.github/workflows/alib-conformance.yml` runs the suite on every PR, posts a status check
180+
|`○`
181+
|T2
182+
|Stops drift; visible signal.
183+
184+
|16
185+
|*Conformance badge* — README badge + `docs/CAPABILITY-MATRIX.adoc` row showing "aLib conformance: 18/20"
186+
|`○`
187+
|T2
188+
|Pairs with #15.
189+
190+
|17
191+
|*Multi-target harness* — run conformance against the native interp *and* the wasm codegen target, separately
192+
|`○`
193+
|T2
194+
|Verifies that "type-checks" and "executes" are both green at the aLib surface — directly mitigates the PR #107 class of issue (check PASS / eval FAIL).
195+
196+
|18
197+
|*Conformance-comparison view* — side-by-side AffineScript vs reference implementations (phronesis, Rust, Haskell) where available
198+
|`○`
199+
|T2
200+
|Pairs with `COMPOSITION-GUIDE.md` in aLib; useful for "did we break parity" diagnosis.
201+
|===
202+
203+
== Tier 3 — Contributions back to aLib upstream
204+
205+
AffineScript's distinctive properties (affine resource types,
206+
row-polymorphic effects, dependent types, reversibility) suggest spec
207+
extensions that aLib doesn't currently capture. These items propose
208+
*upstream PRs* to `hyperpolymath/aggregate-library`.
209+
210+
[cols="1,3,1,2,5"]
211+
|===
212+
|# |Item |Status |Track |Rationale
213+
214+
|19
215+
|*Affine-witness column* — `semantics.affine_consumes: [inputIndices]` in `aggregate.json` schema
216+
|`○`
217+
|T3
218+
|For each op, declare which inputs are *consumed* vs *borrowed*. Trivially `[]` for current ops (all pure), but the schema extension lands now so future op contributions can use it. Upstream PR to aLib repo.
219+
220+
|20
221+
|*Linearity / reversibility tagging* — `semantics.reversible: bool` + `semantics.inverse_op: string` (e.g. `subtract` is inverse of `add`)
222+
|`○`
223+
|T3
224+
|aLib already mentions "Reversibility" in its design principles but doesn't formalise per-op. Upstream PR; idaptik DLC use case is the motivating consumer.
225+
226+
|21
227+
|*Effect-row metadata* — `semantics.effect_row: [labels]` (`Net`, `Fs`, `Random`, `Time`, `IO`)
228+
|`○`
229+
|T3
230+
|All current 20 ops are pure (`[]`); extension lands the schema field for future capability-aware contributions. Pairs with stdlib roadmap #42, #43.
231+
232+
|22
233+
|*Idempotency property* — formalise `semantics.properties[Idempotent]` (`abs(abs(x)) = abs(x)`)
234+
|`○`
235+
|T3
236+
|aLib semantics.properties has `Commutative`, `Associative`, `Identity element`; idempotency is missing. Upstream PR.
237+
238+
|23
239+
|*Monotonicity property* — `semantics.properties[Monotonic]` for `max` / `min` / `length` / `absolute`
240+
|`○`
241+
|T3
242+
|Same family as #22; missing property class.
243+
244+
|24
245+
|*Affine-friendly op proposals* — propose `take` / `drop` / `split` / `join` as collection ops that consume their input (affine-friendly)
246+
|`○`
247+
|T3
248+
|Current `filter` / `map` / `fold` are all *borrow* shapes; AffineScript's affine surface would benefit from explicit-consume variants. Upstream proposal.
249+
250+
|25
251+
|*ADR for affine extension* — single ADR in aLib documenting the schema extensions in #19/#20/#21/#22/#23 + the rationale
252+
|`○`
253+
|T3
254+
|Bundle the schema-extension items into one upstream PR with proper rationale, so aLib maintainers can review the *whole shape* rather than five disconnected fields.
255+
|===
256+
257+
== Cross-cutting observations
258+
259+
. *aLib is small by design.* 20 ops is the entire surface today. The
260+
conformance work (T1 + T2) is therefore *bounded* — completable in
261+
a handful of PRs, not a multi-quarter epic.
262+
. *T3 contributions are the higher-leverage half.* AffineScript's
263+
affine + effect + dependent type system suggests spec features aLib
264+
doesn't yet have. Contributing the *method extensions* upstream is
265+
where AffineScript adds value back, not just consumes.
266+
. *T1 items #4 and #5 are upstream-blocked* on stdlib roadmap #1, #2,
267+
#8, #9 (runtime gaps for `List.++`, `List.len`, `String.concat`,
268+
`String.length`). Don't try to do T1 collection/string conformance
269+
before those runtime gaps close.
270+
. *Multi-target harness (T2 #17) is the antidote to the
271+
PR #107 problem.* Currently `affinescript check` and `affinescript
272+
eval` can diverge; running conformance against *both* targets
273+
catches the gap automatically.
274+
. *aLib license is `MIT OR Palimpsest-0.8`*; AffineScript is MPL-2.0.
275+
Contributions upstream are spec-level (no code transfer); no
276+
license-compat issue.
277+
278+
== Suggested sequencing
279+
280+
[cols="1,2,5"]
281+
|===
282+
|Phase |Goal |Items
283+
284+
|*A*
285+
|Conformance scaffolding
286+
|#10 (`alib.affine` module) → #11 (schema loader) → #12 (test-vector executor)
287+
288+
|*B*
289+
|Pure ops first
290+
|#1 (arithmetic-9) → #6 (conditional) → #2 (comparison) → #3 (logical) — these don't need runtime list/string fixes
291+
292+
|*C*
293+
|Collection + string ops
294+
|*Gated on stdlib roadmap A* (List/String runtime). Then #4 + #5 + #7 + #8 + #9.
295+
296+
|*D*
297+
|CI + visibility
298+
|#15 (workflow) → #16 (badge) → #17 (multi-target) → #14 (reports) → #18 (comparison view)
299+
300+
|*E*
301+
|Upstream contributions
302+
|#25 (ADR draft) → #19/#20/#21/#22/#23 as one upstream PR → #24 (affine-op proposals as a follow-up)
303+
|===
304+
305+
== Tracking
306+
307+
* Umbrella tracker: (TBD — opened alongside this PR)
308+
* Per-tier child issues: (TBD — opened alongside this PR)
309+
* Upstream tracking: `hyperpolymath/aggregate-library` (T3 items
310+
result in PRs there, not in this repo)
311+
312+
When an item's status changes, update its row in this file in the
313+
*same* PR that lands the change; do not let the table drift.
314+
315+
== See also
316+
317+
* link:ROADMAP.adoc[ROADMAP.adoc] — language / compiler progress.
318+
* link:bindings-roadmap.adoc[bindings-roadmap.adoc] — framework
319+
bindings (host-runtime FFI surfaces).
320+
* link:stdlib-roadmap.adoc[stdlib-roadmap.adoc] — standard library
321+
items (runtime, RSR rewires, universals).
322+
* link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] — per-feature
323+
readiness (overrides everything).
324+
* link:https://github.com/hyperpolymath/aggregate-library[aggregate-library]
325+
— upstream methodology repo.
326+
* link:https://github.com/hyperpolymath/aggregate-library/blob/main/COMPOSITION-GUIDE.md[aLib COMPOSITION-GUIDE]
327+
— the method of aggregation across phronesis/Rust/Haskell.
328+
329+
== License
330+
331+
SPDX-License-Identifier: MPL-2.0

0 commit comments

Comments
 (0)