# 0.6 发布检查表(RELEASE-CHECKLIST) > 用途:**没有全部通过,就不发版**。每条都必须附证据(命令输出 / 文件 / 哈希), > 不接受"应该没问题"。当前状态:**未发布**(绝大多数条目尚未满足)。 ## A. 工程硬门(可程序验证) | # | 条件 | 状态 | 证据 | |---|---|---|---| | A1 | 全部单测通过 | ✅ 满足 | **40 套 / 543 项**(`check-release.mjs` 全量复核) | | A2 | 变异检验全部被捕获、源文件字节还原 | ✅ 满足 | **214 个变异 / 38 个源文件**(装配闸门 6(含 BOM 假阴性 1) + 判定保质期 3、预算闸门 5+花费闸门 4+**编排 4**、留出集判据 3+3、迁移保留 2、共存 3、**成本依据 7**、**生产接线 8**、**宿主资源定位 5 + 静态守卫 1 + 文档检查器 2**) | | A3 | 真机验证器对已知样本判对 | ✅ 满足 | **12 项**(好/坏×2/可疑/缺失 + 采样不早退 + 不泄漏 + GL 计数不变量 + 外部依赖可观测 + 全套件零残留) | | A4 | 交付门真实链路通过(L0 不发送 / L1 不唤醒) | ✅ 满足 | EV-0044 | | A5 | 跨会话不泄漏 | ✅ 满足 | EV-0033(另一会话装配 0 字符) | | A6 | 重启后状态恢复 | ✅ **满足(真机)** | **EV-0081 修复后**:隔离 home、**两个独立进程**、真实模型。新进程 trace = `recordInput→advanceTurn→interpret→parse→clarify→setContext`——**没有 `init`**,revision **4 → 6** 续上;状态存在插件自己的 `po06-state/.json`。修复前此门**根本过不去**,因为会话读不出来(见 A16) | | A7 | 真实多轮 / fork 行为 | 🟡 **多轮✅(真机);fork 已实现+单测✅,真机未验** | **多轮(EV-0085)**:SDK JSON-RPC 通路在一个长驻进程里连发两轮——第 1 轮 `committed`(包 406 / rev 4 / items 4 / 首步 `init`),第 2 轮 `committed`(包 **548** / rev **7** / items **6** / 首步 **`recordInput` 无 `init`**)⇒ 状态跨轮延续并增长;会话日志 seq 映射显示**第 2 轮 step1 的装配快照带包**,内容是**第 1 轮**的包 ⇒ 第 2 轮模型确实看到了第 1 轮的要求。"零延迟"由此精确化为:**包永远落后一步**(同轮第 2 步起;跨轮下一轮可见;单步轮次等到下一轮)。**fork(EV-0091 / ADR-0039)**:宿主分叉给**新 sessionId**(`SessionHeader.parentSession`),而状态按 id 存 ⇒ 不处理会**静默丢失累积约束**;已实现继承(深拷贝 / 改写归属 / 留出处,仅在首次触达且自身无状态时)。**单测 20/20 含别名反例;3 个变异守住浅拷贝/归属/出处**。⚠ **真机分叉未验**;⚠ 含 fork 的 web 端到端亦未验 | | A8 | 配置迁移在真实文件上执行过 | ⛔ **未执行(且现在不应执行)** | **只读 dry-run 已做**(EV-0062,`scripts/migrate-report.mjs`):逐字节证明未写、未建备份;**8 项需你决定**。**ADR-0036 已实现**(EV-0064):迁移不再删除旧键,真实配置上 `lostTopLevel` 由 **6 → `[]`**。规则就绪,但**"要不要真写"仍需你明确同意**;旧插件仍在装时写配置属高危动作 | | A9 | 包 / UI / 模板 / schema / 装配入口版本一致 | ✅ 满足 | `npm pack` 实测:`dsh-external-dsh-po06-0.6.0-beta.6.tgz`(**149.1 KB / 35 个文件**,sha256 `1c183b6cd129d02289cc669af6ba63eee7869d89b4f96ac5acafbac3009d0471`);包内容 = `files` 清单(**30 个 lib**(含 P9 的 `settings.js`/`control-api.js`/`client.js`)+ `package.json` + `README.md` + bundle 层 + 封存题集);版本三处一致(`package.json` = README = git tag `v0.6.0-beta.6`,由 `check-release` 的版本检查兜住)。⚠ **仍为 `private:true`**(`npm publish` 会被拒)——这是**故意**的:只发 GitHub Release 附件,避免把未经效果验证的包误发上公共注册表 | | A10 | 灰度与装配接线 | ✅ 满足(判定带保质期) | `po06/lib/assembly-gate.js` 接在 `systemPrompt.context` 上;**EV-0054 真实宿主两侧对照 PASS**。判定带 **TTL**:首版是永久缓存,会让守卫只"对过一次"——旧插件运行时被注入时不再撤销(EV-0061/ADR-0035)。⚠ 由**真实配置文件**驱动的端到端仍缺(写 `~/.dsh/prompt-optimizer.json` 需你同意);⚠ **没有装配变化信号接到 `invalidate()`**,撤销最坏等一个 TTL | | A11 | 卸载后无残留 | ✅ 满足 | **两条链路都验过**:① `scripts/install-drill.mjs`(包内容/仓库外 import/源树字节,EV-0056);② `scripts/npm-drill.mjs`(**真实 npm 安装/卸载**,EV-0057)——装得上(**未装 cordis 也可** ⇒ peer 确实 optional)、版本一致、另起进程可 import(**且坏件确实 import 失败**)、卸载后 `node_modules` 与 `package.json` **零残留** | | A12 | 双重拦截守卫接入装配流程 | ✅ 满足 | 本机旧插件 tri-state=`true`(运行时证据"存在动态上下文 prompt-optimizer:capability(342 字符)")⇒ 判定 `DOUBLE_INTERCEPT` ⇒ 装配贡献 **0 字符**(EV-0054) | | A13 | **"验证跑的是哪一份代码"可复核** | ✅ 满足 | 每份报告带 `moduleUrl`。此前只有 adapter 报告有,导致无法判断"这次 apply 跑的是哪份代码"——**实测确实遇到注入新产物却 apply 了旧缓存实例**(EV-0056;现象已记录、**根因未查明**) | | A14 | **能通过标准通道被装配**(`dsh plugin add` + `bundles`) | ✅ 满足 | 原先**缺 `dsh.bundle`**:`dsh plugin add` 打印 "declares no dsh.bundle — installed as a plain dependency, **not a profile layer**" ⇒ **装上但永远不会生效**(EV-0066)。已补 `cordis.patch.yml` + `dsh.bundle.patch` 并入 `files`;重装后警告消失、`bundles` 自动收录、`--dump-config` 出现 `- id: dsh-po06` 且无 duplicate/not found。**已在第二个 profile(隔离 home 的 `headless`)复现**(EV-0078) | | A15 | **生产可达性**:每条用户可见能力都有**生产侧调用点**或**真实会话投递证据** | ✅ **满足(headless 真机全链)**;⚠ **web 端到端未验** | **EV-0078(缺口)→ EV-0079(接线)→ EV-0080(跑通)→ EV-0083(web 装配核验)**。headless 真机(隔离 home、真实模型):台账 `outcome:committed`、`packetChars:327`、trace 走满 `init→…→setContext`;会话日志宿主快照 **485→814 字符**、`source.sections` 含 `prompt-optimizer:intent`;包逐条引用用户原话并把拿不准的事标成**未决项**。**web profile 装配已核验**(`moduleUrl` = web 那份;`profile={name:'web',source:'argv'}`;`stateStore` 已接;`productionTrigger.ok:true`;verdict `ACTIVE`)。⚠ **但"web 里真的把包送进模型历史"仍无证据**:web 接口是 WebSocket/Typert(非 REST),P8b 探针需要 live agent 而刚启动的实例没有 | | A16 | **不得损坏会话日志**:0.6 跑过的会话必须仍能被宿主打开/续跑 | ✅ **满足(真机)** | **EV-0081(缺陷)→ 同轮修复。** 根因:状态被当作自定义会话事件追加,而该事件**没有 `ignorable` 标记** ⇒ 宿主"拒绝重建整个会话"。查证三条:① `Session.append` 的信封只收 `sourceEventSeqs`/`surfaceOp`,**插件无法置 `ignorable`**;② 事件类型表是**构建期静态**的,第三方无法注册;③ 投影缓存按宿主契约"**never authoritative, only a fold shortcut**",不是持久化机制 ⇒ **状态必须由插件自己拥有**。修法:新增 `po06/lib/store.js`(`/po06-state/`,原子替换,会话 id 消毒防穿越),`commitPatch` 加 `persist` 出口,`land()` 是唯一落盘出口。真机验证:**`--session-id` 无错**(修复前 `refusing to interpret the log`),且会话日志**零 append**。⚠ `po06-state` 尚无淘汰策略(`keep` 字段未实现) | | A18 | **发出去的包 == tag 里那份代码**(逐字节,可重跑) | ✅ 满足 | `scripts/verify-artifact.mjs --tag --tgz `(EV-0133):成员集合 == tag 内 `files` 声明、逐成员与 `git show :…` 字节相同、版本四处一致、checklist 登记的 sha256(完整/缩写)与实物一致。**beta.4 实测 PASS**(32 成员 / 27 lib / 比对 32 全同)。⚠ 未接进 `check-release`(门禁跑在打包**之前**,而它核对的是**已发出**的文件)⇒ 它是发版步骤里的**人工命令**,写在下面的打包步骤里 | > **隔离验证配方(EV-0066 + EV-0069:**启动已实测通过**)**: > ```powershell > $env:DSH_HOME = 'C:\Users\WestFox\.dsh-po06-iso' # 独立 home:profile/配置/会话全分开 > dsh plugin --profile web add # 装 0.6(dsh 会自动写进 bundles) > # 再在 \prompt-optimizer.json 写 {settingsVersion:1, enabled:true, rollout:{mode:'all'}} > dsh --profile web --port 0 --no-open # --port 0 = 让 OS 挑空闲端口,不抢 3080 > ``` > 实测:启动成功;HTTP **200**、29,427 字节、含 `__DSH_BOOT__`;0.6 从**隔离 home** 加载; > 闸门判 **`enabled: true`(0.6 首次进入 enabled)**;该 profile 里**只有 dsh-po06**(无 0.5.x)。 > 全程未碰日常 home/profile/配置。 > ⚠ 想用 P8b 探针看"默认态是否贡献意图包",**必须先在那个实例里有一个会话**—— > 新 home 的 `agents.list()` 是空的,探针会报 `no agent to probe`(EV-0069); > 读源码确认探针取的是 `agents.list()[0]`,所以**刚启动的实例永远探不到**(EV-0083)。 > ⚠⚠ **每次换 profile 或重建后,必须重新核对"装进去的是哪一份"**: > `dsh plugin add <同一个 tgz 路径>` 会因 pnpm 缓存复用而**装回旧代码** > (实测在 web profile 上重演:`profile/stateStore/trigger` 全是 `undefined`、verdict 还是旧串)。 > **每次构建用新路径**,装完先 `Select-String` 一下新代码里的标志串再跑(EV-0079/EV-0083)。 | A17 | 打包产物自足性**进发版门**(不再靠人记得跑) | ✅ 满足 | `check-release` 现在会跑 `install-drill.mjs`(约 1 秒):tgz 只含 `files` 声明的东西、`eval/` **只允许封存题集**、bundle 层与题集都在、仓库外可 import、源树字节未变。**此前这条演练红了好几轮却没人知道**——没有任何东西会跑它(EV-0110) | ## B. 效果门(**当前全部未满足**) | # | 条件 | 状态 | |---|---|---| | B1 | 留出集冻结且未参与调参 | ✅ 已封存(**v2**) | `HOLDOUT-v2.md` sha256 `509db317…`(**每次运行前自动校验**,不符即拒绝)。v2 = v1 的 18 题**逐字节未改** + 追加 H-19/H-20(ADR-0040,由测试逐题校验);v1 文件保留以备复核 | | B2 | E-001 对照运行完成 | 🟡 **S1 跑完 36/36;截至 S1,没有任何一条可信判据显示两臂有差别(EV-0095)** | 用户授权 S1(上界 105,048),**实测 103,368**(run1 42,884 因仪表缺陷白花;run2 49,623 完整;机制实验 10,861)。**可信判据**:36/36 全产出、0 失败;放大 **A0/C0**(不判别);答案长度相当(14,521 / 13,249 字符);**完全指定任务(H-07/08/09)的必要内容 A 7/9 · C 7/9(无差别)**;分析可复现(`node po06/scripts/analyze-e001.mjs`)。**⚠ 已撤回**:据"实现细节类问句 A4/C9"称"0.6 让模型多问不该问的事"——该指标不可靠(`classifyQuestion` 单词命中且 impl 优先,标记词含任务名词 `package`;删掉这一个词后 C 臂坏分降 25% 而 A 臂不变),逐条读出的 C 臂问句多为**风险与后果提示**(那是想要的行为)。**⚠ 无效/缺口**:H-11 无工具下不可满足(EV-0093);"约束守住"无直接仪器。**"该不该问"已由用户判读完成(EV-0105)**:61 条真问句(A 25 / C 36)中两臂**各 0 条**被判"不该问" ⇒ **该判据非区分,在 S1 上作废**(它曾是 0.6 的主要卖点);9 条重复**全部是臂内重复、跨臂 0 条**;未标记 7/9 条仍计入分母(未标记 ≠ 合格)。⚠ n=3/题、单模型、单次;S2/S3 未跑。**B 臂(0.4.4)仍无实测成本依据** | | B2b | 「约束守住」判据**有适用题且有仪器**(新增 S4) | ✅ 已就绪(**未跑**) | 留出集 v2 追加 H-19 / H-20(含"引依赖"禁令,ADR-0040)。仪器经**离线**验证:**六种真实违规形态全部判出**(安装命令任意包名 / pip / require / ESM import / Python import / 散文提库名),标准库·相对路径·明确拒绝**零误报**;2 个变异守住"漏检"与"误报"两条路径(EV-0108)。**S4 预算:2 题 / 上界 35,016 / 期望 11,672**(`node po06/scripts/plan-e001.mjs` 可复核)。⚠ **零花费,未在任何模型上跑过**——这只证明"测得动",**不证明"守得住"** | | B3 | 存在 B 臂(0.4.4)可复现基线 | ✅ 哈希已冻结 | tag `v0.4.4-beta.1` = `475f0d91…` | | B4 | 关键类别无明显退化 | ⛔ 无数据 | | B5 | 严重失败率不恶化 | ⛔ 无数据 | | B6 | 用户负担(提问/纠正)不增加 | ⛔ 无数据 | | B7 | 总成本在门槛内 | ⛔ 无数据 | > 已跑的那次 **A/C n=1** 对照(`exp/po06/bench/D-01/`)**不计入** B2: > n=1、系统提示词被简化、缺 B/D 臂、无用户评分。 ## C. 用户裁决项(只有用户能定) | # | 条件 | 状态 | |---|---|---| | C1 | 用户认可坦克成品质量(A 臂 vs C 臂) | ⛔ **待答** | | C2 | 用户同意真实迁移执行 | ⛔ **待答** | | C3 | 用户约定真实提问联调时机 | ⛔ **待答** | | C4 | 用户同意重启宿主做 hydrate 验证 | ⛔ **待答** | ## D. 发布动作(按顺序,未开始) 1. 版本对齐:`package.json` / 插件内署名 / README / Release tag **同一版本**。 2. 打包并记录产物 sha256;与源码 hash 一起登记。 3. 隔离环境装配 → 验证 host 侧 `apply()`、路由、原文直通。 4. 真实 GUI 刷新验证(**不得**另起服务器冒充当前 GUI)。 5. 灰度:先 `allowlist` 一个会话,跑通再扩大。 6. 回滚演练:装回旧包 → 验证旧会话可读、消息不重复。 7. 发布说明:写明已验证项、**未验证项**、已知限制、回滚方式。 8. **发布前必跑**:`node po06/scripts/check-tag-target.mjs --remote`。 判据是"**tag 名里的版本号 == 该 tag 所指提交里 `po06/package.json` 的 version**"—— 挡的是"产物在、名字对、指向却是另一条线"(EV-0150 的实测事故:API 自动建的 tag 落在了 `main`)。 顺序也固定:**先推 tag,再发 Release**(让 API 用已有 tag,而不是替你造一个)。 ### G 段进度(0.6.0-beta.11 → beta.14 · P10 操作面对齐 0.5:引擎两件能力 + 五控件栏) > 起因:用户实测反馈 **"我不适应 0.6 的操控/检测模式,能不能让 0.6 对上 0.5 的 UI"**(允许改文案与架构,但整体操作类似)。 > 计划与规格:`po06/P10-UI-ALIGN-PLAN.md`、`po06/P10-0.5-UI-SPEC.md`(含 0.5 的 10 条**不要照抄**的缺陷)。 | 步 | 状态 | 证据 | |---|---|---| | 1 设置契约 | ✅ | `tier`(推导) / `permission` / `historyMode` / `turns` / `readTools`;定点核对 23/23;EV-0148 | | 2 会话上下文 | ✅ 已装机 | `session-context.js`:每会话 12 回合、单段 4000 字、旁观者声明、5 级降级**写进注入文本** | | 3 只读工具 | ✅ 已装机 | `read-tools.js`:read/glob/grep + 根目录词法&realpath 双校验 + 轮次 3/硬顶 6 + 60s + 不静默回落 | | 4 **断线修复** | ✅ | 真机台账照出 `policyFor` 缺三个字段 ⇒ 上下文与工具**在真机上永不生效**(三个开关是死开关);已修并经 `readPolicy` 核对 252 字/3 回合;**EV-0149** | | 5 五控件栏 | ✅ **渲染已验** | 挂 `conversation.input.left`(order 20):档位 关闭/轻度/标准/重度、权限 审查/自动、上下文 0~10 + 回合/全文、读项目文件、模型选择(+ 行尾 detail 开关);旧的 dock 胶囊退役 | | 6 打包与装机 | ✅ | **beta.14** 装进 `web` profile:**33/33 个 lib 逐字节一致**;热重载 `client ✓`;真机 `/status` = `0.6.0-beta.14` | | 7 **真机 DOM(渲染)** | ✅ | 全新浏览器 profile + 真实页面实测:**16 个 `data-po06` 标记全在**(`bar/tier/tier-*/perm/perm-*/ctx-wrap/ctx/ctx-num/ctx-mode/readtools/model/detail`),**值与后端一致**(`tier=light`(轻度)、`perm=auto`、`ctx=6`、`mode=turns`、`rt=off`),**几何 690×52 @ y=418**(排除"被输入区裁掉/尺寸塌成 0") | | 8b **引擎在生产里生效**(真机) | ✅ | 用户正在用的 3080 进程实测 `/po06/api/turns`:`histChars=7066`、`histTurnsRead=4`、`toolsEnabled=false`、`via=plain` —— **上下文真的被注入了**(EV-0149 修好前该值恒为 0);读文件关着时确实不派工具。`/turns` 现有 12 个 P10 归因字段(`packetOverBudget/OverBy/Budget`、`historyChars/TurnsRead/Available`、`toolsEnabled/Reason/Rounds/Calls/Fallback`、`interpretVia`)。
**仍未验**:界面上 `turn-facts` 那一行的**渲染**(数据源已验;浏览器探针因单次吐 568KB 日志、会冲掉执行者上下文,本轮主动跳过) || 8 真机**交互**复验 | 🟡 **一半** | **真机接口往返已验证**:设 `heavy` ⇒ 三项变 `[auto,detailed,generous]`、设 `off` ⇒ `[off,standard,standard]`、设回 `light` ⇒ `[auto,standard,standard]`(与 `TIER_PRESETS` 逐项吻合);每次写盘 `backup=yes`;**不带写头的 POST 被 403 拒**(跨站写防线在真机有效);用户设置已还原为 `light`。
**仍未验**:「浏览器里点一下 → 真的发出那次 POST」这一段(客户端 78 条载荷断言跑在假 React + 假 fetch 上) | | 9 浮层按 0.5 形态重排 | ❌ 未做 | 条目/轮次/提示词编辑仍在旧浮层里;`shell.overlay` 仍是占位 | | 10 发布(beta.14) | ✅ | tag `v0.6.0-beta.14` + Release(tgz + `SHA256SUMS`);**先推 tag 再发 Release**,落点正确 | | 11 发布(beta.16,与装机版本对齐) | ✅ | tag `v0.6.0-beta.16` + Release:tgz 189,390 B、sha256 `1ff70cfb9a48e10a3ef81be865591ad32bdd4a2f26f207dc30e98edba555573c`;标记 `prerelease`(第 8 步那半格未验) | | 12 **tag 落点事故(已修)** | ✅ 修 | 发 beta.16 时我**忘了先建本地 tag** ⇒ GitHub API 自动建的 tag 落在**默认分支 `main`(0.5 那条线)**:强制更新输出为 `+ 634c16b...70f23ee (forced update)`,其中 `634c16b` = `refs/heads/main`。已本地建 annotated tag 并强制覆盖远端,**用 API 复核落点 = `14c6acc`**(beta.16 提交)。
**教训**:**永远先推 tag,再发 Release**——否则产物在、名字对、指向却是另一条线(本项目最忌的"看着对、其实是别的") | | 13 **要求①:控件栏两层化**(2026-09-21 用户临时要求) | ✅ **真机几何已验** | `bar`(外层, `flexDirection:column`) = **489×50 @ y=419**、`bar-row-1` = 475×22 @ y=419、`bar-row-2` = 489×24 @ y=445、**`stacked: true`**;19 个 `data-po06` 标记齐。判据是**量到的矩形**(一排直线时外层只会 ~22-24px 高),不是"源码里写了 column"。**EV-0151** | | 14 **要求②:`?` 帮助按钮**(2026-09-21 用户临时要求) | ✅ **真机已验** | 点击真机 `[data-po06="help-btn"]` ⇒ `help-pop` 打开、**2132 字 / 11 节**、`leak:false`(无〔依据〕/无实现者说明)、来源行自报 `…\dsh-po06\HELP-0.6.md(2632 字)`;同时 `GET /po06/api/help` = `source:file / chars:2632 / 11 节`。正文**只有一个真相来源**(包里的 md,客户端不内置副本)。
顺带修两处静默分叉:① md 里一条没包在〔依据〕里的实现者注记会被显示 ⇒ 移进实现者区;② 该 md **不在 `files` 白名单**⇒ 真装出来读不到 ⇒ 已加进 `files` + 守卫测试钉住(client-file 14/14、control-api 14/14)。**EV-0151** | | 15 要求③:每轮结果**复用弹窗**(可看"这一轮改了什么" + 可改) | 🔁 **方案已改** | 原设计(事后查看:`/turns` 透出 `packetText` + `POST /turn-edit` + 手改下一轮生效)由子代理实现时**中途失败、无交付报告**;我已**全部回退**(原因:方案随之改成"发送前审阅",且未完成代码不入库)。
**新方案**见第 17 行:弹窗=**发送前的审查面**(0.5 形态),编辑后的文本就是本轮注入的包 | | 16 发布(beta.17 / beta.18) | 🟡 **beta.18 已发;beta.17 有意不发** | **beta.18**:tag `v0.6.0-beta.18` → **`ba424e7`**(`check-tag-target` PASS;API 复核:annotated tag `068f539…` 剥开后指向 `ba424e70789b…`)+ Release(`prerelease`)附件 `dsh-external-dsh-po06-0.6.0-beta.18.tgz` **192,912 B**、`SHA256SUMS-0.6.0-beta.18.txt` 107 B,**无认证复核**(不带 token)能查到两个附件。
sha256 **`478b3309ed9aea2b40c102b85c9ea1297ca1e2260a8d0e1ab29ac3fef8b77751`**;`scripts/verify-artifact.mjs --tag v0.6.0-beta.18` ⇒ **PASS**(38 成员 / 33 lib、与 tag 逐字节 0 处不同)。
**beta.17 不发**(装机迭代,被 beta.18 取代;与 beta.11–15 同例,如实登记而不是假装发过)。
**注**:本机**没有 `gh` CLI**(EV-0147 已知),走的是 **git 凭据里的 token + REST API**(脚本 `~/.dsh/po06-beta/make-release-beta18.mjs`)。 | | 18 **P11 拦截链的真机缺陷(已修)** | ✅ 修 / ⚠ 待真机复验 | 用户真机反馈:"没办法真实拦截消息,过几秒还会消失"。台账三条**同一根因**:`intercept ok=false reason=threw:recordUserInput: messageId required`——拦截发生在消息进入宿主**之前**,而我给 pipeline 传了 `messageId: null`,于是每次都抛错 ⇒ 拿不到包 ⇒ 走 fail-open 按原文发出(面板闪一下、1.6 s 后消失)。
**修法**:拦截路径自造 `po06-intercept-`;并记下"这条原话已被前置解释过",放行后宿主照常追加该消息时**不再解释第二遍**(`skipped:'intercepted-already'`,否则同一句话跑两次模型且会覆盖刚定的包)。
**同时确认**:用户当时档位 = **关闭**(`assist-off` / `gate-disabled`),该档按设计**完全不拦**——这一条不是缺陷,已在 `HUMAN-TEST.md` 里写明前提。 | | 19 **拦截界面 = 直接移植 0.5 浮层**(用户原话:"你完全可以直接把0.5的相关UI拿过来用,完全没必要重新自己制作") | 🟡 实施中 | 子代理按 `C:\Users\WestFox\.dsh\po05-src\lib\client.js` 整块移植:可拖动头部 / 滚动区 / **常驻底栏** / 缩放柄 / 关闭收成 46px 悬浮球(0.5:1487-1687、1922-1970、1796-1835、3397-3650)+ 状态行 / 产出 / 审查 textarea / 原文折叠 / 内联错误行 / 底栏五变体;按钮接 0.6 已有处理函数;`data-po06` 锚点全保留;**不伪造** 0.5 的首字 ms / Σ tok / 成了-要返工(0.6 没有 run id)。 | | 20 要求② 的三条界面修正(用户 2026-09-21) | ✅ 实施 / ⚠ 待真机看 | ① `?` 正文重写:删掉"下一轮才生效 / 第 2 步生效"的过期说法(真机校验:`第 2 步`/`晚一拍`/`下一轮开始生效` 均 **false**),节 4 记「全文模式滑块只有 关/开」,节 8 改成"在哪里看",节 10 如实标注拦截链尚未真机验完;② 全文模式滑块退化为**关/开**两格(底层仍存 `turns`,切回回合模式不丢量程);③ 行尾按钮文字改「**详情**」+ 保留状态灯,详情面板**撤掉**「它在替我做什么」「最近几轮」,`ItemsList` 删除,"无出处"警告挪进审查面板(`intercept-unsourced`)。守卫:client-file **15/15**。 | | 27 **发布(beta.25 / beta.26 / 0.6.1)** | ✅ **已发** | **0.6.1**(正式号,非 prerelease):tag `v0.6.1` → **`dee652d`**(`check-tag-target` PASS;**远端落点 API 复核 PASS**:`v0.6.1` = `dee652d`,版本 0.6.1)+ Release **393232829**(),附件 `dsh-external-dsh-po06-0.6.1.tgz` **241,638 B** + `SHA256SUMS-0.6.1.txt` 98 B,**无认证复核**查得到两个附件;sha256 **`42f9df7c79f4a22ae97b693395eb8c3b200b64b9a4661bd564eda344b36e0cbd`**;`verify-artifact` **PASS**(39 成员 / 33 lib 逐字节一致,版本四处一致)。
**装机演练(按 README 步骤真跑一遍,隔离 home)**:从 Release 直链下载 ⇒ sha256 与 `SHA256SUMS` **一致** ⇒ `dsh --profile po061 --from-default-profile web --dump-config` ⇒ `dsh plugin --profile po061 add `(profile `dependencies` 写入 + **`dsh.profile.bundles` 含本包**)⇒ `check-install.mjs --expect-version 0.6.1` ⇒ **33/33 lib 与仓库逐字节相同 / 装配树含该层 / 同 profile 无旧插件 / ✅ 可以开始试了**。
**中间两版(都已发,仅装机迭代)**:`v0.6.0-beta.25` → `3925c29`(Release 393136558,tgz 244,100 B,sha256 `dd5dd3e5…`);`v0.6.0-beta.26` → `cb0d688`(Release 393146375,tgz 244,545 B,sha256 `0e22d368…`)。
⚠ **beta.26 抓到一次 tag 落点事故(EV-0152 同款)**:git 通道 Connection reset ⇒ 本地 tag 没推上去 ⇒ `POST /releases` **自动建 tag 并落在默认分支 `main`(0.5 线)**(远端 `v0.6.0-beta.26` 一度指向 `634c16b`,那里没有 `po06/package.json`)。处置:`git push --force origin refs/tags/…` 覆盖为 `cb0d688`,API 复核 **PASS**;并把"**发 Release 之前先验远端 tag 落点、不对就中止**"写进发布脚本(`make-release.mjs`),下次自动挡。
**本版内容**:去掉「条目与结案」面板与其宿主通路(目标每轮自动产生,不再需要人工勾选)· 每轮独立产目标**不遗传**(`advance_turn` 把上一轮条目整体退成 `stale`)· 思维层可滚动但隐藏滚动条 · token 真实用量三分量 · 只读工具三条真因修复 · README 加照抄即可的下载+安装步骤 · `?` 帮助写明"不遗传"及其代价。
**未跑的门(如实登记)**:全量 **45 套 · 44 通过**,唯一未过是 `wire.test.mjs` 里 2 条**早已过时**的断言(EV-0143 断言 system 完全等于覆盖文件但 0.6 会在其后追加会话上下文;EV-0131 静态自检判空写法对不上);`check-release` 因此仍有阻断;真机 + 真模型端到端与效果对比**未跑**;**本版没有任何"效果更好"的证据**。 | | 26 发布(beta.24) | ✅ **已发** | tag `v0.6.0-beta.24` → **`1f6e98e`**(`check-tag-target` PASS)+ Release `prerelease`(id **393105451**,),附件 `dsh-external-dsh-po06-0.6.0-beta.24.tgz` **239,566 B**、`SHA256SUMS-0.6.0-beta.24.txt` 106 B,**无认证复核**查得到两个附件。
sha256 **`d2588cde76d1f28bb550cb5e80bc0c97711f11ca24453862efe40801771433b8`**;`verify-artifact` ⇒ **PASS**(39 成员 / 33 lib,与 tag 逐字节一致,版本四处一致)。
**本版内容(两条用户真机反馈)**:① **思维层恢复可滚动**——上一版把 `overflow` 改成 `hidden` 时把**滚动能力一起拿掉了**(用户:"现在思维层的内容无法滚动了");现在固定高度不变、可滚动、滚动条外观隐藏(`scrollbar-width:none` + 注入 `::-webkit-scrollbar{width:0}`,卸载即摘),`ThinkBody` 改**粘底**(用户一往上滚就停手,不再拽回底部)。② **轮次之间不再互相污染**——真因是解释层**只能加不能销** ⇒ 状态只增不减 ⇒ 旧问题每轮被重新编译进包;现在放行 `set_item_status` 但**只许退不许复活**且**必须有逐字依据**(无依据只丢这一条并记 `dropped`),另加"只针对本轮的要求带 `scope:'turn'`(下一轮自动退役)"的提示词规则。
守卫:`provenance-ref` 7→**11**(销账落地/缺依据记账/不许复活/turn 透传);`interpreter` 的旧契约"不得使用 set_item_status"按新契约改成**更强**的两条(其它 op 仍必须拒)。本轮全绿:interpreter 19 · pipeline 19 · reducer 18 · compiler 16 · client-file 15 · control-api 16 · intercept-timing 8 · tool-note 3 · provenance 4 · provenance-ref 11。
**装机**:`/status` = 0.6.0-beta.24,33/33 lib 一致,热重载 `client ✓`;**client bundle 变了 ⇒ rev `2d73589eb21b` → `c5ff5d0d89cd`(130,580 B)⇒ 已打开的页面必须重载一次**。
**未跑的门(如实登记)**:全量门禁里 `check-release` 仍 **FAIL(4 项阻断)**——wire 两条**过时断言**(EV-0143 断言 system 完全等于覆盖文件,但 0.6 会在其后追加会话上下文,那正是用户要求的同轮注入;EV-0131 静态自检判空模式)+ `verifier-html.test` 与变异检验输出无法解析 + 文档数字与产物不一致;真机 + 真模型端到端未跑;两条修复**仍待用户复验**。生成记录(`eval/release-check.json` 的 FAIL 判定)已如实入库,不掩盖。 | | 25 发布(beta.23) | ✅ **已发** | tag `v0.6.0-beta.23` → **`e564e5f`**(`check-tag-target` PASS)+ Release `prerelease`(id **393082811**,),附件 `dsh-external-dsh-po06-0.6.0-beta.23.tgz` **237,588 B**、`SHA256SUMS-0.6.0-beta.23.txt` 106 B,**无认证复核**查得到两个附件。
sha256 **`66cd2b4caceeff4b50e128b4769f7ad80fe7b2eb2596f64ee0ff5c9ac8bd253d`**;`verify-artifact --tag v0.6.0-beta.23 --tgz …` ⇒ **PASS**(39 成员 / 33 lib,逐字节 0 处不同,版本四处一致)。
**为什么要这一版而不是止于 beta.22**:beta.22 的产物**不含**随后的宿主侧修复,留着就会"装机件 ≠ 产物"——本项目最忌的"看着对、其实是别的"。
**本版内容**:① **来源引用归一**——开只读工具时模型写 `kind:'tool'/'file'`,而 `toolCallId`/`uri` 只有宿主才有 ⇒ 原先整份补丁 `BAD_SCHEMA`、合法条目陪葬(`no-packet` 的机制);现在只补宿主能机械核对的事实(引文在本轮原话 ⇒ 补 `human.messageId`;引文在本轮读入材料 ⇒ 改记 `kind:'model'`),补不了的逐条丢弃并记 `dropped`。② `provenance:'machine'` **从未生效**的顺序缺陷(`quoteSource` 由 `validateProvenance` 后写,构造条目时读它永远 undefined)⇒ 从读入材料推出来的条目曾看起来像"你说过的";现在补标 + 反向回锚。③ 台账 `trace` 不再吞 `reason`、`interpretHead` 200→4000 字。④ 含 beta.22 的界面工作。
守卫:**新增 `test/provenance-ref.test.mjs` 7/7**,连同 interpreter 18 · pipeline 19 · reducer 18 · provenance 4 · compiler 16 · tool-note 3 · control-api 16 · intercept-timing 8 全绿(其中 interpreter「空 ops 视为无操作」曾被本次改动打破,已按原契约修回)。
装机:`/status` = **0.6.0-beta.23**,33/33 lib 逐字节一致,热重载 `client ✓`(**client bundle 字节未变 ⇒ rev 仍 `2d73589eb21b`**,不影响已打开页面)。
**未跑的门(如实登记)**:全量测试、变异检验、`check-release`、真机 + 真模型端到端;人工验收 `po06/HUMAN-TEST.md` 与「只读工具开启下的真机整链」**仍待用户复验**。 | | 24 发布(beta.22) | ✅ **已发** | tag `v0.6.0-beta.22` → **`e793562`**(`check-tag-target` PASS:tag 名里的版本 == 该提交 `po06/package.json` 的 `0.6.0-beta.22`)+ Release `prerelease`(id **393077393**,),附件 `dsh-external-dsh-po06-0.6.0-beta.22.tgz` **234,770 B**、`SHA256SUMS-0.6.0-beta.22.txt` 106 B,**无认证复核**(不带 token)查得到两个附件。
sha256 **`319276c455955adb6cf1fca1fcf79a37461e7e88a1dee15c51567f0a202d138c`**;`verify-artifact --tag v0.6.0-beta.22 --tgz …` ⇒ **PASS**(39 成员 / 33 lib,逐字节 0 处不同,版本四处一致)。
**本版内容**:界面与 0.5 对齐(档位 `关闭/轻度/标准/重度`、两行控件栏、`?` 用户手册、浮层分思维层/产出层)· 思维层**固定范围 + 无滚动条 + 正文不截断**(`ThinkBody` 自动跟到底)· token 用 provider **真实上报**的 `入/出/缓存` 三分量(过千记 k/M,缺则 `—`,不估算)· **只读工具必报 `no-packet` 的真因**:解释层标识符笔误 `TOOL_SYSTEM_NOTE is not defined`(正确名 `TOOL_NOTE`)⇒ 29 ms 内抛错、既看不到思维也无产出,已修 + 守卫 `test/tool-note.test.mjs`。
守卫:client-file 15 · control-api 16 · intercept-timing 8 全绿;装机 33/33 lib 逐字节一致、热重载 `client ✓`。
**未跑的门(如实登记)**:全量测试、变异检验、`check-release`、真机 + 真模型端到端;人工验收 `po06/HUMAN-TEST.md` **仍待执行**。 | | 23 **beta.21:`no-packet` 的真因(已修,待复测)** | 🟡 | 用户复测报 `no-packet` + 看不到思维。台账 10 条同一形态:`intercept ok=true outcome=noop pkt=0 **ms≈1.0s** hist=0`。
**`ms≈1s` 是破案点**(真解释 20–57 s;同日成功那条 `ms=14490 pkt=9612`)⇒ 去读宿主模型清单:**第一条 = `deepseek-official / deepseek-flash`**,而我的兜底正是"清单第一条" ⇒ **flash 解释 ⇒ 1 秒回"没有改动" ⇒ 包 0 字**。
**修法**:兜底顺序 = 已观测 → 会话模型选择 → **宿主默认模型服务** → 才轮到清单第一条(记 `host-default-first` + `picked`),并在面板上明说"本轮用的是兜底模型";台账补 `textChars/reasoningChars/interpretError/interpretHead`。
**同版另三件**(用户上一轮要求):思维层/产出层分开(照 0.5)· 产出层「回退上一版」= 真包级回退(10 版)+ `GET /api/packet` 读回 · 审查档失败绝不自动发送。
守卫:intercept-timing **8/8**(含"宿主默认优先于清单第一条"回锚)、client-file 15、control-api 16。
**未复测**:修复晚于用户那次复测(台账最后一条仍是修复前的 13:44:47)。**EV-0153** | | 22 **beta.20**(装机过,未发) | 🟡 | 用户真机反馈四件(拦截后不跑优化 / 看不到思考 / 没有产出 / 审查档仍自动发出)**逐条归因并修复**:
· 台账三条真因:`threw:recordUserInput: messageId required`(已修,beta.19)、`gate-disabled`(启用判定是异步懒判定、pipeline 同步读 ⇒ 第一次拦截必白跑 ⇒ 现在 `awaitGateDecision` 等到落地,上限 25 s)、`no-model-route`(解释层模型靠 `request/header` 观测、前置拦截时还没观测到 ⇒ 现在 `ensureModelRoute`,**台账记来源**);
· 「审查档几秒后自动发出」= fail-open 无条件放行(包括审查档)⇒ 现在 `settleFailure` 分两路:自动=fail-open 按原文发出并留原因;**审查=绝不自动发送**,停在 error 态等用户点「按原文发出 / 重试」;
· 「看不到思考」⇒ 解释层 `drain` 加 sink → 宿主进度面 + `GET /api/interpret-progress`;
· 顺带:**包级回退真能做**(每会话存最近 10 版非空包 + `/rollback kind=packet`),条目级仍如实 501。
**新守卫** `test/intercept-timing.test.mjs`(7/7,后扩到 8/8;并修掉一处**夹具假绿**:粘性全局兜底没清)。
今日本地全绿:client-file 15 · control-api 16 · policy 7 · settings 9 · pipeline 19 · compiler 16 · reducer 18 · projection 9 · intercept-timing 8。
**未发 Release**(被 beta.21 取代)。 | | 21 发布(beta.19) | ✅ **已发** | tag `v0.6.0-beta.19` → **`1136a1e`**(`check-tag-target` PASS;远端复核:annotated `a93155b…` 剥开后 = `1136a1e…`)+ Release `prerelease`(id 392981268),附件 `dsh-external-dsh-po06-0.6.0-beta.19.tgz` **217,924 B**、`SHA256SUMS-0.6.0-beta.19.txt` 107 B,**无认证复核**查得到两个附件。
sha256 **`9739a5d2146581025a11d7b7cf50bf728630d3675f90520f23fc91e6789a3354`**;`verify-artifact --tag` ⇒ **PASS**(39 成员 / 33 lib,逐字节 0 处不同);**tgz 内含 `package/HELP-0.6.md`**(beta.18 缺它)。
装机:`/status` = **0.6.0-beta.19**,33/33 lib 与仓库逐字节一致,热重载 `client ✓`。
**beta.18 的 Release 说明已加缺陷警示**(提示改用 beta.19)。
**人工验收**:`po06/HUMAN-TEST.md`(一遍跑完);截至发版**尚未有人跑过**。 | | 17 **要求③ + "同轮生效" = P11 前置拦截** | 🟡 步骤 1 + 客户端拦截已实现 | 用户 2026-09-21 拍板:走 **0.5 的拦截法**(**每条都拦**、**不设超时**、保留手动"跳过";「关闭」档不拦);**不预取草稿**(用户否);不做中途注入的"即时块"。
0.5 机制逐条行号见 `po06/P11-INTERCEPT-PLAN.md`(捕获阶段 Enter/click、发送按钮 aria-label 白名单、`preventDefault+stopPropagation`、`inputActions` 放行、去重、关闭档停用、审查/自动、fail-open 按原文发出、单例闸门)。
**宿主侧唯一新轮子**:`runInterceptInput` + `POST /po06/api/interpret`(复用 `runProductionInput`,台账 `trigger:'intercept'`,只写内存态动态上下文)+ `POST /po06/api/packet`(审查态改过的正文 = 本轮注入的包)。**真机验接线(3080)**:空 session ⇒ 400、假 session ⇒ 400、缺写头 ⇒ 403(都不碰真实会话)。
**客户端**:拦截判据/放行/去重/诊断标记 + `data-po06-actions`(能不能拦是真机可读的)。
**未验**:整链真机(拦下→解释→放行→本轮第一步带包)——按用户要求改由**用户一次性人工验收**(`HUMAN-TEST.md`)。
**代价**:每轮 +21–57 s(真机台账),换来整轮上下文一致。 | > ⚠ **本段未跑的门(必须随发布如实登记)**:全量测试、变异检验、`check-release`、 > **真机 + 真模型的端到端**("模型是否真去调工具、上下文是否真改善产出"完全没验)。 > 客户端跑过的是:`node --check` + `client-file.test.mjs` 13/13 + 一个临时脚本(迷你 React 真渲染 + 假 fetch,78 条断言,脚本已删)。 > 过程中它抓出一个真问题:**只靠 DOM `disabled` 挡不住程序化事件**,仍会真的写盘 ⇒ 已加处理函数级守卫。 > **两处「0.5 有、0.6 有意不同」**:`readTools` 默认**关**(0.5 默认开,工具轮次要花时间与 token); > 工具轮次 **3 / 60s**(0.5 是 5 / 90s,解释层是旁路,不该拖住一轮对话的观感)。 ### F 段进度(0.6.0-beta.10 · UI 热修:模型选择 / 提示词编辑与撤销 / 注册自愈) > 起因是用户实测反馈。**先纠正一个我自己的误判**:上一轮我对外说"重装 + 重启就会好", > 实际根因是宿主把"这个包没有客户端"**缓存成了永久结论**(EV-0144)—— > 这属于"说了没有证据支持的话",记在这里。 | 步 | 状态 | 证据 | |---|---|---| | 1 版本对齐 | ✅ | `package.json` = 根 README = `README.en.md` = `po06/README.md` = **0.6.0-beta.10** | | 2 打包 + sha256 | ✅ | `dsh-external-dsh-po06-0.6.0-beta.10.tgz`(**153.5 KB / 36 个文件**,sha256 `dc3ab3ce33a8c3d18f9dcbab5e060f9170709f3d65470addae15410688c49e3e`) | | 3 装配 | ✅ | 用发行版自带安装器 `dsh plugin --profile web add ` 装入用户日常 profile;**装出来的 `lib/` 与仓库逐文件一致 31/31** | | 4 真机可用性 | ✅ | 热重载后实测:`/po06/api/status` = **200 / beta.10**、`/po06/api/models` = **35 个模型、0 错误**、`prompt.text` = **1708 字**、客户端 bundle **200**、`client ✓`;真实 Edge DOM:`dock → panel → controls / items / turns / prompt`(EV-0146) | | 5 灰度 | 🟡 直接 `all` | 同前几段 | | 6 回滚 | ✅ 可回 | profile 备份 + 依赖可指回上一版 tgz | | 7 发布说明 | ✅ | 本节 + `po06/UI-HOTFIX.md` + EV-0146/0147;**tag `v0.6.0-beta.10` 已推、GitHub Release 已发布**(含 `tgz` + `SHA256SUMS` 两个附件,公开可下载已复验): | > ⚠ **本段与 D/E 段的关键差别**:**没有重跑 `check-release`**(用户明确要求跳过非必要测试)。 > 因此"543 项测试 / 214 个变异全绿"**只对 beta.9 那棵树成立**,不覆盖 beta.10 的四处改动 > (`model` 接线、`/models` 端点、提示词 `text` + `undo`、`apply` 里的注册自愈)。 > 本段第 2、4 步的数字,就是本轮实际跑过的全部验证。 ### E 段进度(0.6.0-beta.9 · P9.5 真机界面落地:注册自愈 + 设置真的生效) > 本轮起因是用户实测反馈:**"重启后完全没有 UI"**。查出真因不是界面代码坏,而是宿主 `client-modules` > 把"这个包没有客户端"缓存成了 `NULL` 且**永不复核**(EV-0144)——进程在坏清单那一次启动后, > 磁盘上再修好也不会注册界面。处置:重打 beta.9 → 逐文件镜像 → **热重载(免重启)** → 定点清缓存重解析。 | 步 | 状态 | 证据 | |---|---|---| | 1 版本对齐 | ✅ | `package.json` = 根 README = `po06/README.md` = 本次 **0.6.0-beta.9** | | 2 打包 + sha256 | ✅ | `npm pack` ⇒ `dsh-external-dsh-po06-0.6.0-beta.9.tgz`(**152.3 KB / 36 个文件**,sha256 `01f1bc3a5ee2efd429c10c6a072a5cfff68446576c1766bcbed05c256f7819bf`);**tgz 与仓库 `lib/` 逐文件一致 31/31** | | 3 隔离装配 | ✅ | profile `web` 的 `node_modules/.../lib` 镜像后 31/31 字节一致;依赖由 beta.8 指向 **beta.9** tgz | | 4 **真机 UI 可见性** | ✅ **已闭环** | 在用户正在用的 **PID 82276** 内热修后:`clientModules.table`/`graph()` 出现本包;真机 Edge DOM:`dock → panel → controls / items / turns / prompt`,**4 个 `