Skip to content

fix(scheduler): block unexecuted xdt-node pre-run checks - #6237

Open
shenjiacheng-sudo wants to merge 8 commits into
makecindy:mainfrom
shenjiacheng-sudo:cindy/sweet-stallman
Open

shenjiacheng-sudo wants to merge 8 commits into
makecindy:mainfrom
shenjiacheng-sudo:cindy/sweet-stallman

Conversation

@shenjiacheng-sudo

@shenjiacheng-sudo shenjiacheng-sudo commented Oct 16, 2026 •

Copy link
Copy Markdown

这次改了什么

摘要

正式包关闭 RunAsNode fuse 后,xdt-node 曾可能只启动 GUI 并以0退出;后续 preload 启动回执也不能证明实际检查正文执行,异步 preload 可提前退出,手工 replay 还会改变 Node 的 cwd/parent 解析。此版本改为真实原生 Node + 一次性 native supervisor + 正文显式 entered/completed 协议。不再注入或重放 CLI/NODE_OPTIONS preload。

宿主仅在正文完成声明、真实 Node 退出、shell退出一致为0或2时 run/skip。缺证明、提前退出、异常、冲突、超时或取消均 block;stdout/quiet、启动握手和单纯exit0不代替正文完成。协议是合作式声明,不能证明恶意同进程代码或业务逻辑正确性。

变更类型

  • fix 缺陷修复
  • docs / test:支持范围、迁移与资源分层

范围

  • 关联 Issue:定时任务前置检查:xdt-node 兜底在正式包不执行脚本且静默放行(另盼自动识别 fnm 等 node 版本管理器) #5573;修复前置检查静默放行。fnm等版本管理器发现未实现,不自动关闭整个Issue。

  • 运行器提交:b83d8a7bb9a550da25188d1b02fe705fe627f40b,替换旧内部preload/receipt机制;处理 r4302532398、r4302532407、r4302532415。

  • native/pre-run-node/supervisor.c 无第三方native依赖。POSIX使用本轮独占短Unix socket、OS peer PID、nonce/ack和shell进程组;Windows源码使用当前账号ACL named pipe、Unicode argv/env、挂起创建后绑定KILL_ON_JOB_CLOSE Job Object。业务fd3不作为控制通道;supervisor的私有报告fd不继承给shell。

  • forge prePackage准备目标平台真实Node、helper、client、完整Node LICENSE。Make与scheduler复用现有Node22.23.2 URL/SHA256 pin和下载/校验/解压基础设施。运行期不下载、不安装;准备失败阻止打包或运行,旧完整stage不会被半成品覆盖。

  • 默认unit保留纯合同与一条真实Node/stdin/quiet smoke;完整真实进程矩阵进入已声明manual/exclusive integration tier。保留必要覆盖,不改AGENTS、CI、审批、fuse或插件基座。

  • 更新生成器、安装工具说明、五语错误及支持文档 docs/pre-run-node-runtime.md。现有runner/script-runner仍在模型创建前按decision阻止,owner/cwd/stdin/quiet及显式timeout语义沿用。

  • 存在breaking change:xdt-node旧exit-only脚本会明确block,文件和配置不自动改写。需审阅更新正文:条件加载CINDY_PRE_RUN_GATE_CLIENT,在实际检查开始 await gate.enter(),检查结束 await gate.complete(0或2),然后以一致退出码结束。普通node/python/shell保留原退出契约;没有停用fallback。

  • 最新补提交:4e438032ace73ad4c230a1496faadef6ab5c287c,处理 r4303367789/r4303367793。包内 afterCopyExtraResources 校验完整目标与 pin manifest 后仅保留目标 host,保留源码多架构缓存及其他 tools;两条 macOS 签名路径在通用 tools 签名之后以专属 allow-jit 重签 Node,strict 验签,本机架构再运行签后 JIT smoke。签名/执行失败均阻止产出;跨架构不假定 Rosetta 可用,明确记录未执行。

UI 变化

仅五语失败说明,无布局/视觉变化。引用 docs/design-rules/DESIGN.md §11 Voice & Content:准确说明未收到完成验证或无法准备运行环境,不断言Node从未启动。没有运行App做界面或Light/Dark目检。

怎么验证的

自动验证

macOS arm64、实际Node22.22.3;逐场景guard,own RSS上限256MiB、30秒、新增swap/critical只停自身。以下已完成检查各自窗口swapDelta均为0;不把采样RSS当成完整峰值成本承诺。

  • 旧cb6生产入口已独立取得三项真实红灯(assertion exit1):异步preload退出时gate无副作用却run;CJS microtask和NODE_OPTIONS ESM chdir均多执行changed preload。reviewer的Node24结果仍只属review来源。
  • 新生产入口三项原生对照全部exit0:异步退出变failed/block且无gate文件;两种cwd场景只执行原生original一次、有gate文件且run。实际编译native helper并直接bundle生产executePreRunHook;只替换Electron app身份,不mock执行器/IO/Node。
  • 同生产入口25个独立低RSS场景全部exit0:正文0/2与quiet、空PATH、深TMPDIR及独占目录清理、业务fd3、缺协议/缺完成/退出冲突/late throw/shell掩盖失败/wrong nonce、permission最小读取及业务写拒绝、拒绝client读取、preload exit0/2/throw、CJS、eval/argv、fork/Worker原生参数及错误归属证明拒绝、超时/取消后的进程消失、多根拒绝。它们是本地生产入口harness结果,不是完整Vitest矩阵通过。
  • 实际stagePreRunNode拒绝unsupported/offline/tampered archive,旧完整stage保留且无半成品;exit0。
  • native C:cc -std=c11 -Wall -Wextra -Werror -O2 -pthread,exit0。
# apps/desktop,固定Node22.22.3,外层guard限制own256MiB
node --max-old-space-size=96 --max-semi-space-size=1 --optimize-for-size ../../node_modules/vitest/vitest.mjs run --project=standard --pool=threads --maxWorkers=1 --minWorkers=1 src/main/scheduler-host/__tests__/preRunHook.test.ts
13/13,exit0;maxOwn222560KiB。

# 根目录,外层guard,单并发
node --test --test-concurrency=1 --test-name-pattern='desktop scheduler runtime matrix|desktop unit excludes|checkIncludeCoverage|planRuns includes manual' scripts/__tests__/test-workspaces.test.mjs
6/6,exit0:真实selector/allowlist/manual合同。
node --test --test-concurrency=1 scripts/__tests__/dev-docs-contract.test.mjs
10/10,exit0。

# 相关Desktop TS/config与MCP工具文件定向检查
ESLint exit0;gate-client.cjs node --check exit0;git diff --cached --check exit0。
node scripts/check-i18n.mjs
node scripts/check-i18n-glossary.mjs
均exit0,五语key一致、无新增术语违规;既有告警保留。
node scripts/check-dco.mjs --base origin/main --head HEAD
7个commit签署通过,exit0;远端DCO App仍以实际check为准。

最新两条打包 review 的定向验证

macOS arm64,现有 Node22.22.3 二进制的独占副本(不是 pinned22.23.2 archive 或实包);本轮授权 own512MiB、heap128MiB、串行单worker、30秒guard,新增swap/critical只停自身。初次normal启动条件因pressure2返回75未开测;后按本轮swap/critical边界执行,各场景swapDelta=0。旧25项运行矩阵未重跑。

  • 旧签名 pass 的真实命令 codesign --force --options runtime --sign - <Node副本>:entitlements为空、实际JIT执行SIGTRAP,安全断言红灯exit1。新生产 signPreRunNode:allow-jit为唯一权限,strict verify/JIT=4999950000成功;同签后Node经生产 executePreRunHook/native supervisor 执行正文并写文件,passed/run、quiet标记、exit0,guard maxOwn254112KiB。
  • 连续arm64/x64的真实文件树旧copy行为红灯exit1:第二包含arm64+x64及.stale-generation。新生产 prunePackagedPreRunNode 后两包各仅目标host,source缓存及其他tools保持,缺supervisor时在删除已有代次前失败,exit0。
# 根目录;以下Node固定22.22.3,逐命令own512MiB guard,串行
node --max-old-space-size=128 node_modules/vitest/vitest.mjs run --config vitest.config.ts --root apps/desktop --project=standard --pool=forks --maxWorkers=1 scripts/pre-run-node-signing.test.mjs
4/4 exit0;注入签名顺序/Developer ID参数/失败保护/cross-target不冒称执行。
node --max-old-space-size=128 node_modules/vitest/vitest.mjs run --config vitest.config.ts --root apps/desktop --project=runtime-integration --pool=forks --maxWorkers=1 src/main/scheduler-host/__tests__/preRunHook.integration.test.ts -t 'keeps only the target|validates the target|runs a gate with the ad-hoc'
新增3/3 exit0,87项未选择;maxOwn515792KiB,swapDelta0。
plutil -lint apps/desktop/native/pre-run-node/node.entitlements.plist
exit0;git diff --cached --check exit0。
node scripts/check-dco.mjs
8 commits签署通过exit0。

定向ESLint:helper/声明/签名合同/forge-pre-run-node.ts/资源层测试均0 errors;forge.config.ts既有unused import仍1,ci/lib.mjs既有100降98,本轮无新增错误(对HEAD前版本执行同配置比较)。首次CLI选错config路径及根lint找不到配置的启动失败已纠正,不计为测试通过;没有修改lint/CI规则。完整tsc继续交CI。

手工验证

未启动App或修改正式宿主。本地真实native/Node入口验证使用本worktree的当前源码、独占临时目录和真实脚本文件/输出/进程清理证据。

未执行的验证

  • 完整 runtime-integration Vitest(单worker,heap96/64)因采样278544/279408KiB超256MiB预算被guard停,exit75;generator完整测试也因273232KiB停,exit75。没有测试结果,不计通过。没有新增swap;当时未提高预算。本轮只对上述新增签名/架构用例授权512MiB,没有重跑完整矩阵。--jitless尝试因Vite所需WebAssembly不可用在测试前exit1,也不计结果。
  • 完整pnpm test:runner、完整package typecheck交CI;不宣称CI通过。manual/exclusive运行时矩阵不由当前CI自动执行,仍需显式补验。
  • 成功下载/校验/stage完整上游Node archive、含当前修改且fuse关闭的真实安装包、Developer ID/公证与实包签名/TCC、Windows编译及Job实机、macOS x64/Linux均未验证。源码实现和编译macOS helper不代替这些验收。

风险

风险分类

  • system prompt:生成检查脚本的utility prompt与工具说明更新
  • 协议兼容:xdt-node正文完成协议与旧脚本迁移
  • 权限 / 安全:执行门禁核心行为、失败保护及本轮进程归属
  • 原生层:新增C helper及真实Node打包资产
  • 跨平台差异

影响与回滚

  • 保持RunAsNode/NodeOptions/inspect fuse关闭,不改插件基座、审批、账号身份或业务权限。存量插件影响:无。
  • 新增正文await可改变旧timer时序;原生preload/CLI解析不代表任意用户异步逻辑时序完全相同。合作式complete声明不能证明业务逻辑正确或所有外部副作用完成。
  • 普通CJS/ESM、CLI/NODE_OPTIONS由原生Node处理,-e及argv已验;-p保留原生语法但本轮未验。stdin仍传JSON,node -程序源码与JSON组合不支持;不以临时文件掩盖既有冲突。特殊loader/addon、自定义非cmd COMSPEC未验。单轮仅一个受控根Node,fork/Worker不能替父报告。
  • permission需用户显式允许读取client,业务权限不自动扩张。POSIX主动setsid脱组不在进程组回收保证内;Windows严格树归属仍待平台验收。
  • 每个目标包新增真实Node/helper及完整许可,增加包体和原生编译/签名/Node安全升级责任。Windows需目标SDK/MSVC C11环境;Linux同架构;macOS使用目标-arch。包体增量、正式证书签名和平台成功stage尚未测量;已验证本机Node副本ad-hoc签后运行。
  • 维护者合并/发行前应核准上述迁移与资产代价,补实包、平台与manual矩阵;本PR未作可合并保证。不能回退到已证会静默放行的旧receipt机制;如回退此提交,应保留明确block保护、经用户审阅调整检查命令,不能删除门禁或打开fuse。

提交前检查

  • 已自审完整diff,未包含sqlite-vec运行资产、私有日志、凭证或Trellis
  • 每个commit带DCO签名
  • UI文案注明设计依据
  • 支持文档及parity现状账更新,没有修改工程/审批规则
  • 已记录真实结果、资源停止与未验证项

Signed-off-by: shenjiacheng <3329362278@qq.com>
@shenjiacheng-sudo
shenjiacheng-sudo requested a review from a team as a code owner October 16, 2026 11:31
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T16:25:46.460517Z 4e43803 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[High impact] Changes how pre-run hook commands execute and validate.

合并前应先修复内部预加载代码导致 ESM 工作线程启动失败的问题。

Findings

  1. P1 工作线程无法启动 ▶
Fix with agent prompt
### Issue 1
apps/desktop/src/main/scheduler-host/pre-run-hook.ts:85-89
当 `xdt-node` 脚本创建 ESM `Worker` 时,新增的 `--import` 会随默认的 `process.execArgv` 再次执行。但主线程已经关闭 fd3,工作线程中的 `writeSync(3, ...)` 会抛出 `EBADF`,导致原本可运行的检查失败并阻止任务。本地 Node 24.21.0 验证中,主线程成功写出回执,随后工作线程在这段预加载代码中失败。

请在首次写出回执后,从 `process.execArgv` 移除这项内部预加载参数,避免后续工作线程继承,并补上回归测试。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

本次改动要求 xdt-node 通过独立 fd3 返回随机启动回执;缺少回执时阻止本轮任务,收到回执后仍按最终退出码决定结果。

  • The scheduler only trusts xdt-node checks that prove Node started.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[xdt-node 启动] --> B[预加载代码向 fd3 写回执]
  B --> C[等待进程结束]
  C --> D{收到匹配回执?}
  D -->|否| E[失败并阻止]
  D -->|是| F{最终退出码}
  F -->|0| G[运行任务]
  F -->|2| H[跳过本轮]
  F -->|其他| E
Loading

Reviews (1) · Last reviewed commit: "fix(scheduler): block unexecuted xdt-nod..." · Reviewed by Greptile

Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1a5c8544e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
…irection

Signed-off-by: shenjiacheng <3329362278@qq.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50bf12c0ae

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Comment thread apps/desktop/src/main/scheduler-host/__tests__/preRunHook.test.ts Outdated
@MagicLizi MagicLizi added the touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) label Oct 17, 2026
…load forks

Signed-off-by: shenjiacheng <3329362278@qq.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 190c8418ca

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Comment thread apps/desktop/src/renderer/i18n/locales/en/common.json Outdated
Comment thread apps/desktop/src/main/scheduler-host/__tests__/preRunHook.test.ts Outdated
…ission flags

Signed-off-by: shenjiacheng <3329362278@qq.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f83c6b09d6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Signed-off-by: shenjiacheng <3329362278@qq.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e15be9780e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/main/scheduler-host/__tests__/preRunHook.test.ts Outdated
Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Signed-off-by: shenjiacheng <3329362278@qq.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb6eee7ae3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Comment thread apps/desktop/src/main/scheduler-host/pre-run-hook.ts Outdated
Comment thread apps/desktop/src/main/scheduler-host/__tests__/preRunHook.test.ts Outdated
Signed-off-by: shenjiacheng <3329362278@qq.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b83d8a7bb9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/forge-pre-run-node.ts
Comment thread apps/desktop/forge-pre-run-node.ts
Signed-off-by: shenjiacheng <3329362278@qq.com>
@MagicLizi

Copy link
Copy Markdown
Contributor

维护者确认门在本 PR 上拦截,需要维护者明确确认后才能进入合并流程。

触发类别(当前 blocker:security):

  • security/security-sensitive:危险写法 shell-string-exec 2 处(pre-run-hook.ts:342 spawn shell:true、preRunHook.integration.test.ts:71 execFileSync),安全类不吃 bugfix/小改动豁免;
  • rules/rules-change:改到规则文档 docs/product-rules/agent-user-parity.md;
  • arch/core-paths + huge-diff:核心路径 1643 行、总 diff 2369 行。

改动概述:xdt-node 预跑检查改为真实原生 Node + native supervisor + 正文 entered/completed 完成协议,未执行检查一律 block;打包仅保留目标 host Node 并以 allow-jit 专属 entitlement 重签。详细材料见讨论 issue:#6353

请维护者直接在 PR 上 Approve 以放行;需要作者修改则 Request Changes。

@MagicLizi MagicLizi added awaiting-discussion 等待维护者讨论(review-pr) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示) labels Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants