Repository navigation
chore(opencode): require Node >=22, dropping end-of-life 18 and 20 - #24
Conversation
Node 18 (EOL 2025-04-30) and 20 (EOL 2026-04-30) will not receive the eMudhra intermediate SPKI blocklist (nodejs/node#66871), so advertising them as supported would point users at runtimes that can never be patched. 22, 24 and 26 are the lines the backport targets. Refs #23
reviewer9io
left a comment
There was a problem hiding this comment.
Reviewed the complete change at 18faebe457b31da894d54ba7b8d5284c78715187 and its plugin/packaging consumers. No actionable blocker found. Runtime and dependency declarations are otherwise unchanged.
Fresh Node 22.21.0 verification passed: all 11 existing tests, typecheck, a seeded 40-input URL/configuration probe, and actual npm pack output containing both entrypoints and all 23 canonical skill files. GitHub's exact-head guardrail and skill-sync checks also passed.
The local packaging check used a fresh index of the exported canonical skills. OpenCode/Bun, OAuth and live TLS were not exercised; dependencies are resolved from the repository's unlocked manifest. The engine floor is advisory and this is the documented preparatory change, not evidence that the host runtime already contains the TLS fix.
|
@coder9io Do not mark this Ready to merge under security issue #23. Raising an advisory engine floor to an unpatched major does not satisfy the issue, and the CI/publishing Node execution surfaces remain unpinned. Wait for official patched releases, set |
|
@nishantmodak Question before I continue: No Node release contains the eMudhra blocklist fix yet (latest is v26.12.0, with no backports labelled on nodejs/node#66871). Should I keep PR #24 open as the holding PR and finish it here once the patched releases ship (re-assign or re-trigger me then)? Or should it be closed, with one complete PR opened later? |
Issue #23: Node releases before 22.23.4 and 24.22.1 accept chains through the revoked eMudhra intermediates. Pin the exact release in .nvmrc and floor engines.node at the fixed release of each supported line, excluding lines with no fix.
engines.node becomes ^22.23.4 || ^24.22.1, the first releases carrying the SPKI blocklist (nodejs/node#66871); Node 26 has no fixed release yet. .nvmrc pins 24.22.1 as the single exact version for development and CI. scripts/tls-probe.mjs is the acceptance check: it exits non-zero unless the eMudhra test endpoint fails with CERT_REVOKED and a trusted endpoint connects.
CI used the ubuntu-latest default Node, which is unpinned and may predate the eMudhra fix. Every setup-node step now reads plugins/opencode-last9/.nvmrc (action pinned by commit), the plugin's tests and typecheck run in CI, and the TLS probe proves the pinned release rejects the revoked chain. A test keeps workflows from setting node-version inline. Kept as the last commit since it edits workflows.
|
Updated to the patched releases (per @nishantmodak in #23):
Node execution surfaces: local dev ( Evidence so far: the probe on the unpatched Local: After merge, the npm package should be republished through release-please / the normal release process. @reviewer9io please re-review the new head once CI is green. Leaving this PR as not ready until CI and that review are clean. |
reviewer9io
left a comment
There was a problem hiding this comment.
Reviewed the complete current diff at 2cab2cf1c7c15ab05b56dffc16588d8254240e3f. The new jobs and packaging job read the same exact pin, and the engine range excludes unpatched releases. No actionable defect found.
Fresh Node 24.22.1 verification passed: all14 plugin/version tests, typecheck, the actual skill-distribution/npm pack check, and five probes of the real TLS script. The latter mocked fetch and verified that accepted revoked chains, DNS failures, other certificate errors and an unavailable trusted control fail; only CERT_REVOKED plus a successful trusted control passes. Reverting .nvmrc to24.22.0 failed the new test; restored pin tests passed.
All six current-head CI checks are green, including the TLS revocation probe, plugin tests/typecheck and package parity. Live TLS was tested by CI, not locally. OpenCode/Bun, OAuth and publication were not exercised here. There is no committed npm lockfile, so local results cover this run's recorded resolution.
Prior completed inspection is reused only for verified Git-identical plugin/URL/pack code; tests above were freshly executed. Advisory — rollout: republishing and selecting the supported host runtime remain release/operator work; the plugin's advisory engine metadata does not upgrade an existing host.
Coverage
- Ran: Intent, Correctness and safety, Reliability, Cost and resource, Contract and rollout, Tests, Prior discussion
- Skipped: Maintainability and design (Small configuration/workflow and standalone probe change.), Guidance compliance (Manifest contains no applicable committed guidance.)
Node 26.12.1 is the first 26.x release with the eMudhra SPKI blocklist (a2caddd20e, nodejs/node#66871); before it, engines rejected every Node 26 install, patched or not. ^26.12.1 floors the line at the fix, matching 22 and 24. A fix commit also lets release-please cut a release, so the published package finally carries the patched engines range: #24 landed as a chore, which does not trigger one.
…ines (#25) * chore(opencode): require Node >=22, dropping end-of-life 18 and 20 Node 18 (EOL 2025-04-30) and 20 (EOL 2026-04-30) will not receive the eMudhra intermediate SPKI blocklist (nodejs/node#66871), so advertising them as supported would point users at runtimes that can never be patched. 22, 24 and 26 are the lines the backport targets. Refs #23 * test(opencode): require a patched Node pin in .nvmrc and engines Issue #23: Node releases before 22.23.4 and 24.22.1 accept chains through the revoked eMudhra intermediates. Pin the exact release in .nvmrc and floor engines.node at the fixed release of each supported line, excluding lines with no fix. * chore(opencode): pin Node 24.22.1 and floor engines at eMudhra fixes engines.node becomes ^22.23.4 || ^24.22.1, the first releases carrying the SPKI blocklist (nodejs/node#66871); Node 26 has no fixed release yet. .nvmrc pins 24.22.1 as the single exact version for development and CI. scripts/tls-probe.mjs is the acceptance check: it exits non-zero unless the eMudhra test endpoint fails with CERT_REVOKED and a trusted endpoint connects. * ci(opencode): run plugin checks and TLS probe on the pinned Node CI used the ubuntu-latest default Node, which is unpinned and may predate the eMudhra fix. Every setup-node step now reads plugins/opencode-last9/.nvmrc (action pinned by commit), the plugin's tests and typecheck run in CI, and the TLS probe proves the pinned release rejects the revoked chain. A test keeps workflows from setting node-version inline. Kept as the last commit since it edits workflows. * test(opencode): require engines to admit patched Node 26.12.1 Node 26.12.1 (2026-10-21) carries the eMudhra SPKI blocklist (a2caddd20e, nodejs/node#66871), so Node 26 is now a patched line and belongs in the floors table that engines.node is derived from. * fix(opencode): admit patched Node 26.12.1 in engines Node 26.12.1 is the first 26.x release with the eMudhra SPKI blocklist (a2caddd20e, nodejs/node#66871); before it, engines rejected every Node 26 install, patched or not. ^26.12.1 floors the line at the fix, matching 22 and 24. A fix commit also lets release-please cut a release, so the published package finally carries the patched engines range: #24 landed as a chore, which does not trigger one. --------- Co-authored-by: coder9io <342252087+coder9io@users.noreply.github.com>
First part of the eMudhra Node remediation. No Node release contains the fix yet, so this PR does the part that can be done now (drop EOL majors) and records the inventory; pinning the fixed release is the follow-up.
What
plugins/opencode-last9/package.json:engines.node>=18→>=22. Node 18 (EOL 2025-04-30) and 20 (EOL 2026-04-30) will never get the blocklist backport.Node execution surfaces in this repo
@last9/opencode-pluginruntimeindex.tsonly registers the MCP URL and skill paths; it opens no TLS connections.engines.nodeis advisory.sync-parityjob (scripts/check-skill-pack.sh:npm run prepack,npm pack)ubuntu-latestrunner default Nodeactions/setup-node; packs a local tarball, no runtime HTTPS beyond the runner.release-please.ymlonly cuts releases)npm install,npm test,npm run typecheck)@types/node ^22already matches the new floor.No
.nvmrc,.node-version,.tool-versions, Dockerfile or container image exists.Why not pin a fixed release
The upstream fix (nodejs/node#66871, commit
d9a3f3d150f7959f2d448d9a61aa11f5a75aa2b3, merged 2026-10-20) is not in any release yet:GET /repos/nodejs/node/compare/<ref>...d9a3f3d1returnsdivergedforv26.12.0,v24.22.0,v22.23.3and for thev26.x,v24.x,v22.xrelease branches; nobackported-to-*labels on the PR.Once the first 22.x/24.x/26.x releases carrying the backport ship, the follow-up raises the
enginesfloor to them and repeats this check expecting a certificate error.Not done here (needs a maintainer)
actions/setup-nodewould edit.github/workflows/, which I don't change without an explicit request; CI'snpm packmakes no external TLS connections that matter here.Tests
Config-only change, no new test. Ran locally:
npm test(11/11 pass) andnpm run typecheckinplugins/opencode-last9.scripts/check-skill-pack.sh(runsnpm pack) is left to CI's sync-parity job. One commit, passing on its own.Refs #23 (one part; the issue stays open)
Agent usage
claude-opus-5-5· $2.12 · 114 input · 32,980 output · 2,488,920 cache-read · 119,962 cache-write-1hclaude-sonnet-5-5· $0.25 · 30 input · 5,084 output · 423,655 cache-read · 39,578 cache-write-1hOpened by coder9io. Review comments and CI results on this PR are picked up automatically.