Skip to content

fix(runtime): honor Node prerelease version precedence - #6006

Merged
huangruiteng merged 1 commit into
loopx-project:mainfrom
mikamikasuki:codex/fix-node-minimum-prerelease-probe
Oct 9, 2026
Merged

huangruiteng merged 1 commit into
loopx-project:mainfrom
mikamikasuki:codex/fix-node-minimum-prerelease-probe

Conversation

@mikamikasuki

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

  • Outcome basis: A self-contained, reproducible runtime compatibility defect; a separate issue is unnecessary for this narrowly scoped repair under CONTRIBUTING.md.
  • Goal/source and gap: LoopX requires Node.js 22.22.3 or later, but the probe discarded version suffixes and accepted the pre-release v22.22.3-rc.1 as ready. That version has lower SemVer precedence than the required stable 22.22.3.
  • Observable before → after, with the validation row that proves it: Before, three clean probes of a launcher reporting v22.22.3-rc.1 returned ready; after, the probe reports unsupported and retains 22.22.3-rc.1 for diagnosis. The regression and comparison controls are in the Validation table.
  • Issue/task and intended base: No separate issue is needed for this self-contained fix; base main at 9632a9bdf2486b48f50fc859bb2dd40d475c47e4.

Author Declaration

  • Written by: model_agent — GPT-6 Luna Medium, OpenAI.
  • Some coding work was AI-assisted. I personally reviewed the changes, verified the relevant behavior and tests, and take responsibility for the submission.

Implemented against

  • Specification and revision: package.json Node engine requirement and docs/guides/installing-loopx.md at 9632a9bdf2486b48f50fc859bb2dd40d475c47e4; Semantic Versioning 2.0.0, items 9–11.
  • Criteria:
Criterion (spec clause) Disposition Symbol / path Test or command
A pre-release equal to the minimum numeric version has lower precedence than the stable minimum implemented probe_node in loopx/control_plane/runtime/node_probe.py test_node_probe_uses_prerelease_precedence_at_minimum_version
Version diagnostics preserve the pre-release suffix; build metadata does not alter the minimum comparison implemented NodeProbe.version Same regression parameterization
  • Self-check before submission: Reproduced the false-ready result three times on the exact base with a synthetic executable, verified the new regression failed before the fix, searched issues and PRs for Node version parsing and pre-release handling, and reviewed the final two-file diff.

Scope And Continuation

  • Completed scope and remaining work: The runtime probe now applies the minimum-version comparison with pre-release precedence and retains that suffix in the reported version. No runtime dispatch or other version policy changed.
  • Slice boundary / successor: Complete within this parser fix.

Validation

  • Tested revision: b5e54a2be606cbb2e60fb4ac057779b8588f94ba (base 9632a9bdf2486b48f50fc859bb2dd40d475c47e4)
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence / limitation
regression_parity passed On exact base, three clean v22.22.3-rc.1 probes returned ready. The new regression failed on the old parser and passes with the fix; controls cover a later pre-release and build metadata.
unit passed tests/control_plane/test_effect_runtime_node_probe.py and tests/control_plane/test_turn_journal_runtime_readiness.py: 42 passed.
static passed Ruff on changed files, Python compilation, and git diff --check passed.
  • Coverage and gaps: The tests exercise parser output and readiness reporting. The reproducer used a synthetic Node launcher; no real pre-release Node binary was used.

Frontend / Visual Evidence

  • UI impact: none
  • Before: N/A
  • After: N/A
  • States and viewports shown: N/A
  • Source data: none
  • Attention review: N/A

Type of Change

  • Bug fix

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)

Technical Direction

  • Direction / acceptance reference, when applicable: N/A; this fix follows the existing Node runtime prerequisite.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A; no authority fixture changed.
  • Semantic dimensions changed, or reviewed no-impact rationale: N/A; no authority vocabulary changed.
  • Provider conformance arms run: N/A.
  • Read-only legacy/file/PostgreSQL three-arm rehearsal: N/A.

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths.
  • I did not duplicate maintainer-owned benchmark work.
  • I kept the change scoped to this runtime version defect.
  • I marked UI impact as none.
  • Every commit includes a DCO Signed-off-by trailer.

Signed-off-by: mika <211269698+mikamikasuki@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent — gpt-6.1-sol / OpenAI; runtime_reported; reasoning_effort=xhigh.

动机

APPROVE:当前精确 head 没有发现阻塞问题。

使用 LoopX 的用户在检查 Node 运行环境时,可能把最低版本的候选发布版误认为已满足稳定版本要求。
例如 Node 报告 22.22.3-rc.1,旧版 doctor 把它显示成 22.22.3 并判为就绪;新版拒绝这个低于稳定版的候选版本,保留后缀,并提示启用符合要求的 Node。
已用两端真实构建并安装的 wheel 验证拒绝与恢复:最低版本 RC 在新 head 退出 1,稳定版、构建元数据及恢复后的合格 Node 仍退出 0。
本 PR 只修正最低版本判断及诊断,不安装或升级 Node,不扩大权限,也不证明所有候选版、原生 Windows 或真实 App 宿主已经合格。

精确 head:b5e54a2be606cbb2e60fb4ac057779b8588f94ba;不可变 merge base:9632a9bdf2486b48f50fc859bb2dd40d475c47e4。PR 元数据中的当前 main OID 另有推进,本评审的两端验证固定在上述版本,没有用移动主干替代补丁前版本。

改动思路

复用既有 Node probe 的宿主 IO 与类型化结果,把版本边界修正在原 owner 内;不新增通用版本框架、持久状态或平行的 TypeScript 决策源。
当前 PR 完成最低 Node 稳定版本的 RC 判断修复;原权限、探测超时、失败恢复及 doctor 入口保持。

实际安装的 CLI 进入原 installation doctor,再经 runtime_readiness 调用 probe_node。探测读取 PATH 中 Node 的版本,原 15 秒超时和错误分支继续负责失败;版本比较仍使用原最低数字元组,只在数字相等时区分候选发布后缀。结果复用原 READY/UNSUPPORTED 等枚举,再由原 doctor 必需检查决定退出码。没有新权限、配置开关、自动安装、缓存或重试状态。

构建元数据不影响优先级。较高数字版本的候选版仍按原数字阈值通过,但现在保留其后缀;这符合本次稳定最低阈值的比较目标,不表示所有候选版的运行能力已合格,也没有额外引入拒绝所有 RC 的新政策。

具体改动

关键代码讲解

  • _VERSION_RE:完整匹配后单独捕获 prerelease,保留原可选 v 前缀与构建元数据输入范围;不再把所有后缀都丢掉。它不是新通用 SemVer 语法验证器。
  • probe_node:前三个 capture 组成数字版本,数字低于最低值,或等于最低值且存在 prerelease,均返回原 UNSUPPORTED。诊断 version_text 附回候选后缀,构建元数据仍不影响最低值比较。原真实子进程、15 秒边界、异常分类和无 effect 行为保持。
  • runtime_readiness:未修改的实际消费者继续把 unsupported 映射为不足的运行环境,并给出原 Node 修复动作。真实 wheel CLI 验证该链没有把失败降为提示,也没有把工具可用性当成宿主权限。

全 diff 是两文件 +33/-4:产品探测 +11/-4,三个参数化回归例 +22。规范依据是固定 9632a9bdf2486b48f50fc859bb2dd40d475c47e4 的 docs/guides/installing-loopx.md 与 package.json 的 Node engine,外部优先级依据是 SemVer 2.0.0 第 9–11 条。Node 22.22.3 or newer:implemented,原最低稳定版本要求进入真正的 doctor 必需检查。SemVer prerelease precedence:implemented,同数字候选版低于稳定版,构建元数据不参与优先级;两端独立输入矩阵验证这些条件。整体路线图的长期宿主资格仍是更大的验收,未在这里宣称完成。

对主干的风险

同一组 Node probe、turn journal readiness、host permission source suites,head 62 passed、base 59 passed,包含真实子进程超时清理、启动失败、取消及失败不派发的原覆盖。另用相同物理版本报告器运行独立 15 输入矩阵:最低 RC、RC+build、alpha 和 0 均从旧版 ready 变为 unsupported;低数字仍拒绝;稳定最低值、build、较高数字候选版和正常版本的资格保持;缺段或含空格的非法输出仍 probe_failed。比较的判据来自原最低版本要求和 SemVer,而非从新 helper 复制预期值。

两端通过正常 uv build 构建 wheel,在各自隔离 Python 3.12.15 环境实际安装,确认导入 site-packages 后,从源码树外运行真实 console doctor。每端五个实例覆盖最低 RC、稳定值、build、非法输出及恢复。最低 RC 的旧版 exit 0、detected 22.22.3,新 head exit 1、detected 22.22.3-rc.1,保留原 activate Node 22.22.3 or newer 动作。稳定、build、非法输出和恢复后的完整 readiness 在仅归一化测试路径后一致;恢复合格 Node 后两端均 exit 0。head 安装态 deep doctor 的真实 Node 24.21.0 / SQLite 语义探测也通过。候选版报告器是合成输入,不冒充实际 RC 引擎执行验收。

原生 premerge 的 5 项直接检查、5 项 catalog、8 项风险检查全部通过,无失败、跳过或 manual hold;Ruff、diff hygiene、DCO、开发 advisory 与完整 semantic 检查通过。没有查询、轮询或等待远端 CI。全库 suite、原生 Windows、实际 RC 二进制、真实 App/Lark 宿主与模型理解未测;当前修复不改这些宿主集成。没有复制别的 PR 的旧失败来充当本 head 的失败归因。

语义与 CI 对齐

复用现有 NodeProbeOutcome 与原 runtime 消费者,外部版本字符串留在物理 IO provider;没有新增闭合集合或共享协议。最低 RC 的默认判定变化已在 PR 和新命名回归例中明确披露,候选后缀的诊断变化也已验证。原 guard 文案、权限边界和必需检查义务不变,没有默认关闭的新功能需要激活对照。机器拒绝仍是 exit 1,修复动作没有替代或授予权限。

我的整体评价

交付判断 goal_achieved 只指本次最低版本 RC 的误判修复。user_experience 为 improved:用户看到真实不足的版本与原修复动作;long_horizon 为 preserved:重复探测无缓存或新增状态,原超时清理与失败后恢复可继续使用。一次 doctor 成功不等于完整宿主、Goal 或路线图已验收。

复用既有 Node probe 的宿主 IO 与类型化结果,把版本边界修正在原 owner 内;不新增通用版本框架、持久状态或平行的 TypeScript 决策源。
当前 PR 完成最低 Node 稳定版本的 RC 判断修复;原权限、探测超时、失败恢复及 doctor 入口保持。

Future-facing pass 检查了相邻版本解析与 runtime 消费者,现有局部 IO owner 已足够;为这个数字最低阈值增加通用版本框架或平行决策层会增加维护成本。保留原类型、调用边界和 build 资格,不增加兼容版本分支。批准与 GitHub 总状态、merge readiness 和维护者合并权限分别判断;本控制面修改留给维护者合并。更换 head 后需要重新验证。

English verdict: APPROVE — exact head b5e54a2. The immutable base incorrectly accepts the minimum Node prerelease and drops its suffix. Independent physical inputs and genuinely built/installed base/head wheels reproduce rejection, unchanged stable/build/malformed behavior and recovery through the real doctor entrypoint. Source suites pass 62/59; native premerge checks and head installed deep Node/SQLite probe pass. Real prerelease binaries, native Windows, live App/Lark, full repository tests and model comprehension remain unverified. No remote CI was consulted; merge authority is separate.

@huangruiteng
huangruiteng merged commit f80dfab into loopx-project:main Oct 9, 2026
22 of 27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants