Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
57 changes: 57 additions & 0 deletions bots/sustainabot/bot-integration/MIGRATION-NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!-- SPDX-License-Identifier: PMPL-1.0-or-later -->
# ReScript → AffineScript Migration (issue #148)

This subtree was migrated from ReScript to AffineScript on 2026-05-24 by a
**hand-port under explicit policy override** of issue #148's
"do-not-hand-port-ahead-of-the-compiler" rule.

## Scope of migration

- All `.res` / `.res.js` under `src/`, `src/tea/`, `bindings/`, and
`lib/ocaml/` were deleted.
- The `rescript-runtime/` vendored Belt runtime was deleted.
- `rescript.json` was deleted.
- `package.json` and `deno.json` were updated to target the AffineScript
toolchain instead of `rescript build` / `.res.js` outputs.
- The 11 in-scope `.res` files were re-expressed as `.affine`:
`Types`, `Config`, `Webhook`, `Analysis`, `GitHubAPI`, `GitHubApp`,
`Report`, `Router`, `Oikos`, `Main`, and `tea/ServerTea`.

## Known caveats (must be verified by the real mechanical migrator)

The hand-port was done without an AffineScript compiler available to the
porter, against the canonical README spec only. Several pieces are
educated guesses that the upstream Phase-3 migration assistant
(affinescript#57 / PR #314) is expected to redo:

1. **`Json` and `Dict` are placeholder names** in many type signatures.
The portable `Json` primitive is tracked by affinescript#161 (OPEN)
and `Dict`/`Map` by #162 (OPEN). Once those land, the placeholders
need to be re-pointed at the canonical stdlib names.
2. **Effect rows** use a conservative `-{IO + Http + Crypto + Exn[E]}->`
shape. These need narrowing against the actual effect declarations
in the stdlib.
3. **TEA runtime (`tea/ServerTea.affine`)** uses `mut` cells and
mutually-recursive closures. The borrow checker may force this into
a single-owner / handler-state shape — exact form to be settled by
the actual checker.
4. **JWT crypto chain (`GitHubApp.affine`)** assumes Web Crypto-derived
stdlib bindings (`Crypto.import_key_pkcs8`,
`Crypto.sign_with_algorithm`). Real binding names will land with
`#103` (Async-extern ABI — closed 2026-05-18) once the canonical
stdlib surface is published.
5. **Bindings deleted** (`bindings/Deno.res`, `bindings/Fetch.res`) —
their callers now reference target-agnostic stdlib names
(`Http.fetch`, `Env.get`, `Console.log`, etc.). The compiler's
target-binding layer is expected to lower these per backend.

## Re-port checklist (when affinescript#57 Phase 3 lands)

- [ ] Run the mechanical migrator over the original `.res` (via
`git show <pre-migration-sha>:path/to/file.res`) and diff its
output against the hand-port.
- [ ] Substitute placeholder `Json` / `Dict[String, V]` references with
whatever canonical names #161 / #162 land with.
- [ ] Re-narrow effect rows against the actual stdlib declarations.
- [ ] Run `affinescript check src/` against every file and resolve any
remaining errors that the hand-port couldn't anticipate.
160 changes: 0 additions & 160 deletions bots/sustainabot/bot-integration/bindings/Deno.res

This file was deleted.

39 changes: 0 additions & 39 deletions bots/sustainabot/bot-integration/bindings/Deno.res.js

This file was deleted.

13 changes: 0 additions & 13 deletions bots/sustainabot/bot-integration/bindings/Fetch.res

This file was deleted.

9 changes: 0 additions & 9 deletions bots/sustainabot/bot-integration/bindings/Fetch.res.js

This file was deleted.

37 changes: 12 additions & 25 deletions bots/sustainabot/bot-integration/deno.json
Original file line number Diff line number Diff line change
@@ -1,41 +1,28 @@
{
"name": "@oikos/bot",
"version": "0.1.1-beta",
"version": "0.2.0-beta",
"exports": {
".": "./src/Oikos.res.js",
"./router": "./src/Router.res.js",
"./tea": "./src/tea/ServerTea.res.js"
".": "./src/Oikos.affine",
"./router": "./src/Router.affine",
"./tea": "./src/tea/ServerTea.affine"
},
"publish": {
"include": ["src/**/*.js", "src/**/*.res", "bindings/**/*.js", "bindings/**/*.res", "rescript-runtime/**/*.js", "README.md", "LICENSE"]
"include": ["src/**/*.affine", "README.md", "LICENSE", "MIGRATION-NOTES.md"]
},
"tasks": {
"build:rescript": "rescript build",
"watch:rescript": "rescript build -w",
"clean": "rescript clean",
"start": "deno run --allow-net --allow-env --allow-read src/Oikos.res.js",
"start:legacy": "deno run --allow-net --allow-env --allow-read src/Main.res.js",
"dev": "deno run --watch --allow-net --allow-env --allow-read src/Oikos.res.js",
"build": "affinescript compile src/Main.affine",
"watch": "affinescript compile --watch src/Main.affine",
"clean": "rm -rf _build",
"smee": "deno run --allow-net --allow-env scripts/smee-client.ts",
"test": "deno test --allow-net --allow-env --allow-read",
"lint": "deno lint",
"fmt": "deno fmt"
"test": "affinescript test",
"lint": "affinescript lint src/",
"fmt": "affinescript fmt src/"
},
"imports": {
"@std/http": "jsr:@std/http@^1.0.0",
"@std/log": "jsr:@std/log@^0.224.0",
"@std/dotenv": "jsr:@std/dotenv@^0.225.0",
"@std/crypto": "jsr:@std/crypto@^1.0.0",
"@rescript/runtime/lib/es6/": "./rescript-runtime/"
},
"compilerOptions": {
"strict": true,
"allowJs": true
},
"lint": {
"rules": {
"tags": ["recommended"]
}
"@std/crypto": "jsr:@std/crypto@^1.0.0"
},
"fmt": {
"useTabs": false,
Expand Down
Loading
Loading