# 0.6 发布检查表(RELEASE-CHECKLIST) > 用途:**没有全部通过,就不发版**。每条都必须附证据(命令输出 / 文件 / 哈希), > 不接受"应该没问题"。当前状态:**未发布**(绝大多数条目尚未满足)。 ## A. 工程硬门(可程序验证) | # | 条件 | 状态 | 证据 | |---|---|---|---| | A1 | 全部单测通过 | ✅ 满足 | **48 套 / 645 项**(`check-release.mjs` 全量复核;第 65 轮的时点) | | A2 | 变异检验全部被捕获、源文件字节还原 | ✅ 满足 | **231 个变异 / 42 个源文件**(装配闸门 6(含 BOM 假阴性 1) + 判定保质期 3、预算闸门 5+花费闸门 4+**编排 4**、留出集判据 3+3、迁移保留 2、共存 3、**成本依据 7**、**生产接线 9**、**宿主资源定位 5 + 静态守卫 1 + 文档检查器 10 + 线缆仪器 1 + 只读工具 3**) | | 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**。 | | 34 **只读工具开启时的两处真机缺陷**(看不到思考 + no-packet) | ✅ **已修**(**三处叠加**,含新增守卫套件) | **用户原话**:"只读工具开启的情况下,拦截UI不会显示思考.并且no-packet问题,之前似乎只修复了无只读工具模式…说明之前你忘了把开启的情况下也修复,可能你做的是两套独立的流程?"
**先读台账再动手**(`~/.dsh/po06-wire.jsonl`:469 行,其中 `readTools=true` 64 行):**2026-09-21 那三条**是 `via=tools / rounds=1..3`(工具路径当时能跑,但 `reasoningChars=0`);**2026-09-22 16:02 起**变成 `rounds=0 calls=0 toolLoopError=stream-threw:signal is not defined`。
**三处真因**:① `lib/read-tools.js` 建流写 `...(signal ? { signal } : {})`,而 `signal` **从未在该作用域定义** ⇒ 建流即 `ReferenceError` ⇒ **工具循环一轮都没跑**(取消信号也送不进去);② `lib/index.js` 的 `plainDrain(makeStream, t0)` **没有 sink 参数**,而"工具产出不是那份 JSON"时**必然**走回落(开工具时的主路)⇒ 回落那次的流式片段到不了进度面 ⇒ **界面只有"已用 N 秒"**;③ `lib/pipeline.js` id 归一:台账 `BAD_SCHEMA | ops[7].item: item.id invalid: undefined; ops[8..10]: -tmuetqc4p / -tmuetqc4p_jb / -tmuetqc4p_e6` ⇒ 整轮被拒、包 0 字——机制是模型有几条 `add_item` 没 id,旧代码把 `''` 记进 `taken` 却不修,后面的空 id 走"撞号"分支被改成 `'' + '-t' + turnId尾`(以 `-` 开头、仍非法)。
**修法**:① `const signal = o.signal || null`;② `plainDrain(makeStream, t0, sink)` 并把 `onDelta` 传进回落;③ 缺 id/非法 id ⇒ **宿主补名**(前缀跟 kind,记 `why:'invalid-id'`),撞号才改名(记 `why:'collision'`)——id 只是宿主内部的名字,正文/原话/依据都不动。
**结构性修复**:新增 `test/read-tools.test.mjs` **8/8**(这条路径此前**零测试**:真跑工具循环 / 信号传下去 / 思维到 sink / **回落不吞思维** / JSON 走 tools / 无 root 不花钱 / 只读边界 / sink 抛错不拖累收集);`pipeline.test.mjs` 加"缺 id ⇒ 补名后照常成包"(并用 schema 的真 `ID_RE` 反查补出来的名字)。**变异 +3**(`readtools: signal-declaration-removed`(复现原 bug)、`index: fallback-sink-dropped`、`pipeline: invalid-item-id-not-repaired`)**全部被抓住**。
**门禁**:`check-release` **PASS**(**当时全绿**;当轮计数见 `po06/eval/release-check.json` 的历史快照,**不复述在这里**——本项目"历史行写死现状数字"正是发版门反复抓到的漂移来源)。
⚠ **尚未在真机上复验**(要用户实测"开着只读工具"的一次完整拦截);**本条也尚未发布**(在售 tgz 仍是 `fac2c0b`)。 | | 36 发布(**0.6.10** · 跟随宿主 0.1.7 的**第二处**契约变化:工具结果改一等 `role:'tool'` 消息) | ✅ **已发**(正式版;`releases/latest` 就是它) | **0.6.10**:提交 **`7fe99dc`**(远端 `refs/heads/dev/0.6` = `7fe99dc03aeeb02014a81a94e6fb8c2864f8503c`);tag `v0.6.10` → **`7fe99dc`**(`check-tag-target` PASS + **远端落点 API 复核 PASS**:该处 `po06/package.json` = 0.6.10)+ Release **395296106**(),附件 `dsh-external-dsh-po06-0.6.10.tgz` **274,883 B** + `SHA256SUMS-0.6.10.txt` **99 B**;sha256 **`e3111c9bfb56c361cb172e3019d47a5e48174be7a0d33117d7c1e6f803d652c0`**;`verify-artifact --tag v0.6.10` **PASS**(**40 个成员** / 33 lib 逐字节一致,版本四处一致);**无认证复核**(不带 token)查得到两个附件。
**为什么会有这一版(发布 0.6.9 之后按台账复核抓出来的)**:`signal is not defined` 的最后一条在 **2026-09-24T00:59Z**(部署 0.6.9 之前),部署后 4 行 `rounds = 1..2`、`calls = 2` ⇒ 第 64 轮那三处修复**确实生效**;但这 4 行**全部**带 `llm-error: DeepSeek Messages cannot represent user/tool-result content`(`code: UNSUPPORTED_CONTENT`)⇒ **开了「只读工具」的每一轮断在工具循环第 2 轮**。根因是 0.1.7 把工具结果做成**一等 `role:'tool'` 消息**(`createToolResultMessage({callId, content, isError})`:内容块**直接**是 content、id 由工厂生成),而循环仍在造 `role:'user'` + `tool-result` 块并手搓字符串 id;**这条路径此前零测试**。
**修法**:`lib/llm-lib.js` 新增 `toolResultShape(mod)`——有 `createToolResultMessage` ⇒ `tool-role`(走工厂)/ 只有 `createUserMessage` ⇒ `legacy-user-block` / **都没有 ⇒ 不猜**(不造消息、循环自然收敛、由调用方回落);`lib/read-tools.js` 的结果消息与"助手请求工具"消息都改走它。顺手修掉**一直存在**的接线缺陷:`loadLlmLib` 的 `env` 默认空表而生产调用点从没传 ⇒ `DSH_PO06_LLM_LIB` 这类显式覆盖**永远读不到**(两处调用点现在都显式传 `env/argv1/cwd`)。
**守卫(+2 用例;read-tools 8 → 10)**:工具结果必须是 `role:'tool'` 一等消息、带 `toolCallId` 与 `source.kind:'tool'`、**不得再出现 `tool-result` 这种块类型**;只认旧形状时退回、两者都没有时**不造消息**。夹具 `test/fixtures/llm-lib-017.mjs`(按 0.1.7 导出对齐的假宿主模块)。
**门禁**:`check-release` **PASS**(**发版当时全绿**:测试 0 失败、变异漏捕 0、打包自足性 PASS、文档四类门禁全 ✅)。
⚠ **未验(如实登记)**:**真机复验 ✅ 已取得**(部署 0.6.10 之后,用户继续使用时自然发生)——台账最后三条 `2026-09-24T03:06:47Z` / `03:07:28Z` / `03:09:07Z` 都是 `trigger=intercept` / `ok=true` / `outcome=committed` / `toolsEnabled=true` / `rounds=1` / **`toolLoopError=-`**:**开着只读工具的真实拦截跑通了、不再断在第 2 轮、每轮都出包**(此前 4 行全部带 `UNSUPPORTED_CONTENT`)。口径:这证明"**工具路径不再被宿主拒绝**",**不**等于"读到的内容改善了产出"(效果门仍未测)。其余未验:观感类结论需真人看;S4 未授权未跑;B 臂成本基线仍缺。
⚠ **效果侧无变化**(等级仍是「实验构建」)。 | | 35 发布(**0.6.9** · 适配宿主 `dsh 0.1.7-rc.1` 的会话格式 v4 + 只读工具修复 + 计数/守卫对齐) | ✅ **已发**(正式版;`releases/latest` 就是它) | **0.6.9**:提交 **`f511d4f`**(远端 `refs/heads/dev/0.6` = `f511d4f7d9ca6c98eab37e35a5fdcf831f05d620`);tag `v0.6.9` → **`f511d4f`**(`check-tag-target` PASS + **远端落点 API 复核 PASS**:该处 `po06/package.json` = 0.6.9)+ Release **395255214**(),附件 `dsh-external-dsh-po06-0.6.9.tgz` **272,612 B** + `SHA256SUMS-0.6.9.txt` **98 B**;sha256 **`50498410234147519390138499c247e64f6c2c5d398ad76a2616f1b3890e08ec`**;`verify-artifact --tag v0.6.9` **PASS**(**40 个成员** / 33 lib 逐字节一致,版本四处一致);**无认证复核**(不带 token)查得到两个附件。
**本版把两条"已修但没发出去"的东西交付**:① **ADR-0087**——投递来源改**生产者自报 kind**(`plugin:@dsh-external/dsh-po06`,去掉旧 `plugin` 字段),因为 0.1.7 的**会话格式 v4 准入明确拒收** `kind:'plugin'`(`dsh-session-format-v3-to-v4` 抛 `format v4 message requires a producer-owned source kind`)⇒ 不改就是"写会话日志那一步抛错、投递直接失败";台账仪器同步加 `producerOf()` **兼容两代形态**(只认一代 = 换宿主后旧台账全读不出来)。② **第 34 条**的只读工具三处修复(`signal` 未定义 / 回落吞思维 / 非法 item id 整轮被拒)。
**发版途中抓到并修掉的两处(都在"骗人"那一类)**:① `test/check-install.test.mjs` 的假包 `package.json` 只有 `name`/`version` ⇒ 宿主 0.1.7 **在装配前检查 `dsh.bundle`**、直接跳过整个 bundle ⇒ 装配树为空、三条"应放行"用例全红;夹具改为**从仓库那份派生**(只覆盖 `version`)+ 补包根两份手册。② 变异体 `checkinstall: missing-bundle-layer-not-flagged` **长期存活**:删掉拦截后,用例的退出码/后果/结论三条断言照样成立(宿主自己也拦);现在断言咬住脚本的判定出口(`--json` 的 `problems` 必须点名 bundle 层),不写死措辞 ⇒ 5 个 checkinstall 变异全部被抓住。
**门禁**:`check-release` **PASS**(**发版当时全绿**:测试 0 失败、变异漏捕 0、打包自足性 PASS、文档四类门禁全 ✅;**当轮计数不复述**,以 A1/A2 为准——此后又加了守卫)。
⚠ **仍未在真机上复验的两件事(如实登记,不假装)**:**0.1.7 上的真实投递**(只验到"按宿主源码与迁移表改对形状 + 有守卫")与**只读工具开启时的一次完整拦截**——两条都要一次真机实跑才作数。
**发完之后补测到的(EV-0157)**:0.6.9 在**运行中的 rc.1** 上装配成功(33 模块逐字节 + 热重载 `active`,`/po06/api/status` = 0.6.9 / `enabled:true` / `rollout:all` / `problems:[]`,**客户端字节未变 ⇒ 不必刷新页面**);投递构造点静态复核:`deliverNotice` 与 `deliverAndWake` **都**汇于 `buildMessage`(`PRODUCER_KIND` 唯一写入点)⇒ 一处改对 = 两条路径都改对。**但台账仪器读运行中会话:插件来源消息 15 份,无一条是我们自己的 notice**——`runtime-context` 那条"插件辅助上下文"是 `systemPrompt.context` **注入**的,两条投递路径本轮**都没被触发**⇒ **notice 形态的真机投递仍是未验项**。**发布了 ≠ 验过了。**
⚠ **效果侧无变化**:S4 未授权未跑;B 臂(冻结的 0.4.4 对照)成本基线仍缺;**仍没有任何"效果更好"的受控证据**(等级仍是「实验构建」)。
⚠ **环境事实(0.1.7 起)**:本机沙箱在该模式下**不允许派生任何子进程** ⇒ `check-release` 会一次性报"全套测试 + 变异门 + 打包演练"全部 `exit=null`,看着像"整个项目崩了",其实是权限。**判据:`exit=null` + `Access is denied` ⇒ 先查沙箱模式,别改代码。** | | 33 **宿主 0.1.7-rc.1 适配**(**异构宿主真机实测** + 投递来源 kind 跟随"会话格式 v4") | ✅ **已完成**(隔离环境实测 + 守卫;**没动在跑的 0.1.6 环境**) | **起因**:用户拿到 `dsh 0.1.7-rc.1` 的更新,要求"测试适配一下"。做法是**先取证、再实测**,不按版本号猜。
**官方口径**(来源:,2026-09-23 发布,prerelease/immutable):明写与本项目有关的七项——① 安装与启动**检查与 DSH 版本的兼容性**(不兼容给原因、可按确切版本给例外);② 设置改由**当前 Profile 的插件配置**保存(旧 `settings.yaml` 只导入一次);③ Agent 生命周期 / 会话历史 / Shell 沙箱接口**异步化**;④ 客户端模块加载与热重载语义重写;⑤ PTC / workflow 改名;⑥ `spill-policy` 的 `maxInlineBytes` → **`maxInlineTokens`**;⑦ 组合包支持多个 patch 与免重载配置字段。
**隔离实测**(临时前缀装 `dsh@0.1.7-rc.1`,509 包 / 14 分钟;隔离 home;HEAD 现打的 tgz):**装得上**(兼容性门禁没拦,33 个 lib、`lib/client.js` 在、`check-install` ✅);**起得来**(2.4–7.6 s,`GET /po06/api/status` 200;写 `po06.json` 后 `enabled:true / rollout:"all" / ours:true` ⇒ 设置读取与启用判定照常);**客户端 bundle 真取到**(启动 combo 资源表含 `@dsh-external/dsh-po06/client.js`,combo 200 / 5,665,496 B;单包 chunk 200 / **162,924 B** / `text/javascript`)。详见 `EVIDENCE.md` **EV-0155**。
**顺手抓到的 CLI 变化**:0.1.7 是 `dsh [--profile] [options] [app-args...]`(profile 是**位置参数**),旧写法 `dsh --profile <名字> web` 会报 `too many arguments`;README 里的 `dsh --profile <名字>` 与 `dsh web` **两种都仍成立 ⇒ 安装说明不用改**。
**唯一确证的破坏(已修)**:投递消息的 `source.kind`。0.1.7 的**会话格式 v4 准入校验明确拒收**旧名字——`dsh-session-format-v3-to-v4`:`if (… || value["kind"] === "plugin") throw new SessionFormatError("format v4 message requires a producer-owned source kind")` ⇒ 继续写 `kind:'plugin'` 会在**写会话日志那一步抛错**、投递直接失败;规范名有据(同模块 `producerKind()` 对第三方插件的兜底 = `plugin:<包名>`)。**修法(ADR-0087)**:`lib/index.js` 新增 `PRODUCER_KIND = 'plugin:@dsh-external/dsh-po06'` 用于 `buildMessage()`(去掉旧 `plugin` 字段),`lib/eval-llm.js` 同步;`form:'notice'` + `summary ≤ 120` 保留。**对两代都成立**:0.1.6 的 v3 对用户消息 kind 不设白名单;"绝不自我触发"那道闸本来就是正向白名单(只认 `kind === 'user'`);0.1.6 的 UI 也没对我们做过 `kind==='plugin'` 的特判。
**台账仪器同步**:`scripts/dump-wire.mjs` 读的是**历史日志**,两代形态会躺在同一份台账里 ⇒ 新增 `producerOf()` 归一(旧包装取 `plugin` 字段 / `plugin:<包名>` 归一成裸包名 / `kind:'user'` 不算贡献),单测 5 → **10/10**(含"混代台账")。
**守卫**:`wire.test.mjs` **34/34**(静态:`lib/` 代码里不得再出现 `kind: 'plugin'`、必须用 `PRODUCER_KIND`、`notice` 形态保留);变异 **+2**(`index: producer-kind-reverted-to-plugin`、`dumpwire: producer-kind-new-shape-ignored`)**都被抓住**。
**没做(不许当成通过)**:0.1.7 上**浏览器里的真实渲染与交互**未验;**前置拦截**只在 0.1.6 验过;0.1.7 上的**真机 + 真模型投递**未跑;0.1.7 异步化改造对其它调用点**未逐行核对**。 | | 32 门禁收尾(**无版本变化** · 文档检查器"外部引用豁免" + 计数对齐) | ✅ **已完成**(`check-release` 判定 **PASS**) | **为什么值得记**:此前唯一剩下的阻断项是"文档数字与产物不一致",而 `check-docs --strict` 里**计数 / 预算 / 门面 / 引文四类全 ✅**——红的是**指向检查**:12 处"指向不存在的文件",**全部**落在本文件的历史发布行,且**文档一个字都没写错**(是检查器太天真)。三类:Release 附件 `SHA256SUMS-<版本>.txt`、tgz **内部**路径 `package/HELP-0.6.md`、本机发布工具 `make-release.mjs`(住 `~/.dsh/po06-beta/`,有意不进仓)。
**修法**:把"明确住在别处"的引用做成**带理由的表** `EXTERNAL_REF_RULES`(产物 / Release 校验清单 / tgz 内路径 / 本机工具 / 运行时配置),**只认形态**——SHA256SUMS.txt 这种少一段的错名字照样报红;且**豁免必须看得见**:现在打印 `ℹ 外部引用豁免 23 处(当轮:运行时配置 9 · 产物 10 · 包内 2 · 本机工具 2;第 63 轮又加了宿主 `settings.yaml` 一类 ⇒ 现在 25 处)`,免得"通过"里混着"其实没查"(本项目吃过"假通过"的亏)。
**守卫(+2 测试 / +2 变异)**:`test/check-docs.test.mjs` **19/19**——① 三类外部引用不报红且豁免计数可见;② **反着钉**:形近的假仓内路径(package-note.md、SHA256SUMS.txt、make-release-notes.md、lib/nope.js)照样报红。变异 `external-ref-rule-too-broad`(豁免放宽 = 检查自己盖住真问题)与 `external-exemption-invisible`(豁免不可见)**都被抓住**。
**门禁实测(当轮值)**:`check-release` **PASS**——当轮 45 个套件、603 条用例全部通过;变异 216 条、被改源文件 38 个、漏捕 0;源文件字节还原;打包自足 PASS;文档四类门禁全 ✅ 且 `--strict` 退出 0。**这是 0.6 线第一次 `check-release` 全绿。**(此后又加了守卫 ⇒ **当前计数一律以 A1/A2 两行为准,本行不复述**——历史行里写死现状数字,就是发版门反复抓到的漂移来源)
**计数对齐**:根 README 中/英、`po06/README.md`、`CHANGELOG.md`、本文件 A1/A2 的 **601→603**、**214→216**(**历史条目按"当时的计数"保留**)。
**名词口径**:`EVAL-REGISTRY.md` 顶部补 ADR-0086 四臂释义,并明写"**B 臂成本基线缺失 = 没测过 0.4.4 跑同一套题花了多少钱**,与'给优化 AI 设输出上限'无关"(ADR-0085)。
⚠ **本条不改产品字节**(只动文档 + 检查器 + 测试)⇒ **包内 `po06/README.md` 的计数已变成 603/216,仓库 HEAD 与在售 tgz(tag `fac2c0b` / sha256 `f01d815f…`)出现差异**;按本项目"装机件 = 产物"的规矩,应在下一次发布时一并重传(或单独重传一次)——**如实登记,不掩盖**。
**未跑的门(如实登记)**:S4(约束守住)未授权未跑;**B 臂(冻结的 0.4.4)成本基线仍缺**;真机 + 真模型端到端未跑;**仍没有任何"效果更好"的专业跑分证据**。 | | 31 发布(**0.6.8-stable** · 三条真机问题修复 + 配置数据丢失修复 + 首页 README 重构 + 诚实声明按作者口径改写) | ✅ **已发**(正式版;`releases/latest` 就是它)**· 首发后原地重传三次** | **0.6.8-stable**(用户指定命名;`-stable` 按**正式版**发布,不当预发布):tag `v0.6.8-stable` → **`fac2c0b`**(`check-tag-target` PASS + **远端落点 API 复核 PASS**:tag 剥开后指向 `fac2c0b`,该处 `po06/package.json` = 0.6.8-stable)+ Release **393870777**(),附件 `dsh-external-dsh-po06-0.6.8-stable.tgz` **270,510 B** + `SHA256SUMS-0.6.8-stable.txt` **105 B**;sha256 **`f01d815fd1c1569165477cb6f7bbe2c378518d0e181f9747a1e724f4aefcfde1`**;`verify-artifact` **PASS**(40 成员 / 33 lib 逐字节一致,版本四处一致,登记值一致)。
**重传三次(如实登记)**:① 首发 `f031bcc` / Release 393815142 / sha256 `ba78c648…`;② 因**配置被重置的数据丢失**(见 ⑤)重传为 `578e1fa` / 393826707(sha256 `192fe68d…`);③ 因**首页 README 重构**(0.5 整段搬进 `README-0.5.md`/`README-0.5.en.md`)重传为 `7a088df` / 393862945 —— 该次 **tgz 字节未变**(根 README 不在包内);④ 因**诚实声明按作者口径改写**(`po06/README.md` 在包内 ⇒ 字节真的变了)重传为 **`fac2c0b` / 393870777**(sha256 `f01d815f…`)。对外只有当前这一份。
**本版四件事(都是真机报障)**:① **no-packet**——空产出有界重试一次 + 宿主兜底一条"这一轮没提取到"的待确认条目 ⇒ **这一轮必有包**;条目超上限改为截断记账、销账指向不存在条目改为逐条丢弃、取消不再被记成解析失败、失败/中止的一轮**一律收尾**(撤下上一轮的包);② **浅色模式**——颜色改为**由主题驱动**(两个真因:主题 token 在宿主的 `body` 上而判定读的是 `documentElement` ⇒ 读空按深色;token 选择器只覆盖"自身" ⇒ 后代各自声明浅色、深面板里嵌浅块);③ **语言跟随 DSH**(`zh`/`en`,含 `?` 手册,即时切换);④ **启用判定修对**:`rollout` 缺失/写错不再把显式 `enabled:true` 静默关掉,`/status` 增加 `gate` 结论分布。
⑤ **配置被重置的数据丢失**:设置读路径没剥 **BOM**(Windows/PowerShell/记事本写出的 UTF-8 带 BOM)⇒ `JSON.parse` 抛 ⇒ 配置被当成"空的" ⇒ `writeSettings` 写回一份**只有设置项**的文件,`settingsVersion`/`enabled`/`rollout` 被静默抹掉 ⇒ 插件不再被认作自己的配置 ⇒ **明明开着却什么都不做**(这就是 `gate:rollout-off` 那条报障的真因)。现在:配置读取一律先剥 BOM;读不出来时先从最近一份可解析的**备份**捞回启用意图字段并如实上报 `gateRepaired`/`recoveredGateFrom`;无论如何都保证 `settingsVersion` 标记在。
**首页 README 重构**:根 README 中/英从 269/266 行收到 **126/147 行**,只讲 0.6(一句话 · 机制四步 + 三条不变量 · 30 秒安装 · 界面与控件表 · 0.6 的 FAQ · 隐私与边界 · 诚实声明 · 版本与证据);0.5 整段搬到 **`README-0.5.md` / `README-0.5.en.md`**(252/249 行),顶部**声明**"这是上一代文档、装的是另一个包、里面的实测数据只属于 0.5、不是 0.6 的证据";根 README 里**不再显示任何 0.5 实测数据/旧档位名/旧包名**(脚本核对 0 处残留),中英严格同构,语言切换入口在**文档最上面**。
**诚实声明按作者口径改写**:效果部分改为 **作者实测观察**(DeepSeek-V4.1-Flash + PTC + PowerShell:常见 one-shot 与长任务迭代里**实际效果明显强于同环境同提示词**;少量项目统计**疑似降低 token 消耗、节省开销**;**未做专业跑分**),并保留 **S1 受控对照"没测出差别"** 的事实、标明两者**不互相证明**。
**回归守卫(新增)**:WCAG 对比度(浅/深两套都算)· 主题信号三级判定(含"都读不到按浅色")· 主题选择器必须覆盖"自身/祖先/宿主属性"三条路径 · 空产出必有包 · 关档一个字节都不注入 · 客户端读过的服务必须在 `exports.inject` 里声明 · **带 BOM 的配置照常读且不丢字段**。
**装机演练(按 README 中英步骤真跑,隔离 home)**:Release **直链**下载 ⇒ sha256 与 `SHA256SUMS` **一致** ⇒ `--from-default-profile web --dump-config` 建干净 profile `po061` ⇒ `dsh plugin add`(`dependencies` 与 `dsh.profile.bundles` 都写入)⇒ `check-install --expect-version 0.6.8-stable` ⇒ **33/33 lib 与仓库逐字节相同 · 两份手册(中/英)都在 · 装配树含该层 · 同 profile 无旧插件 · ✅ 可以开始试了**。
**对外文本对齐**:根 README 中/英的「最新版」行与 30 秒安装块、`po06/README.md` 的标题/一句话/下载直链、CHANGELOG 顶部条目、Release 说明与附件**全部指向 0.6.8-stable**;`v0.6.8-beta.2` 已标回 **prerelease**(测试版就该是预发布,`latest` 留给正式版)。
**全文测试**:当轮 45 个套件、603 条用例全绿。
**未跑的门(如实登记)**:观感类结论(浅色观感、英文界面)需真人看;**专业跑分 / 留出评估未完成**(只跑完 S1);变异检验本轮未跑完(为不污染发布提交而中断,已按 EV-0082 的纪律恢复源码)。 | | 30 发布(0.6.8-beta.2 · 英文适配 + 崩溃修复) | ✅ **已发** | **0.6.8-beta.2**(用户指定命名;**已按"最新版"发布**:不标 prerelease,仓库首屏 `releases/latest` 就是它):tag `v0.6.8-beta.2` → **`6a3f0c9b`**(`check-tag-target` PASS + 远端落点 API 复核 PASS)+ Release **393596111**(),附件 `dsh-external-dsh-po06-0.6.8-beta.2.tgz` **255,016 B** + `SHA256SUMS-0.6.8-beta.2.txt` **105 B**;sha256 **`e80de48982de1ebabdff27b5f4764c95f0ee6d63ffeb43f8a508b9e327286302`**;`verify-artifact` **PASS**(40 成员 / 33 lib 逐字节一致,版本四处一致)。
**本版内容**:① **英文 UI 适配**——语言只跟 DSH 的「语言」设置(`ctx.locale` → LocaleFace),客户端 49 条文案走 `L(zh,en)`,`?` 手册按语言取宿主 `/help?lang=zh\|en`(新增 `HELP-0.6.en.md` 并进 `files`);② **一处真机白屏崩溃修复**——读 `ctx.locale` 却没在 `exports.inject` 里声明,cordis 抛 `cannot get property "locale" without inject` ⇒ 客户端 entry `FAILED`、引导层停在 `Failed to load plugins`;修法=`exports.inject = ['slots','locale']` + 读服务一律走包住的 `readSvc()`(最坏回落中文,绝不整页崩);③ README 中/英对外文本对齐(0.5 版本号更正为最后发布 `v0.5.0-beta.1`、0.5 安装不再指向会 404 的 `releases/latest`、英文 README 结构与中文对齐并标明附录边界、两处 README 的 0.6 之前日志条目移除)。
**同版本号原地重发两次(如实登记)**:首发 tag `6f9b972` 发出后 30 分钟内发现语言探测写错(真机上恒中文)⇒ 重发为 `86ee837`;随后真机崩溃(用户报告"dsh 突然崩溃")⇒ 再重发为 **`6a3f0c9b`**(现在对外的那份)。前两份字节已不在任何 Release 里。
**本条新加的三条回归守卫**:静态「读过的每个 `ctx.<服务>` 都必须在 `exports.inject` 里声明」+ 运行时「用照 cordis 语义(未声明就抛)的 ctx 驱动 `apply()`:无 locale 服务时仍注册满 3 个插槽、语言回落中文」+ `check-install` 补查两份手册是否都装上。
**装机演练(隔离 home)**:演练当时本机 **github.com:443 不可达**(README 直链下载超时,6 次重试失败)⇒ 改用 **API 通道取回同一份发布字节**(`/releases/assets/{id}`,sha256 **与 Release 的 `SHA256SUMS` 逐字一致**)⇒ `--from-default-profile web --dump-config` 建干净 profile `po061` ⇒ `dsh plugin add`(`dependencies` 与 `dsh.profile.bundles` 都写入)⇒ `check-install --expect-version 0.6.8-beta.2` ⇒ **33/33 lib 与仓库逐字节相同 · 两份手册都在 · 装配树含该层 · 同 profile 无旧插件 · ✅ 可以开始试了**。
**本机 web profile 现状**:`/status` = **0.6.8-beta.2**、`problems: []`、`?` 英文手册接口实测 `lang=en / 4139 字`(中文 1879 字);部署副本含 inject 声明与 `readSvc` 守卫。
**全文测试(当时全绿)**:45 个套件全绿(当时的口径;现状计数见 A1 行与根 README)(含本次按现状改写的 `wire.test.mjs` 两条历史断言)。
**未跑的门(如实登记)**:观感类结论(英文界面观感、DSH 里切语言的即时切换)需真人看;真机 + 真模型端到端与效果对比未跑;`check-release` 剩 **1** 条阻断(变异检验未跑完,本轮为不污染发布提交而中断并按 EV-0082 的纪律恢复源码);**本版没有任何"效果更好"的证据**。 | | 29 发布(0.6.3 ~ 0.6.8-beta.1) | ✅ **已发** | **0.6.8-beta.1**(prerelease,用户指定命名):tag `v0.6.8-beta.1` → **`839f027`**(`check-tag-target` PASS + **远端落点 API 复核 PASS**)+ Release **393544572**(),附件 `dsh-external-dsh-po06-0.6.8-beta.1.tgz` **250,168 B** + `SHA256SUMS-0.6.8-beta.1.txt` **105 B**;sha256 **`d185d213be6c8213762218689a477692af61f39034e80232cfed237af976fa01`**;`verify-artifact` **PASS**(39 成员 / 33 lib 逐字节一致,版本四处一致)。
**代码与 0.6.7 等价**(本版做的是版本命名 + 对外文本对齐)。
**装机演练(按 README 步骤真跑,隔离 home)**:Release 直链下载 ⇒ sha256 与 `SHA256SUMS` **一致** ⇒ 建干净 profile ⇒ `dsh plugin add`(`dependencies` 与 **`dsh.profile.bundles`** 都写入)⇒ `check-install --expect-version 0.6.8-beta.1` ⇒ **33/33 lib 与仓库逐字节相同 · 装配树含该层 · 同 profile 无旧插件 · ✅ 可以开始试了**。
**对外文本对齐**:仓库描述(About)从 0.5 口径改成 0.6 主线口径;默认分支上 README.md / README.en.md / po06/README.md 标题都是 **0.6.8-beta.1**,CHANGELOG 补了 `v0.6.8-beta.1` 与 `v0.6.3~0.6.7` 补记(这几版此前只登记在本文件里),无旧主线表述;`po06/README.md` 不再承诺 `releases/latest`(beta 属 prerelease,`latest` 会停在上一个正式版)。
**中间版本**:`v0.6.3`→`54e59ad`(拖拽回归)· `v0.6.4`→`f32a38c`(夹紧+引文判据)· `v0.6.5`→`7803fca`(优化选项按钮 / 撞 id 改名 / 跳过真的停)· `v0.6.6`→`b03e722`(弹层可见)· `v0.6.7`→`823603f`(铺满整格 / 下拉可读 / 副色),各自都有 Release 与附件。
**未跑的门(如实登记)**:观感类结论需真人看;真机 + 真模型端到端与效果对比未跑;`check-release` 仍因 `wire.test.mjs` 2 条过时断言而阻断;**本版没有任何"效果更好"的证据**。 | | 28 发布(0.6.2) | ✅ **已发** | tag `v0.6.2` → **`ac68da8`**(`check-tag-target` PASS + **远端落点 API 复核 PASS**)+ Release **393445260**(),附件 `dsh-external-dsh-po06-0.6.2.tgz` **242,777 B** + `SHA256SUMS-0.6.2.txt` 98 B;sha256 **`c0bcfa22691f99a6ea1c4c47a97999e5edef3464d65c34cffdd23846bcbe130f`**;`verify-artifact` **PASS**(39 成员 / 33 lib 逐字节一致)。
**本版内容(用户 2026-09-22)**:① 拦截弹窗正文区 `overflow:hidden → auto` ⇒ **0.5 式全局滑块**,按钮行/产出层不再被裁(自适应:面板 `maxHeight: min(78vh,660px)` + 窗口变化重新夹紧;思维层仍是固定窗口、内部滚动条隐藏 ⇒ 不回退成两根可见滑块);② 注入一小段样式表(卸载即摘)补**交互反馈与极简动效**——按钮 130ms 过渡 + 悬停/按下/键盘焦点/禁用态、浮层入场 140ms、运行中状态灯呼吸、思维层新内容淡入、`prefers-reduced-motion` 全关;③ 观感收敛(圆角 14px、阴影更收、配色继续用 `--dsw-*` 变量)。
装机:`/status` = **0.6.2**,33/33 lib 一致,热重载 `client ✓`;client rev `0a6e24fb92cd`(133,640 B)实测 **200**。
**未跑的门(如实登记)**:**无截图证据**(GUI 观感需真人看);`check-release` 仍因 `wire.test.mjs` 2 条过时断言而阻断;真机 + 真模型端到端未跑;**本版没有任何"效果更好"的证据**。 | | 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`**(用户明确要求跳过非必要测试)。 > 因此"当前的测试 / 变异全绿"**只对 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 个 `