Migrate ReScript corpus to AffineScript via res-to-affine (#488)#47
Merged
Merged
Conversation
Transpile all 32 unique ReScript modules (src/ + ui/src/) to .affine using
the estate res-to-affine migration assistant (affinescript#488), walker
engine over the pinned tree-sitter-rescript grammar. Per-file mode was
chosen by translated-yield: --translate for type-dominant modules,
--partial for function-bearing modules.
Each .affine carries migration markers (the six idaptik anti-patterns),
the translated structural declarations / fn skeletons, and the full
original ReScript quoted inline for the human finishing the port. This is
a partial port by design ("re-decompose, not transliterate"): it is not a
drop-in compilable replacement — the HTTP-server, Web-Crypto, and Tea-UI
layers await AffineScript bindings that do not exist yet.
Clean cutover (replaces .res with .affine):
- delete 32 .res sources + 28 compiled .res.mjs artifacts
- delete stale lib/ocaml/ duplicate (28 .res + .cmj/.ast artifacts)
- remove rescript.json, ui/rescript.json, lib/rescript.lock
- strip rescript tasks/imports from deno.json + src/deno.json and the
rescript build scripts/devDep from ui/package.json
Known follow-ups (the repo no longer builds, as expected for a cutover):
- 3 TS consumers (svalinn_bench.ts, IntegrationTests.test.ts,
PropertyTests.test.ts) import the removed *.res.mjs — dangling until
re-pointed at AffineScript output.
- Modules with polymorphic variants / nested-module types and the Tea UI
translate to 0 forms (kept as quoted originals) pending re-decomposition.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LvRZrgsjBFTzuukgjDyrr1
hyperpolymath
marked this pull request as ready for review
June 26, 2026 20:40
hyperpolymath
added a commit
that referenced
this pull request
Jun 26, 2026
…gates (#48) Follow-up to the merged #47 (ReScript → AffineScript migration). Addresses the two things flagged there. ## Task A — TS consumers of the removed ReScript output `src/benches/svalinn_bench.ts`, `src/tests/IntegrationTests.test.ts`, and `src/tests/PropertyTests.test.ts` imported the deleted `*.res.mjs` (`Jwt` / `OAuth2` / `PolicyEvaluator`). Replaced those dangling imports with **typed throwing stubs** and marked every test/bench `ignore: true`, so the suite **type-checks and skips honestly** until AffineScript gains a JS backend — at which point you re-point the stubs at the compiled output and drop `ignore`. Files run through `deno fmt`. ## Task B — the two governance failures (both pre-existing, not caused by the migration) Worth stating clearly: **neither failure was introduced by #47** — the migration actually made the ReScript anti-pattern check pass (`✅ No non-exempt ReScript files`). - **Licence consistency** — `LICENSE` had no `SPDX-License-Identifier:` header. Added `SPDX-License-Identifier: MPL-2.0` + `SPDX-FileCopyrightText` at the top. - **Language / package anti-pattern policy** — the sole finding was the banned Python file `tools/mvp/svalinn_gate.py` (the SaltStack carve-out was removed estate-wide). Ported it to a **Rust crate** at `tools/mvp/svalinn-gate/`: - Faithful port: `serde_json` + `base64`, shells out to `openssl pkeyutl -verify -rawin` over the same DSSE PAE bytes, same `verify` flags, same `{ ok, error: { id, message, details } }` JSON envelope and exit codes. - **Verified it compiles** (`cargo build --release`) and smoke-tested the CLI contract (arg handling, `ERR_POLICY_DENIED` envelope, exit 1). - Updated the consumer `svalinn_gateway.ts` spawn, `tools/mvp/README.adoc`, and `MVP.adoc` to invoke the built binary. `target/` is gitignored; `Cargo.lock` is committed. After this, the **anti-pattern policy** and **Licence consistency** checks should go green (no `.py` remains; LICENSE has SPDX). ## What this PR does *not* claim to fix The `Format Check` / `Type Check` / `Test` / `Lint` cluster reflects the repo-wide cutover state from #47 (e.g. existing files that aren't `deno fmt`-clean, and AffineScript not yet compiling to JS). This PR makes the **three files it touches** fmt-clean and import-clean, but does not repo-wide reformat or restore a green build — that's out of scope here. What it is for, for the record: `svalinn_gate.py` → `svalinn-gate` is the **MVP policy gate** — given a container's DSSE/in-toto attestation bundle, a policy, and a trust store, it admits or denies the image (bundle shape, transparency-log quorum + known operators, subject-digest match, required predicates, and a valid signature from an allowed signer). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LvRZrgsjBFTzuukgjDyrr1 --- _Generated by [Claude Code](https://claude.ai/code/session_01LvRZrgsjBFTzuukgjDyrr1)_ Co-authored-by: Claude <paraordinate@yahoo.co.uk> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
hyperpolymath
pushed a commit
that referenced
this pull request
Jun 26, 2026
…ipt.json The `Type Check` CI job ran `deno check main.ts compose/cli.ts` (working-directory src), but src/main.ts and src/compose/cli.ts never existed — since the .res→.affine migration (#47) src/ holds AffineScript, not a Deno TS app, so the check was failing on missing modules (TS2307). The only real TS entrypoint is the MVP gateway, so point the check (ci.yml + the src/deno.json `check` task) at tools/mvp/svalinn_gateway.ts. Also remove the stale src/rescript.json — a ReScript build config left behind by the #47 cutover. Note: `deno check` segfaults in the dev sandbox on Deno-API-using files, so the gateway type-check is verified by CI rather than locally. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvRZrgsjBFTzuukgjDyrr1
hyperpolymath
added a commit
that referenced
this pull request
Jun 26, 2026
…script.json (#49) Fixes the one CI check left red after #47/#48 that is actually in svalinn's control. ## Problem The `Type Check` job ran `deno check main.ts compose/cli.ts` (`working-directory: src`), failing with: ``` TS2307: Cannot find module '.../src/main.ts'. TS2307: Cannot find module '.../src/compose/cli.ts'. ``` Those entrypoints **never existed**. Since the `.res → .affine` migration (#47), `src/` holds AffineScript, not a Deno TS app — `src/main.ts` / `src/compose/cli.ts` were aspirational references. The only real TS entrypoint in the repo is the MVP gateway, `tools/mvp/svalinn_gateway.ts` (0 imports, self-contained). ## Fix - `.github/workflows/ci.yml` — Type Check now runs `deno check tools/mvp/svalinn_gateway.ts`. - `src/deno.json` — the `check` task points at the same entrypoint (so `deno task check` matches CI). - Removed **`src/rescript.json`** — a stale ReScript build config the #47 cutover missed. ## Verification note `deno check` segfaults in my dev sandbox on any Deno-API-using file (a v8/sandbox issue — a trivial file checks fine), so I couldn't run the gateway type-check locally; **CI is the verifier**. If the gateway turns out to have a latent type error, that's a real pre-existing finding I'll fix on this branch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LvRZrgsjBFTzuukgjDyrr1 --- _Generated by [Claude Code](https://claude.ai/code/session_01LvRZrgsjBFTzuukgjDyrr1)_ Co-authored-by: Claude <paraordinate@yahoo.co.uk> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2 tasks
hyperpolymath
added a commit
that referenced
this pull request
Jun 27, 2026
…/main.ts (#55) ## What & why `Build Binaries` has been failing on every PR with: ``` TS2307 [ERROR]: Cannot find module 'file:///.../src/main.ts'. error: Type checking failed. ``` The job still compiled `src/main.ts` and `src/compose/cli.ts` — files the **Type Check job's own comment** says *"were never created"*. Since the `.res→.affine` migration (#47–#51), `src/` holds **AffineScript**, not a Deno TS app, so those entrypoints don't exist and the build crashed every run. This is the *same stale-entrypoint infra bug* PR #49 already fixed for `typecheck` (which now points at the MVP gateway) — it was simply missed for `build`. ## Fix - Build the real, type-checked TS entrypoint: **`tools/mvp/svalinn_gateway.ts`** (the approved MVP gateway), matching the Type Check job. - Drop the bogus `svalinn-compose` step — `compose/cli.ts` never existed and `src/compose/` is AffineScript (`ComposeOrchestrator.affine`, `ComposeTypes.affine`). - Permissions match the gateway's actual runtime surface: `Deno.serve` (net), `Deno.readTextFile` (read), `Deno.writeTextFile`/`makeTempFile`/`remove` (write), `Deno.env` (env), `Deno.Command` for `vordr`/`svalinn-gate` (run). - Artifact path follows the entrypoint out of `src/` → repo-root `dist/`. ## Verification Compiled locally with **deno 2.9.0**: ``` $ deno compile --allow-net --allow-read --allow-write --allow-env --allow-run \ -o dist/svalinn tools/mvp/svalinn_gateway.ts svalinn └── svalinn_gateway.ts (61.44KB) # rc=0, 108 MB binary produced ``` The old `src/main.ts` command crashes, as expected. Workflow YAML re-parsed clean. ## Relationship to D3 / `AGENTIC.a2ml` Not a ReScript patch — it touches only a CI workflow path, so it does **not** conflict with the "don't patch pre-existing ReScript breakage" rule. The migration already turned Type Check / Lint / Format / Test / Extended Tests **green**; this stale build path was the only remaining svalinn-side red. > The other red check, `scan / Hypatia`, is an Elixir compile error **inside the `hyperpolymath/standards` scanner** (`lib/rules/structural_drift.ex:1019: undefined variable "real_subdirs"`) — it lives in a different repo and cannot be fixed from svalinn. ## Type of Change - [x] CI/Build configuration ## Surface Impact - [x] No surface changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Generated by [Claude Code](https://claude.ai/code/session_01XhuUim2UaLDziQRrFgtBTJ)_ Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Jun 27, 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.
What
Transpiles all 32 unique ReScript modules in svalinn (
src/+ui/src/) to.affineusing the estateres-to-affinemigration assistant (affinescript#488), then performs a clean.res → .affinecutover.How
tools/res-to-affinefrom the affinescript repo (OCaml/dune) and ran it with the walker engine over the pinnedtree-sitter-rescriptgrammar (990214a).--translatefor type-dominant modules → compilable AffineScriptstruct/type/constdecls.--partialfor function-bearing modules →fnskeletons (switch→match, best-effort bodies,_type holes)..affinecarries: the migration-marker block (the six idaptik anti-patterns, with source lines + the AffineScript answer), the translated forms, and the full original ReScript quoted inline so nothing is lost.Important: this is a partial port by design
Per the assistant's standing rule — "re-decompose, not transliterate" — the output is not a drop-in compilable replacement. AffineScript currently has no bindings for the HTTP server (
Deno.serve→GatewayServer), Web-Crypto subtle (importKey/verify→Jwt/OAuth2), or a UI framework (theui/layer is Elm-architectureTea+ JSX). ReScript polymorphic variants and nested-module types also have no 1:1 form. Those modules translate to 0 forms and are kept as quoted originals + markers, awaiting re-decomposition and bindings.Cutover (replaces .res with .affine)
.affine(5,956 lines).ressources + 28 compiled.res.mjslib/ocaml/duplicate (28.res+.cmj/.astartifacts — was a verbatim mirror ofsrc/, not used by the build)rescript.json,ui/rescript.json,lib/rescript.lockdeno.json+src/deno.json; removed rescript build scripts/devDep fromui/package.jsonKnown follow-ups (the repo no longer builds — expected for a cutover)
src/benches/svalinn_bench.ts,src/tests/IntegrationTests.test.ts,src/tests/PropertyTests.test.ts) import the removed*.res.mjsand now have dangling imports — re-point at AffineScript output once it exists.deno.lock/src/deno.lockstill reference the removed rescript deps (regenerate withdeno).🤖 Generated with Claude Code
https://claude.ai/code/session_01LvRZrgsjBFTzuukgjDyrr1
Generated by Claude Code