Skip to content

feat: support ZCode Desktop on Windows - #57

Draft
imxyanua wants to merge 11 commits into
EvoMap:mainfrom
imxyanua:codex/zcode-desktop-windows
Draft

imxyanua wants to merge 11 commits into
EvoMap:mainfrom
imxyanua:codex/zcode-desktop-windows

Conversation

@imxyanua

@imxyanua imxyanua commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Extend the Windows ZCode CLI adapter to Desktop. Depends on #54. Desktop-only diff

Desktop Settings → local marketplace → shared Evolver plugin
  → shared Recipe, evidence and private draft flow
  → bundled ZCode CLI for isolated completion

The Desktop bundle includes a local marketplace with the stamped plugin version. When ZCODE_CLI_PATH is unset, the adapter discovers the CLI in the standard Windows Desktop install. An invalid explicit path blocks completion. The draft targets upstream main for CI. The Desktop-only comparison isolates the ten changed files while the CLI base is under review.

Evidence

  • Windows Node 22 and 26 each passed 12 ZCode tests and 15 architecture, packaging and calibration checks. The pack test verifies that the marketplace and plugin versions match.
  • A copied native ZCode 0.17.0 runtime in a disposable profile installed the packed marketplace entry and reported six runnable hooks.
  • Earlier Windows Desktop UI acceptance used real Grok and an official unreleased Proxy 2.0.50 build. A passing test produced a private draft, and cancellation after a pass produced no reuse report or candidate. The split was tested without rerunning Desktop UI or the live provider and Proxy.

Merge Danger

Two-way. The Desktop layer adds the local marketplace and a runtime discovery path to the existing ZCode package. Keep this draft stacked on #54 until the CLI base has landed.

Recheck dead-owner turns against native terminal status, keep delayed end handlers within their own session epoch, and only settle reuse evidence actually queued. Continue reading the completion handshake after stdout capture reaches its limit.
Keep verified report payloads in the injection ledger after a local queue failure. Retry using the original check evidence and leave unverified injections out of delivery.
Forward the supplied record after native terminal confirmation and handle a missing status reader. Give a dead owner a bounded grace for terminal metadata and omit any stale worktree. Isolated model declarations default to an empty environment.
Keep the cross-shell calibration regression already landed upstream in EvoMap#55.
Require an explicit regular ZCode CLI bundle for background completion. Install through CLI plugin directories, and exercise the package without a Desktop installation.
Package a local marketplace and discover the Desktop-bundled CLI only when no explicit standalone CLI path is configured.
@evomap-aiqa-bot

evomap-aiqa-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Sentinel 已审核此变更,并发现 2 个已核验问题。

无法定位到 diff 的已核验问题

绑定模型配置读取时绕过了声明的环境变量覆盖

🟠 严重程度:中(P2)
当前实现先以原始 env 调用 prepareConfig(declaration, env, workdir, model),随后才执行 declaration.env 生成 overrides 和 runEnv。因此绑定配置的 configFile.source(env) 看不到声明通过 env 函数提供的路径、凭...(truncated)

Finding:finding_055092c7c8eea31b9b21e637 · 文件:lib/runtime/model-executor.js · 详情:/api/v1/aiqa/findings/finding_055092c7c8eea31b9b21e637

closeInputOn 抛错会逃逸 Promise 并成为未捕获异常

🟠 严重程度:中(P2)
新增回调直接在 child.stdout 的异步 data 监听器中执行,没有 try/catch 或 Promise rejection 通道。回调一旦因格式异常抛出,异常不会被 runProcess 的 Promise 捕获,而会作为 Node 未捕获异常传播;同时�...(truncated)

Finding:finding_a0502d94e04f32e280e71861 · 文件:lib/runtime/process/spawn.js · 详情:/api/v1/aiqa/findings/finding_a0502d94e04f32e280e71861

当前为 advisory 仓库:这些 item 会逐条保留,但不阻塞合并。

另有 10 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。

审核覆盖提示: 2 个 hunk/条目缺少完整输入;它们不作为 bug 报告。

开发 agent 查询详情: 调用 MCP 工具 sentinel_pr_review_context,传入 owner_repo="evomap/evolver-agent-plugin"、pr_number=57、head_sha="d6d9127486da9599e591d82bd0eed34390e9ab81",并按条目追加 finding_id 或 finding_key。

由 Sentinel 审核 · 目标提交 d6d9127486da

@evomap-aiqa-bot

Copy link
Copy Markdown

Sentinel 保留了 10 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
开发 agent:请 review 以下 advisory,并逐条给出“已验证无风险 / 已修复 / 转为后续事项”的结论;不要只做整体确认。

  • [P2] 空白 ZCODE_DATA_BASE_DIR 使 provider 配置路径变成不可用 — providerConfigOf() 使用 env.ZCODE_DATA_BASE_DIR?.trim() ?? nativeHomeOf(env);空白字符串经 trim() 后为 ...(truncated) · hosts/zcode/model.js · advisory_7ba657450378a42ed9d9414b
  • [P2] 监视器未绑定 session epoch,旧终态可能被应用到替换会话 — 监视器只用 sessionId + turnId 验证当前会话,没有保存或比较启动时的 sessionEpoch。更关键��...(truncated) · lib/runtime/turn-monitor.js · advisory_6a09bea509e1f27b146e7f0d
  • [P2] epoch 检查与报告入队不原子,迟到回调仍可写出旧会话报告 — reportTurn 只在读取 session 后检查一次 sessionEpoch,随后异步执行 reports.enqueue。如果同一 ...(truncated) · lib/app/turn-end.js·advisory_385ce7b0fbe14f3e8429e5bb`
  • [P3] 会话重置与候选写入之间存在 TOCTOU,旧范围可在新 epoch 中复活 — 新增的 epoch 校验发生在 candidates.update 之前,但会话可以在校验完成后、候选写入前切换��...(truncated) · lib/app/turn-end.js · advisory_ac830472def50c2f6712ceac
  • [P3] 确认模式在读取终态记录失败后永久关闭 turn,重试无法补偿 — turn 在读取 host 记录前已经被关闭;若 recordOf 抛出临时错误,finally 仍将其 settled。随后�...(truncated) · lib/app/turn-end.js · advisory_8dd3975c0e4cf30288dca9c5
  • [P3] 确认模式的公开结束入口本身未校验原生终态 — 新增 confirmTurnCompletion 的端口说明要求仅原生终态可接纳 observed evidence,但 turnEnded 未读�...(truncated) · lib/app/turn-end.js · advisory_83be129faf0573e2538e1977
  • [P3] 原生状态尚未可见时会永久丢失稍后到达的正常结束记录 — closeUnfinishedTurn 在状态缺失时仍以 error 关闭 turn;随后正常结束事件进入 turnEnded 时,tu...(truncated) · lib/app/turn-end.js · advisory_322bc60bd3f7ca2015a0c3f1
  • [P3] 调用方模型覆盖宿主确认路由,可能把工作范围并入错误账户 — 新增代码使用 model ??= modelForTurn?.(...),因此只要调用方传入非空 model,宿主终态记录确��...(truncated) · lib/app/turn-end.js · advisory_19a3a8d778a1f8faf03b49e0
  • [P3] 失败分支可能清空 last-known-good 数据 — 状态链探针:failure branch writes data/cache-like state; verify it does not clear useful last-known-good content · lib/runtime/store/file-stores.js · slice:client_orchestration_01:state_chain_ff9609a9143112d6
  • [P3] 缺少 turnStatus 时恢复任务静默退出,遗留会话无法收敛 — sessionStarted 只根据 confirmTurnCompletion 禁用旧的孤儿恢复路径;但 recoverNativeTurns 在 turnSt...(truncated) · ``lib/app/session-start.js`` · advisory_a21b203761a99d7d973b3cb5`

需要完整证据时,可用行末 finding_key 查询 Sentinel PR review context。

由 Sentinel 审核 · 目标提交 d6d9127486da

Copying the index advances its mtime, which can make Git trust a cached stat entry for a same-size edit. Use the source index timestamp rounded down before adding untracked entries. A deterministic regression checks both diff parts and the untouched source index.

(cherry picked from commit bbd7c68)
@evomap-aiqa-bot

evomap-aiqa-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Sentinel 已审核此变更,并发现 3 个已核验问题。

无法定位到 diff 的已核验问题

确认完成模式下读取终态记录失败会永久丢失该轮处理

🟠 严重程度:中(P2)
当前 PR 将终态记录读取提前到已关闭 turn 之后;若 recordOf 拒绝,finally 仍把该 turn 标为 settled。确认完成模式又禁止 opened 缺失时走原有的 rejudgeWorkTurn() 补偿,因此重投无法重新读取记录、报...(truncated)

Finding:finding_8e7612a76e912b5e5d10cac7 · 文件:lib/app/turn-end.js · 详情:/api/v1/aiqa/findings/finding_8e7612a76e912b5e5d10cac7

当前为 advisory 仓库:这些 item 会逐条保留,但不阻塞合并。

另有 12 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。

审核覆盖提示: 2 个 hunk/条目缺少完整输入;它们不作为 bug 报告。

开发 agent 查询详情: 调用 MCP 工具 sentinel_pr_review_context,传入 owner_repo="evomap/evolver-agent-plugin"、pr_number=57、head_sha="1faff1639d9ff1210966561149eb3d39cd3b7eb1",并按条目追加 finding_id 或 finding_key。

由 Sentinel 审核 · 目标提交 1faff1639d9f

@evomap-aiqa-bot

Copy link
Copy Markdown

Sentinel 保留了 12 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
开发 agent:请 review 以下 advisory,并逐条给出“已验证无风险 / 已修复 / 转为后续事项”的结论;不要只做整体确认。

  • [P2] 空白数据目录变量会破坏 provider 配置默认路径 — providerConfigOf() 使用 env.ZCODE_DATA_BASE_DIR?.trim() ?? nativeHomeOf(env)。空白值经 trim() 后成为 ''...(truncated) · hosts/zcode/model.js·advisory_c63002bdfde4abafffb599f8`
  • [P2] 缺少 completed_at 的取消或失败记录会永久保持 pending — 状态查询只有在记录为 running 或 completed_at IS NOT NULL 时才读取该行。因此,若 ZCode 将 sta...(truncated) · hosts/zcode/profile.js·advisory_a993df93f9ba80f753a3602a`
  • [P3] monitorTurn 仍未绑定启动时的 sessionEpoch — watcher 每次轮询只验证当前 session.turnId === at.turnId,没有保存并比较启动时的 sessionEpoch。...(truncated) · lib/runtime/turn-monitor.js · advisory_b7b10fc10c8775fa9be35654
  • [P3] epoch 校验与报告入队不原子,旧会话报告仍可写入 outbox — reportTurn 只在入队前读取并校验一次 sessionEpoch,随后执行不可回滚的外部 reports.enqueue��...(truncated) · lib/app/turn-end.js · advisory_7646e078f16a88788b93397a
  • [P3] 恢复任务未将宿主终态绑定到 session epoch — 恢复任务从当前 session 快照取得 sessionEpoch,但宿主状态只按 sessionId + turnId 查询。如果��...(truncated) · lib/app/session-start.js · advisory_b04c919b8a2f24d86cee759c
  • [P3] 确认完成模式下读取宿主记录失败后无法重试 — turn 会在读取宿主记录前被 closeTurn() 关闭。recordOf 抛错后,finally 仍将 session 标记为 set...(truncated) · lib/app/turn-end.js · advisory_3e29d3cdd6e90ed38bba5ff8
  • [P3] 停止非验证命令后不会重新启动终态追踪 — 新代码明确为“权限等待过久或 Stop 后 native row 才出现”增加补偿调度,但 shell 路径被限��...(truncated) · lib/agent/driver.js · advisory_9d922745cbaf42a3e00c20aa
  • [P3] 取消或失败终态可能永久停留在 pending — 终态消费者似乎用 completed_at 判断轮次是否结束,但宿主的取消或失败记录可能没有该字��...(truncated) · lib/app/background.js`, `lib/app/turn-end.js`, `lib/app/ports.js`, `lib/turn-outcomes.js · advisory_edd5c30fccf8089c38bd4618
  • [P3] 失败分支可能清空 last-known-good 数据 — 状态链探针:failure branch writes data/cache-like state; verify it does not clear useful last-known-good content · lib/runtime/store/file-stores.js · slice:client_orchestration_01:state_chain_ff9609a9143112d6
  • [P3] 异步终态追踪未绑定 session epoch — 恢复任务和 monitorTurn 均未固定启动时的 sessionEpoch;同时,端口层的 epoch 校验与报告入��...(truncated) · ``lib/app/session-start.js, lib/app/session-end.js`, `lib/runtime/turn-monitor.js`, `lib/app/ports....(truncated)` · `advisory_8ada31bc35881b4b6365ef73`
  • [P3] 终态记录读取失败后轮次被提前结算,导致永久丢失 — 完成确认流程在成功读取宿主终态记录前,将 turn 标记为已结算或移除可重试状态。读取失...(truncated) · lib/app/ports.js`, `lib/app/turn-end.js · advisory_9589a72ed04d1b3266436601
  • [P3] 配置路径失败可能同时破坏 last-known-good 回退 — 空白数据目录环境变量会覆盖默认 provider 配置路径并触发加载失败;另一分片指出失败分��...(truncated) · ``hosts/zcode/profile.js, hosts/zcode/model.js`, `lib/runtime/environment.js`, `lib/runtime/store/f...(truncated)` · `advisory_9c1839f1fc6814d11a71a4de`

需要完整证据时,可用行末 finding_key 查询 Sentinel PR review context。

由 Sentinel 审核 · 目标提交 1faff1639d9f

Comment thread lib/app/turn-end.js Outdated
export async function turnEnded(ports, { sessionId, turnId, reason, answer = '', model = null, projectDir, recordOf = null, source = OBSERVED }) {
const opened = await closeTurn(ports, sessionId, turnId);
export async function turnEnded(ports, { sessionId, turnId, reason, answer = '', model = null, projectDir, recordOf = null, source = OBSERVED, expectedTurn }) {
const opened = await closeTurn(ports, sessionId, turnId, expectedTurn);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

终态记录读取失败后提前结算,重投无法恢复

🟠 严重程度:中(P2)
turnEnded 先通过 closeTurn 关闭 open turn,随后才在 recordTurn 中读取宿主记录;读取异常时,finally 仍调用 settledSession。同一终态事件重投后已找不到 open turn,而新增的 confirmTurnCompletion 分支直接返回 null,禁用了原有 rejudgeWorkTurn 补偿路径。

Finding:finding_150213f6cd70a7087748bc8f

Comment thread lib/app/turn-end.js
const opened = await closeTurn(ports, sessionId, turnId, expectedTurn);
if (!opened) {
if (!(turnId && recordOf && source === OBSERVED)) return null;
if (ports.confirmTurnCompletion || !(turnId && recordOf && source === OBSERVED)) return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

终态记录读取失败后 turn 被永久结算,重试无法补偿

🟠 严重程度:中(P2)
closeTurn 在读取宿主终态记录前先关闭 turn;若 recordOf 抛错,finally 仍将该 turn 标记 settled。之后重试时已找不到 open turn,而新增的 confirmTurnCompletion 分支直接返回 null,不会执行原有 rejudgeWorkTurn 补偿,也不会再次读取终态记录。

Finding:finding_7709a85b775177a249bb4ec4

Reopen only the current confirmed turn when evidence reads fail before any reports or candidate writes. Release uncommitted JSONL claims for immediate recovery on redelivery.
@evomap-aiqa-bot

evomap-aiqa-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Sentinel 已审核此变更,未发现已核验问题,但发现需要人工确认的风险。

另有 22 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。

审核覆盖提示: 2 个 hunk/条目缺少完整输入;它们不作为 bug 报告。

开发 agent 查询详情: 调用 MCP 工具 sentinel_pr_review_context,传入 owner_repo="evomap/evolver-agent-plugin"、pr_number=57、head_sha="f18bfe591c30a48e0343185c346059e8450d308a",并按条目追加 finding_id 或 finding_key。

由 Sentinel 审核 · 目标提交 f18bfe591c30

@evomap-aiqa-bot

Copy link
Copy Markdown

Sentinel 保留了 22 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
开发 agent:请 review 以下 advisory,并逐条给出“已验证无风险 / 已修复 / 转为后续事项”的结论;不要只做整体确认。

  • [P2] 确认模式会丢弃升级前没有 pendingReport 的未报告资产 — pendingReportsOf() 仅返回带 pendingReport 的资产;但旧 ledger 格式没有该字段。确认模式下 pen...(truncated) · lib/app/session-end.js·advisory_602017c12fe26ea9de846fd6`
  • [P2] 终态监视器未绑定 session epoch,迟到完成可关闭替换会话 — watcher 和锁键只绑定 sessionId + turnId,没有保存并比较启动时的 sessionEpoch。会话被替换后�...(truncated) · lib/runtime/turn-monitor.js · advisory_3219bfa100bea080f8b536b0
  • [P3] epoch 竞态导致 notes/baseline lease 未释放也未提交 — readTurnEvidence() 成功取得 notes 和 edits 后,recordTurn() 可能因 epoch 变化返回 null。调用方��...(truncated) · lib/app/turn-end.js · advisory_20696d72e8f03940341c626f
  • [P3] 恢复任务可能把旧 epoch 的终态应用到新会话 — recoverNativeTurns() 从当前 session 快照读取 { turn, turnId, sessionEpoch },但查询宿主终态时只传�...(truncated) · lib/app/session-start.js · advisory_28482d87ab254917b0f2009f
  • [P3] monitorTurn 未绑定启动时的 sessionEpoch,旧终态可能写入新会话 — 当前 watcher 每轮只校验 session.open 和 session.turnId === at.turnId,没有保存并比较 watcher 启动�...(truncated) · lib/runtime/turn-monitor.js · advisory_67ac33bdb3e3d251b0cad724
  • [P3] closeInputOn 回调异常会逃逸并终止宿主进程 — 新增的 stdout data 事件处理器直接调用 closeInputOn(line),未捕获该回调抛出的异常。事件监...(truncated) · lib/runtime/process/spawn.js · advisory_2e37cf46b74ba5dcb98c6e1a
  • [P3] 取消或失败但缺少 completed_at 的 turn 会被错误保持为 pending — 状态查询只接受 status = 'running' 或 completed_at IS NOT NULL 的记录。若 ZCode 对 cancelled 或 err...(truncated) · ``hosts/zcode/profile.js`` · advisory_919be3ed93ceb08a65b65151`
  • [P3] 空白数据目录变量会使 provider 配置路径失效 — providerConfigOf() 使用 env.ZCODE_DATA_BASE_DIR?.trim() ?? nativeHomeOf(env)。当环境变量为 " " 时,t...(truncated) · ``hosts/zcode/model.js`` · advisory_fff032a9242c0aec2a314b59`
  • [P3] epoch 切换后旧 turn 的报告仍可能写入 outbox — reportTurn() 只在读取 session 时检查一次 sessionEpoch,随后先执行 await reports.enqueue(...),入�...(truncated) · lib/app/turn-end.js · advisory_9a5667b0728198f34753f03d
  • [P3] regularFile 会拒绝指向真实文件的可执行符号链接 — 当前 PR 新增的 isRegularFile() 使用 lstatSync(file).isFile()。对于常见的“符号链接指向真实可�...(truncated) · lib/runtime/process/which.js · advisory_9a96d07b5856e0507f588f2d
  • [P3] native turn 状态首次不可见时恢复任务不会继续重试 — recoverNativeTurns 查询到非终态或 undefined 时,reasonOfNativeStatus 返回空值,任务随即正常完...(truncated) · lib/app/session-start.js · advisory_2ce69ac67d8bcb1ceebd322f
  • [P3] 候选范围写入仍存在 epoch TOCTOU,旧范围可复活到新 session — rememberWorkTurn() 先读取候选快照,再单独读取 session epoch,最后调用 candidates.update()。sessio...(truncated) · lib/app/turn-end.js · advisory_a03726ffc9c494b51d023af5
  • [P3] 确认模式会丢弃没有 pendingReport 的未报告资产 — pendingReportsOf() 只返回仍未报告且已有 pendingReport 的资产;但确认模式下 sessionEnded() 将 ...(truncated) · lib/app/session-end.js · advisory_a250ce28e576412ae882460d
  • [P3] pairedNotes 会把同一 callId 的重复执行合并为一次检查 — 新增实现把整个输入中的相同 callId 都视为同一个 shell 调用。若宿主在重试、重复执行或�...(truncated) · lib/turn/record.js · advisory_ca8dece977b93e49940f7272
  • [P3] SessionStore.update 的可选返回值被无条件解引用 — ports.js 中 SessionStore.update 的契约是 Promise<object|undefined>。新增的 closeTurn() 在 opened 已...(truncated) · lib/app/turn-end.js · advisory_6866674a0c8f0224d5b598a5
  • [P3] native turn 首次不可见时恢复流程可能永久停止 — session 启动后的恢复任务在首次读取 native turn 状态不可见时不会继续重试;与此同时终态和...(truncated) · lib/app/session-start.js`、`lib/session/state.js`、`lib/app/session-end.js · advisory_1725f2b50c5ef20421dd40f3
  • [P3] 失败分支可能清空 last-known-good 数据 — 状态链探针:failure branch writes data/cache-like state; verify it does not clear useful last-known-good content · lib/runtime/store/file-stores.js · slice:release_integrity_03:state_chain_ff9609a9143112d6
  • [P3] 旧 session 的终态可污染新 session — 多个独立 slice 都指出异步恢复、终态监视、turn 报告和 TOOL_RESULT 补偿没有统一绑定启动时...(truncated) · ``lib/app/turn-end.js、lib/runtime/turn-monitor.js`、`lib/app/session-end.js`、`lib/app/tool-res...(truncated)` · `advisory_3a1b49ddef94f752383b54af`
  • [P3] 确认流程与旧格式资产的生产契约不一致 — 资产生产或迁移路径允许存在没有 pendingReport 的旧格式未报告资产,但确认流程仅处理带 ...(truncated) · ``lib/injected-ledger.js、lib/app/session-end.js`、`lib/app/session-start.js`、`lib/session/stat...(truncated)` · `advisory_672c058fda87a0928f5fa3fe`
  • [P3] 重复 callId 可能被错误合并,导致一次执行缺少检查 — pairedNotes 按 callId 合并重复执行记录,但同一 callId 可能对应重试、重复补偿或不同执��...(truncated) · lib/turn/record.js`、`lib/app/tool-result.js`、`lib/app/session-end.js · advisory_b4ffb7706f747777caa49680

另有 2 条候选未在评论中展开;可通过下方 Sentinel PR review context 查询全部条目。

开发 agent 查询详情: 调用 MCP 工具 sentinel_pr_review_context,传入 owner_repo="evomap/evolver-agent-plugin"、pr_number=57、head_sha="f18bfe591c30a48e0343185c346059e8450d308a",并按条目追加 finding_id 或 finding_key。

由 Sentinel 审核 · 目标提交 f18bfe591c30

@evomap-aiqa-bot

evomap-aiqa-bot Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Sentinel 已审核此变更,并发现 1 个已核验问题。

另有 16 个需要人工确认的风险;黄色 advisory 不阻塞合并,建议开发 agent review advisory 评论并逐条确认。

审核覆盖提示: 2 个 hunk/条目缺少完整输入;它们不作为 bug 报告。

开发 agent 查询详情: 调用 MCP 工具 sentinel_pr_review_context,传入 owner_repo="evomap/evolver-agent-plugin"、pr_number=57、head_sha="977fc4355b3a8a658648ce7a7882f64bb079c87f",并按条目追加 finding_id 或 finding_key。

由 Sentinel 审核 · 目标提交 977fc4355b3a

@evomap-aiqa-bot

Copy link
Copy Markdown

Sentinel 保留了 16 个尚未确认的审核候选。这些黄色条目不阻塞合并;红色 P0/P1 与其他独立硬门禁不受影响。 单一猜测、缺少变更行证据或纯 checklist 的候选会统一降为 P3。
开发 agent:请 review 以下 advisory,并逐条给出“已验证无风险 / 已修复 / 转为后续事项”的结论;不要只做整体确认。

  • [P2] epoch 切换后已取得的 notes lease 未释放 — readTurnEvidence() 已通过 notes.take() 取得 lease;如果 epoch 在其后发生变化,recordTurn() 的新�...(truncated) · lib/app/turn-end.js · advisory_45f0de78d153709e1a07d9d4
  • [P2] 旧监视器可将宿主终态应用到替换后的会话 — 监视器及锁键只绑定 sessionId + turnId,没有保存启动时的 sessionEpoch。轮询只检查当前 sessi...(truncated) · lib/runtime/turn-monitor.js · advisory_e1b7d887744cc1df83098570
  • [P2] 确认模式关闭会话时会永久遗漏没有缓存报告的资产 — pendingReportsOf() 只返回带 pendingReport 的未报告资产,但返回值始终是数组;即使为空,后�...(truncated) · lib/app/session-end.js · advisory_97e2cffac15d864aad5167f2
  • [P2] 空白 ZCODE_DATA_BASE_DIR 会破坏默认 provider 配置路径 — providerConfigOf() 使用 env.ZCODE_DATA_BASE_DIR?.trim() ?? nativeHomeOf(env)。变量为纯空白时,trim() ��...(truncated) · hosts/zcode/model.js · advisory_0f790fffeb88dae5fb796fbd
  • [P2] 宿主未落终态时,死亡进程的 turn 将永久保持 open — PR 在确认模式下完全禁用原有 queueOrphanReports(),而 recoverNativeTurns() 只有在 reasonOfNativeSta...(truncated) · lib/app/session-start.js·advisory_6c439daa28674ffece94fc37`
  • [P3] 会话切换可在报告入队期间写出旧 epoch 数据并遗留 evidence lease — reportTurn() 只在入队前检查一次 epoch,随后执行不可回滚的异步 reports.enqueue()。若等待期�...(truncated) · lib/app/turn-end.js · advisory_9ea2b176bea76b229fd0eeb7
  • [P3] 后续 ZCode 测试未创建状态数据库父目录 — 前一个测试在创建 DatabaseSync 前显式执行 mkdirSync(dirname(file), { recursive: true }),但新增的��...(truncated) · test/runtime/turn-monitor.test.js · advisory_d5f3b7483bb54ad4bbcf5c16
  • [P3] 恢复查询未绑定 sessionEpoch,旧终态可能关闭新 epoch — session 快照包含当前 sessionEpoch,但 turnStatus() 只按 sessionId 和 turnId 查询。若查询命中�...(truncated) · lib/app/session-start.js · advisory_bbf3330bcc90763101da824f
  • [P3] 恢复任务可把旧 epoch 的宿主终态应用到新会话 — 恢复快照保存了当前 sessionEpoch,但宿主状态查询只传递 sessionId + turnId。若宿主跨 epoch ��...(truncated) · lib/app/session-start.js · advisory_6d958ffbc6589ab065e8a8de
  • [P3] 声明确认能力但未提供状态查询时会禁用所有孤儿恢复 — sessionStarted() 只依据 confirmTurnCompletion 禁用旧的 queueOrphanReports();但新恢复入口在缺少 ...(truncated) · lib/app/session-start.js·advisory_f46989315b8e9b1ebdff7954`
  • [P3] closeInputOn 无法处理未以换行结尾的握手响应 — 新协议只有在 stdout 中出现换行时才调用 closeInputOn(line);最后一个未终止的片段始终留在 ...(truncated) · lib/runtime/process/spawn.js · advisory_b35692ccbe413b067fc5aef0
  • [P3] 恢复状态查询未携带 session epoch — 恢复快照包含 sessionEpoch,但宿主状态接口只按 sessionId + turnId 查询。若宿主跨 epoch 复用�...(truncated) · lib/app/session-start.js · advisory_b7db9925a1ee342bdcad6896
  • [P3] 失败分支可能清空 last-known-good 数据 — 状态链探针:failure branch writes data/cache-like state; verify it does not clear useful last-known-good content · lib/runtime/store/file-stores.js · slice:release_integrity_03:state_chain_ff9609a9143112d6
  • [P3] 确认模式关闭会话时永久丢弃未报告资产 — 会话结束逻辑将“支持确认完成”视为可以直接关闭,但旧格式资产或没有缓存报告的资产...(truncated) · lib/app/session-end.js · advisory_4f5007a33abcb512bd7a589d
  • [P3] 缺少 completed_at 的取消或失败记录会一直被判为 pending — 查询仅接受 status = 'running' 或 completed_at IS NOT NULL 的记录。若宿主已写入 cancelled/error��...(truncated) · hosts/zcode/profile.js · advisory_0c75475a5aa30fcd67d2636b
  • [P3] 工具结果触发的延迟调度可能未绑定会话 epoch — 新入口在异步记录工具结果后,使用事件开始时捕获的 at 和 turnId 调度终态确认。现有��...(truncated) · lib/agent/driver.js · advisory_3a79d1f08f6779b9d84923bd

需要完整证据时,可用行末 finding_key 查询 Sentinel PR review context。

由 Sentinel 审核 · 目标提交 977fc4355b3a

Comment thread lib/app/session-end.js
await turnEnded(ports, { sessionId, reason: openTurnReason, projectDir, recordOf: () => NOTHING_DONE });
const ending = sessionOf(await ports.sessions.read(sessionId));
const due = unreportedOf(ending, sessionId, Infinity);
const pending = ports.confirmTurnCompletion ? pendingReportsOf(ending, sessionId) : null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

确认模式关闭会话时丢弃旧格式的未报告资产

🟠 严重程度:中(P2)
pendingReportsOf() 只返回带 pendingReport 的资产。确认模式下其返回值即使是空数组也为真,因此不会回退到 unreportedOf();随后代码仍调用 endedSession()。旧 ledger 中没有 pendingReport 的未报告资产会留在已关闭 session 内,且确认模式同时禁用了启动时的 queueOrphanReports() 补偿。

Finding:finding_065eeec6c2da6f546353dbc9

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.

1 participant