Skip to content

Commit 8af9b46

Browse files
docs(adr): ADR-019 — compiler distribution: Releases + thin Deno/JSR shim (#260 S1) (#283)
INT-04 (#181) "publish compiler + runtime": the runtime JS packages ship to JSR (#261, publish authorised + dispatched 2026-05-19); the compiler is a native OCaml binary, NOT a JSR/npm package. Its distribution was an escalated one-way-door fork (#260, AskUserQuestion). Owner chose option 4 = GitHub Releases binaries + thin Deno/JSR shim. Slice S1 — decision record only, no code (the discipline for a one-way-door, mirroring ADR-015/016): - ADR-019 in docs/specs/SETTLED-DECISIONS.adoc + the META.a2ml `[[adr]]` block (next free id; 016 was #234, 017/018 taken by concurrent merged ADRs). Releases-canonical dual-channel: release.yml emits per-platform binaries + SHA256SUMS (single source of truth; Guix/Nix/npm are additive fetch-derivations later, not separate producers); a thin `@hyperpolymath/affinescript` Deno/JSR shim downloads + checksum-verifies + caches + execs the pinned binary (HTTPS-only, no secrets, one version+checksum per shim release). Staged S1..S4. - INT-10 (`affinescript-lsp` distribution) UNBLOCKED by this decision and filed as #282 (consumes the shim; gated on #260 S2/S3). - TECH-DEBT INT-04 row + ECOSYSTEM INT-10 row truthed. Gate: dune test --force green (docs/a2ml only; zero code, zero regression). Refs #260 #181 #282. Not Closes — staged campaign; owner closes per ISSUE-CLOSURE.
1 parent 0fccded commit 8af9b46

4 files changed

Lines changed: 107 additions & 3 deletions

File tree

.machine_readable/6a2/META.a2ml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,3 +1192,71 @@ references = [
11921192
"docs/RESCRIPT-ELIMINATION.adoc (#229 canonical map; Tier-3 ESC-01)",
11931193
"META.a2ml [[adr]] ADR-012 (grammar changes are correctness assertions)",
11941194
]
1195+
1196+
[[adr]]
1197+
id = "ADR-019"
1198+
status = "accepted"
1199+
date = "2026-05-19"
1200+
title = "Compiler distribution: GitHub Releases binaries + thin Deno/JSR shim (#260)"
1201+
context = """
1202+
INT-04 (#181) is "publish compiler + runtime". The runtime JS packages
1203+
are JSR-publishable and that path is done (affinescript#261). The
1204+
*compiler* is a native OCaml binary — it is NOT a JSR or npm package,
1205+
so "publish the compiler" needed a distribution strategy. This gates
1206+
INT-10 (`affinescript-lsp` distribution, which "waits on a published
1207+
compiler"). The fork was escalated (issue #260; AskUserQuestion
1208+
2026-05-19) over four options: (1) GitHub Releases binaries, (2)
1209+
Guix/Nix channel, (3) thin JSR/npm shim, (4) Releases + shim. The
1210+
owner chose (4).
1211+
"""
1212+
decision = """
1213+
Dual-channel, Releases-canonical:
1214+
1215+
- *Canonical artifact.* Extend the existing `release.yml` (`v*` tags)
1216+
to build per-platform compiler binaries (Linux x86_64 first;
1217+
macOS/Windows as the build matrix allows) and attach them to the
1218+
GitHub Release together with a `SHA256SUMS` manifest. Releases are
1219+
the single source of truth; Guix/Nix and any npm tail become
1220+
*additive fetch-derivations over the same artifact* later (NOT in
1221+
this ADR's slices) — no second producer of the binary.
1222+
- *Ergonomic front door.* A thin Deno/JSR package
1223+
`@hyperpolymath/affinescript` (Deno-first per CLAUDE.md; no OCaml
1224+
source shipped) whose setup step downloads the host-platform binary
1225+
from the pinned Release, verifies it against the `SHA256SUMS`
1226+
checksum *embedded in that shim version*, caches it, and execs it.
1227+
HTTPS-only; no secrets in the shim; provenance = this repo's own
1228+
release workflow. Each shim version pins exactly one compiler
1229+
version+checksum (supply-chain: no floating fetch).
1230+
- *Consumer.* INT-10 `affinescript-lsp` resolves the compiler via the
1231+
shim (`deno add` ergonomics) — this is what unblocks it.
1232+
- npm tail: only if/when an npm-native consumer needs it, mirroring
1233+
the owner-sanctioned affine-vscode npm exception; deferred, not in
1234+
scope here.
1235+
1236+
Staged (ledger #260 / INT-10; each a gated PR):
1237+
- S1 (this): ADR-019 + plan; file INT-10. No code.
1238+
- S2: `release.yml` per-platform binary + `SHA256SUMS` matrix.
1239+
- S3: the `@hyperpolymath/affinescript` shim package (download +
1240+
checksum-verify + cache + exec) + its tests; publish is owner-gated
1241+
via the existing manual JSR workflow (like INT-04).
1242+
- S4: wire INT-10 `affinescript-lsp` onto the shim.
1243+
"""
1244+
consequences = """
1245+
- One-way: fixes the install contract (Releases artifact name/layout +
1246+
shim package name). Reversible per-slice; Releases-canonical keeps
1247+
Guix/Nix/npm strictly additive.
1248+
- INT-10 (`affinescript-lsp` distribution) is unblocked once S2+S3
1249+
land; filed now.
1250+
- Supply chain: every shim release pins one checksummed binary; no
1251+
floating download.
1252+
- This decision is settled; do not reopen without amending this ADR.
1253+
Ledger #260 / INT-10 in docs/TECH-DEBT.adoc.
1254+
"""
1255+
references = [
1256+
"https://github.com/hyperpolymath/affinescript/issues/260",
1257+
"https://github.com/hyperpolymath/affinescript/issues/181",
1258+
".github/workflows/release.yml",
1259+
".github/workflows/publish-jsr.yml (INT-04; owner-gated publish)",
1260+
"docs/PACKAGING.adoc (INT-04; the JS-package half)",
1261+
"docs/specs/SETTLED-DECISIONS.adoc (ADR-019 section)",
1262+
]

docs/ECOSYSTEM.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,9 @@ corrected. INT-02 dep cleared. Runtime BLOCKED by #255 (wasm
227227
loop-codegen defect, pre-existing)
228228
|INT-09 |`affinescript-cadre` router/navigation runtime |ledger-only
229229
|planned (blocked by INT-07)
230-
|INT-10 |LSP distribution (`affinescript-lsp`) |ledger-only |planned
231-
(blocked by INT-04)
230+
|INT-10 |LSP distribution (`affinescript-lsp`) |#282 |unblocked —
231+
distribution decided (ADR-019: Releases + thin Deno/JSR shim, #260).
232+
Consumes the shim once #260 S2/S3 land
232233
|INT-11 |Browser host parity (DOM loader + reconciler end-to-end) |
233234
ledger-only |planned (blocked by INT-02/08)
234235
|INT-12 |typed-wasm convergence: AffineScript-emitted fixtures into the

docs/TECH-DEBT.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ compiler-emitted xmod wasm (closes INT-01↔INT-02). Unblocks INT-05/08/11
189189
Component-Model re-target, staged S1..S6); S3+ hard-gated on S2
190190
toolchain (`wasm-tools`/`wasm-component-ld`)
191191
|INT-04 |Publish to JSR/npm |S2 |#181 packaging READY (dry-run green,
192-
manual workflow); owner-gated publish; compiler-binary = #260
192+
manual workflow); JSR publish authorised + dispatched (owner go
193+
2026-05-19); compiler-binary distribution decided = **ADR-019**
194+
(#260, Releases + thin Deno/JSR shim, staged S1..S4) — unblocks INT-10
193195
|INT-07 |`affinescript-tea` runtime |S2 |#182 runtime + run loop shipped
194196
(TeaApp/parseTeaLayout, Linear-msg enforced); INT-01 cleared (#253)
195197
|INT-08 |DOM reconciler |S2 |#183 implemented + compiles; `.as`→`.affine`

docs/specs/SETTLED-DECISIONS.adoc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,3 +409,36 @@ parts of `burble`) port under this doctrine; per-file execution is the
409409
This decision is settled; do not reopen without amending the ADR. Full
410410
ADR in `.machine_readable/6a2/META.a2ml` (ADR-018); #229 canonical map in
411411
`docs/RESCRIPT-ELIMINATION.adoc`; escalation issue #245.
412+
413+
== Compiler Distribution: GitHub Releases Binaries + Thin Deno/JSR Shim (ADR-019)
414+
415+
INT-04 (#181) is "publish compiler + runtime". The runtime JS packages
416+
are JSR-publishable and shipped (#261); the *compiler* is a native
417+
OCaml binary — not a JSR/npm package — so its distribution was an
418+
escalated one-way-door fork (issue #260, AskUserQuestion 2026-05-19)
419+
over Releases-binaries / Guix-Nix / JSR-shim / combination. The owner
420+
chose the *combination*.
421+
422+
Decision: *Releases-canonical, dual-channel*. The existing
423+
`release.yml` (`v*` tags) is extended to build per-platform compiler
424+
binaries + a `SHA256SUMS` manifest attached to the GitHub Release (the
425+
single source of truth — Guix/Nix and any npm tail are additive
426+
fetch-derivations over it later, not separate producers). A thin
427+
Deno/JSR package `@hyperpolymath/affinescript` is the ergonomic front
428+
door: it downloads the host-platform binary from the pinned Release,
429+
verifies it against the `SHA256SUMS` checksum embedded in that shim
430+
version, caches and execs it (HTTPS-only, no secrets, one
431+
version+checksum pinned per shim release — no floating fetch).
432+
`affinescript-lsp` (INT-10) consumes the shim, which is what unblocks
433+
INT-10. An npm tail is deferred (only if an npm-native consumer needs
434+
it, mirroring the affine-vscode exception).
435+
436+
Staged (ledger #260 / INT-10): *S1* this ADR + plan + file INT-10 (no
437+
code); *S2* `release.yml` per-platform binary + `SHA256SUMS` matrix;
438+
*S3* the shim package (download + checksum-verify + cache + exec) +
439+
tests, publish owner-gated via the existing manual JSR workflow; *S4*
440+
wire INT-10 `affinescript-lsp` onto the shim.
441+
442+
This decision is settled; do not reopen without amending the ADR. Full
443+
ADR in `.machine_readable/6a2/META.a2ml` (ADR-019); ledger #260 /
444+
INT-10 in `docs/TECH-DEBT.adoc`.

0 commit comments

Comments
 (0)