Repository navigation
Conversation
|
Sentinel 已审核此变更,并发现 1 个已核验问题。 GitHub CI 未通过。 此状态来自当前 CI gate,不是 Sentinel finding;请以最新 CI attempt 的日志为准。 另有 34 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 aafc954c44c8 |
|
Sentinel 保留了 34 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 aafc954c44c8 |
| import { closeProxyWhenSettled, fakeProxy } from '../../helpers/fake-proxy.js'; | ||
|
|
||
| async function run(command, args, { env, cwd, input = '', shell = false }) { | ||
| const child = spawn(command, args, { env, cwd, shell, windowsHide: true, stdio: ['pipe', 'pipe', 'pipe'] }); |
There was a problem hiding this comment.
Hook 超时仅在进程退出后检查,死锁会导致测试与 CI 一直挂起
🟠 严重程度:中(P2)
run() 只监听子进程的 error 和 close,没有计时器、取消信号或进程树终止逻辑。handler.timeout 仅在 await run() 返回后才通过耗时断言检查,因此无法处理真正的挂起;使用 shell: true 时还会多出 shell/实际命令两级进程,外层测试取消也未确保清理整棵进程树。
Finding:finding_b3e5a29e395eaffce41cf652
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
|
Sentinel 已审核此变更,未发现已核验问题,但发现需要人工确认的风险。 另有 34 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 7acad49cebcc |
|
Sentinel 保留了 34 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 7acad49cebcc |
|
Sentinel 正在审核此变更,尚未形成最终结论。 大 PR 拆片审核中
开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 50c741f4920e |
|
Sentinel 已审核此变更,并发现 4 个已核验问题。 无法定位到 diff 的已核验问题工作已完成后 admission 释放失败会把成功结果改报为失败🔴 严重程度:高(P1) Finding: 释放失败会遗留当前进程永远无法回收的锁🔴 严重程度:高(P1) Finding: status 与 update 的预检查绕过安装锁,可观察到包和注册表的中间状态🟠 严重程度:中(P2) Finding: 状态锁释放超时被静默吞掉,存活进程无法再次更新🟠 严重程度:中(P2) Finding: 当前为 另有 29 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 d8d51771bc47 |
|
Sentinel 保留了 29 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 d8d51771bc47 |
|
Sentinel 已审核此变更,并发现 3 个已核验问题。 无法定位到 diff 的已核验问题工作锁已释放却向调用方报告失败,重试会重复执行任务🔴 严重程度:高(P1) Finding: 当前为 另有 30 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 ed9e802e41d4 |
|
Sentinel 保留了 30 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 ed9e802e41d4 |
| return token; | ||
| attempt = admitted(lockPath, () => { | ||
| try { | ||
| fs.writeFileSync(lockPath, token, { mode: 0o600, flag: 'wx' }); |
There was a problem hiding this comment.
admission 释放失败时仍可能遗留当前进程持有的主锁
🔴 严重程度:高(P1)
主锁写入成功后,releaseAdmission() 若连续重试失败,admitted() 执行回滚;但回滚对主锁的读取或删除同样可能失败并抛出。acquire() 此时丢弃已取得的 token 并返回失败,而主锁文件保留当前仍存活的 PID。后续调用既不能持有该 token 来释放锁,也不会将其视为死进程锁回收,直到宿主进程退出。
Finding:finding_a5ce73178c4d6352afd22263
| if (dryRun) return { operation, path: target, dryRun: true }; | ||
| if (operation === 'remove') { | ||
| if (own) underInstallLock(plugins, () => updateState(registryFile, { version: 1, plugins: [] }, current => { | ||
| validRegistry(current); ownEntry(current, target); |
There was a problem hiding this comment.
remove 在锁外使用旧快照,可能跳过并发完成的安装
🟠 严重程度:中(P2)
registry、own 和 previous 都在 .evolver-plugin-install 锁外读取;remove 只有旧快照中的 own 为真时才进入锁并重新检查。若读取时尚未注册,而并发 install 随后提交注册,remove 会完全跳过加锁及当前状态检查,却返回 installed: false, registered: false。
Finding:finding_b1d69b87adee09290cf11502
|
Sentinel 已审核此变更,并发现 1 个已核验问题。 另有 29 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 397a7038b9f6 |
|
Sentinel 保留了 29 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 397a7038b9f6 |
| // Keep separators inside strings, backticks and comments out of the command scan. A name in an argument is no | ||
| // check. This recognises direct commands and known wrappers; it does not evaluate arbitrary shell control flow. | ||
| const SHELL_DATA = /\\[\s\S]|`[^`]*(?:`|$)|'(?:''|[^'])*(?:'|$)|"(?:\\[\s\S]|`[\s\S]|[^"\\`])*(?:"|$)|#[^\r\n]*/g; | ||
| const ENVIRONMENT = /^(?:env\s+)?(?:[A-Za-z_]\w*=\S*\s+)*/; |
There was a problem hiding this comment.
带引号的可执行文件不再被识别为验证命令
🟠 严重程度:中(P2)
新增的 SHELL_DATA 会将整个单引号或双引号段替换为 __data__。当引号包围的是命令本身时,后续命令识别收到的是 __data__ test,而不是 npm test,因此返回非验证命令。
Finding:finding_9f068c69dcc138f62ab1342f
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
Retain admitted unresolved native turns across the next prompt. Finalize from their original identity and evidence, without consuming the newer turn notes or replacing its model route. Keep pending entries recoverable until reports and candidate work have settled.
|
Sentinel 正在审核此变更,尚未形成最终结论。 大 PR 拆片审核中
开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 dc096ad1691e |
Leave a turn to native recovery when its snapshot overlaps the next prompt. Keep the newer range intact when an older turn falls outside the retained window.
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
|
Sentinel 已审核此变更,并发现 4 个已核验问题。 无法定位到 diff 的已核验问题任务身份校验测试被前一个拒绝 decoder 状态污染🔴 严重程度:高(P1) Finding: 固定的 Job 状态文件未在结束后删除,第二次启动必然失败🔴 严重程度:高(P1) Finding: 当前为 另有 29 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 26e5fd46a6bb |
|
Sentinel 保留了 29 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 26e5fd46a6bb |
| const model = modelIsCurrent ? range.model : null; | ||
| const base = range.turns[0] === removedTurn ? turns[0].head ?? null : range.base; | ||
| const problem = rangeRouteProblem(range); | ||
| return { ...pending, [sessionId]: { ...range, turns, base, project: null, model, changedAt: changedAtAfter(range, now), ...(problem && { routeConflict: problem }) } }; |
There was a problem hiding this comment.
移除路由冲突来源后仍永久保留 routeConflict
🟠 严重程度:中(P2)
withoutWorkTurn() 删除 turn 后,仍对删除前的 range 调用 rangeRouteProblem(range);该函数又优先返回已有的 range.routeConflict。返回对象通过 ...range 同时保留旧 routeConflict 和 blocked。即使冲突 turn 已删除、base 已推进且剩余 turn 的 binding 完全一致,该范围仍被 isRouteBlocked() 判定为阻塞,只能等 TTL 后整体删除。
Finding:finding_05fc5c847c83045e6f4b3267
| if (!Array.isArray(profile.legacy)) problems.push('legacy must be a list of leftovers to adopt'); | ||
| if (profile.settingsFile !== undefined && !isFunction(profile.settingsFile)) problems.push('settingsFile must be a function of the environment'); | ||
| if (profile.modelRecord !== undefined && (!isFunction(profile.modelRecord.file) || typeof profile.modelRecord.query !== 'string')) problems.push('modelRecord requires file(env) and a fixed query'); | ||
| if (profile.turnEnd.statusRecord !== undefined && (!isFunction(profile.turnEnd.statusRecord.file) || typeof profile.turnEnd.statusRecord.query !== 'string')) problems.push('turnEnd.statusRecord requires file(env) and a fixed query'); |
There was a problem hiding this comment.
Profile 校验会重复报告同一配置错误
🟠 严重程度:低(P3)
本次新增代码重复执行了已存在的 turnEnd.statusRecord 和 commands.background 校验;每项无效配置都会被加入 problems 两次,导致用户或调用方收到重复诊断。
Finding:finding_ca9c439ce558815cd61d85bf
A worker can exit before fork, leaving an owner marker without a native child receipt. Give the guardian and orphan recovery mutually exclusive claims on the startup marker so recovery can remove a prelaunch directory while keeping claimed scratch without closure proof.
|
Sentinel 已审核此变更,并发现 4 个已核验问题。 无法定位到 diff 的已核验问题删除或消费 turn 后,
|
|
Sentinel 保留了 39 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 9cbfbf63d06e |
| if (turns.length > 0) { | ||
| const modelIsCurrent = isNativeRange(range) | ||
| ? turns.at(-1).modelBinding === bindingOf(range.model) | ||
| : removedTurn !== range.turns.at(-1); |
There was a problem hiding this comment.
路由冲突在冲突 turn 移除后仍永久阻塞范围
🔴 严重程度:高(P1)
withoutWorkTurn() 在生成已删除 turn 的新范围前,仍对旧 range 调用 rangeRouteProblem(range)。旧范围已有 routeConflict 时,该函数立即返回旧冲突;返回对象又通过 { ...range } 保留旧的 routeConflict 和 blocked。即使剩余 turns 已全部使用当前绑定,范围仍被视为路由阻塞,无法再次蒸馏,并会在阻塞 TTL 后被清理。
Finding:finding_ade414a27ef75fd7217fa360
| const terminal = facts?.terminal; | ||
| if (facts?.status !== 'ok' || !facts.schemaSupported || facts.bind?.origin !== 'user' | ||
| || facts.bind.turnId !== native.turnId || facts.bind.promptId !== native.promptId | ||
| || facts.mark?.fileId !== native.mark.fileId || !Number.isSafeInteger(facts.bind.mark) |
There was a problem hiding this comment.
初次读取失败的延迟 turn 在后续成功读取时会解引用空 mark
🟠 严重程度:中(P2)
capturePrompt() 明确允许在初次 facts 非 ok 时保存 mark: null。但 reconcileDeferredTurn() 后续处理成功响应时直接读取 native.mark.fileId,没有像当前 turn 路径那样使用 native.mark?.fileId。因此一次“初读失败、迟到响应成功”的合法部分响应序列会抛出 TypeError,且 deferred 状态中的空 mark 不会被修复,重试仍会重复失败。
Finding:finding_bf3a7d331558cd3e5aef76e8
An older dist/kimi can outlive a newer managed installation. Compare the staged and currently installed versions under the activation lock before replacing the package. Keep explicit version requests available for intentional source builds.
Keep the Kimi native monitor wiring and the ledger delivery changes from upstream PR EvoMap#58.
|
Sentinel 已审核此变更,并发现 3 个已核验问题。 无法定位到 diff 的已核验问题新增 native turn 测试文件无法解析并执行🔴 严重程度:高(P1) Finding: 当前为 另有 38 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 f3ad91480b38 |
|
Sentinel 保留了 38 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 f3ad91480b38 |
| assert.match(workflow, /needs: \[test, windows-minimax\]\n\s+if: startsWith\(github\.ref, 'refs\/tags\/v'\)/); | ||
| const windows = workflow.slice(workflow.indexOf(' windows-minimax:'), workflow.indexOf(' publish:')); | ||
| assert.match(windows, /if: startsWith\(github\.ref, 'refs\/tags\/v'\)\n\s+runs-on: \[self-hosted, Windows, X64, evox-gcp-win\]/); | ||
| assert.match(workflow, /needs: \[test, windows-minimax\]\r?\n\s+if: startsWith\(github\.ref, 'refs\/tags\/v'\)/); |
There was a problem hiding this comment.
标签发布不运行也不等待 Kimi Windows 验证
🔴 严重程度:高(P1)
新增契约确认 windows-kimi 只在 pull_request 或 workflow_dispatch 运行,而正式标签发布属于 push;同时 publish.needs 仍只有 [test, windows-minimax]。因此 Kimi 已进入打包及发布清单,但标签发布既不执行也不等待其 Windows 原生 hook 和打包验证。
Finding:finding_5d18ec7de33710e930404a45
| if (!observed) return; | ||
| // Native terminal wins over owner death; orphan recovery must not turn a completed check into an abort. | ||
| const result = await reconcile({ ...at, sessionEpoch: session.sessionEpoch }); | ||
| if (result?.facts?.limited || ['unreadable', 'unsupported'].includes(result?.facts?.status)) return; |
There was a problem hiding this comment.
事实分页达到上限后永久停止终态监控
🟠 严重程度:中(P2)
native-facts.js 返回可续读的 mark 并将超限批次标记为 limited,但监控器看到 limited 后立即退出,而不是继续使用该游标轮询。若 finish/fail/cancel 记录位于下一批,当前监控任务不会读取该终态。是否存在另一个可靠恢复入口在给定代码中未得到证明。
Finding:finding_0caf85023cca8930b06ee9a4
Bind only a fresh native TurnStarted matching the submitted prompt, owner, and file anchor when available. Keep the route binding captured at submit rather than selecting current credentials for an older turn.
Reevaluate the captured binding of the remaining work. Omit the old worktree diff for the repaired range and retain only runtime blocks tied to the same binding.
|
Sentinel 已审核此变更,并发现 2 个已核验问题。 另有 27 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 0624dfbfe0b8 |
|
Sentinel 保留了 27 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 0624dfbfe0b8 |
| const { turn, turnId, sessionEpoch, pid, prompt, turnHead, isCommand, withheld, native } = session; | ||
| const deferred = { turn, turnId, sessionEpoch, pid, prompt, turnHead, isCommand, withheld, native, open: false }; | ||
| return { native: null, deferredNativeTurns: [...(session.deferredNativeTurns ?? []), deferred].slice(-MAX_TURN_IDS) }; | ||
| } |
There was a problem hiding this comment.
未收敛的 deferred native turn 会被容量上限静默丢弃
🟠 严重程度:中(P2)
deferNativeTurn() 将仍等待 native 终态的 turn 写入 deferredNativeTurns 后立即执行 .slice(-MAX_TURN_IDS),最旧的未完成 turn 被移出唯一用于延迟终态匹配的状态。其后到达的终态无法再被 observedNativeTurn() 找到,finishDeferredNativeTurn() 的报告和候选收敛路径会拒绝该 turn。
Finding:finding_43ce269bcb11c4f12d4f8629
| if (process.platform === 'win32') { | ||
| if (child.jobEmpty !== true || !Number.isSafeInteger(child.helperPid) || child.helperPid <= 0) throw new ModelUnavailable('unsafe_runtime'); | ||
| pids.push(child.helperPid); | ||
| } |
There was a problem hiding this comment.
孤儿目录中的 PID 重用会阻塞后续所有模型调用
🟠 严重程度:中(P2)
恢复逻辑只通过 kill(pid, 0) 判断记录的 PID 是否仍存活,未验证其是否仍是原 guardian/native 进程。PID 被无关进程重用时,清理会抛出 MODEL_UNAVAILABLE,使新的完成请求在创建新隔离目录前失败。
Finding:finding_5845bd95085ca54435ce6756
|
Sentinel 已审核此变更,并发现 2 个已核验问题。 无法定位到 diff 的已核验问题未收敛的 deferred turn 超过容量后被静默淘汰🟠 严重程度:中(P2) Finding: 当前为 另有 28 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 526d93e75079 |
|
Sentinel 保留了 28 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
另有 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 526d93e75079 |
|
|
||
| function dropWorkTurn(ports, sessionId, opened, expected) { | ||
| return ports.candidates.update((pending) => { | ||
| if (expected && !rangeOf(pending, sessionId)?.turns.some((turn) => turn.turn === opened.turn && turn.sessionEpoch === opened.sessionEpoch)) return undefined; |
There was a problem hiding this comment.
失败补偿会删除并发完成路径写入的有效候选
🟠 严重程度:中(P2)
rememberWorkTurn() 写入 candidate 后重新读取 session;若状态已经转成 deferred,它会调用 dropWorkTurn() 补偿。但删除条件只验证 turn + sessionEpoch 仍存在,没有验证 candidate 的版本、内容或写入者。若 deferred 完成路径已在此期间更新同一 candidate,旧调用会把这个更新后的有效结果删除。rejudgeWorkTurn() 的非 work 删除分支也使用同一个无版本保护的补偿函数。
Finding:finding_3c1c5bd8f183da352a455ffd
Summary
Add local Windows support for Kimi Code CLI 2.4.1. Run
node scripts/install-kimi.mjs install, then start a new CLI session. Desktop follow-up #56The CLI layer accepts the local CLI client and its Windows process owner. It uses one managed package and preserves the selected Kimi profile, preferences and drafts. Private distillation uses the captured route. Publishing remains an explicit command with Proxy verification.
Evidence
kimi.exe.Merge Danger
Two-way. The installer can unregister the plugin while retaining user data. The native-turn, ACP and distill integration remains in the CLI base for review. See the earlier maintainer review.