Repository navigation
affinescript: estate-wide ReScript→AffineScript migration tracker [meta] #406
Description
Estate-wide ReScript → AffineScript migration tracker
Cross-repo epic tracking all .res → .affine migration work across the hyperpolymath estate. Lives in affinescript because the migration-assistant tool + the language-grammar features were here.
Status (2026-05-31)
Prior blocker (#228) substantially CLEARED. The original blocker statement was: "Per-repo migration work waits for the type-path grammar to land." That gate has now lifted:
- feat(parser)!: ADR-014 — module-qualified type/effect paths (Refs #228) #241 (MERGED 2026-05-19) — parser slice (ADR-014):
Pkg.Type/Pkg::Typeparse at type AND effect positions - feat(typecheck): module-qualified type/effect path resolution (ADR-014, Refs #228) #447 (MERGED 2026-05-30) — resolution slice: typecheck enforces module exists; mirrors INT-01: cross-module WASM import emission (substrate) #178 for value paths
- feat(parser): builtin/lowercase qualified paths + TOTAL field name (Refs gitbot-fleet#148) #372 (MERGED 2026-05-27) — builtin / lowercase qualified path slice
- LANG: type/effect grammar has no module-qualified path —
Pkg.Type/Pkg.Effectunrepresentable (estate-wide port blocker; ADR-014) #228 itself is still OPEN — pending ADR write-up / formal closure, but its parse blocker is gone - Adjacent qualified-path gaps live in LANG: qualified-path adjacent gaps (lowercase modules, use multi-seg, brace-list) — Refs #228 #448 (4 items: lowercase-module qual head, multi-segment
use, brace-list, bare-unknown-TyCon strictness) — not blockers for migration
Migration assistant (#57) DELIVERED 2026-05-31. Through Phase 3 declaration translation:
- Phase 1 + 2: text scanner → tree-sitter walker, 6 anti-patterns
- Phase 3 slices: aliases / sums (feat(res-to-affine): Phase 3 slice 1 — structural type-decl translation (Refs #57) #477), records / generics (feat(res-to-affine): Phase 3 slice 2 — record + generic type-decl translation (Refs #57) #481), literal
let→const(feat(res-to-affine): Phase 3 slice 3 — literal let→const translation (Refs #57) #484) - Tooling: SessionStart provisioning (chore(config): SessionStart toolchain hook + Phase-3 state note (Refs #57) #482)
- Successor: [Repo] res-to-affine partial-port mode: switch→match / function translation + module-qualified references #488 tracks expression/function partial-port mode + module-mapping (
--partialflag already landed)
tools/res-to-affine/main.exe is the per-PR substrate going forward; --translate (compiler-verified declarations) and --partial (best-effort function skeletons) both work on real estate .res files today.
Children
- Track: ReScript→AffineScript migration backlog (8 .res files; was ~543 LOC at filing) boj-server#67 — Track: ReScript→AffineScript migration backlog (~543 .res LOC) [now 8 files: 5 in
panll/src/, 3 incartridges/orchestrator-lsp-mcp/panels/src/] - Track: ReScript→AffineScript migration backlog (~4,939 LOC) gitbot-fleet#148 — Track: ReScript→AffineScript migration backlog (~4,939 LOC) [hand-port DONE via affinescript#199; only re-validation against mechanical port remains, gated on [Repo] res-to-affine partial-port mode: switch→match / function translation + module-qualified references #488]
- hyperpolymath/idaptik#84 — Track: ReScript→AffineScript migration backlog (~518 .res) [now 460 — STEP 8 megaport dominates with panll]
- Earn-core: web client trustworthy — test suite + ReScript→AffineScript under CI metadatastician/burble#48 — Earn-core: web client trustworthy [now 15 .res across client/admin/tools]
- Migrate ReScript → AffineScript (Stage 1 DONE; 75 .res remain across recon-silly-ation/gui/tools/forge-ops) reposystem#33 — Migrate ReScript → AffineScript; drop vendored BuckleScript .ast artifacts [now 75 files]
- rule: detect SafeDOMExample.res (banned ReScript dialect, should be .affine) hypatia#336 — rule: detect SafeDOMExample.res (banned ReScript dialect, should be .affine)
- sustainabot: add SafeDOMExample.res→.affine standing recipe gitbot-fleet#214 — sustainabot: add SafeDOMExample.res→.affine standing recipe
- [Repo] Migration assistant tool: parser + metaparser for .res→.affine skeletons #57 — [Repo] Migration assistant tool: parser + metaparser for .res→.affine skeletons [CLOSED 2026-05-31; successor [Repo] res-to-affine partial-port mode: switch→match / function translation + module-qualified references #488]
Estate inventory (refreshed 2026-05-31)
Total: ~2,315 .res/.resi across ~70 repos (excluding panll-clone dup). Down from 3,996 baseline.
Top backlog:
- panll 726 / idaptik 460 → STEP 8 megaport (50% of remaining)
- ssg-collection 125 → STEP 7 large (one repo here now)
- stapeln 88 / reposystem 75 / developer-ecosystem 68 / kaldor-iiot 49 / isers 43 / error-lang 38 / claude-integrations 37 / zotero-tools 34 / svalinn 32 / patallm-gallery 32 / ambientops 28 / grim-repo 25 / verisimdb 23 / echidna 21 / avow-protocol 20 → STEP 6 mid-tier (~15 repos)
- ≤20 file × ~55 repos → STEP 5 tail
- developer-ecosystem dropped 460 → 68 (~85% reduction since 2026-05-28)
Campaign coordination
- Umbrella: [campaign] ReScript → AffineScript estate migration (UMBRELLA) standards#252
- Steps: [campaign #252] STEP 1 — LAYER-1 POLICY: hypatia path_allow_prefixes + standards mirror PR set standards#260 (1, CLOSED) / wasm codegen:
++list-concat is a placeholder I32Add (produces garbage/zero-length lists) #264 (2, CLOSED) / test(loader): INT-02 — prove + regression-lock the host-agnostic loader bridge #267 (3, CLOSED) / feat(parser): CORE-01 pt2 — &mut e exclusive-borrow surface (zero conflict delta) #269 (4, CLOSED) / docs(adr): ESC-01 — ADR-018 no raw/FFI escape (typed extern is the only host bridge) #272 (5, OPEN) / feat(typecheck): #234 S2b — build per-call-site effect side-table (ADR-016) #276 (6, OPEN) / feat(codegen): #234 S4 — retire hardcoded async_primitives (ADR-016 complete) #278 (7, OPEN) / test(codegen): #235 — engine-validate #199 closure ABI independent of CPS #279 (8, OPEN, megaport) / feat(tw-verify): #10 — enforce L13 module-isolation on emitted wasm #280 (9, OPEN, plugin-host)
Per-repo work proceeds with the migration assistant in the per-PR cycle. STEP 5 / STEP 6 batches now unblocked. STEP 9 still gated on AS host bindings (orthogonal).
Activity
hyperpolymath commentedon May 30, 2026
Status refresh (2026-05-30):
The tracker is still live and accurate — but the gating blocker #228 (
LANG: type/effect grammar has no module-qualified path) has bifurcated:The estate-wide migration umbrella for the campaign half lives at standards#252 (UMBRELLA: ReScript → AffineScript estate migration) with 9 STEP sub-issues #260-#280; this affinescript-side #406 acts as the producer-side counterpart.
Recommend: keep #406 open as the producer-side tracker, but link standards#252 explicitly in the body so the relationship is bidirectional.
hyperpolymath commentedon May 30, 2026
Estate-wide meta tracker — children status refresh 2026-05-30.
Status of each tracked child:
.resin client/admin/tools; test-suite + CI work also genuinely outstanding.Estate-wide totals
.res/.resiacross ~80 reposCross-campaign closures (standards#252)
++list-concat is a placeholder I32Add (produces garbage/zero-length lists) #264 — closed (inventory refreshed in-thread)Pkg.Type/Pkg.Effectunrepresentable (estate-wide port blocker; ADR-014) #228)STEPS 5–8 (#272/#276/#278/#279) + STEP 9 (#280) remain OPEN as the per-tier residue trackers.
Blocker check
Body says blocked on affinescript#228 (qualified-path grammar). Still OPEN — confirmed today. That blocker continues to gate the estate elimination per affinescript#229.
Keeping this meta-tracker open as the estate-wide rollup.
hyperpolymath commentedon May 30, 2026
Estate-wide orphan-res discovery 2026-05-30.
A scan for
.resfiles where a sibling.affineexists at the same basename ("orphan-res pattern") reveals 57 estate-wide pairs, indicating the hand-port wave got further than the per-repo trackers reflect:.restotal — Phase 5 hand-port near-total; perREADINESS.adoc,.resretained as fallback until.affineCI-verifiedImplication for per-repo trackers
The current "N
.resremain" counts in per-repo trackers (e.g., idaptik#84 says 516, burble#48 says 27) overstate the remaining port work by the orphan-res count — those files have.affinesiblings already.True "needs-port" estimate:
Path to discharge
Per bilateral-retention pattern (cf. standards#241 sweep today +
burble/READINESS.adoc), orphan-res deletion is gated on.affineCI verification — the.resis the live fallback until then. Two paths:.affineCI integration — once the AS toolchain compiles + runs the.affinein CI, delete the paired.res. This is per-repo engineering work.Pkg.Type/Pkg.Effectunrepresentable (estate-wide port blocker; ADR-014) #228 sweep — affinescript#228 (qualified-path grammar) unlocks.affineparsing; once it lands, oracle-validation across the orphan-res set becomes mechanical, and verified pairs can be swept-deleted in one campaign.Recommendation
File a new sub-issue or use this meta-tracker as the rollup. The orphan-res sweep is load-bearing for closing burble#48, partial accessibility-everywhere/stapeln progress, and refining idaptik#84's true scope.
feat(shared): ReScript→AffineScript shadow port of Domain.res (#25)
feat(shared): ReScript→AffineScript shadow port of Route.res (#24)
hyperpolymath commentedon Jun 1, 2026
Status update — AS stdlib codegen pattern now established (2026-06-01) 📌
For ticket coordinators / anyone tracking this gap:
lib/codegen_deno.ml. Tests live intests/codegen-deno/*.What this means for the gap tracked in this ticket:
stdlib/*.affine→ wire indeno_builtinstable + prelude → smoke-test intests/codegen-deno/*.🤖 Cross-estate AS-status sweep on 2026-06-01.