Closes the P1 todo from earlier today: Step 7.5 PASS report is
bound to the exact bytes of the spec at dispatch time. Any
subsequent edit — wording polish, user-requested change, anything
— invalidates the report and forces a fresh dispatch before the
Step 8 commit.
Three edits:
- Step 7.5 gets a 'Re-dispatch on any post-PASS edit' subsection
stating the rule and explaining why (PASS attests to bytes).
- Step 8 wording: '... edit in place, re-run Step 7 AND re-dispatch
Step 7.5, then return here. Only proceed after approval AND a
fresh Step 7.5 PASS.'
- Common Rationalisations + Red Flags gain matching entries
('just polishing wording, no need to re-dispatch' / 'Editing the
spec after PASS without re-dispatching').
Roadmap P1 todo retired with this commit.
17 KiB
AILang Roadmap
Priority-ordered list of upcoming work — milestones, features, todos, and ideas. The orchestrator maintains this file. The user can request additions; the orchestrator chooses what to remove or reprioritise as work progresses.
Conventions
- One checkbox per entry.
- [ ]is open;- [~]is in progress (work has started — a plan exists, a branch is open, or commits are landing);- [x]is done. A finished entry may stay briefly for context, then is removed (with a one-line mirror indocs/journals/). - Each entry is tagged by kind and lives under a priority
bucket:
- [milestone] — big chunk that will get a
docs/specs/<milestone>.md. - [feature] — smaller addition inside a milestone, no full spec.
- [todo] — concrete task that can run without a brainstorm (cleanup, doc fix, mechanical refactor, test backfill).
- [idea] — not yet decision-ready, no commitment.
- [milestone] — big chunk that will get a
- Optional
depends on:line names another entry that has to land first. - Optional
context:line points to the journal entry (per-iter file underdocs/journals/or, for pre-2026-05-11 entries, the archiveddocs/journal-archive.md) where the rationale lives. The roadmap is intentionally terse; rationale stays in the journals. - Priority buckets:
- P0 — in flight. Spec or plan already exists.
- P1 — next up. Decision made; not yet started.
- P2 — medium-term. Decided in principle, scheduled later.
- P3 — ideas. No commitment; may be cut.
P0 — In flight
(empty — canonical-type-names milestone closed 2026-05-11; Floats closed 2026-05-10 and was removed once it stopped being load-bearing context. Pick the next milestone from P1.)
P1 — Next
-
[milestone] Post-22 Prelude — Eq/Ord — shipped milestone 23 (2026-05-12).
OrderingADT,Eq/Ordclasses, primitive instances on Int / Bool / Str, polymorphic free fnsne/lt/le/gt/ge, runtimeail_str_eq+ail_str_compare, end-to-end coverage including user-ADT-instance integration. Float has neither instance by design; polymorphic helpers at Float fire Float-awareNoInstanceper DESIGN.md §"Float semantics". -
[milestone] Post-22 Prelude — Show + print rewire — ship
Showtypeclass withShow Int/Bool/Str/Floatinstances; rewireprintthroughShow.show. Gated on heap-StrABI runtime work (int_to_strneeds to allocate). Originally queued as 22b.4 in the typeclass milestone, kept on hold pending demand and the heap-Strprerequisite.- context: brainstorm 2026-05-12 (iter 23.5 wrap). Heap-
StrABI is the load-bearing prerequisite; until it ships,Show Intcannot allocate aStrto return.
- context: brainstorm 2026-05-12 (iter 23.5 wrap). Heap-
P2 — Medium-term
-
[milestone] Cross-model authoring-form test — empirically measure whether
.ail.jsonor.ailxis the form a foreign LLM author reaches for and succeeds with. Setup: three configurations per task — (i) JSON-mandated, (ii).ailx-mandated, (iii) free choice (both corpora available, model picks). Multiple subjects to check whether form-preference is model-robust. For each (model × form × task): system prompt includes DESIGN.md verbatim (~28k tokens); user prompt is the task plus the form mandate; an error- roundtrip loop feedsail check/ail parseerrors back to the model until green or iter-limit. Measure: first-attempt success (yes/no), iterations to green, total tokens spent, error classes encountered (schema violation, type mismatch, hash mismatch, syntax error in the chosen form); for free-choice runs, which form the model picked unprompted. The output is a JOURNAL'd dataset + interpretation + a concrete DESIGN.md edit on Decision 6 — either ratify "ailx is the AI authoring projection" with empirical backing across N subjects, or retire the form if JSON wins consistently across all subjects.- context: brainstorm 2026-05-12 (aborted in favour of two roadmap
entries). The Decision-6 prose currently asserts
.ailxis the AI authoring projection while §"Feature-acceptance criterion" cites JSON-as-canonical-authoring-surface as a behavioural counterexample to human-driven feature picks. The tension is real; only empirical data over multiple downstream subjects resolves it. - depends on: Round-trip completeness invariant (P1 above) —
without it, measured preference is confounded by expressive-
power gaps. Strongly benefits from (but is not strictly
blocked by):
ail check/build/runaccept.ailxextension (P2 todo below); workspace search beyond entry- module's directory (P2 todo below). Both will be encountered during the test if not closed first. - smoke-test evidence (2026-05-12): Qwen3-Coder-Next reads
DESIGN.md and produces a structurally correct AILang program
that passes
ail checkin two turns; first turn missed the module-name-matches-file-path rule, second turn fixed it afterail checkerror was fed back. ~28k prompt tokens, ~150 completion tokens, ~2-5 s latency per turn. - how to address the IONOS endpoint:
- URL:
https://openai.inference.de-txl.ionos.com/v1/chat/completions - protocol: OpenAI-compatible chat completions API.
/v1/modelsreturns the catalogue. - auth: HTTP header
Authorization: Bearer <token>. Store the token outside the repo (e.g.~/.ionos_token,chmod 600). Tokens are JWTs; the one used in the 2026-05-12 smoke test was IONOS-issued and time-bound — refresh when re-engaging. - model IDs to try (subset of the IONOS catalogue as of
2026-05-12, sorted by relevance to this test):
Qwen/Qwen3-Coder-Next— code-specialised, smoke-tested.meta-llama/Meta-Llama-3.1-405B-Instruct-FP8— large general instruct, useful as a contrast subject.meta-llama/Llama-3.3-70B-Instruct— mid-size instruct.openai/gpt-oss-120b— OpenAI open-weight 120B.mistralai/Mistral-Small-24B-Instruct— smaller subject, stresses spec comprehension.meta-llama/CodeLlama-13b-Instruct-hf— older code model, useful as a low-capability floor.
- request shape: standard
messages: [{role: "system", ...}, {role: "user", ...}, ...], with DESIGN.md (107 KB / ~28k tokens) in the system message and the task + form mandate in the first user message. Subsequent turns alternateassistant/userwith theail checkerror verbatim in the user message. - response shape:
choices[0].message.contentcarries the generated program (request "no markdown fences, no explanation" in the prompt to skip post-processing).usage.prompt_tokens+usage.completion_tokensgive per- turn token spend. - cost estimate: ~56k tokens per task per (model × form) configuration including a few correction roundtrips; a full matrix (4 tasks × 3 forms × 4 models × 1 run each) is ~2.7M tokens total. Multiply by repetition count if a median-of-3 design is chosen.
- URL:
- context: brainstorm 2026-05-12 (aborted in favour of two roadmap
entries). The Decision-6 prose currently asserts
-
[feature] Operator routing through
Eq/Ord—==,<etc. resolved via the typeclass instead of the built-in primitive comparators. No commitment; gated on bench re-baselining to make sure the indirection doesn't tank latency.- context: JOURNAL 2026-05-09
- depends on: Post-22 Prelude — Eq/Ord (shipped 23.5)
-
[todo]
types/ctor_indexoverlay shape question — decide whether the env's two parallel ctor maps should collapse into one overlay, or stay split. Surfaced during the env-construction unify audit.- context: JOURNAL 2026-05-10 ("Audit close: env-construction unify")
-
[todo] CLI human-mode diagnostic surface for
WorkspaceLoadError— non-JSONail checkroutes ct.1 errors viaanyhow/thiserrorDisplay (Error: <message>) instead of going throughworkspace_error_to_diagnostic, so the bracketed[code]prefix the JSON path carries is missing. Plausibly applies to every CLI subcommand that callsload_workspace(&path)?directly.- context: JOURNAL 2026-05-11 ("Iteration ct.1") — surfaced by ct.1.8 tester.
-
[todo] Retire dead
KindMismatcharm —validate_classdefs'swalk_kind_mismatchpath is structurally unreachable through well-formed schema post-ct.1 (the canonical-form validator catches the malformedType::Con { name: param }shape earlier). The enum variant +walk_kind_mismatchhelper stay as dead-but-defensive code; a future tidy can delete both.- context: JOURNAL 2026-05-11 ("Iteration ct.1").
-
[todo] Re-key
Registry.type_def_moduleto handle bare-name-collision-across-modules —BTreeMap<String, String>keyed by bare type name silently overwrites when two modules each definetype Foo;normalize_type_for_registrywould then collapseM.FooandN.Footo whichever insert won. Acceptable for current corpus (distinct bare type names across modules), but the proper fix is to key by(owning_module, bare_name) → defining_module.- context: JOURNAL 2026-05-11 ("Iteration ct.1") — flagged by ct.1.5a quality reviewer.
-
[feature] 22c — typeclass corpus expansion. User-defined classes beyond the prelude four; multi-parameter classes; superclass chains; richer instance bodies. Deferred from milestone 22.
- context: JOURNAL 2026-05-09
-
[milestone] Module-qualified class names + type-driven method dispatch — retire the
MethodNameCollisionworkaround (crates/ailang-core/src/workspace.rs:472) that today keeps bare class names viable by enforcing workspace-global method-name uniqueness. Replaces name-driven method resolution (ModuleGlobals::class_methods: IndexMap<String, ClassMethodEntry>,crates/ailang-check/src/lib.rs:983; consumed bymono::rewrite_class_method_calls,crates/ailang-check/src/mono.rs:657) with type-driven dispatch — look upeqcandidates by argument type, pick the unique class instance, fail closed on ambiguity. Once shipped, two libraries can each declareclass Eqwith their owneq. Carries its own DESIGN spec: inference rules, ambiguity diagnostics, and the canonical-form extension for class-reference fields (InstanceDef.class,SuperclassRef.class,Constraint.class) that the canonical-type-names milestone explicitly out-of-scoped.- context:
docs/specs/2026-05-10-canonical-type-names.md"Out of scope: Class names" — the workaround is named there so it stays visible until this milestone retires it.
- context:
-
[todo] Boehm full retirement — remove the transitional Boehm GC path now that RC + uniqueness is the canonical memory story.
- context: JOURNAL pre-22, "Boehm transitional"
-
[feature] Closure-pair slab / pool — codegen tweak to pool the env+code closure pairs instead of one-shot heap allocs. Bench-gated.
-
[todo]
FnDef::syntheticflag — formalise the monomorphiser-emitted FnDefs so downstream passes can tell user-authored from synthesised at a glance. Currently inferred from symbol naming. -
[todo] 21'h iteration — final 21' carry-over (latency methodology pass). Numbering kept for continuity with the 21' arc.
-
[todo]
io/print_floatalways-emit-.0— surface printer always emits.ore/Eso re-lex routes to Float; the runtime printer (printf("%g\n", v)) doesn't, so2.0prints as2(Int-shaped). Asymmetric. Either switch the runtime path to a.0-fallback printer (matching surface) or document the%gcontract in DESIGN.md §"Float semantics" so the LLM-author knowsio/print_float's output is for-humans not round-trip.- context:
docs/specs/2026-05-10-fieldtest-floats.mdfinding F1.
- context:
-
[todo] Rustdoc warning sweep —
cargo doc --no-depsreports 16 pre-existing warnings (15 inailang-check, 1 inailang-core: private-item links from public doc, unresolved intra-crate links). All predate the design-md-consolidation milestone; treat as a one-off sweep.- context: JOURNAL 2026-05-10 ("Audit close: design-md-consolidation").
-
[todo]
design_schema_drift.rsfidelity widening — current test checks anchor presence anywhere in DESIGN.md; the audit found that[high]schema gaps in §"Data model" are invisible because anchors live in Decision 11 instead. Constrain the test to scan only §"Data model" + ParamMode block, or extract JSON-schema blocks into a machine-readable file the test consumes.- context: JOURNAL 2026-05-10 ("Audit close").
-
[todo] Split
BadCrossModuleTypeRefinto two diagnostics — the current single shape collapses unknown-owner and known-owner / unknown-type-in-owner into one message. The two cases suggest different fixes (add(import <owner>)vs. fix the type name). In the known-owner branch, list the owner's available type defs as candidates the waybare-cross-module-type-reflists candidates from imports.- context: fieldtest 2026-05-11 —
examples/ct_3*.ailxexhibits both branches with identical-shape diagnostics.
- context: fieldtest 2026-05-11 —
-
[todo] Workspace search beyond entry-module's directory —
load_workspaceonly finds sibling.ail.jsonfiles in the same directory as the entry module, so any consumer of prelude/std in a subdirectory has no way to resolve cross-module imports. Add either a--workspace-rootflag onail check/ail build/ail run, or upward-search from the entry module's directory. Alternatively ratify the flat-workspace assumption in DESIGN.md if intentional.- context: fieldtest 2026-05-11 — fieldtest fixtures could not be
placed under
examples/fieldtest/because of this; predates the canonical-type-names milestone but surfaces every time.
- context: fieldtest 2026-05-11 — fieldtest fixtures could not be
placed under
-
[todo]
ail check/build/runaccept.ailxextension — todayail check foo.ailxproduces a misleading JSON-parse error (json: expected value at line 1 column 1) because the loader only accepts.ail.json. Either teach the CLI subcommands to auto-parse.ailxinternally, or detect the extension and emit a "did you meanail parse foo.ailx?" hint. The LLM-author's natural first command should not be the one that produces a misleading diagnostic.- context: fieldtest 2026-05-11 — orthogonal to canonical-type-names but every fieldtest invocation hits this on its first command.
-
[todo]
check_in_workspaceper-module overlay narrowing —crates/ailang-check/src/lib.rs:1234still clears+rebuildsenv.ctor_indexper-module; ct.3.2 narrowed the analogous mono overlay to types-only. The typecheck-side overlay'senv.ctor_indexhalf serves the duplicate-detection diagnostic at workspace-build time, not the runtime ctor lookup (which is type-driven post-ct.2.2). Narrowing is mechanical but needs a careful read to confirm no other consumer survives.- context: JOURNAL 2026-05-11 ("Iteration ct.4") — milestone close follow-up.
P3 — Ideas
-
[todo]
compare_primitives_smoke.ailxcounterpart — the canonical happy-path exhibit for canonical-type-names ships only as JSON. Per Decision 6, Surface is the LLM-author surface; the milestone should have a.ailxcounterpart. Two paths: authorexamples/compare_primitives_smoke.ailxto round-trip into the existing JSON, OR retire the JSON fixture in favour ofexamples/ct_1_ordering_signum.{ailx,ail.json}as the new canonical happy-path exhibit.- context: fieldtest 2026-05-11 (spec_gap).
-
[todo] Codegen
lookup_ctor_in_patterntype-anchoring —crates/ailang-codegen/src/lib.rs:1790still walks every module's ctor_index by bare ctor name. Plumbing the scrutinee's qualifiedType::Conthrough pattern lowering would type-anchor it symmetric to the ct.2.2 typecheck-side fix. Not load-bearing (uniqueness is enforced at typecheck), but cleaner.- context: JOURNAL 2026-05-11 ("Iteration ct.3" + ct.4 close).
-
[todo]
compare_primitives_smokeIR-shape assertion — observecompare__Int/compare__Bool/compare__Strsymbols in the emitted IR. Blocked onemit-irCLI not running mono; resolution paths include extending the CLI to run mono, using library APIs directly in e2e.rs, or adding--dump-irtoail build. The E2E stdout assertion already covers correctness; the IR-shape test would catch refactor regressions that rename mono symbols.- context: JOURNAL 2026-05-11 ("Iteration ct.4") — dropped from ct.4.4 when the BLOCKED condition surfaced.
-
[idea] Latency methodology rework — switch from per-run timing to a histogram-based approach so tail-latency regressions are visible without re-running. Queued from 21'g.
-
[idea] Parser-test backfill for 22b.4a-era duplicate-clause sites (class × 3, class method × 2, instance × 3, instance method × 1). No regression pin today; only worth it if a 22b.4a-era diagnostic needs to change.
- context: JOURNAL 2026-05-10 ("Iteration 22-tidy.7")
-
[idea]
write_typeType::Forallarm incrates/ailang-prose/src/lib.rssilently drops constraints in inline-type rendering. Dormant — surface forms today only carry forall at fn-signature top level. Fix only if a future feature carries forall + constraints inline.- context: JOURNAL 2026-05-10 ("Iteration 22-tidy.6")
-
[idea] Richer integration paths between RC and uniqueness — deferred from the 21' arc; revisit once the uniqueness inference covers more program shapes.