Skip to content

feat(shim): close INT-10 — pin v0.1.1 (full coverage), bump shim 0.1.2 - #295

Merged
hyperpolymath merged 1 commit into
mainfrom
int10-282-close-v011
May 20, 2026
Merged

feat(shim): close INT-10 — pin v0.1.1 (full coverage), bump shim 0.1.2#295
hyperpolymath merged 1 commit into
mainfrom
int10-282-close-v011

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

  • Final wiring for INT-10 (INT-10: affinescript-lsp distribution (consume the ADR-019 compiler shim) #282). The v0.1.1 Release (cut after ci(release): swap retired macos-13 runner for macos-15-intel #292 swapped the retired macos-13 runner) produced all three platform binaries — the macos-x64 leg picked up a macos-15-intel runner this time and built cleanly. This PR pins all three:
    • linux-x64: b8f2cab7380306ca07b9599d7fe2470328236e7287a51c78c3bbb5e973fef5dc
    • macos-x64: 6bc3837ef94f9b56a8bb63cec84c3f0ddf2d7e1092f49aa1d389da389b28b5e2
    • macos-arm64: 7f7cb5ee6b7ef37818498813891a2cd636300da7cb4a59e938031c78c0ee3589
  • pins.js VERSION v0.1.0v0.1.1, all three sha256 fields filled, interim "macos-x64 stuck" comment dropped.
  • Shim @hyperpolymath/affinescript bumped 0.1.10.1.2 in lockstep (pins.js header rule); LSP-side SHIM_SPEC tracks it.

Aside

The canonical SHA256SUMS on the v0.1.1 Release was uploaded by me manually because release.yml's checksums job has no actions/checkout and gh release download failed on the missing .git. That bug was hidden on v0.1.0 by the macos-13 stall (the checksums job never even started). Fix in #294.

Verification

  • deno test (packages/affinescript-cli): 6/6 green
  • cargo test (tools/affinescript-lsp): 26/26 green
  • Real end-to-end smoke (host = linux-x64) against the live v0.1.1 Release:
    resolved: /tmp/affs-cache-v011/affinescript/v0.1.1/affinescript-linux-x64
    exit: 0
    
    resolveCompiler() downloaded the new binary, SHA-verified against the new pin, cached, execed --version. macOS legs not smoked from this host but the same code path is covered by the shim tests.

Closes #282. Refs #260, #181. ADR-019 in docs/specs/SETTLED-DECISIONS.adoc.

🤖 Generated with Claude Code

Final S4 wiring for #282.  The v0.1.1 Release (cut on main after #292
swapped the retired macos-13 runner) produced all three platform
binaries — the macos-x64 leg picked up a runner this time and built
cleanly on macos-15-intel.  This PR pins all three:

  linux-x64:    b8f2cab7380306ca07b9599d7fe2470328236e7287a51c78c3bbb5e973fef5dc
  macos-x64:    6bc3837ef94f9b56a8bb63cec84c3f0ddf2d7e1092f49aa1d389da389b28b5e2
  macos-arm64:  7f7cb5ee6b7ef37818498813891a2cd636300da7cb4a59e938031c78c0ee3589

`pins.js` `VERSION` v0.1.0 → v0.1.1, all three sha256 fields filled,
and the "macos-x64 stuck in queue" interim comment is dropped.

Shim package bumped 0.1.1 → 0.1.2 in lockstep (pins.js header rule),
and the LSP-side `SHIM_SPEC` tracks it.

Side note (not blocking): the canonical `SHA256SUMS` on the v0.1.1
Release was uploaded by me manually because release.yml's `checksums`
job has no `actions/checkout` step and `gh release download` failed on
the missing `.git` (the bug was masked on v0.1.0 by the macos-13 stall
that never let `checksums` run).  Fix landed in #294.

Verification
- `deno test` (packages/affinescript-cli): 6/6 green
- `cargo test` (tools/affinescript-lsp): 26/26 green
- Real end-to-end smoke (host = linux-x64): `resolveCompiler()`
  downloaded `affinescript-linux-x64` from v0.1.1, SHA-verified against
  the new pin, cached at /tmp/affs-cache-v011/affinescript/v0.1.1/,
  execed `--version` → exit 0.  macos-x64 and macos-arm64 not smoked
  from this host but the same code path is covered by the shim tests.

Closes #282.  Refs #260, #181.  ADR-019 in docs/specs/SETTLED-DECISIONS.adoc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 40 issues detected

Severity Count
🔴 Critical 12
🟠 High 16
🟡 Medium 12

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stray AI.a2ml in root -- use 0-AI-MANIFEST.a2ml only",
    "type": "banned",
    "file": "AI.a2ml",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Superseded by 0-AI-MANIFEST.a2ml",
    "type": "banned",
    "file": "AI.djot",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Issue in quality.yml",
    "type": "missing_workflow",
    "file": "quality.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in security-policy.yml",
    "type": "missing_workflow",
    "file": "security-policy.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action actions/checkout@v4 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action denoland/setup-deno@v2 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/example/smoke_driver.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/cli.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath
hyperpolymath merged commit 59caafa into main May 20, 2026
15 checks passed
@hyperpolymath
hyperpolymath deleted the int10-282-close-v011 branch May 20, 2026 06:48
hyperpolymath added a commit that referenced this pull request May 20, 2026
Two bundled changes that both feed the @hyperpolymath/affinescript
0.1.2 publish path.

JSR fast-check: typed entrypoint
--------------------------------
JSR's `deno publish` emits an `unsupported-javascript-entrypoint`
warning whenever a JS module has no associated `.d.ts`.  Without the
declaration, JSR falls back to type inference and consumers see no
editor types on the package page.  Add `mod.d.ts` (TypeScript carve-
out, same precedent as `packages/affine-js/types.d.ts`) and a
`/// <reference types="./mod.d.ts" />` in `mod.js` so JSR picks it up.
Dry-run is now clean and the published files grow by one 2.87 KB type
file.

Cross-runtime: Deno, Bun, Node
------------------------------
The shim's consumers — LSP installers, IDE extensions, build scripts
wiring AffineScript into a CI pipeline — overwhelmingly live in Node
and Bun ecosystems, not Deno.  Forcing them to install Deno solely to
fetch+verify+exec a binary defeats the "ergonomic install" purpose of
the shim.  Refactor `mod.js` to detect the runtime once at module
load (`isDeno`/`isBun`/`isNode`) and branch every host effect through
a small helper layer:

  hostOs() / hostArch() / envGet() — process.* on Bun+Node, Deno.*
                                     on Deno; arch normalised to
                                     Deno's spelling ("x86_64"/"aarch64")
                                     so hostTarget() stays unchanged.
  readBytes() / writeBytes() / mkdirRecursive() / chmodExec()
                                   — Deno.* on Deno, Bun.file/Bun.write
                                     on Bun, node:fs/promises on Node.
  spawnInherit()                   — Deno.Command / Bun.spawn /
                                     node:child_process.spawn.
  thisIsMain()                     — import.meta.main on Deno+Bun;
                                     URL comparison on Node.

The public API (hostTarget, sha256Hex, cachePath, resolveCompiler,
run) is unchanged; mod.d.ts captures the contract.

Browsers and Cloudflare Workers are explicitly NOT supported: the
shim's job is fetch+save+exec, and steps 2–3 are not possible in a
sandboxed JS runtime.  Documented inline in the module header.

CLAUDE.md
---------
Add two carve-outs:
  - TypeScript Exemptions: `packages/affinescript-cli/mod.d.ts`.
  - Runtime Exemptions (NEW section): `packages/affinescript-cli/mod.js`
    is the one approved Node+Bun exemption in the repo.  Same
    "explicit user approval" gate as the TS exemptions.

Verification
------------
- `deno test` (packages/affinescript-cli): 6/6 green (unchanged).
- `deno publish --dry-run`: 4 files including mod.d.ts, no warnings.
- Cross-runtime smoke (hermetic fake fetch + fake binary; same
  contract as the Deno suite — download + checksum + cache + exec +
  argv passthrough + exit-code):
      Deno: OK
      Bun:  OK
      Node: OK
  Run under deno 2.x, bun 1.3.14, node 22.11.0.

Refs the @hyperpolymath/affinescript JSR-publish path (post-#295 follow-up).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 20, 2026
…ke (#297) (#300)

Closes the five-site `0.1.0` drift documented in #297: the compiler
binary's `--version`, REPL banner, LSP `initialize` response, and the
ONNX `m_producer_version` field were all hand-edited to "0.1.0" and
never bumped when v0.1.1 was tagged, so the v0.1.1 binary still
reported "0.1.0" (caught during the #282/#295 shim smoke).

Approach: option (1) from #297 — generated `Version` module + CI
substitution.  One small module + one small workflow step; no
runtime dependency on `dune-build-info` or any new opam package.

Source-of-truth single file
---------------------------
  lib/version.ml            new — `let value = "0.1.1"`, 1 string,
                                  baked from the tag at release time

Five sites collapsed onto it
----------------------------
  bin/main.ml         `let version = Affinescript.Version.value`
  lib/repl.ml         `Printf.printf "AffineScript REPL v%s\n"
                                     Version.value`
  lib/lsp_server.ml   `("version", `String Version.value)`
  lib/onnx_codegen.ml `m_producer_version = Version.value`
  dune-project        `(version 0.1.1)` (matches the latest release;
                       opam metadata regenerated)
  lib/dune            `version` added to the modules list

Release pipeline bake step
--------------------------
`.github/workflows/release.yml`: new step between `Install
dependencies` and `Build release` that rewrites BOTH `lib/version.ml`
and `dune-project` from `${GITHUB_REF_NAME#v}` (stripping the leading
`v`) before `dune build --release`.  Subsequent tag bumps need no
hand-edit — cut a `vX.Y.Z` tag and the binary self-reports `X.Y.Z`.

Cross-checked locally
---------------------
  $ opam exec -- dune build --release
  (clean, no warnings introduced)

  $ _build/default/bin/main.exe --version
  0.1.1

  $ grep '^version'     affinescript.opam   # 0.1.1
  $ grep '^let value'   lib/version.ml      # 0.1.1
  $ grep '^(version'    .build/dune-project # 0.1.1

All four sites coherent.

Closes #297.  Refs #282 (the closure-PR smoke that surfaced the drift).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 20, 2026
…JSR publish (#303)

INT-04 and INT-10 were both marked DONE in TECH-DEBT, but the wording
predated the actual JSR publish:

  - INT-04 line said "JSR publish authorised + dispatched (owner go
    2026-05-19)" — speculative; the real first-time publish landed
    2026-05-20 (six dispatched runs through the scope/package/trusted-
    publisher/SPDX-licence/.d.ts/cross-runtime gates).
  - INT-10 said DONE but didn't note the LSP's shim-resolution path
    only became *executable* after today's publish (code was correct
    but inert against a 404 JSR URL).

Updates
- docs/TECH-DEBT.adoc — INT-04 + INT-10 lines reflect the live publish,
  with explicit note that @hyperpolymath/affine-js + affinescript-tea
  remain dry-run-OK / not-yet-dispatched.
- docs/PACKAGING.adoc — JSR-publishable table now has 3 rows with a
  Status column; @hyperpolymath/affinescript row records the LIVE
  0.1.2 (2026-05-20) state, cross-runtime carve-out, MPL-2.0 licence
  pointer.  New "First-time JSR publish gotchas" subsection captures
  the five gates that fail one at a time (scope claim, package create,
  trusted GH repo link, SPDX licence, sibling .d.ts + triple-slash
  reference) — dry-run misses gates 2 + 3 so they cost a round-trip.
- .machine_readable/6a2/STATE.a2ml — new session-note-2026-05-20
  following the existing `session-note-YYYY-MM-DD = "…"` convention,
  capturing every landed PR (#291/#292/#293/#294/#295/#298/#299) and
  the estate macos-13 sweep (casket-ssg#8, proven#29, repos-monorepo#9),
  plus the open follow-up tickets (#297/#300, #301, #302).  This file
  is the STATE.a2ml mirror, not the lead; TECH-DEBT.adoc is the spine.

No code change.  TECH-DEBT update protocol calls for ledger + STATE
mirror in lockstep; PACKAGING is the human-facing companion.  Memory
entries (`reference_macos_13_runner_retired`,
`reference_estate_gitbot_auto_closes_on_refs`,
`reference_estate_mirror_state_2026_05_20`,
`reference_jsr_publish_recipe`) live in `~/.claude/projects/.../memory/`
and are out of repo scope.

Refs #282 (closed), #301, #302, #297, #300.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant