Repository navigation
fix(dsh): retain safe admission stages and probe causes - #8521
huangruiteng merged 3 commits into
Conversation
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max
动机 / Motivation
这项改动面向排查 DSH 自动续跑没有开始的操作者。探测、绑定、配额或最后一次准入核验失败时,他们需要知道卡在哪一步。旧警告常把不同失败压成同一个 missing;本提案添加安全阶段和原因记录,但日志失败不能妨碍原有的用户消息恢复。已验证正常情况下能定位失败阶段并隐藏原始输出;当前 head 在导出器抛错时会丢掉原拒绝流程,并在九个候选时遗漏首个超时。范围是 Driver 诊断;GoalBar 的用户可见错误仍由独立 issue #8506 负责,取消竞态由 #8520 处理。
改动思路 / Approach
绑定、配额、预约和输入恢复由原 Driver/Core 拥有。阶段、路径存在样本及探测原因只是派生的观察值。 原行为不变会留下笼统 missing;把状态接进 GoalBar 又扩大到独立用户流程。保留现有错误类型,收集有界安全原因;诊断写入变为 best effort,并始终保留最早的主候选及末次原因。 当前风险不在标签的数量,在观察器被放到关键状态转换之前。 当前范围是 Driver 日志和共享命令错误的安全摘要;状态转换仍由原 Driver 负责。 诊断收集是有用的,但控制路径不应依赖日志;把记录降为无副作用的观察并为首末探测保留空间,比重写准入状态更小。
具体改动 / Changes
依据 DSH 设计:docs/plans/2026-08-20-dsh-native-skill-driver.md,固定修订 d3ac3bd。逐项:Human input priority — not_met;Same-session revalidation — implemented;Separate cancellation race — out_of_scope。
关键代码讲解
- cli.ts:68:安全字段来自枚举式代码和候选标签;新增 cwd 样本可区分缺少工作目录和可执行文件。输出裁剪需要保留原因而不披露原文。
- cli.ts:417:继续沿现有候选顺序探测,区分非零退出、格式/版本无效及传输失败,并把安全摘要放入现有 typed 错误。
- driver.ts:692:拒绝竞争输入前新增 warning;调用顺序决定导出错误能否跨过原有恢复动作。
- driver.ts:862:维护、解析、绑定、配额和 heartbeat 阶段只是当前尝试的派生信息。测试覆盖短标签、合成失败和真实缺 cwd;未变更 GoalBar schema 或组件。
对主干的风险 / Risks
[P2] 日志失败不得阻断用户消息恢复(driver.ts:693)。预步骤同时拿到原自动续跑预约和用户消息,已配置的 Cordis exporter 在 warn 时抛错。基线返回 reject 并恢复该消息;当前 head 抛出日志错误,Driver 没有把用户消息放回队列,也没执行预约退休路径。日志故障变成会话控制故障。把记录与拒绝、退休及恢复解耦;所有新日志观察器都应隔离导出错误,确保原状态转换和返回值。 复验:真实 Cordis Logger 启用 throwing exporter,给已领取预约加一条人工消息;验证 reject、原消息恰好恢复一次、下游不执行。
[P2] 有界输出仍须保留主要探测原因(cli.ts:70)。托管 launcher 可用,PATH 有四个版本化解释器;第一候选探测超时,后八次返回非零。真正第一条 timeout 在 Logger 输出消失,最后八条只剩 exit,用户仍分不清首个 launcher 超时和普通 Python 退出。上限保持八条,但预留主候选和末候选,按探测顺序保留可用条目,必要时报告省略数量。 复验:运行有真实可执行 stub 的九候选路径,断言首个 timeout 和末个 exit 均可见,至多八条,且不含 cwd、argv 或原始输出。
语义与 CI 对齐
现有测试 120 项、三组类型检查、源包构建、DCO 与 diff/RFC 配对均通过。两条反例通过真实 exporter 和真实探测进程复现,是当前 head 的运行语义或承诺缺口。合成 #8520 后取消三例恢复通过,两条反例仍在。变更质量核验保留这两项阻断;远端 CI 和全仓 premerge 未验证。
我的整体评价 / Verdict
精确 head:324c61469e818c9131d2045be65d788d834a1d36。长程推进:日志抛错时跳过原恢复,属于回归。用户体验:可能需要重发已提交的人工输入;主超时未显示也削弱故障定位。诊断收集是有用的,但控制路径不应依赖日志;把记录降为无副作用的观察并为首末探测保留空间,比重写准入状态更小。核对了 Driver pre-step、logger 与未修改的 GoalBar service;没有渲染变化。 未在已安装 DSH、Windows 或旧 SDK 上重启会话;未查询远端 CI,也未跑整仓 premerge。本地 package build 不代表安装或合并资格。
English verdict: REQUEST_CHANGES — 324c614; a real logger exporter failure bypasses user-message restoration, and the ninth candidate can hide the primary timeout.
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max
动机 / Motivation
启用了 DSH 自动续跑的操作者,需要知道一次尝试停在版本探测、绑定还是最后的准入检查。主干的日志常把探测失败写成笼统的 missing。上一评审提交补了阶段和原因,却会在日志导出器抛错时丢掉待恢复的用户消息,九个候选时也会丢掉首个超时。本提交让日志异常留在诊断边界内,竞争输入按原规则恢复一次,并在八条记录内保留首个原因和最后一次失败。范围是 Driver 日志。GoalBar 的失败展示由 #8506 跟进,探测取消由 #8520 跟进。
改动思路 / Approach
现有同一 Session 的 Driver 持有预约与人工输入优先权,LoopX 绑定和配额持有真实准入权。 在既有 warn 回调隔离导出异常,在既有错误格式化器保留首尾即可。准入、消息恢复和重试沿用已有 owner。 当前 PR 的范围是 Driver 警告边界、CLI 探测摘要及相应回归。 先用同一批输入核验 Driver 是否照常拒绝竞争预约,再检查诊断是否在同一条版本探测路径保留首因和末次结果。
具体改动 / Changes
依据 docs/plans/2026-08-20-dsh-native-skill-driver.md 的固定修订 d3ac3bd。Human input priority 为 implemented。Passive before activation 为 implemented。Same-session receipt 为 implemented。Bounded probe record 为 implemented。GoalBar failure presentation 为 out_of_scope。 同一会话 Driver 设计 · #8506
关键代码讲解
cliErrorFields对已有 typed 失败取首项及最后七项,按候选实际顺序记录,并显示省略数。真实 launcher 的首个超时仍可见,记录不带命令原文、路径或输出。 cli.ts L68 · cli.spec.ts L20- Driver 在原
warn回调隔离同步导出异常。原onPreStep继续退休预约并恢复人工输入。早到时下游未调用,晚到时下游调用一次,两种时序都只恢复一次。 driver.ts L507 · driver.ts L673 · driver.spec.ts L470 evaluate只记录当前尝试的阶段和安全原因。当前 Session 继续经过原绑定与配额检查,现有同轮结算用例实际调用 LoopX CLI,并验证只结算一次。 driver.ts L866 · admission-closeout.integration.spec.ts L275
对主干的风险 / Risks
在上一提交重跑新提交的三个回归用例,三项都失败。独立测试进一步覆盖两种输入时序下的健康、缺省和抛错导出器,真实九候选探测以及八、九、十三条记录的边界。新提交共通过 179 项定向测试,独立探针 11 项通过。主干与本提交都通过真实 CLI 的同轮结算对照。三个 TypeScript 配置、两份包构建、公开边界、DCO、双语 RFC 和精确变更质量回执均通过。 上一轮评审
我的整体评价 / Verdict
精确 head 为 def68a81a4435fda2d70cc5abbf6746ed076a6d2。批准。上一轮的两项发现已在当前提交复验。日志故障时原消息能恢复,诊断保留首因和末次结果。本轮未复验安装态 DSH、Windows、完整 premerge 或远端 CI。真实 CLI 测试使用隔离的 File authority 和受控宿主。
English verdict: APPROVE — def68a8. The revised Driver preserves human input under exporter failure, and bounded logs retain the primary and final probe causes.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
def68a8 to
529e7e2
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · GPT-5 · OpenAI · self_reported
动机 / Motivation
启用 DSH 自动续跑的操作者在一次准入失败后,需要知道失败停在版本探测、Session binding、quota 还是 heartbeat。旧 warning 把多数 CLI 失败压成一句 missing,还可能只显示最后一次候选退出;排查者无法区分首个 launcher timeout、缺失 cwd 的 ENOENT 和普通 Python fallback exit。
当前 PR 在现有 Driver/CLI 边界输出一条 bounded diagnostic:阶段、闭合 kind/code、候选标签、cwd 是否存在、signal 状态和耗时。它保留首个探测和最后七条摘要,并在 export 时省略数量;pre-step 只记录拒绝分支和其他消息的 source kind。范围仅限本地 warning,不改变准入、预约、人工消息恢复、GoalBar 或持久状态;不声称能还原历史事故或覆盖安装态重启。
改动思路 / Approach
现有 LoopXCliError 仍是错误 owner,resolveLoopXCommand 仍是候选 fallback owner,Driver 仍拥有 evaluation、reservation 和 pre-step 控制流。新增信息只是这些对象上的瞬时派生证据:CLI 层从真实 spawn/probe 样本生成 allowlisted 字段,Driver 层记录当前 stage,并在各 reject 点先发出 best-effort warning,再执行原有 retirement 和消息恢复。
flowchart LR
A[evaluate] --> B[resolve-command]
B --> C[resolve-binding]
C --> D[quota]
D --> E[heartbeat]
B -. failure .-> F[LoopXCliError diagnostics]
F --> G[allowlisted warning fields]
G --> H[warn exporter; errors swallowed]
C --> I[onPreStep recheck]
I -. reject .-> J[record branch + retire + restore]
图示对应精确 head 529e7e2791 的现有控制流,不代替执行证据。诊断机制是本地 observer,不是新的 policy 或控制状态;所有 warning 都插在原来的状态转换之前,而 exporter 异常被隔离在 callback 内。因此本 PR 的边界是“让既有失败可定位”,不是重新定义失败处理。
现有 typed CLI error 和 Driver warning boundary 已拥有失败发生点;只在这些 owner 上附加派生诊断,继续由原控制流决定 admission 和 recovery。
具体改动 / Changes
关键代码讲解
LoopXCliError增加可选 diagnostics 容器;旧构造调用保持兼容。它是进程内错误元数据,不进入 canonical state 或持久协议。cliErrorFields从闭合 kind/code/candidate 集合生成文本;探测超过八条时保留第一条和最后七条,并输出 omitted count。路径、argv、stdout/stderr 和任意异常文字不进入记录。spawnCwdExists在真实 runner 调用前采样 cwd;不可读是unknown,而不是伪造“不存在”。探测结果连同 OS code 写入新的 typed failure。LoopXContinuationDriverwarning boundary 捕获同步 exporter 异常,日志失败不会越过 reservation retirement 或用户消息恢复。onPreStep在 reservation mismatch、competing input、authority recheck 和 downstream batch 分支记录 stage/reason/source kinds;evaluate/buildPlan记录 maintenance-slot、resolve、quota 和 heartbeat。
该 PR 没有独立的新 diagnostic specification;判定以 PR 的 outcome statement 和变更前的 same-session Driver contract 为约束:
| criterion_id | 既有合同要求 | 当前 head |
|---|---|---|
DRIVER-HUMAN-PRIORITY |
人工或插件输入优先于自动 reservation;拒绝后恢复竞争消息。 | implemented:新增 warning 不改变原 retirement/restore 顺序;throwing exporter 回归通过。 |
DRIVER-PRESTEP |
入模型前复核 Agent、Session、reservation、竞争输入和 binding。 | implemented:记录各既有分支,不新增或跳过检查。 |
DRIVER-BOUNDED-DIAGNOSTICS |
安全失败信息不得暴露 raw subprocess output 或本地绝对路径。 | implemented:闭集字段、cwd boolean、source-kind allowlist、八条 probe 上限与负向披露测试。 |
DRIVER-SINGLE-OWNER |
准入、预约、retry、cancellation 和 settlement 继续由原 owner 管理。 | implemented:只扩展本地 warning 与错误元数据。 |
对主干的风险 / Risks
最强回归是诊断 observer 反过来改变控制流:旧实现中 Logger exporter 抛错可能越过 pre-step 的 retire/restore,导致已提交的人工消息丢失。当前 warn wrapper 把 exporter 异常限制在 observer 内;真实 Cordis Logger 加 throwing exporter 的 before/downstream 两阶段都只恢复一次用户消息,且 reservation 照常退休。
第二个风险是诊断文本泄露或误导。实现只从固定 kind、OS code、candidate、boolean 和 safe integer 生成记录;probe 文本用首项加末七项,避免九候选时丢掉主 timeout,也不携带 argv、路径或进程输出。未知值落为 internal、none、unknown,不会被原样拼接。第三个风险是 rebase 时丢掉新主线语义;冲突解决明确保留 host-context message 过滤、supportedLoopXVersion 和 { signal } quota API。
验证状态:完整 DSH plugin suite PASS(293/293);真实 admission-closeout integration PASS(10/10);host/client/test typecheck PASS;host/client build PASS;premerge PASS(6/6,使用 240 秒 per-check cap;quality phase 在当前 main 上实测约 141 秒);package artifact smoke PASS。registry latest/integrity 校验只适用于已发布版本,因此不在本 PR 声称为通过。新 head 的远端 DSH Ubuntu/Windows checks 仍在队列中,不作为本地判定依据。
语义与 CI 对齐
这是 intentional diagnostic delta:相同准入决策保持不变,失败 warning 从笼统异常文本变为有界结构化字段。它复用现有 LoopXCliError、pre-step 分支和 warning callback,仅新增进程内可选 metadata;没有新 authority、持久 vocabulary、重试或 settlement 语义。真实 CLI integration 同时断言 reject、guard 数、无 queued work 和安全字段,说明更新后的测试不是只匹配新字符串。
我的整体评价 / Verdict
这个 PR 解决了现有 owner 内可复现的诊断缺口,并且最重要的失败边界——Logger export 抛错不会打断 reservation retirement、人工输入恢复或后续准入——已被真实 exporter 反例覆盖。新增字段数量克制,格式有界,候选 fallback 仍沿原顺序;没有建立第二套日志 sink、持久状态或 GoalBar 投影。
没有发现阻塞问题。剩余风险是未在安装态 DSH、Windows 重启或历史线上事故中复验,以及真实用户是否能有效使用结构化日志;这些不否定 source head 的 local/real-process 证据。建议批准精确 head 529e7e2791584b2c7df31fa1817d379e053a9cfa。
English verdict: APPROVE 529e7e2 — verified bounded admission diagnostics, exporter-failure isolation, preserved user-message restoration and current-main DSH behavior; no blocking finding.
Goal And Delivered Outcome
A Driver admission failure currently loses its stage and cause. In particular,
missingcan mean exhausted version probes, a swallowed probe timeout/output limit, or a later spawnENOENT(including a missing Session cwd). A standalone version probe cannot distinguish these cases.Emit one safe diagnostic record with the admission stage, CLI kind and underlying probe kind, OS/exit code, candidate label, cwd-existence sample, combined-signal state and elapsed milliseconds. Preserve the primary probe and the last seven probe summaries, in probe order, with an omitted count when the eight-record limit is exceeded. Diagnostic exporter failures cannot interrupt admission, reservation retirement or restoration of competing user input. Pre-step rejections identify the exact branch and other messages' source kinds only.
main, fresh branch from the current target after rebase.Repair Update
The branch was rebased onto current
mainwithout dropping concurrent DSH behavior:runtime-context,time-contextandskill-cataloghost messages.supportedLoopXVersionparser while attaching the safe candidate label.{ signal }options contract while settingstage=quota.Exact repair head:
529e7e2791584b2c7df31fa1817d379e053a9cfa.Author Declaration
Implemented against
packages/dsh-loopx-plugin/src/cli.tsandsrc/driver.ts.evaluate,buildPlan,authorityStillAllowsLoopXCliError,resolveLoopXCommand,runJsonCommandonPreStep,preStepRejectioncliErrorFields,spawnCwdExistsThe cwd field is sampled immediately before invoking the runner;
unknownmeans no readable sample, not a nonexistent directory. Candidate labels and OS/error kinds are selected from closed scalar allowlists. These are local diagnostic labels, not a new authority or persisted control-plane vocabulary.Scope And Continuation
Complete within the Driver logging gap. Shared CLI helpers retain only metadata needed by the existing logger. No command output or exception message is rendered in these records, and no new logging sink, dependency or configuration is introduced. Warnings are best effort at the Driver's existing callback boundary.
Windows runtime provisioning, installed-host recovery and GoalBar's independent #8506 projection remain outside this PR.
Validation
529e7e2791584b2c7df31fa1817d379e053a9cfa.mainincludes real CLI closeout cases, exceeding the generic 120-second default.Remote CI is diagnostic until the new head is observed. The exact-head local checks above cover stage/source safety, numeric bounds, exporter failure isolation, real spawn cwd behavior and restored user input.
Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Make the existing DSH Driver failure diagnosable without changing its admission policy, user-message recovery or independent GoalBar failure-projection work.
Shared-authority RFC fixture impact
N/A; no shared-authority, storage or provider promotion change.
Boundary Checklist