diff --git a/docs/ROADMAP.adoc b/docs/ROADMAP.adoc index 6a742576..4b922afc 100644 --- a/docs/ROADMAP.adoc +++ b/docs/ROADMAP.adoc @@ -24,6 +24,34 @@ currently flagged stale (DOC-05, issue #176). toc::[] +== Satellite roadmaps + +This main ROADMAP focuses on *compiler / language* progress. Three +satellite roadmaps split out adjacent surfaces so each can evolve at +its own cadence without crowding this document. + +[cols="1,3,3"] +|=== +|Scope |Doc |Shape + +|*Framework bindings* (host-runtime FFI surfaces — Pixi, DOM, Tauri, GitHub, etc.) +|link:bindings-roadmap.adoc[bindings-roadmap.adoc] +|50 items / 5 tiers, idaptik → estate → universal + +|*Standard library* (the `.affine` files in `stdlib/`) +|link:stdlib-roadmap.adoc[stdlib-roadmap.adoc] +|50 items / 5 tiers, runtime gaps → RSR rewires → universals + +|*aLib conformance & contributions* (`hyperpolymath/aggregate-library` methods) +|link:alib-roadmap.adoc[alib-roadmap.adoc] +|25 items / 3 tracks, implementation → runner/CI → upstream affine extensions +|=== + +The three satellites + this main ROADMAP + link:ECOSYSTEM.adoc[ECOSYSTEM.adoc] ++ link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] + +link:TECH-DEBT.adoc[TECH-DEBT.adoc] together cover the full surface; +where any two disagree, CAPABILITY-MATRIX wins. + == Current Status (January 2026 Baseline) **Overall Completion (historical baseline): 85%** @@ -326,4 +354,7 @@ SPDX-License-Identifier: MPL-2.0 * link:README.adoc[Project Overview] * link:affinescript-spec.md[Language Specification] * link:STATE.scm[Current Project State] +* link:bindings-roadmap.adoc[Framework Bindings Roadmap] — host-runtime FFI surfaces +* link:stdlib-roadmap.adoc[Standard Library Roadmap] — `stdlib/` items +* link:alib-roadmap.adoc[aLib Conformance Roadmap] — aggregate-library methods # AffineScript v2 Grammar Phase 1 diff --git a/docs/alib-roadmap.adoc b/docs/alib-roadmap.adoc new file mode 100644 index 00000000..6c49d09c --- /dev/null +++ b/docs/alib-roadmap.adoc @@ -0,0 +1,331 @@ += AffineScript ↔ aLib Conformance & Contribution Roadmap +:toc: macro +:toclevels: 3 +:icons: font + +25 items across three tiers, structuring AffineScript's relationship +with `hyperpolymath/aggregate-library` (aLib): conformance +*implementation* (passing aLib's test vectors), conformance +*infrastructure* (runner, reporting, CI), and *contributions* of +affine-aware semantics back to aLib upstream. + +[IMPORTANT] +==== +This document complements link:ROADMAP.adoc[ROADMAP.adoc] (language / +compiler progress), link:bindings-roadmap.adoc[bindings-roadmap.adoc] +(framework bindings), and link:stdlib-roadmap.adoc[stdlib-roadmap.adoc] +(standard library). Where this file disagrees with +link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] or +link:ECOSYSTEM.adoc[ECOSYSTEM.adoc], those documents win. + +Compiled 2026-05-28 from a fresh read of +link:https://github.com/hyperpolymath/aggregate-library[hyperpolymath/aggregate-library] +v0.1.0 + estate-wide use of the aLib methodology. +==== + +toc::[] + +== What aLib is — and is not + +`hyperpolymath/aggregate-library` is a *methods repository*, not a +stdlib replacement. It demonstrates how to: + +* identify a minimal overlap between systems with very different + constraints, +* express that overlap as a stable spec surface + semantics notes + + conformance test suite, +* enforce reversibility through disciplined boundaries and test + vectors. + +The current overlap is intentionally small — 20 operations across 6 +categories — chosen to *stress-test the method*, not to be a "shared +stdlib". + +[cols="1,3"] +|=== +|Category |Operations + +|arithmetic |add, subtract, multiply, divide, modulo, negate, absolute, max, min +|comparison |(per `aggregate.json` — 1+ ops; coverage spec) +|logical |(per `aggregate.json`) +|string |concat, length, reverse, substring +|collection |contains, empty, filter, fold, length, map +|conditional |(per `aggregate.json`) +|=== + +NOTE: Counts above are from `data/aggregate.json` v1.1.0 (generated +2025-12-27, 20 total operations). When aLib publishes a new version, +this table updates here in the same PR that bumps the consumed +version. + +== Reading guide + +Each entry carries: + +* *Status* — `○` nothing built, `◐` scaffold, `◑` partial, `●` usable. +* *Track* — `T1` implementation, `T2` runner/infra, `T3` contributions. +* *Rationale* — what the item delivers, and which downstream consumer + benefits. + +Item numbers are stable across revisions. + +== Tier 1 — Conformance implementation + +Implement the 20 operations in AffineScript such that aLib's test +vectors pass. Most ops *already* exist in `stdlib/` partially; the +work here is alignment with aLib's `signature_string`, semantics, and +edge-case requirements. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |Track |Rationale + +|1 +|*Arithmetic-9 implementation* — `add`, `subtract`, `multiply`, `divide`, `modulo`, `negate`, `absolute`, `max`, `min` aligned with `specs/arithmetic/*.md` +|`◑` partial +|T1 +|`stdlib/math.affine` covers most; verify signatures match aLib + properties (commutative, associative, identity) hold. + +|2 +|*Comparison ops* — `eq`, `ne`, `lt`, `le`, `gt`, `ge` per `specs/comparison/` +|`◑` partial +|T1 +|Trait surface; pairs with `traits.affine` (stdlib #18). + +|3 +|*Logical ops* — `and`, `or`, `not`, `xor` per `specs/logical/` +|`◑` partial +|T1 +|Mostly built-in operators; conformance is verifying short-circuit + truth-table behaviour matches aLib semantics. + +|4 +|*String-4 implementation* — `concat`, `length`, `reverse`, `substring` per `specs/string/*.md` +|`◑` partial +|T1 +|`stdlib/string.affine` exists; runtime gaps (stdlib roadmap #8, #9) are upstream blockers. + +|5 +|*Collection-6 implementation* — `contains`, `empty`, `filter`, `fold`, `length`, `map` per `specs/collection/*.md` +|`◑` partial +|T1 +|`stdlib/collections.affine` exists; runtime gaps (stdlib roadmap #1, #2) are upstream blockers. Generic over list at minimum; ideally generic over `Foldable`. + +|6 +|*Conditional op* — `if-then-else` as expression per `specs/conditional/` +|`●` usable +|T1 +|Language built-in; verify spec semantics match. + +|7 +|*Edge-case coverage* — implement and test NaN, infinity, overflow, empty-string, empty-list edge cases per each op's `edge_cases` field +|`○` +|T1 +|aLib specs intentionally leave overflow / NaN "implementation-defined" but require *documented* behaviour. AffineScript declares its choice here. + +|8 +|*Properties verification* — `add` is commutative, `multiply` is associative, `abs` is idempotent, etc. +|`○` +|T1 +|aLib `semantics.properties` is the contract; AffineScript proves (or property-tests) each. + +|9 +|*Signature alignment audit* — every AffineScript op's signature matches the aLib `signature_string` +|`○` +|T1 +|Mechanical comparison; ensures cross-language portability of code written against the aLib surface. + +|10 +|*Conformance module* — `stdlib/alib.affine` re-exporting the 20 ops under their aLib names +|`○` +|T1 +|Single import point for consumers wanting the *aLib surface* rather than the *AffineScript-idiomatic surface*. +|=== + +== Tier 2 — Conformance runner & infrastructure + +Build the machinery that *runs* aLib's test vectors against +AffineScript implementations and reports results. This is what makes +aLib's "method" actually testable for our language. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |Track |Rationale + +|11 +|*`aggregate.json` schema loader* — parse aLib's v1.1.0 schema in AffineScript (or via build tool) +|`○` +|T2 +|First step; feeds every later runner item. + +|12 +|*Test-vector executor* — iterate `operations[].test_cases[]`, dispatch to the corresponding `alib.affine` op, compare output +|`○` +|T2 +|Core conformance loop. + +|13 +|*Properties auto-checker* — for each declared property (e.g. commutative), run randomized inputs and assert +|`○` +|T2 +|Pairs with item #8; property-based testing under the hood. + +|14 +|*Conformance report emitter* — JSON + a2ml output: per-op pass/fail, properties verified, edge cases covered +|`○` +|T2 +|Estate convention: a2ml machine-readable; JSON for human / CI. + +|15 +|*CI workflow* — `.github/workflows/alib-conformance.yml` runs the suite on every PR, posts a status check +|`○` +|T2 +|Stops drift; visible signal. + +|16 +|*Conformance badge* — README badge + `docs/CAPABILITY-MATRIX.adoc` row showing "aLib conformance: 18/20" +|`○` +|T2 +|Pairs with #15. + +|17 +|*Multi-target harness* — run conformance against the native interp *and* the wasm codegen target, separately +|`○` +|T2 +|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). + +|18 +|*Conformance-comparison view* — side-by-side AffineScript vs reference implementations (phronesis, Rust, Haskell) where available +|`○` +|T2 +|Pairs with `COMPOSITION-GUIDE.md` in aLib; useful for "did we break parity" diagnosis. +|=== + +== Tier 3 — Contributions back to aLib upstream + +AffineScript's distinctive properties (affine resource types, +row-polymorphic effects, dependent types, reversibility) suggest spec +extensions that aLib doesn't currently capture. These items propose +*upstream PRs* to `hyperpolymath/aggregate-library`. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |Track |Rationale + +|19 +|*Affine-witness column* — `semantics.affine_consumes: [inputIndices]` in `aggregate.json` schema +|`○` +|T3 +|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. + +|20 +|*Linearity / reversibility tagging* — `semantics.reversible: bool` + `semantics.inverse_op: string` (e.g. `subtract` is inverse of `add`) +|`○` +|T3 +|aLib already mentions "Reversibility" in its design principles but doesn't formalise per-op. Upstream PR; idaptik DLC use case is the motivating consumer. + +|21 +|*Effect-row metadata* — `semantics.effect_row: [labels]` (`Net`, `Fs`, `Random`, `Time`, `IO`) +|`○` +|T3 +|All current 20 ops are pure (`[]`); extension lands the schema field for future capability-aware contributions. Pairs with stdlib roadmap #42, #43. + +|22 +|*Idempotency property* — formalise `semantics.properties[Idempotent]` (`abs(abs(x)) = abs(x)`) +|`○` +|T3 +|aLib semantics.properties has `Commutative`, `Associative`, `Identity element`; idempotency is missing. Upstream PR. + +|23 +|*Monotonicity property* — `semantics.properties[Monotonic]` for `max` / `min` / `length` / `absolute` +|`○` +|T3 +|Same family as #22; missing property class. + +|24 +|*Affine-friendly op proposals* — propose `take` / `drop` / `split` / `join` as collection ops that consume their input (affine-friendly) +|`○` +|T3 +|Current `filter` / `map` / `fold` are all *borrow* shapes; AffineScript's affine surface would benefit from explicit-consume variants. Upstream proposal. + +|25 +|*ADR for affine extension* — single ADR in aLib documenting the schema extensions in #19/#20/#21/#22/#23 + the rationale +|`○` +|T3 +|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. +|=== + +== Cross-cutting observations + +. *aLib is small by design.* 20 ops is the entire surface today. The + conformance work (T1 + T2) is therefore *bounded* — completable in + a handful of PRs, not a multi-quarter epic. +. *T3 contributions are the higher-leverage half.* AffineScript's + affine + effect + dependent type system suggests spec features aLib + doesn't yet have. Contributing the *method extensions* upstream is + where AffineScript adds value back, not just consumes. +. *T1 items #4 and #5 are upstream-blocked* on stdlib roadmap #1, #2, + #8, #9 (runtime gaps for `List.++`, `List.len`, `String.concat`, + `String.length`). Don't try to do T1 collection/string conformance + before those runtime gaps close. +. *Multi-target harness (T2 #17) is the antidote to the + PR #107 problem.* Currently `affinescript check` and `affinescript + eval` can diverge; running conformance against *both* targets + catches the gap automatically. +. *aLib license is `MIT OR Palimpsest-0.8`*; AffineScript is MPL-2.0. + Contributions upstream are spec-level (no code transfer); no + license-compat issue. + +== Suggested sequencing + +[cols="1,2,5"] +|=== +|Phase |Goal |Items + +|*A* +|Conformance scaffolding +|#10 (`alib.affine` module) → #11 (schema loader) → #12 (test-vector executor) + +|*B* +|Pure ops first +|#1 (arithmetic-9) → #6 (conditional) → #2 (comparison) → #3 (logical) — these don't need runtime list/string fixes + +|*C* +|Collection + string ops +|*Gated on stdlib roadmap A* (List/String runtime). Then #4 + #5 + #7 + #8 + #9. + +|*D* +|CI + visibility +|#15 (workflow) → #16 (badge) → #17 (multi-target) → #14 (reports) → #18 (comparison view) + +|*E* +|Upstream contributions +|#25 (ADR draft) → #19/#20/#21/#22/#23 as one upstream PR → #24 (affine-op proposals as a follow-up) +|=== + +== Tracking + +* Umbrella tracker: (TBD — opened alongside this PR) +* Per-tier child issues: (TBD — opened alongside this PR) +* Upstream tracking: `hyperpolymath/aggregate-library` (T3 items + result in PRs there, not in this repo) + +When an item's status changes, update its row in this file in the +*same* PR that lands the change; do not let the table drift. + +== See also + +* link:ROADMAP.adoc[ROADMAP.adoc] — language / compiler progress. +* link:bindings-roadmap.adoc[bindings-roadmap.adoc] — framework + bindings (host-runtime FFI surfaces). +* link:stdlib-roadmap.adoc[stdlib-roadmap.adoc] — standard library + items (runtime, RSR rewires, universals). +* link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] — per-feature + readiness (overrides everything). +* link:https://github.com/hyperpolymath/aggregate-library[aggregate-library] + — upstream methodology repo. +* link:https://github.com/hyperpolymath/aggregate-library/blob/main/COMPOSITION-GUIDE.md[aLib COMPOSITION-GUIDE] + — the method of aggregation across phronesis/Rust/Haskell. + +== License + +SPDX-License-Identifier: MPL-2.0 diff --git a/docs/bindings-roadmap.adoc b/docs/bindings-roadmap.adoc new file mode 100644 index 00000000..e0e92685 --- /dev/null +++ b/docs/bindings-roadmap.adoc @@ -0,0 +1,452 @@ += AffineScript Framework Bindings Roadmap +:toc: macro +:toclevels: 3 +:icons: font + +Top 50 framework bindings, sequenced by current need. + +[IMPORTANT] +==== +This document complements link:ROADMAP.adoc[ROADMAP.adoc] (language / +compiler progress) and link:ECOSYSTEM.adoc[ECOSYSTEM.adoc] (Stage A–E +contracts, INT-01..12). Where this file disagrees with either of those, +those documents win — this is the *bindings-side* view. + +Compiled 2026-05-28 from the idaptik PR #107 pilot +(link:https://github.com/hyperpolymath/idaptik/pull/107[hyperpolymath/idaptik#107]) ++ estate-wide binding-need inventory + general-purpose modern-language +binding patterns. +==== + +toc::[] + +== Reading guide + +Each entry carries: + +* *Status* — one of: +** `○` — nothing built +** `◐` — scaffold or stub only +** `◑` — partial; coverage audit needed +** `●` — usable today +** `◯` — blocked by a non-binding issue (codegen, runtime, etc.) +* *Package home* — where the binding lives or should live. +* *Rationale* — what motivates this entry. Where applicable, the + concrete consumer that needs it (e.g. an idaptik file path). + +Item numbers are stable across revisions of this document; do not +renumber when promoting or deferring items. + +== Tier 1 — Required for the current idaptik migration + +These ten bindings *block* the bulk of the 509 remaining `.res` files +in idaptik (see idaptik PR #107 for the pilot pattern). Without them, +no further significant ReScript → AffineScript work is tractable. + +[cols="1,3,1,2,5"] +|=== +|# |Binding |Status |Package home |Rationale + +|1 +|*PixiJS core* (Application, Container, Sprite, Graphics, Text, Ticker, FederatedEvent) +|`◐` scaffold +|`affinescript-pixijs` +|idaptik `src/bindings/Pixi.res`; all 215 `src/app/*.res` files depend on this. Currently 1 `.as` stub + 1 Idris2 ABI + 1 Zig FFI; needs full PixiJS 8.x surface. + +|2 +|*@pixi/sound* (`Sound.from`, play, stop, volume, setVolume, loop) +|`○` +|`affinescript-pixijs` sub-module, or `affinescript-pixi-sound` +|idaptik `src/bindings/PixiSound.res`; BGM + SFX. + +|3 +|*@pixi/ui* (Button, FancyButton, Switch, Slider, Input, ScrollBox) +|`○` +|`affinescript-pixijs` sub-module +|idaptik `src/bindings/PixiUI.res`; all HUD / menu code. + +|4 +|*motion* (animate, animateMini, tween, ease, spring) +|`○` +|`affinescript-motion` +|idaptik `src/bindings/Motion.res`; player + UI transitions. + +|5 +|*WASM-exports calling pattern* — invoke individual `exports.fn_name(args)` from a `WasmExports` value +|`◐` host-side; AS-side `○` +|`stdlib/Deno.affine` extension or new `stdlib/wasm.affine` +|`stdlib/Deno.affine` already exposes `wasmInstance(bytes) -> WasmExports` + the type, but no surface to *call* exports. idaptik `vm/wasm` is blocked here; ~30 per-Zig-fn extern fns needed, or one generic `wasm_call(exports, name, args) -> Float`. *Smallest scope, highest leverage — recommended kickoff.* + +|6 +|*Phoenix Channels / WebSocket* (Socket connect/disconnect, Channel join/leave/push, presence) +|`○` +|`affinescript-phoenix` +|idaptik `src/app/multiplayer/PhoenixSocket.res` + LobbyManager; needed for any multiplayer / sync-server feature. + +|7 +|*DOM* — fill the `for-in` / `while` codegen gap (issue #255) so the existing reconciler runs +|`●` / `◯` blocked-by-#255 +|`affinescript-dom` +|187-line virtual-DOM + reconciler exists; blocked on a wasm-codegen defect. Unblocking #255 turns this from compile-only to runtime-usable. *Not a binding gap — a codegen bug.* + +|8 +|*WebGL / Canvas2D context* (HTMLCanvasElement, getContext, drawImage, fillRect, transform stack) +|`○` +|`affinescript-canvas`, or extension to `affinescript-dom` +|idaptik-ums uses raw Canvas2D (App.res: 1178 LoC of DOM + canvas); also needed for any non-Pixi-based UI. + +|9 +|*IPC / structuredClone* for host↔guest message passing (postMessage, MessageChannel, transfer ownership) +|`○` +|`affinescript-ipc`, or under `Deno` +|idaptik-ums uses Gossamer IPC for level I/O; pattern is broad — any embedded-engine binding needs it. + +|10 +|*JSON Schema validation (Ajv)* — already exists as `stdlib/Ajv.affine` +|`◑` partial +|`stdlib/Ajv.affine` +|idaptik UMS pipeline validates level configs; broader use across the estate's a2ml + schema work. Surface-coverage audit needed. +|=== + +== Tier 2 — Estate-wide near-term needs + +Surface that other estate repos are actively wanting. + +[cols="1,3,1,2,5"] +|=== +|# |Binding |Status |Package home |Rationale + +|11 +|*GitHub API* (repos, issues, PRs, releases, checks, search, GraphQL) via the existing Zig C-ABI +|`◐` via `hpm-github-api-rsr` +|`affinescript-github`, consumes hpm-github-api-rsr +|OikosBot AffineScript port (RSR-stack Phase 5) needs this. + +|12 +|*Anthropic API* (`messages.create`, tool_use, streaming, prompt caching) +|`○` +|`affinescript-anthropic` +|`ai-cli-crash-capture` already lives under affinescript; the claude-api skill flags this as a common need. + +|13 +|*HTTP client + server* — already `stdlib/Http.affine` (client-side) +|`◑` partial +|`stdlib/Http.affine` +|`http-capability-gateway` shipped Zig server (PR#23); AffineScript-side server bindings would let `.affine` programs serve HTTP without Zig. + +|14 +|*WebSocket client + server* (raw `ws://`, separate from Phoenix) +|`○` +|`affinescript-websocket` +|Generalisation of #6; multiplayer + dev-tooling. + +|15 +|*SQLite* — already `stdlib/Sqlite.affine` +|`◑` partial +|`stdlib/Sqlite.affine` +|Coverage audit needed; SQLite is the estate's default persistence layer. + +|16 +|*Crypto* — already `stdlib/Crypto.affine` (signs / hashes) +|`◑` partial +|`stdlib/Crypto.affine` +|`hpm-crypto-rsr` already shipped; rewire AffineScript stdlib to consume the RSR C-ABI per the RSR-stack pending work. + +|17 +|*Tauri 2.0* (invoke, listen, emit, window, dialog, fs, shell) +|`○` +|`affinescript-tauri` +|Estate-wide mobile policy: "Tauri 2.0+ for mobile". Highest-leverage mobile binding. + +|18 +|*Dioxus* (rsx!, signal, use_resource, server fns) +|`○` +|`affinescript-dioxus` +|Estate-wide mobile policy alternative; pure-Rust native UI. + +|19 +|*Zig FFI canonical patterns* — `extern fn` shape for calling Zig C-ABI exports from AffineScript +|`◐` idiomatic patterns exist +|`stdlib` + ADR-style doc +|"Zig = APIs + FFIs" estate directive. Each `hpm-*-rsr` lib exposes Zig exports; AffineScript needs canonical patterns for binding them. + +|20 +|*Telegram (Grammy)* — already `stdlib/Grammy.affine` +|`◑` partial +|`stdlib/Grammy.affine` +|Coverage check; Grammy bots are an estate pattern. +|=== + +== Tier 3 — Broadly useful (web universals) + +Standard surface any serious language ships with within a few years. + +[cols="1,3,1,2,5"] +|=== +|# |Binding |Status |Package home |Rationale + +|21 +|*Web Audio API* (AudioContext, GainNode, BufferSource, AnalyserNode) +|`○` +|`affinescript-web-audio` +|Beyond @pixi/sound: signal processing, synthesis; the Faust compile target's runtime peer. + +|22 +|*Gamepad API* (`navigator.getGamepads`, axes, buttons, haptics) +|`○` +|`affinescript-gamepad`, or in `affinescript-dom` +|Games — idaptik-grade input needs this; also broadly useful. + +|23 +|*Pointer / Touch / Keyboard / IME* (PointerEvent, TouchEvent, KeyboardEvent, compositionstart/end) +|`○` +|`affinescript-dom` extension +|Input handling beyond simple click. + +|24 +|*IndexedDB* (database, transaction, objectStore, cursor) +|`○` +|`affinescript-indexeddb` +|Client-side persistent storage; pairs with SQLite for browser-side cases. + +|25 +|*Web Workers / Service Workers* (postMessage between threads, SharedArrayBuffer, lifecycle) +|`○` +|`affinescript-worker` +|Parallelism on the web; offline-first patterns. + +|26 +|*Fetch / Streams* (ReadableStream, WritableStream, TransformStream, AbortSignal) +|`◑` partial via Http +|`stdlib/Http.affine` extension +|Modern HTTP / streaming surface beyond simple GET. + +|27 +|*Cache API + Storage* (localStorage, sessionStorage, CacheStorage, Storage Foundation) +|`○` +|`affinescript-storage` +|Web persistence. + +|28 +|*Notifications + Permissions* (Notification API, `navigator.permissions`) +|`○` +|`affinescript-notifications` +|PWA patterns. + +|29 +|*Geolocation + Sensors* (Geolocation, DeviceMotion, DeviceOrientation) +|`○` +|`affinescript-sensors` +|Mobile / device-aware apps. + +|30 +|*MediaDevices* (`getUserMedia`, MediaStream, MediaRecorder) +|`○` +|`affinescript-media` +|Audio / video capture; voice + video features. +|=== + +== Tier 4 — Backend / cloud / data + +Server-side and external-service integrations. + +[cols="1,3,1,2,5"] +|=== +|# |Binding |Status |Package home |Rationale + +|31 +|*Postgres* (libpq via FFI, or `postgres.js`) +|`○` +|`affinescript-postgres` +|Production backend default; pairs with SQLite for dev. + +|32 +|*Redis* (commands, pub/sub, streams) +|`○` +|`affinescript-redis` +|Caching, pub/sub, queues. + +|33 +|*S3 / object storage* (PutObject, GetObject, presigned URLs, multipart) +|`○` +|`affinescript-s3` +|Universal blob storage. + +|34 +|*GraphQL client* (query / mutation / subscription, fragments, cache) +|`○` +|`affinescript-graphql` +|Many estate-relevant APIs expose GraphQL. + +|35 +|*OpenTelemetry* (tracer, span, exporter, OTLP) +|`○` +|`affinescript-otel` +|Observability surface; required for any production deployment. + +|36 +|*OpenAI API* (chat.completions, tool calls, streaming) +|`○` +|`affinescript-openai` +|Even though Anthropic is preferred, OpenAI surface is broadly compatible (LiteLLM, Ollama). + +|37 +|*Cloudflare API* (DNS, certs, Pages — *not* Workers, which is estate-banned) +|`○` +|`affinescript-cloudflare` +|CF management plane only; Workers runtime is excluded by policy. + +|38 +|*Stripe* (PaymentIntent, Customer, Subscription, webhooks) +|`○` +|`affinescript-stripe` +|Payments. + +|39 +|*Supabase* (auth, postgrest, realtime, storage) +|`○` +|`affinescript-supabase` +|If the estate accepts a BaaS, this is the FOSS-leaning default. + +|40 +|*Slack + Discord APIs* (REST + webhooks + slash commands) +|`○` +|`affinescript-slack`, `affinescript-discord` +|Bots + estate ops notifications. +|=== + +== Tier 5 — Tooling / FFI / language interop + +Build, test, and cross-language surface. + +[cols="1,3,1,2,5"] +|=== +|# |Binding |Status |Package home |Rationale + +|41 +|*Idris2 ABI surface* (proof carriers, Cexp, formal-verification linkage) +|`◑` partial via existing `ipkg` work +|upstream estate convention +|"Idris2 = ABIs" directive. The estate uses Idris2 for proof carriers on FFI boundaries. + +|42 +|*Rust FFI* (cbindgen-style C-ABI calling) +|`◐` pattern emerging +|doc + stdlib +|Adjacent to Zig FFI; needed for Tauri / Dioxus consumers. + +|43 +|*OCaml interop* (host-compiler dialogues — minimal; affinescript itself is OCaml) +|`◐` implicit via host +|meta-binding +|Mostly a build-time concern, but worth documenting. + +|44 +|*Just / task-runner integration* (recipe discovery, dependency graph) +|`○` +|doc +|Estate-wide Just usage; affinescript projects auto-emit Justfile shape. + +|45 +|*Vite plugin / HMR* — already `affinescript-vite` +|`◑` partial +|`affinescript-vite` +|Build-tool side (*not* a binding TO Vite); pattern for other bundler plugins (Webpack, Rollup, esbuild) should follow this shape. + +|46 +|*esbuild / Rollup plugin* +|`○` +|`affinescript-esbuild`, `affinescript-rollup` +|Alternative bundlers. Lower priority than Vite. + +|47 +|*Playwright / browser automation* (page, locator, expect, fixtures) +|`○` +|`affinescript-playwright` +|E2E test estate convention (idaptik has 5 Playwright suites). + +|48 +|*Test framework* — already `stdlib/testing.affine` +|`◑` partial +|`stdlib/testing.affine` +|Coverage check; test surface is the gate for everything else. + +|49 +|*VS Code extension API* — already `stdlib/Vscode.affine` + `VscodeLanguageClient.affine` +|`●` usable +|`stdlib/Vscode.affine` +|The `.affine` VSCode extension itself uses this (issue #35 Phase 3). Coverage audit. + +|50 +|*Language Server Protocol (LSP)* — generic, not tied to VS Code +|`◑` partial via VscodeLanguageClient +|`stdlib/lsp.affine` +|Editor-agnostic LSP surface; affinescript's own LSP can dogfood. +|=== + +== Cross-cutting observations + +. *PixiJS + sub-packages dominate Tier 1.* Of the 10 critical-for-idaptik + bindings, four (#1, #2, #3, and #4 by extension) are PixiJS-ecosystem. + Investing in `affinescript-pixijs` unblocks the largest single chunk + of idaptik's 215-file `src/app/` tree. +. *WASM-exports calling is a one-day fix with high leverage.* Item #5 + — adding `extern fn wasm_export_call(exports: WasmExports, name: String, args: [Float]) -> Float` + to `stdlib/Deno.affine` (or 30 per-Zig-fn externs) unblocks idaptik + `vm/wasm` *and* every future WASM-host consumer in the estate. +. *DOM is closest to done* — issue #255 (for-in / while wasm codegen) + is the blocker, not the binding surface itself. That's a codegen bug, + not a binding gap; classified separately so it doesn't get re-scoped + as a binding task. +. *Many "stdlib bindings" need coverage audits, not new code* (#7, #10, + #13, #15, #16, #20, #48, #49) — the file exists; verifying it covers + the consumer's full surface is cheaper than writing new bindings. +. *Banned by policy, excluded from this list:* +* Cloudflare Workers runtime (estate-banned). +* React Native, Flutter (estate-banned). +* Node.js-native binding patterns where Deno-equivalent exists. +* Python interop except for SaltStack (estate policy). +. *Connections / cross-cutting:* Tauri (#17) + Dioxus (#18) consume some + of the lower-level bindings (Notification, MediaDevices, etc.). When + sequencing, do the leaf bindings first so the framework bindings have + things to compose. + +== Suggested sequencing + +[cols="1,2,5"] +|=== +|Phase |Goal |Items + +|*A* +|Unblock current idaptik pilot +|#5 (WASM exports) → #1 (PixiJS core) → #4 (motion) → #2 (sound) → #3 (UI) + +|*B* +|Estate fan-out +|#11 (GitHub API rewire) → #19 (Zig FFI doc) → #6 (Phoenix Channels) → #16 (Crypto rewire) + +|*C* +|Demand-driven +|Everything else; pick when a concrete consumer asks. +|=== + +== Tracking + +* Umbrella tracker: (TBD — opened alongside this PR) +* Per-tier child issues: (TBD — opened alongside this PR) + +When a binding's status changes, update its row in this file in the +*same* PR that lands the change; do not let the table drift. + +== See also + +* link:ROADMAP.adoc[ROADMAP.adoc] — language / compiler progress (this + doc complements it). +* link:ECOSYSTEM.adoc[ECOSYSTEM.adoc] — Stage A–E contracts, INT-01..12. +* link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] — per-feature + readiness (overrides everything). +* idaptik PR #107 — the pilot that surfaced the binding-need shape. + +== License + +SPDX-License-Identifier: MPL-2.0 diff --git a/docs/stdlib-roadmap.adoc b/docs/stdlib-roadmap.adoc new file mode 100644 index 00000000..6881ee25 --- /dev/null +++ b/docs/stdlib-roadmap.adoc @@ -0,0 +1,504 @@ += AffineScript Standard Library Roadmap +:toc: macro +:toclevels: 3 +:icons: font + +Top 50 standard-library items, sequenced by current need. + +[IMPORTANT] +==== +This document complements link:ROADMAP.adoc[ROADMAP.adoc] (language / +compiler progress), link:bindings-roadmap.adoc[bindings-roadmap.adoc] +(framework bindings), and link:alib-roadmap.adoc[alib-roadmap.adoc] +(aLib conformance + affine contributions). Where this file disagrees +with link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] or +link:ECOSYSTEM.adoc[ECOSYSTEM.adoc], those documents win. + +Compiled 2026-05-28 from the idaptik PR #107 pilot +(link:https://github.com/hyperpolymath/idaptik/pull/107[hyperpolymath/idaptik#107]) ++ estate-wide stdlib-need inventory. +==== + +toc::[] + +== Reading guide + +Each entry carries: + +* *Status* — one of: +** `○` — nothing built +** `◐` — scaffold or stub only +** `◑` — partial; coverage / runtime gap +** `●` — usable today +** `◯` — blocked by a non-stdlib issue (codegen, runtime, etc.) +* *File* — the stdlib path the item lives in or should live in. +* *Rationale* — what motivates this entry. Where applicable, the + concrete consumer that needs it (e.g. an idaptik file path, + an RSR-stack hook). + +Item numbers are stable across revisions of this document; do not +renumber when promoting or deferring items. + +[NOTE] +==== +*Scope of this roadmap*: stdlib items only. Where an item overlaps +with a language-level feature (e.g. async/await, capability types), +the surface here is the *stdlib-side* API; the language-level work is +tracked in the main ROADMAP. Such items are flagged `tracked-by-main`. +==== + +== Inventory snapshot (2026-05-28) + +[cols="1,1,3"] +|=== +|File |State |Notes + +|`prelude.affine` |`◑` partial |Imports + re-exports; cross-file `use` from standalone check is unreliable. +|`option.affine` |`◑` partial |Type exists; helpers thin; *not reachable* from standalone single-file check. +|`result.affine` |`◑` partial |Type exists; helpers thin. +|`collections.affine` |`◑` partial |`list` operations; `len` / `++` parse-clean but fail at `affinescript eval`. +|`dict.affine` |`◑` partial |Type exists; runtime coverage incomplete. +|`string.affine` |`◑` partial |Surface present; runtime ops sparse. +|`math.affine` |`◑` partial |Arithmetic only; no trig / log / exp. +|`io.affine` |`◑` partial |Print / read; no path / env / exit-code helpers. +|`json.affine` |`◑` partial |Should consume `hpm-json-rsr` C-ABI. +|`Crypto.affine` |`◑` partial |Should consume `hpm-crypto-rsr` C-ABI. +|`Http.affine` |`◑` partial |Client-side; rewire to `hpm-http-client-rsr`. +|`Network.affine` |`◐` scaffold|Sockets / DNS coverage unclear. +|`Sqlite.affine` |`◑` partial |Coverage audit needed. +|`Grammy.affine` |`◑` partial |Telegram bot coverage. +|`Ajv.affine` |`◑` partial |Schema validation; estate-wide a2ml use. +|`Deno.affine` |`●` usable |`WasmExports` + `wasmInstance` + `readFile`; calling individual exports is a binding gap (see bindings #5). +|`Vscode.affine` + `VscodeLanguageClient.affine` |`●` usable |Issue #35 Phase 3 closed. +|`effects.affine` |`◐` scaffold|Effect-row helpers; tracked-by-main. +|`traits.affine` |`◐` scaffold|Trait helpers; sparse. +|`Core.affine` |`◐` scaffold|Foundational re-exports. +|`testing.affine` |`◑` partial |Test framework; coverage audit. +|=== + +== Tier 1 — Idaptik blockers (runtime + reach) + +These ten items are the stdlib gaps surfaced directly by the idaptik +PR #107 pilot. Without them, the next migration tranche stalls at +`affinescript check` PASS / `affinescript eval` FAIL — i.e. the type +checker accepts code that the runtime can't execute. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |File |Rationale + +|1 +|*`List.len` runtime* — `len([1,2,3])` returns 3 at `eval` +|`◑` partial +|`collections.affine` +|idaptik `Reversible.affine` works around this; every list-heavy port needs it. + +|2 +|*`List.++` runtime* — `[1] ++ [2,3]` returns `[1,2,3]` at `eval` +|`◑` partial +|`collections.affine` +|Same site as #1; the pilot reverted from `++` to `Cons` calls. + +|3 +|*`for x in xs` codegen* — wasm codegen for `for-in` (issue #255) +|`◯` blocked-by-#255 +|N/A (codegen) +|Stdlib-adjacent: any iteration over a `list` triggers this. *Not a stdlib gap — a codegen bug.* Listed so it doesn't get re-scoped as stdlib work. + +|4 +|*`while` + `mut` codegen* — same codegen surface as #3 +|`◯` blocked-by-#255-adjacent +|N/A (codegen) +|Same disposition as #3. + +|5 +|*Cross-file `use` resolvability* — `use stdlib::Option` works from a single-file standalone check +|`◑` partial +|`prelude.affine` + name-resolver +|idaptik pilot had to define a local `enum UndoResult { ... }` because prelude `Option`/`Some`/`None` weren't reachable. Every multi-file consumer hits this. *Partially a name-resolver bug, partially a stdlib organisation choice.* + +|6 +|*Prelude `Option` / `Some` / `None`* — usable from any check mode (not just project build) +|`◑` partial +|`option.affine` + `prelude.affine` +|See #5; specific to the `Option` type which is the most-used stdlib enum. + +|7 +|*Dict runtime* — `Dict.get` / `Dict.set` / `Dict.iter` work at `eval` +|`◑` partial +|`dict.affine` +|idaptik VM state uses a register map; without runtime dict the VM can't execute. + +|8 +|*`String.length`* runtime +|`◑` partial +|`string.affine` +|Per-character cost calculations; idaptik UI code (post-pilot) will need this. + +|9 +|*`String.concat` / `++`* runtime +|`◑` partial +|`string.affine` +|Match arms and debug-print sites in idaptik used inline concat throughout. + +|10 +|*Exhaustive match over imported enums* — pattern compiler resolves `Option::Some(x)` and `Option::None` even when imported via `use` +|`◑` partial +|pattern compiler + `option.affine` +|Same family as #5/#6; causes the local-`enum` workaround pattern. +|=== + +== Tier 2 — Estate convergence (RSR rewires + coverage) + +Estate-wide hooks. The RSR (Rhodium Standard Repository) stack has +shipped 5 libraries with stable Zig C-ABIs; the stdlib should be the +AffineScript-side consumer for each. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |File |Rationale + +|11 +|*Crypto rewire to `hpm-crypto-rsr`* — sha256, sha512, blake3, ed25519, x25519 +|`◑` partial +|`Crypto.affine` +|RSR-stack convention; supersedes hand-rolled crypto in `Crypto.affine`. + +|12 +|*Http rewire to `hpm-http-client-rsr`* — verb coverage, headers, timeout, redirects +|`◑` partial +|`Http.affine` +|RSR-stack convention; consumed by OikosBot AffineScript port (Phase 5). + +|13 +|*Json rewire to `hpm-json-rsr`* — parse / stringify / schema-aware +|`◑` partial +|`json.affine` +|RSR-stack convention; needed for HTTP-server accept-loop payload extraction (RSR-stack pending work). + +|14 +|*GitHub API surface* via `hpm-github-api-rsr`'s 12 `hpm_github_*` exports +|`○` +|new `github.affine`, or extension to `Network.affine` +|OikosBot pattern; Externs convention per Q4 shim. + +|15 +|*`Result` helpers* — `map` / `and_then` / `or_else` / `unwrap_or` / `map_err` +|`◑` partial +|`result.affine` +|Used everywhere; idaptik pilot wanted `Result.map` and fell back to nested matches. + +|16 +|*`Option` helpers* — `map` / `and_then` / `unwrap_or` / `ok_or` / `is_some` / `is_none` +|`◑` partial +|`option.affine` +|Same as #15. Closes the local-`enum UndoResult` workaround pattern. + +|17 +|*Collections trait surface* — `Iter`, `Into`, `From`, `IntoIterator` (or AS-equivalent) +|`◐` scaffold +|`collections.affine` + `traits.affine` +|Required for any non-trivial functional pipeline; tracked-by-main on the *language* side. + +|18 +|*Traits coverage* — `Eq` / `Ord` / `Show` / `Debug` core traits, derive-style +|`◐` scaffold +|`traits.affine` +|Auto-derive lands as language feature; the *trait surface* is stdlib. + +|19 +|*Math expanded* — trig (sin/cos/tan/asin/...), log/exp, pow, sqrt, floor/ceil/round +|`◑` partial +|`math.affine` +|idaptik motion + physics; broadly useful. + +|20 +|*Io expanded* — `Path`, `Env::get`, `Env::set`, `stderr`, `Process::exit(code)`, `args` +|`◑` partial +|`io.affine` +|CLI surface for every `affinescript`-compiled binary; idaptik justfile-replaceable scripts depend on it. +|=== + +== Tier 3 — Broadly useful (universals) + +Standard surface that any serious language ships within a few years. +Not blocking specific consumers today; included so they're discoverable. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |File |Rationale + +|21 +|*Time / Duration / Instant* — monotonic + wall-clock, formatting, parsing +|`○` +|new `time.affine` +|Universal; everything benchmarked or scheduled needs it. + +|22 +|*UUID / Random* — `Uuid::v4`, `Random::next`, seeded PRNG +|`○` +|new `uuid.affine` + `random.affine` +|Random is in `Math` in many languages; UUIDs are universal. + +|23 +|*Regex* — pattern, match, replace, capture groups +|`○` +|new `regex.affine` +|Estate-wide need; backed by a Zig FFI (PCRE2 or RE2 wrapper). + +|24 +|*URL parser* — `Url::parse`, `Url::join`, query parsing, encoding +|`○` +|new `url.affine` +|Pairs with `Http`; universal client surface. + +|25 +|*Base64 / Hex encoding* — encode / decode, URL-safe variant +|`○` +|new `encoding.affine` +|Universal; needed for JWT, image data URIs, etc. + +|26 +|*Logging surface* — `Logger`, levels, structured fields, JSON sink +|`○` +|new `logging.affine` +|Estate observability requirement; pairs with OTel binding (Tier 4 in bindings roadmap). + +|27 +|*Date / calendar* — `Date`, `DateTime`, `TimeZone`, ISO-8601, RFC-3339 +|`○` +|new `date.affine` (sibling to `time.affine`) +|Distinct from #21; calendars are gnarly enough to deserve their own file. + +|28 +|*Number formatting* — fixed-precision, exponent, locale-aware +|`○` +|extension to `math.affine` or new `format.affine` +|Output side of #19. + +|29 +|*Float utilities* — `NaN`, `infinity`, `is_finite`, total-ordering helpers +|`○` +|extension to `math.affine` +|Floating-point edge cases that idiomatic code routinely gets wrong. + +|30 +|*Buffer / Bytes type* — fixed-length byte buffer with view / slice / read / write +|`○` +|new `bytes.affine` +|Universal; required for crypto, binary protocols, wasm interop. +|=== + +== Tier 4 — Concurrency / async / effects + +The next layer of language maturity. Most items here are +*tracked-by-main* — the language work lives in the main ROADMAP; the +stdlib surface is what consumers see. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |File |Rationale + +|31 +|*Async / await canonicalisation* — public surface for `async fn` + `await` +|`○` +|`effects.affine` extension +|Tracked-by-main; row-polymorphic effects mean the surface needs careful design. + +|32 +|*Promise / Task type* — `Task`, spawn, join, race +|`○` +|new `task.affine` +|Companion to #31; concrete handle type. + +|33 +|*Channel / mpsc* — bounded + unbounded, sender / receiver halves (affine fits naturally) +|`○` +|new `channel.affine` +|First-class affine resource; AffineScript should make these *better* than other langs. + +|34 +|*Mutex / RwLock* — guard types, poison handling +|`○` +|new `sync.affine` +|Pairs with #33; affine guard makes RAII trivial. + +|35 +|*Atomic types* — `AtomicI32`, `AtomicU64`, ordering enum +|`○` +|new `atomic.affine` +|Low-level concurrency primitives. + +|36 +|*Cancellation tokens* — cooperative cancellation, parent / child propagation +|`○` +|`task.affine` extension +|Idiomatic structured concurrency. + +|37 +|*Timer / sleep* — `sleep(duration)`, `interval`, oneshot timer +|`○` +|`time.affine` extension +|Pairs with #21; common in idaptik gameplay loops. + +|38 +|*Select / race* — `select!`-style over multiple awaitables +|`○` +|`task.affine` extension +|Required for any non-trivial concurrent flow. + +|39 +|*Stream / observable* — pull-based stream of `T`, map / filter / take +|`○` +|new `stream.affine` +|Pairs with channel (#33) and Fetch/Streams (bindings #26). + +|40 +|*Actor / mailbox* — message-passing actors, supervised +|`○` +|new `actor.affine` +|Gleam / BEAM-style; lower priority but valuable for distributed estate use. +|=== + +== Tier 5 — Conformance / introspection / advanced + +Items that earn their place once the basics are solid. + +[cols="1,3,1,2,5"] +|=== +|# |Item |Status |File |Rationale + +|41 +|*aLib conformance vectors* — implement `aggregate.json`'s 20 ops + run its test vectors +|`○` +|new `alib.affine` + conformance runner +|See link:alib-roadmap.adoc[alib-roadmap.adoc] for the full track; this is the stdlib-side hook. + +|42 +|*Effects calculus expansion* — capability rows, IO / Net / Async / Random / Time as effect labels +|`○` +|`effects.affine` +|Tracked-by-main on the type-system side; stdlib provides the standard labels. + +|43 +|*Capability / permission types* — `Capability`, `Capability`, scoped grant +|`○` +|new `capability.affine` +|Pairs with #42; security-relevant surface. + +|44 +|*Borrow / move helpers* — `Move`, `Borrow`, `BorrowMut`, explicit move points +|`○` +|`Core.affine` extension +|Tracked-by-main on the borrow-checker side. + +|45 +|*Diagnostics / pretty errors* — `Diagnostic` type, span attachment, rendered output +|`◐` scaffold +|new `diagnostics.affine` +|Compiler dogfoods this; library code can emit `Diagnostic` results. + +|46 +|*Reflection / type-info* — runtime `TypeId`, `type_name`, derive-`Debug`-like introspection +|`○` +|new `reflect.affine` +|Universal escape hatch; needed by serialisation (#47), testing (#48). + +|47 +|*Serialisation (binary)* — `Serialise` / `Deserialise` traits, compact binary format +|`○` +|new `serde.affine` +|Pairs with `json.affine` (#13); binary side for protocols, sqlite blobs, wasm IPC. + +|48 +|*Testing expansion* — property-based, snapshot, async tests, fixtures +|`◑` partial +|`testing.affine` +|Pairs with bindings #48 (test framework binding); coverage audit needed. + +|49 +|*Bench harness* — `Benchmark`, statistical reporting, CI-friendly output +|`○` +|new `bench.affine` +|Companion to #48; estate has Hypatia perf rules. + +|50 +|*Doc-comment metadata access* — runtime + compile-time access to `///` doc comments +|`○` +|`reflect.affine` extension +|Powers `affinescript doc`, IDE hovers, JSR-style package docs. +|=== + +== Cross-cutting observations + +. *Tier 1 is mostly runtime, not surface.* Items 1-4, 7-10 all exist + at the type-checker level; the gap is `eval` / wasm-codegen + execution. This means Tier 1 work is mostly in the *compiler* + (interp + codegen), not in the `.affine` stdlib files themselves. +. *Cross-file `use` (#5/#6/#10) is a name-resolver bug, not a stdlib + surface gap.* The fix is in `lib/name_res.ml` (or equivalent); the + stdlib organisation may also need to change (e.g. `Option` / + `Result` always-imported even without explicit `use`). +. *Tier 2 RSR rewires are mechanical* once the calling convention + exists (bindings #19). Doing bindings #19 first unblocks #11/#12/ + #13/#14 in parallel. +. *Tier 4 is mostly tracked-by-main.* The stdlib roadmap captures the + *surface*; the compiler ROADMAP captures the *machinery*. Don't + duplicate-track. +. *No item in this roadmap is a binding* — every binding lives in + link:bindings-roadmap.adoc[bindings-roadmap.adoc]. The line: if + it's calling into a host runtime via `extern fn`, it's a binding; + if it's pure-AffineScript code that organises types and functions, + it's stdlib. Tier 2 RSR rewires straddle this line — they're + stdlib *modules* whose implementation calls bindings. + +== Suggested sequencing + +[cols="1,2,5"] +|=== +|Phase |Goal |Items + +|*A* +|Unblock idaptik PR #107 successor +|#5 (cross-file `use`) → #6 (Option reach) → #1 (List.len runtime) → #2 (List.++ runtime) → #7 (Dict runtime) + +|*B* +|RSR convergence +|bindings #19 (Zig FFI doc) → #11 (Crypto) → #12 (Http) → #13 (Json) → #14 (GitHub) + +|*C* +|Helper coverage +|#15 (Result helpers) → #16 (Option helpers) → #19 (Math expanded) → #20 (Io expanded) + +|*D* +|Universals +|#21 (Time) → #23 (Regex) → #24 (URL) → #25 (Encoding) → #26 (Logging) + +|*E* +|Demand-driven +|Tier 4 + Tier 5; pick when a concrete consumer asks. +|=== + +== Tracking + +* Umbrella tracker: (TBD — opened alongside this PR) +* Per-tier child issues: (TBD — opened alongside this PR) + +When a stdlib item's status changes, update its row in this file in +the *same* PR that lands the change; do not let the table drift. + +== See also + +* link:ROADMAP.adoc[ROADMAP.adoc] — language / compiler progress. +* link:bindings-roadmap.adoc[bindings-roadmap.adoc] — framework + bindings (host-runtime FFI surfaces). +* link:alib-roadmap.adoc[alib-roadmap.adoc] — aLib conformance + + affine-aware contributions back upstream. +* link:CAPABILITY-MATRIX.adoc[CAPABILITY-MATRIX.adoc] — per-feature + readiness (overrides everything). +* link:ECOSYSTEM.adoc[ECOSYSTEM.adoc] — Stage A–E contracts. +* idaptik PR #107 — the pilot that surfaced Tier 1 gaps. + +== License + +SPDX-License-Identifier: MPL-2.0