build: target Node 24 LTS with a single 22+ floor everywhere (#1070) - #2415
Conversation
Opus 4.8 Review — ✅ no blocking findingsReviewed Review detailsNo findings. This PR is a mechanical Node toolchain bump (20 → 24, floor 22) across workflows, install scripts, docs, and lockfiles, plus a single-source [OPUS-REVIEWED] 3314573 Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
UX Review (Fable 5) — ✅ PASSAdvisory UX-level review of This PR is build-toolchain work (Node version pins); the only user-facing surfaces are CLI/installer messages and docs prerequisite lines. I checked every changed string against the flows they appear in (doctor, chat, setup, install) — the change collapses four contradictory version floors into one consistent, actionable message set ("Node.js 22+, 24 LTS recommended" with a fix link), and the new install-time warning fires before the failure it explains. No dashboard UI, no screenshots, no new interaction surfaces. UX-Verdict: PASS Every changed string now states one consistent floor with an actionable fix, replacing four contradictory versions that let doctor pass what chat rejected. [UX-REVIEWED] 3314573 |
Design Review (Fable 5) — ✅ PASSAdvisory design-level review of Design-Verdict: PASS Root-cause fix — one floor constant, one toolchain pin, and a regression gate that makes the drift class structurally impossible in CI. Suggestions
[DESIGN-REVIEWED] 3314573 |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Node 20 reached end-of-life on 2026-04-30 but remained the pinned target across 10 CI jobs, the exact vulnerability-scan pin, the bootstrap script, the installer, and the EC2 template, while the repo stated four different minimum versions (16/18/20/22) that let 'kirocrew doctor' pass on a Node 'kirocrew chat' refuses to start on. One coherent policy, applied everywhere: - Target: Node 24 (Active LTS, EOL 2028-04-30) in all 13 workflow setup-node pins, install.sh, ensure-node.sh TARGET_VERSION, the NodeSource repo in the EC2 template, and a new root .nvmrc. - Exact CI pin: 24.19.0 in dependency-vulnerability.yml and its coupled test assertion; the glibc-217 AL2 fallback moves to the same release. - Floor: 22 for contributors. Python-side checks collapse to one shared constants.MIN_NODE_MAJOR consumed by cli.py, cli_doctor.py, cli_chat.py, and cli_setup.py so doctor and chat can never disagree again; ensure-node.sh enforces the finer 22.12 vite/rolldown floor and drops the EOL 20.x leg; install.sh gains a post-install major check so distro-shipped Node below the floor is caught at install time. - engines/@types: website engines '>=22'; @types/node pinned to 24.13.3 in website and newly pinned in site (was floating to 26.x); site's @vitejs/plugin-react bumped to ^6 because npm 11 (bundled with Node 24) enforces peer ranges at 'npm ci' time and 4.x rejects vite 8. - Docs and messages state one floor: 'Node.js 22+ (24 LTS recommended)'. - Regression gate: test_node_version_pins.py asserts every workflow node-version tracks the .nvmrc major (floating pins equal it, exact pins at or above it), statically and offline. ota-test.yml keeps a comment documenting its load-bearing >= 22 WebSocket floor. Verified on Node 24: website tsc -b + vitest (11627 tests), electron node --test (845), site npm ci + build + test. Closes #1070
71d1ca4 to
3314573
Compare
|
🤖 Kiro Crew Auto-Pipeline [operator: bolichen97] — branch rebased onto latest main after base drift; remaining CI failures (jsdom script-loading in Frontend Tests, ContextVar/event-loop errors on Windows shard 1) are Node-24-related and a resume session has been dispatched to fix them. |
…dev#1070) (kirodotdev#2415) Node 20 reached end-of-life on 2026-04-30 but remained the pinned target across 10 CI jobs, the exact vulnerability-scan pin, the bootstrap script, the installer, and the EC2 template, while the repo stated four different minimum versions (16/18/20/22) that let 'kirocrew doctor' pass on a Node 'kirocrew chat' refuses to start on. One coherent policy, applied everywhere: - Target: Node 24 (Active LTS, EOL 2028-04-30) in all 13 workflow setup-node pins, install.sh, ensure-node.sh TARGET_VERSION, the NodeSource repo in the EC2 template, and a new root .nvmrc. - Exact CI pin: 24.19.0 in dependency-vulnerability.yml and its coupled test assertion; the glibc-217 AL2 fallback moves to the same release. - Floor: 22 for contributors. Python-side checks collapse to one shared constants.MIN_NODE_MAJOR consumed by cli.py, cli_doctor.py, cli_chat.py, and cli_setup.py so doctor and chat can never disagree again; ensure-node.sh enforces the finer 22.12 vite/rolldown floor and drops the EOL 20.x leg; install.sh gains a post-install major check so distro-shipped Node below the floor is caught at install time. - engines/@types: website engines '>=22'; @types/node pinned to 24.13.3 in website and newly pinned in site (was floating to 26.x); site's @vitejs/plugin-react bumped to ^6 because npm 11 (bundled with Node 24) enforces peer ranges at 'npm ci' time and 4.x rejects vite 8. - Docs and messages state one floor: 'Node.js 22+ (24 LTS recommended)'. - Regression gate: test_node_version_pins.py asserts every workflow node-version tracks the .nvmrc major (floating pins equal it, exact pins at or above it), statically and offline. ota-test.yml keeps a comment documenting its load-bearing >= 22 WebSocket floor. Verified on Node 24: website tsc -b + vitest (11627 tests), electron node --test (845), site npm ci + build + test. Closes kirodotdev#1070 Co-authored-by: Stan Tian <pepmach7@gmail.com>
Summary
Node 20 reached end-of-life on 2026-04-30 but remained the pinned target across 10 CI jobs, the exact vulnerability-scan pin, the bootstrap script, the installer, and the EC2 template — while the repo stated four contradictory minimum versions (16/18/20/22) that let
kirocrew doctorreport green on a Node thatkirocrew chatrefuses to start on.This lands one coherent policy: Node 24 (Active LTS, EOL 2028-04-30) as the pinned target, floor 22 for contributors, plus a regression gate so the pins cannot silently rot again.
Pins → 24
setup-nodepins (10×20, 3×22) →24;ota-test.ymlkeeps a comment documenting its load-bearing ≥ 22WebSocketfloordependency-vulnerability.yml20.19.4→24.19.0, with its coupled test assertion updated in the same commitensure-node.sh:TARGET_VERSION=24,GLIBC217_VERSION=24.19.0(verified: unofficial-builds publisheslinux-x64-glibc-217for v24.19.0)install.shNODE_VERSION="24", EC2 template NodeSourcepub_20.x→pub_24.x, new root.nvmrccontaining24(previously no local toolchain pin existed)Floors → one shared 22
kiro_crew.constants.MIN_NODE_MAJOR = 22replaces the duplicated_MIN_NODE_VERSION = 16incli.py/cli_doctor.py, the inline< 20gate incli_chat.py, and the>= 16message incli_setup.py— doctor and chat can no longer disagreeensure-node.shfloor20.19→22.12(the vite 8 / rolldown^20.19.0 || >=22.12.0engines line, minus the EOL 20.x leg);_version_meets_floordrops the 20.x branchinstall.shgains a post-install major check so a distro-shipped Node below the floor is caught at install time instead of as a confusing frontend-build failureengines / @types/node
website/package.jsonengines"20 || >=22"→">=22";@types/node25.5.0(Node 25 is EOL) →24.13.3(matches electron's resolution); minimal lockfile churn (8 lines)site/package.json: adds an explicit@types/node24.13.3pin (was floating to 26.x) and bumps@vitejs/plugin-react^4.3.2→^6.0.5: npm 11 (bundled with Node 24) enforces peer ranges atnpm citime, and plugin-react 4.x declaresvite ^4||^5||^6||^7against the repo's vite 8 — the old lockfile fails barenpm ciunder npm 11, sopages.ymlon Node 24 would have gone red without thiswebsite/electronlockfile untouched (already resolves@types/node24.13.3 via electron 43)Regression gate
test/test_node_version_pins.py: everynode-versionin.github/workflows/**must track the.nvmrcmajor (floating pins equal it, exact pins at or above it). Static and offline — no network.Testing
isort/flake8/mypyclean; fullpytest— failure set identical to pristineorigin/mainon this host (20 env-only sandbox-unavailable failures; verified by running the same subset on a clean worktree)npx tsc -bclean;npx vitest run11627 passed (869 files)npm test(node --test) 845/845 passedsite/on Node 24 + npm 11: barenpm ci+npm run build+npm testall pass (the old lock reproducibly failsnpm cihere)Intl.DurationFormatempirically confirmedundefinedon Node 22 and present on Node 24 before touching the format.ts baseline commentsbash -non both shell scripts;set -euo pipefailbehavior of the new install.sh check verified against a broken-node simulationOut of scope
Electron upgrade (already
^43.2.0, embeds a Node 24-line runtime), Playwright pin inensure-playwright.mjs,.vulnerability-exceptions.jsonretirement — separate issues per #1070.Closes #1070