# dsh-arbiter-wf(**0.8.4-stable**) ## 0.8.0-preview:独立裁判层(改名首版) 新增 `consult_task`,模型和思考档位沿用优化 AI 配置。启用本会话提示词辅助后可调用;要让顾问读取项目成果文件,开启已有“只读工具”选项。 - 重复失败却没有新证据时:`mode: diagnose_failure`,提供具体问题和可选 `hypothesis`,返回下一步和停止条件。 - 首次交付前:先自验并取得原始工具结果,再调用 `mode: review_result`;可提供最多四个项目内成果相对路径 `artifacts`。不提交自己的通过结论。 - 自动读取最近一条真人消息以来的证据;成果复核不提供主模型正文或先前顾问结果。不实现跨轮记忆。 - 验收状态分满足、不满足、未验证;顾问不是用户授权,也不能代替用户的视觉体验测试。 - 取消信号传至模型并等待收尾(依赖 provider 遵守取消);默认不设顾问总时间上限,不自动重试。 - 只有显式设置 `DSH_PO06_ADVISOR_TIMEOUT_MS` 才启用调用方截止;只读查证仍有轮次上限,模型流/输出终止仍由 provider 决定。 - 若调用方显式设置截止,到点不会空手而归:已有完整报告就保留并标为部分产出;只跑到一半也会交回思考尾部与查证记录,供调用方判断下一步。 - 专项输入:`scope` 是**检查维度、不是行业**(geometry形体与装配 / appearance画面观感 / code代码正确性 / interaction交互逻辑 / performance性能证据 / delivery交付覆盖 / custom其它专项),`focus` 为具体对象与检查点。省略scope保持general兼容;专项不能泛化成整体通过。按任务实际需要选维度,一次只选一个,不适用就不选。 - 通用性约束:提示词与参数说明不含任何行业的专用词汇,由 `advisor-generality.test.mjs` 机械拦截——专项是“怎么查”,不是“查什么行业”。任何领域的成果都用同一套维度,`custom` 兜住维度外的情形。 - 几何/外观只发图片、不注入开发历史或源码、不开放源码工具;误传文件在卡片标“本次范围排除”。代码/交互/性能仅发相关源码与原始日志,图片排除;可用`evidenceRefs`选择本次工具证据编号。用户原话和权限边界始终保留。 - 按高风险阶段成形、返工成本将升、用户反馈和关键改动触发复核;视觉先独立看图,有疑点再同focus追源码,不固定堆次数。小任务可只做一次general。 - 交付复核使用`scope: delivery`和`requiredReviews: [{scope,focus}]`逐项核对本轮覆盖、未解决项与材料变更。requiredScopes仅类别提示,不能用某一focus通过冒充整类别通过。覆盖仅同会话同真人请求,有界保存;材料指纹/已记录源码写事件变化后需重审。外部或任意shell写入不能保证全部感知。 - 卡片显示专项对象、排除材料,delivery显示缺失项与既有报告的版本状态。当前仍没有强制拦截交付或自动调用,真实识图效果待用户手测。 - 斜杠命令允许列表(0.8):设置项 `slashReview`(命令名数组,不带斜杠,默认 `[]` = 所有斜杠命令仍交还宿主)。 - 只有**列在名单里、且宿主确认当前已注册**的命令才走「拦截 → 优化 → 可编辑确认」;官方命令(/clear、/model、/compact 等)与未注册命令照旧直发,行为与改动前一致。 - 名单项不存在(没装对应插件)**不会报错**。分两种情形: - **问得到命令表**(有 live agent):未注册的命令不进放行集合,我们不拦,完全等同没配这一条; - **问不到命令表**(无 live agent / 服务缺失):退回名单本身照常拦截,并在 `/status.slashReview` 标 `verified:false` + 具体原因,不假装核对过、也不静默失效。 - 任一情形下 `/status` 都照常 200、不抛异常;无会话时不拦截。 - 浮层可改内容,但不允许把命令本身换掉:编辑后不再是原命令时,按用户按下发送时的原话发出。 - 与 rollout 的 `allowlist` 是两回事:那个管「哪些会话启用」,本项管「哪些斜杠命令可被拦截」。 - 启用方法:`~/.dsh/po06.json` 写 `"slashReview": ["vmake"]`,改完重启 DSH 生效。 - 材料参数:`files: [{path, purpose}]`(关键成果源码/配置/原始测试日志),`images: [{path, purpose}]`(真实默认画面/近景/异常截图)。`artifacts`旧字符串数组仍兼容。路径相对会话工作目录,files与artifacts合计最多4份、images最多4张。遵守用户文件限制,不自动上传整个工程。 - 文件最多2 MiB,UTF-8文本每份附入最多16,000字符、合计48,000字符;超出明确标截断,不据此判完整通过。图片每张最多5 MiB、合计12 MiB,通过宿主附件服务校验和标准化。 - 只有宿主确认所选优化模型支持图像时才附入真正image块;未知/文本模型显示“未检查图片”,不自动换模型。只读工具关闭时不读取材料。 - 选哪个 shell(2026-10-01 修):工具描述按**命令性质**给判据(POSIX 管线/glob/串联/bash 语义 → bash;PowerShell 对象语义 → pwsh),并保留一条**标明来源**的经验口径:两者都能做时优先 bash,不为同一条命令来回换 shell。 - 起因是我原先在描述里写了「跑 Windows 原生程序时 pwsh 通常更快更稳」——**没有实测支撑**,还把位置放错(塞在 `timeoutMs` 参数说明里),净效果是把模型推离 bash(本会话 pwsh 136 次 : bash 2 次)。 - 实测反向证据:`node -e`、`node --test` 这类 Windows 原生工具链经 bash 跑均正常(0.28–0.33s),且与 POSIX 管线可在同一进程完成;未发现 bash 更慢或更不稳。 - 机器守卫:`bash-execute.test.mjs` 断言描述里不再出现该未实测断言、且必须含「按命令性质选/优先 bash」。 - 卡片逐项显示材料路径、用途、状态及实际附入字符数;文件可展开看咨询时片段,点击路径用DSH侧栏预览当前文件。两者版本可能不同,材料保留内容指纹。图片用同一侧栏预览,不自建文件下载接口。 - 顾问专用卡片同时覆盖直接调用和代码中的子调用,固定四个分区:原 AI 询问内容、顾问思考内容、顾问答复内容、验收结果。询问和答复直接可见;思考与验收独立折叠、默认收起。展开思考可实时看 provider 返回的流,没有提供时明确标注。 - 思考展开时默认跟随最新内容,向上滚动后暂停跟随;查证记录收在思考区内部,原始输出收在验收区内部。答复摘要可随生成显示,未完成校验前不当作最终结论。 - 实时状态按会话和调用 ID 隔离;已完成记录在本机缓存中有界保留最近 80 次,可刷新后回看。旧调用没有补录思考;中止/部分产出不能显示为完整通过。 - 卡片更新需要完整重启 DSH 并硬刷新浏览器;本机仍通过 link 指向开发目录,不必重装。 - token 计数(0.8 修):页脚显示本次咨询的 `Σ 合计 | 入 · 出 · 缓存`。用量有两个来源——宿主投影(已归一化)与进度记录(provider 原始字段)——格式化入口对两种形状都做容错归一。 - 2026-10-01 真机缺陷:卡片优先取原始记录,而格式化只认归一字段 ⇒ 页脚恒显 `Σ — tok`;修在格式化入口,**已落盘的旧卡片刷新后也会显示数字**。 - 仍然不折算、不估算:provider 没给合计就不替它加(只列分项);整场没有上报用量(例如刚开始就到点)则如实显示 `Σ — tok`。 本版已发布。下面的下载链接指向本次发布。 > 💬 中文用户交流:**QQ 群 1121399051**(最新消息、安装帮助、版本公告)。 `@dsh-external/dsh-arbiter-wf` · **0.8.4-stable** · GitHub Release(**未发 npm**:`private: true`,只发附件) → 下载:(附件含 `tgz` 与 `SHA256SUMS`) > **0.7.8(历史版本)的一句话**:**档位终于真的分开了**——补充程度(700 / 1200 / 2000 字)与自主预算 > (1 / 2 / 3 个问题)两个维度逐级递进;此前 `minimal` 从未被任何档位使用、且 standard 与 heavy 的 > detail 相同,所以「重度」实际只等于「标准 + 多问 1 个」。同时**内部控制面信息不再写进工作模型的上下文** > (注入头部原先带「任务 `default` · 意图修订 N」,会被当成任务语义处理,现已移除)。 > 质量解释改为「结果方向」而非制作清单;思维层不再显示裸 JSON 补丁。 > > **仍然成立的一句**:**每一轮都独立想一遍**——上一轮的目标不会带进这一轮,包只由「**你这轮的原话** + > **本轮读入的上下文**」重新得出。**代价**:长期约束("只交单个文件""别动别的文件夹")也要靠上下文 > 每轮重新看出来 ⇒ **别把「上下文」调得太小**。 > > **这一版修的四件事**: > ① **"思考完却拿不到包"**(真机反复出现的那条):模型交空产出(空 `ops` / 没吐 JSON)时**有界重试一次**, > 仍空就补一条"这一轮没提取到"的**待确认**条目(不发明要求、不拦下游)⇒ **这一轮必有包**; > 条目超过单轮上限改为**截断记账**、指向不存在条目的销账**逐条丢弃**、你点「取消」不再被记成"解析失败"。 > ② **浅色模式**:颜色**由主题驱动**(浅色=浅底深字、深色=原观感;切主题即时生效)。 > ③ **界面语言跟随 DSH**(`设置 → 通用 → 语言`,`zh`/`en`):插件内**没有**自己的语言开关,`?` 用户手册 > 也跟着切(**英文界面里不该再夹中文**)。 > ④ **启用判定修对**:`rollout` 缺失/写错不再把显式 `enabled:true` 的插件**静默关掉**(只有显式 `off` 才是不启用), > `/status` 增加**闸门结论分布**(配置意图 ≠ 闸门实际放行,这两件事以前分不开)。 > > 同版沿用:操控面对齐 0.5(档位 `关闭/轻度/标准/重度`、两行控件栏、`?` 用户手册、 > 拦截浮层分**思维层 / 产出层**);思维层**固定显示范围、无滚动条、正文一律不截断**(可往回滚,自动跟到最新); > token 用 provider **真实上报**的 `入 / 出 / 缓存` 三分量(过千记 `k`/`M`,拿不到就显示 `—`,**从不按字数估算**); > 以及「只读工具:开」那类失败的三条真因:① 解释层标识符笔误 `TOOL_SYSTEM_NOTE is not defined`(**29 ms** 内抛错 > ⇒ 既看不到思维、也没有产出);② **一条写坏的来源引用能弄死整轮**(模型写 `kind:'tool'/'file'`,可 > `toolCallId`/`uri` 只有宿主才有 ⇒ 整份补丁 `BAD_SCHEMA`、合法条目陪葬;现在只补宿主确实知道的事实, > 其余逐条丢弃并记账);③ `provenance:'machine'` **从未生效**的顺序缺陷(从读入材料推出来的条目曾看起来像"你说过的")。 > **人工验收就一遍**:见 `po06/HUMAN-TEST.md`(12 步 + 4 个反馈点)。前提:**档位不能是「关闭」**——关闭档按设计不拦截。 > ⚠️ **版本号叫 stable 指的是"这一版对外定为正式版",不是"能力已通过专业跑分"。** > - **内部自洽有证据**:**1141 项测试 + 变异守卫**全绿,含打包自足性与文档漂移门禁。 > - 📊 **作者实测观察(不是专业跑分)**:测试主要在 **DeepSeek-V4.1-Flash + PTC + PowerShell** 环境下进行。 > **目前没有做过专业的跑分测试**;但在常见的各类 one-shot 任务与长任务迭代中, > **实际效果明显强于同环境、同提示词下的 DeepSeek-V4.1-Flash**;另据**少量项目**的统计, > **疑似会降低 token 消耗量、节省开销**。 > - **机器那半边照旧如实登记**:留出评估只跑完 **S1**(103,368 tokens);唯一还没测到的那条判据(**约束守住**) > 题与仪器刚就绪、**还没跑**(S4,期望 11,672)。 > ⇒ 请当成**可以装、可以试、随时可关**的东西,**不是"升级"**。 > - **它默认不启用**:装配期启用闸门保守取 `off`;即便配置开了, > 只要旧版插件仍在装配就会以 `DOUBLE_INTERCEPT` 拒绝启用(EV-0054)。 ## 控制界面(0.6 自带的 UI,不用另装) 装好并启用后,**输入框左侧会出现一排控件**(0.5 的位置与形态——用户实测反馈"不适应 0.6 的操控模式"后按 0.5 重排的)。 浮层仍挂在原来的位置,里面的条目/轮次/提示词编辑都在;设置页里也有一页同样的控件。 | 你能控制 | 它真的改变了什么(不是装饰) | |---|---| | **档位**:关闭 / 轻度 / 标准 / 重度 | **一次写三项**(档位是"糖",不是第二份真相):关闭 ⇒ `assist=off`(不解释不投递);轻度 ⇒ 标准补充/标准预算;标准 ⇒ 尽量补全/标准预算;重度 ⇒ 尽量补全/更多自主。档位为「关闭」时,权限与上下文两栏会置灰 | | **优化权限**:审查 / 自动 | `review` = 产出先给出处与依据待你确认;`auto` = 直接生效 | | **上下文**:回合 0~10 / 全文(**全文时滑块只有 关/开**) | 解释层**真的去读会话上下文**(真机实测:`histChars=7066`、读了 4 个回合)。0/关 = 不读 | | **读项目文件**:开 / 关 | 打开后解释层可用 **`read`/`glob`/`grep`** 查证项目实际内容(限定会话工作目录内、只读、轮次与时限封顶、越界拒绝)。**默认关**(0.5 默认开——工具轮次要花时间与 token,不悄悄放大成本) | | **模型** | 下拉来自**宿主模型目录**;默认"跟随会话模型",选了就以所选路由解释 | | **`?` 帮助** | 弹层正文来自包里的 `HELP-0.6.md`(宿主 `GET /po06/api/help` 取,**客户端不内置副本**);写的是 0.6 的真实行为,读不到就如实说"读不到"并给出文件路径 | | **提示词**(详情面板内) | 能看当前生效正文、能改、**能撤销上一次修改**,也能恢复内置 | **「详情」面板只留「控制」与「解释层提示词」**(用户 2026-09-21 要求撤掉了「它在替我做什么」「最近几轮」两块; 逐轮台账仍在**设置页 → 插件 → 提示词优化器**里看:预算内/超预算、上下文读了多少字/几回合、 有没有派工具(没派会写原因,例如"读文件开关是关的")、有没有从工具路径回落;**缺值显示"未记录"**,不拿 0 冒充"没发生")。 **"无出处条目"的警告没有消失**——它挪进了拦截审查面板(机器自己编的、没有你原话支撑的要求必须看得见)。 > ⚠ **档位的"包预算"是"可丢部分的预算"**:`700/1200/2000` 约束的是可省略的章节, > **你的要求(必保节)永不丢弃**;万一必保节本身就超了,注入文本里会写明【预算不足】与省略了哪些条目。 > ⚠ **已做 / 没做,说清楚**:**条目级、包级的历史回退还没有**(那条路径目前返回 501)。 > 现在可用的"回退"只有三种:把**档位**切到「关闭」、**恢复内置提示词**、**撤销上次提示词修改**。 > 模型下拉需要宿主提供模型目录与 `webServer`(`web` profile 有;`headless` 等没有这一层)。 > 浮层**尚未**按 0.5 的形态重排(0.5 的 `run/outcome/trace` 检视面**有意不做**)。 ## 30 秒:装到独立 profile、启用、关掉 **前提**:`dsh` 已装(`dsh --version` 有输出);**别装进你每天在用的那个 profile**(那里有 0.5.x, 两者同装配会被 `DOUBLE_INTERCEPT` 守卫拒绝启用)。下面命令里的 `po06beta` 只是 profile 名,**随你起**。 **① 从 Release 下载安装包**(两个附件:`tgz` + 校验和): ```powershell # 直链(版本号换成你要的;0.8.4-stable 是最新版) $v = '0.8.4-stable' $dir = "$env:USERPROFILE\Downloads" Invoke-WebRequest "https://github.com/WestFox-AwA/dsh-prompt-optimizer/releases/download/v$v/dsh-external-dsh-arbiter-wf-$v.tgz" -OutFile "$dir\dsh-external-dsh-arbiter-wf-$v.tgz" Invoke-WebRequest "https://github.com/WestFox-AwA/dsh-prompt-optimizer/releases/download/v$v/SHA256SUMS-$v.txt" -OutFile "$dir\SHA256SUMS-$v.txt" # 校验(下载坏了会在安装后才以"行为怪怪的"暴露,先比一下最省事) Get-FileHash "$dir\dsh-external-dsh-arbiter-wf-$v.tgz" -Algorithm SHA256 | Select-Object -ExpandProperty Hash Get-Content "$dir\SHA256SUMS-$v.txt" ``` > 也可以在浏览器里打开 挑对应版本手动下这两个文件。 > ### 装不上时的排查顺序(issue #29) > > | 你看到的 | 真正的原因 | 怎么办 | > |---|---|---| > | 插件市场报 `no matching package found`,随后回落到 git 安装 | 本包**按设计不发 npm**(`private: true`),registry 上永远搜不到 | 用上面的 Release 附件装,别让安装器去搜 npm | > | git 安装报 `schannel: … SEC_E_INVALID_TOKEN` | 本机 git 的 TLS/代理问题(命令连 GitHub 都没连上),与插件无关 | 改用 Release 附件;或 `git config --global http.sslBackend openssl` 后重试 | > | 安装器提示 `allowBuilds` / 构建脚本被拦 | 本包**没有任何构建步骤**,这条提示是通用的 | 不用改 `allowBuilds`;按上一条排查 TLS | > | 装上了但没有拦截(`gate: rollout-off`) | 档位还停在关闭 | 把档位拨到**标准**或**重度** | > 本版是**正式版**(无 `-beta` 后缀),`releases/latest` 会指向它; > 想装旧版就把 `$v` 换成对应 tag。版本号只有一个真源:`po06/package.json`。 **② 新建一个干净 profile 并装进去**: ```powershell # 用发行版自带的 web 模板新建 profile(不含 0.5.x) dsh --profile po061 --from-default-profile web --dump-config # 装本包(tgz 路径换成你下载到的位置) dsh plugin --profile po061 add "$env:USERPROFILE\Downloads\dsh-external-dsh-arbiter-wf-0.8.4-stable.tgz" ``` **③(可选,但强烈建议)一条命令自检**:装好了、装的是这一份、会被装配"(**不调模型、不花钱**): ```powershell # 需要仓库里的脚本;没克隆仓库就跳过这步,直接进 ④ node \po06\scripts\check-install.mjs --profile po061 --expect-version 0.8.4-stable ``` 它会逐条回答: - **装上了吗**:profile 的 `dependencies` 里有没有这个包; - **装的是这一份吗**:把装出来的 `lib/*.js` 与仓库**逐文件比 sha256** ——这个项目在"装的是新件还是 pnpm 缓存里的旧件"上**栽过两次**(EV-0079/0083), 而那种失败**不报错**,只是行为像没装; - **会被装配吗**:`--dump-config` 的组合树里有没有这一层 ——**装了但不在 `dsh.profile.bundles` 里 = 永远不会生效**(EV-0066); - **启用会生效吗**:用**装出来的那份**解析器读配置(不是我复述规则),并说明旧路径为什么不会被误认。 **④ 启用**(写 0.6 **自己的**配置文件;**不会**碰 0.5.x 的 `prompt-optimizer.json`,见 EV-0111): ```powershell Set-Content -Path "$env:USERPROFILE\.dsh\po06.json" -Encoding utf8 -Value '{"settingsVersion":1,"enabled":true,"rollout":{"mode":"all"}}' ``` 也可以装完之后**在面板上拨档位**(档位 关闭/轻度/标准/重度 就是启用开关;`关闭` = 不拦截)。 **⑤ 用那个 profile 开工**:`dsh --profile po061`(它会启动该 profile 的应用并打印带 token 的地址)。 ⚠ **`--profile` 必须写在子命令之前**:`dsh --profile po061 …` 可以,`dsh web --profile po061` **不行** (`web` 子命令明确拒绝父级的 `--profile`,实测报 `web takes none of parent --profile`)。 默认端口被占用时加 `--port 3081`。 **效果什么时候生效(P11 改变的地方)**:网页输入框里按发送/回车会被**前置拦截**—— 先把这一轮解释清楚(实测 21–57 秒,界面上有「优化中… 已用 N 秒」与**跳过并直接发送**,**不设超时**), **再**把你的消息原样发出去;所以包在**这一轮第一个模型调用之前**就已经写好 ⇒ **第一轮第一步就吃到**。 「审查」权限下,解释完成后先给你看正文并可**直接编辑**(点「确认提交」才发)。 **档位=「关闭」时不拦截、不等待、不注入**(走原生路径,0 等待)。 仍然存在的旧路径:**非网页入口**(终端等)发的消息不会被拦,那种情况下包落在同一轮的第 2 步起。 ⚠ 拦截链的**整链真机验收尚未完成**(按用户要求改由人工一遍跑完,见 `po06/HUMAN-TEST.md`)。 **④ 关掉 / 卸掉(随时、一步)**: ```powershell # 关:把 enabled 改 false(或直接删掉这个文件——读不到就是不启用) Set-Content -Path "$env:USERPROFILE\.dsh\po06.json" -Encoding utf8 -Value '{"settingsVersion":1,"enabled":false,"rollout":{"mode":"off"}}' # 卸:从 profile 移除并把 profile 整个删掉 dsh plugin --profile po061 remove @dsh-external/dsh-po06 Remove-Item -Recurse -Force "$env:USERPROFILE\.dsh\profiles\po06beta" ``` > **为什么单独一个 profile**:你每天用的 `web` profile 里装着 **0.5.x**,而且 > `\prompt-optimizer.json` 是它**正在使用的设置**(tier/strategy/ui…)。 > 0.6 早先把启用意图写在同一个路径上——那意味着"想试试 0.6"要先破坏你每天在用的插件。 > 已改掉:0.6 读自己的 `po06.json`,旧路径只做**只读回退**且必须带 0.6 标记(EV-0111)。 ## 跑完之后:怎么看它到底做了什么(`recap.mjs`) 真实项目里用过一轮之后,留下的东西只有三样,**都在 `` 下**: | 文件 | 是什么 | |---|---| | `po06-wire.jsonl` | **每轮用户输入的判定台账**:成没成、包多大、第几版、走了哪些环节 | | `po06-state/.json` | 该会话的**意图条目**(每条带出处:你说过 / 机器补充) | | `po06-reports/*.json` | 自检报告(只在显式自检时写) | 一条命令把它整理成人能读的一页(**不调模型、不花钱**): ```powershell node \po06\scripts\recap.mjs --home "$env:USERPROFILE\.dsh" # 只看某个会话: --session 机器读: --json out.json ``` 它回答两个最该被问的问题: 1. **"它有没有参与?"**——逐轮列出 `committed / skipped / …` 与**意图包字符数**; 没提交的轮次**单独列出来并给出理由**(而不是安静地什么都不做,EV-0078 的教训)。 台账为空时它会直接告诉你"**一次都没被触发过**"(多半是没启用,或装到了别的 home)。 2. **"它替我说了什么?"**——把条目分成 **"你说过"** 与 **"机器补充"** 两类, 并统计**无出处条目数**:按契约那个数**必须是 0**,不是 0 就以**非零退出码**报出来 (无出处 = 不知道是谁说的,那是缺陷,不是排版问题)。 3. **"跨会话有没有串味?"**——每条条目的出处必须落在**它自己所在的会话或它的祖先会话**里。 **分叉继承来的条目指向父会话是「正确」的**("这句话是你在父会话里说的"), 所以判据不能写成"出处必须等于自己"——那会把合法继承全判成泄漏。 指向**链之外**的会话 = 把别处的话当成你在这里说的 ⇒ **非零退出码**。 > 读法的关键:**"你说过"的条目必须是你真说过的原话**——契约要求逐字引文, > **对不上的那一条被丢掉并记账**(不是整份作废:其余条目照常产出,见 `lib/interpreter.js` 的逐条丢弃); > 而"机器补充"是它自己的判断,**不得被当成你的命令**。 > 这一页**只做事实整理,不做质量判定**:哪一版答案更好只能你自己读。 ### 顺带能把「分叉继承」验掉(A7 的另一半) 在 GUI 里对一个**已经用过**的会话点**分叉**,在子会话里**说一句话**,然后重跑上面的命令: 「**〇、分叉继承**」那一节应当出现一行,写明子会话、继承自哪个父会话、继承到的版本。 - **有那一行** ⇒ 宿主分叉时 0.6 **确实**把父会话的意图状态派生给了子会话 (深拷贝 + 改写归属 + 留下出处,ADR-0039)。 - **没有那一行而你确实分叉过** ⇒ 继承**没发生**:子会话会**从零开始**,而且**不会有任何提示** ——这正是那条 ADR 要防的"静默无状态"。 ## 花钱之前:预检(`preflight-e001.mjs`) 留出评估的每一次运行都要花钱,所以**先花零成本问清楚"这一期到底能测到什么"**: ```powershell node \po06\scripts\preflight-e001.mjs --stage S4 [--budget ] ``` 它逐条报出(**不调模型、不花钱**): | 检查 | 为什么 | |---|---| | 封存 hash + 题数,**外加一次负向自检** | 只报"校验通过"没有意义——要证明**篡改真的会被拒** | | 每题的**判据适用性** | S1 的教训:那一期 6 题里 **0 题**适用「约束守住」,而这件事是花掉 103k **之后**才发现的 | | 上界 / 期望 / **其中解释层的前置花费** | 跑之前要花的钱与跑起来要花的钱是两笔 | | 预算判定(低于上界直接拒绝) | 避免跑到一半没钱 | | 包缓存:哪些题**不再花解释层的钱** | 缓存存在但一个都不匹配本期题号时会**明确警告**(别把"有缓存"读成"不花钱") | | 判据要的产物**会不会落盘** | run1 曾只存字符数,白花 42,884 | **结论不是"能跑"就放行**:任一检查不成立就以**退出码 2** 拦住,并在结论里写"**不建议现在跑**"。 ## 它想做什么 让用户在**少写提示词**的情况下更准确地传达意思,并让工作 AI 做得更好、更稳,同时不违背用户本意。 做法上的三个关键选择: 1. **原话保留,机器补充另附** —— 用户的话永远原样留在人类消息里; 机器的解释以**带来源标签的分节**形式附在上下文里(`systemPrompt.context` → 宿主的 `form:'snapshot'` 聚合消息)。 质量展开有地方放(「质量解释…不是新增命令」节),但不可能被读成用户的命令。 2. **`user_requirement` 必须带逐字引文** —— 引文必须是用户原话的**字面子串**,对不上则**只丢这一条**(记账进 `dropped`,其余条目照常)。 这把「机器替用户发明要求」从信任问题变成**字符串比对问题**。 2026-10-06 追加**信息量下限**:引文不足正文的 1/3 且净增超过 20 字时,该条降级为机器理解、不写成用户要求 (拦的是"引一个词就写成一段要求";措辞巧妙的扩写仍可能通过,扩写始终留在 `claims` 里可回查)。 3. **检测到问题不等于可以动手** —— 只有 `fail` 能触发返工; 基础设施故障与未知都不算;返工默认**只记录不发送**(三级投递 L0)。 ## 已验证(有证据) | 能力 | 证据 | |---|---| | plugin 来源消息全链路(构造→投递→持久日志→模型实收) | EV-0010 | | 动态上下文注册 / 排序 / 卸载;去重由宿主负责 | EV-0013、EV-0014 | | 意图状态:CAS、来源身份、用户改口闸门 | EV-0023(18 项)、EV-0025(真实宿主) | | 持久化与 `restore()` 重建一致 | EV-0026 | | 编译分节 + 预算丢弃 + 范围审计 | EV-0029(16 项) | | 解释层契约(逐字引文、白名单、数量上限) | EV-0031(18 项) | | 流水线端到端(离线)与**真实宿主**接入 | EV-0032、EV-0033 | | 澄清规划(分类/预算/去重/授权;超时≠同意) | EV-0035(23 项) | | 长任务作用域(`task`/`turn`)与跨轮退役 | EV-0038、EV-0039 | | 压缩/序列化/fork 保持性 | EV-0040 | | 验证器判定逻辑(只有 `fail` 可返工;六道门) | EV-0041(24 项) | | **真机 HTML 验证器**(好/坏×2/可疑样本全判对) | EV-0042 | | 三级投递交付门(L0 不发送 / L1 不唤醒) | EV-0043、EV-0044(真实宿主) | | 配置迁移不机械映射;旧状态不冒充需求 | EV-0045、EV-0047 | | 灰度保守默认 + 双重拦截守卫(真实宿主拦住了) | EV-0046、EV-0048 | | 旧插件**运行时**探测 | EV-0048 | | **装配期启用闸门真的接在装配路径上**(默认抑制/强制放行两侧对照) | **EV-0054** | | 启用判定带**保质期**:过期即不启用;旧插件**事后**出现会被撤销(附未闭合缺口) | **EV-0061** | | **验证器仪器纪律**(采样不早退、外部依赖可观测、绘制活动与 NaN、不泄漏进程与磁盘) | **EV-0049、EV-0050、EV-0051、EV-0052、EV-0053** | | `npm pack` 实测:包内容 = `files` 清单,版本三处一致 | EV-0054 | | **打包产物**装配演练(仓库外可 import、未夹带 test/scripts/eval、源树字节未变) | **EV-0056** | | **真实 npm 安装/卸载**(未装 cordis 也能装、卸得净;**反向对照证明断言会红**) | **EV-0057** | | **留出集 S1 真题**上的澄清与编译符合判据(不该问的不问、可查事实不丢回用户) | **EV-0059** | | **留出集 S3 真题**上的长任务/环境/取消判据(撤回回到原状、约束跨轮保持、infra 不算已验证) | **EV-0060** | **234 个变异跨 42 个源文件,全部被测试捕获。** > 变异检验中有一条**必须记住的纪律**:变异不仅要求"有测试变红", > 还要求**指定的那条**测试变红(`expectFailIncludes`)。 > 我第一次给"封存 hash 变异"写错了期望片段(写"封存",实际失败的用例名叫"hash 不符…"), > 检验**如实判为未捕获**——这正是它该有的严格程度。 > > 同一纪律后来又救回两次:① 一个变异把解释层从**期望总额**里删掉时, > 12 项测试**全绿**(原测试只钉了上界),暴露出一条缺失的不变量; > ② 期望片段指到了**被断言的消息**而不是**会红的那条用例名**。 > **变异守卫的价值不在于"抓到了",而在于它也会抓我。** ## **未验证**(不要让这些看起来像"也有") | 缺口 | 说明 | |---|---| | **效果(最重要的一条)** | **S1 已跑完,结论是"没差别"**:36/36 单元、0 失败,但**没有任何可信判据显示 A 臂与 C 臂有差别**(放大 A0/C0、完全指定任务必要内容 A 7/9 · C 7/9、稳定性差异弱且方向不一致)。用户逐条判读的「**该不该问**」:两臂**各 0 条**"不该问" ⇒ 该判据**非区分、作废**(它曾是 0.6 的主要卖点)。唯一还没测到的是「**约束守住**」:题与仪器刚就绪(**S4**,数字见 `po06/RELEASE-CHECKLIST.md`)**但一次都没跑**。**仍缺 B 臂(0.4.4)**,且 B 臂无实测成本基线。**预算只能由你授权**(⚠ 与上面「作者实测观察」不冲突、也不互相证明:这一条是**受控对照**、样本很小,结论是"**没测出**差别";那条是**日常使用**里的观察,没有对照、没有第三方复现) | | **在真实项目里用过** | **作者本人用过**(DeepSeek-V4.1-Flash + PTC + PowerShell 的日常项目):据其观察,各类 one-shot 与长任务迭代里**实际效果明显强于同环境、同提示词下的工作模型**,少量项目统计**疑似降低 token 消耗**。**但这不是专业跑分**:没有受控对照、没有第三方复现,也没有稳定的成本基线。 | | **工作模型是否遵守标签** | 未验证。同类契约已有反例:逐字引文模型遵守了(EV-0034),`unknownClass` 字段两次都没遵守(EV-0037) | | ~~重启后 hydrate~~ | ✅ **已验(真机)**:EV-0081 用隔离 home、**两个独立进程**跑通"重启后状态恢复"。**剩下未验的是分叉(fork)**:A7 的另一半 | | 真实多轮 / fork | **多轮已验(真机,EV-0085)**:SDK 通路在一个长驻进程里连发两轮,跨轮约束确实出现在第 2 轮的上下文里。**fork 未验**(代码 + 单测有,真机没有) | | 真实配置迁移(A8) | **刻意未执行**(仅临时目录 dry-run)。⚠ 已确认 0.6 **不再**共用 0.5.x 的 `prompt-optimizer.json`(EV-0111),所以"不迁移"现在是**安全的**,不再是隐患 | | 完整卸载演练 | 打包自足性已进发版门(EV-0110);**profile 级完整装卸仍只做过分步验证**,没做过"装→用→卸→确认干净"的一次到底 | | 发布动作 | `private:true` **保持**(不发 npm,只发 GitHub Release 附件——避免把这个未经效果验证的包误发上公共注册表);**隔离 profile 装配已做了**(`po06beta` + 启用配置 + `DOUBLE_INTERCEPT` 守卫实测),**真实 GUI 刷新验证仍未做** | | UI | **没有客户端界面**,全部经由宿主既有机制 | > 曾经列在这里的「**慢初始化页面**:见画布有尺寸即停,可能过早判定」**已关闭**: > 那正是一个真实仪器缺陷——canvas 的 `width/height` 默认就是 300×150, > 从未被渲染器碰过的画布也算"有尺寸",于是 1.2s 就收工,把"我读得太早"报成结论(EV-0049)。 ## 已知限制与风险 - **`unknownClass` 路由当前"机制就绪、输入缺失"**:真实模型不输出该字段(两次实测), 所有未知退化为「用户偏好」,靠批次上限(默认 2)兜住问卷风险。 代码里用 `unclassified` 计数把它**显示出来**,不静默降级。 - **`informational` 检查没有被守卫**:若有人把决定性检查误标为 `informational`,会造成漏判。 - **交付门生产触发默认关闭**:每次交付都启动浏览器是重操作,是否开启属设置决策。 - **旧插件探测的静态分支会误报**(装了但禁用),这是刻意的保守方向。 - **状态只保留最近 200 个会话**(`po06-state/` 按文件修改时间淘汰,`DEFAULT_KEEP = 200`)。 超出之后**更早会话的意图状态会被删掉**——那个会话本身照常能打开、能继续用, 只是 0.6 不再记得它的约束(**不会有提示**)。保留份数目前写死,改它要动代码。 - **状态文件读不出来时**(JSON 坏 / 形状不对)0.6 会把坏文件**改名留证据** (`<会话>.corrupt-<时间戳>.json`)、记一条 `state-unreadable` 台账,然后按"尚无状态"继续。 **它不会静默覆盖那份文件**;这类事件会在 `recap.mjs` 里单独列出(并让退出码非零)。 若你在那里看到这一节:**残骸文件里很可能就是丢失的长期约束**。 ## 回滚方式 **最短的一条**(beta 期间推荐):把 `po06.json` 的 `enabled` 改成 `false`,或**直接删掉这个文件** ——读不到即不启用,且**不影响你原有的 0.5.x**(两者不是同一个文件,EV-0111)。 1. 若已注入:`dev_uninject_plugin`(或从 profile 移除 junction 与 patch 条目)。 2. 若已迁移配置:从 `/backups/prompt-optimizer.<时间戳>.bak.json` 还原 (`rollbackConfig`,**回滚不会删除备份**)。 3. 旧版本插件不受本包影响;`@dsh-external/dsh-prompt-optimizer`(0.5.x)仍在原处, 它的设置文件 `prompt-optimizer.json` **全程只被 0.6 只读回退读取**,从未被写。 ## 目录 ``` po06/ lib/ 62 个模块(domain / 编译 / 解释 / 澄清 / 长任务 / 验证 / 反馈 / 迁移 / 灰度 / 装配闸门 / 评估计划 / 冒烟 / 宿主资源定位 / 只读工具 / 会话上下文 / 清痕 / **档位策略与领域维度** / **虚拟 POSIX 层**) test/ 104 套测试 + 变异检验 eval/ HOLDOUT-v2.md(已封存,v1 的 18 题逐字节未改 + 追加 H-19/H-20)、HOLDOUT-v1.md(保留以备复核)、 release-check.json、plan-E001.json、smoke-H-12.json scripts/ check-release.mjs(发版前自检)、plan-e001.mjs(留出评估计划与预算闸门)、 install-drill.mjs(打包产物自足性)、npm-drill.mjs(真实 npm 安装/卸载)、 migrate-report.mjs(真实配置只读迁移报告)、make-smoke-spec.mjs(冒烟 spec)、 read-session.mjs(读会话日志:多帧 zstd 解码 + 递归取用量) cordis.patch.yml bundle 层——让 `dsh plugin add` 之后**真的会装配**(EV-0066) RELEASE-CHECKLIST.md ``` 发版前自检:`node po06/scripts/check-release.mjs`