feat(res-to-affine): Phase-1 migration assistant skeleton (Refs #57)#314
Merged
Conversation
Lands the .res→.affine migration assistant proposed in #57 as a tight Phase-1 cut: an OCaml CLI under tools/res-to-affine/ that text-scans a ReScript source for four of the six anti-patterns from idaptik's Wave 3 pilot (side-effect imports, %raw blocks, untyped exceptions / Promise.catch, mutable globals via :=) and emits a .affine skeleton with migration markers + the quoted original. Architecture decision recorded in docs/MIGRATION-ASSISTANT.adoc: canonical .res grammar is rescript-lang/tree-sitter-rescript, vendored manifest-only under editors/tree-sitter-rescript/ (pinned commit 990214a, MIT, compatible with this repo's MPL-2.0). Phase 2 swaps the text scanner for a tree-sitter AST walker; Phase 3 does partial translation of pure-structural forms. See tools/res-to-affine/README.md for the full plan and tools/res-to-affine/test/ for snapshot tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lands the
.res→.affinemigration assistant proposed in #57 as a tight Phase-1 cut:tools/res-to-affine/— OCaml CLI built by the repo'sdunetoolchain. Text-scans a.ressource for 4 of the 6 anti-patterns from idaptik's Wave 3 pilot (side-effect imports,%rawblocks, untyped exceptions /Promise.catch, mutable globals via:=) and emits a.affineskeleton with migration markers + the quoted original at the bottom for reference.editors/tree-sitter-rescript/— manifest-only vendoring of the canonicalrescript-lang/tree-sitter-rescriptgrammar, pinned at commit990214a(v6.0.0, MIT). Not used yet — wired up in Phase 2.docs/MIGRATION-ASSISTANT.adoc— architectural decision: canonical grammar, three-phase plan, alternatives considered.tools/res-to-affine/test/— alcotest snapshot suite. Synthetic fixture exercises all four Phase-1 patterns; spot-checked againstgitbot-fleet/bots/sustainabot/bot-integration/src/*.res(correctly finds 0 inConfig.res/Webhook.res/Oikos.res, 2 inMain.res, 3 inGitHubAPI.res).This PR uses Refs not Closes for #57 — the proposal is multi-phase and this is Phase 1 only. Phase 2 (tree-sitter AST walker) and Phase 3 (partial translation of pure-structural forms) are scoped in
tools/res-to-affine/README.mdand the ADR.Cross-references:
hyperpolymath/gitbot-fleet#148(consumer — 2,133 LOC ReScript subtree blocked on #57).Why Phase-1 is text-scan, not tree-sitter
The user picked tree-sitter integration as the long-run direction (right per LESSONS.md "tree-sitter as canonical grammar source"), but committing all of that in one PR would leave no shippable artefact behind if Phase 2 stalls. Phase 1 is deliberately small and useful in isolation:
.resfile today.Emitterinterface Phase 2 will use, so the swap is local.See
docs/MIGRATION-ASSISTANT.adocfor the full rationale and the alternatives considered (bs-toolstyped AST, hand-rolled OCaml parser, pattern-detector-only).Test plan
dune buildclean repo-wide (no regression to existing 80+ modules underlib/).dune test tools/res-to-affine/test/— 3/3 OK (snapshot, scanner kinds, module-name derivation).gitbot-fleet.resfiles end-to-end: scanner output matches expectations (clean files report 0, files withtry/Js.Exn/Promise.catchreport the right line numbers).Files
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com