# CHANGELOG

面向用户的变更记录。每个版本的**发版说明**（含头等事、兼容矩阵与已知问题）在
`docs/release-notes-<version>.md`；本文件只记一行一条的变更，按版本倒序。

变更分类：**Added** / **Changed** / **Fixed** / **Removed** / **Docs** / **Internal**。

> 本文件随包发布（`package.json` → `files`），发版说明也在包里（`docs/release-notes-*.md`）；
> 指向 `docs/decisions/`、`docs/plans/`、`docs/checkpoints.md` 的链接是**仓库内**文档，只有 GitHub 上可读。

---

## 0.8.4 — 2026-10-24（稳定版）

发版说明：[`docs/release-notes-0.8.4.md`](docs/release-notes-0.8.4.md)。

**`0.8.4-rc.2` 观察期结束后的稳定转正。** 产品代码与 RC.2 相同；稳定版只把包版本改为
`0.8.4` 并更新发布材料。RC.2 已作为候选发布到 npm `next`，正式版发布后 `latest` 与 `next`
都指向 `0.8.4`。兼容范围未变；本线不包含 `main` 上的 W-4 Completion 或 W-5 Search Screen。
RC.2 的 tarball 哈希、测试和人工验收收据保留为历史，不作为 `0.8.4` 稳定 tarball 的哈希。

### Fixed

- **FI1 — 首次安装的 Agent Plane 自动补齐**：首次向导保存后、以及旧/不完整 profile 启动时，
  只补缺失的工具行；写入前保留备份，不覆盖已存在的行，重复执行保持幂等。若行已写入但当前进程
  尚未组合它们，会明确提示重启，而不是把“已保存”误报成“已生效”。
- **WIN-CI1.H3 — RTT 探针的 drain 不再吞掉按住的 Esc**：liveness/RTT 探针在输入过滤器仍扣着
  可能是光标应答开头的单字节时，不再 `reset()` 丢弃它，而是重新安排释放；若后续应答到达则合并为
  应答，若没有到达则按原本的 hold 规则交还为键入。切开的应答仍不会被当成 Esc。
- **APPR.BP1 — AI Reviewer 传递真实授权 Session**：Reviewer 的 `GenerateOptions` 增加授权 Agent 的
  `sessionId`；同一 Session 的复核共享身份，不同 Session / 子 Agent 不共享。Reviewer prompt、
  400-token budget、15 秒 deadline、reasoning effort、授权策略、缓存与 fail-closed 均未变。
- **DOC.R1 — `/doctor` 路由清单纳入已注册 Adapter**：`doctorRouting()` 合并
  `llm-pi-ai.providers` 与 `ctx.llm.listProviders()`，已注册的 `deepseek-official` 不再被误报为
  “不在已配置路由里”；第三方 Provider 缺失、非法模型和子代理不同族仍会告警。注册/配置只表示
  路由存在，不表示网络或 API 调用成功；官方模型目录的实时校验仍为 **OPEN**。

### Docs

- 修正稳定候选说明：不再把 0.8.4 写成 RC.1 的无变化转正，也不再复用 RC.1 的测试数、tarball
  文件数、哈希或升级冒烟收据。RC.2 必须生成并绑定自己的收据。


## 0.8.4-rc.2 — Input, First-install & Diagnostics Fix Candidate

发版说明：[`docs/release-notes-0.8.4-rc.2.md`](docs/release-notes-0.8.4-rc.2.md)。

**相对于已发布的 0.8.4-rc.1，本候选包含 FI1、WIN-CI1.H3、APPR.BP1、DOC.R1 四项维护修复。**
候选使用与 `release/0.8.4` 相同的产品源代码，仅在隔离分支更新版本号、锁文件和材料。
没有合入 W-4/W-5，也没有纳入 PR #8 的 InputReader 调整或 PR #9 的诊断插桩。

### Fixed

- **首次安装代理平面**：只补齐缺失的 `tool-ask-user` / `present` 组合行，先备份、提示重启，冷启动与重复运行幂等。
- **RTT/存活探测丢 Esc**：`TerminalInputPump.drain()` 不再通过 `filter.reset()` 静默丢弃已暂存的输入。
- **审批 Reviewer Session**：直接模型调用携带请求授权的 Agent Session ID，保留 400-token、15 秒、fail-closed 等现行限制。
- **官方 Provider 诊断误报**：`/doctor` 将已注册 Adapter 与 `llm-pi-ai.providers` 配置合并去重；网络可用性与官方模型目录校验不在本轮承诺内。

### Release Gate

- `0.8.4-rc.2` 只允许在独立发布授权后使用 npm `next`，不得改动 `latest`。
- 必须在候选精确 SHA 上通过四条 CI；真实 npm tarball、从 `0.8.4-rc.1` 和 `0.8.3` 的升级冒烟、Windows Terminal/conhost 人工 H-1～H-11 均须重新取证。
- 本 CHANGELOG 条目不是 tag、GitHub Release 或 npm 发布回执；最终 Gate 未通过前不得发布。

## 0.8.4-rc.1 — 2026-10-17（候选版，只上 `next`）

发版说明：[`docs/release-notes-0.8.4-rc.1.md`](docs/release-notes-0.8.4-rc.1.md)。
**输入归属 + 发布安全门的候选版。** 与 0.8.3 相比**有 runtime 行为变化**（下列 Fixed / Changed）；
发布准备这一轮只为兼容加了一处垫片（见 Changed 的第三条），没有别的 runtime 改动。`latest` 仍为 `0.8.3`。

### Fixed

- **粘贴的结束标记被切成两半，键盘从此"失灵"**：`ESC[201~` 的尾半截 `ESC[20` 与"半个光标应答"同形，
  输入过滤器会先扣住它、30ms 后当打字放行；后半截 `1~` 到达时已经没有开头，Reader 于是永远停在"粘贴中"——
  此后每个键都被当作粘贴内容：Esc 关不掉对话框，`/exit` 也退不出去。两处一起修：过滤器不再扣留粘贴流量，
  Reader 把切开的标记留到下一读补齐（200ms 仍不齐才当内容放行）。0.8.3 及更早同样存在（同样是跨 read 的
  粘贴状态），本版由新的粘贴探针在 CI 上撞出来。
- **合并 read 丢键**：一次 read 里的多个键（两次方向键、`PgUp` 连按、改绑键 + 文本、`text\r`）此前只会被
  整段匹配、失败即整段丢弃。现在 Reader 分帧、每个单元各判一次归属，一次 read 与多次 read 终态相同。
- **Screen 的 read 边界**：关闭 Screen 的那个字符之后的同一单元剩余部分不再落到它背后的 Composer。
- **Surface 编辑键归属**：`Home`/`End`/`Delete` 归 Surface，编辑**借来的字段**；无字段时消费掉。
- **借用字段的终端光标**：绘制取正在绘制的字段的列号，而不是隐藏草稿的。
- **非 BMP 字符输入崩溃**：输入 `🚀` / `𠮷` 曾抛 `RangeError`（按 UTF-16 长度判定"一段文本"导致自我递归）；
  改为按**码点**判定，多字符单元仍逐码点重新判定。同一根因的借用字段 grapheme 编辑一并修复。
- **跨 Owner 状态写入**：借用字段的退格/Delete/Ctrl+U/Ctrl+K/**粘贴**不再结束 Composer 的历史浏览、
  不再覆盖它的 `historyDraft`；Surface 内 `Alt+f`/`Alt+F`/`Alt+/` 不再把 `/find ` 写进隐藏草稿。
- **反馈行位置**：回执不再随消息长度/窗口宽度在底栏两行之间漂移，恒在身份行；状态行只留仪表。

### Changed

- **兼容窗口**：新增 `0.2.1-rc.2`，整族 devDeps 与族 root pins 随之前移（cordis 4.0.5、include 1.0.10、
  loader 1.0.6、group 1.0.5），默认线改为它。窗口因此变成
  `>=0.2.0-rc.1 <0.2.1 || >=0.2.1-rc.2 <0.2.2`（两个 comparator 是 node-semver 的 prerelease 规则，
  不是笔误）。
- **摘除 `0.1.7` 线**：`dshReleases` 的 `0.1.7-rc.1` / `0.1.7-rc.2` 改为 `incompatible`，对应的两条 CI 腿
  删除。原因是范围判断：0.2.1-rc.2 移动了族的 root pins，并把 subagent 的 `drainContinuableChildren`
  改名为 `drainChildren`（签名不变、旧名在新宿主上消失），同时面向两代 seam 要在类型面上各写一份分支；
  0.2.0 的两个 rc 仍在窗口内、仍各有一条腿。
- **跨线兼容垫片**：`/subagents kill` 改走 `src/dsh-compat.ts` 的 `drainChildSubagents()`，按宿主实际拥有
  的方法名调用；这是本版唯一为兼容而改的 runtime 代码。
- `dsh-invariants` 没有 0.2.1-rc.2 发布，作为该线的**唯一 per-line 例外**钉在 `0.2.0-rc.2`。

### Internal

- `src/input-reader.ts`（新）与 `src/input-router.ts`（新）：`handleInputText` = Reader → Router → owner；
  归属判定集中在 Router（`dispatchers 1` / `routers 1` / `deadScreenGate 0`）。
- 共享执行体 `composerUnit` 经必要性审核后**保留**（`KEEP_SHARED_WITH_INVARIANTS`，S-1…S-6，AD-20 §19）；
  **未做 executor split**。
- Ctrl+L 的重绘归属经审核后保留双 Painter（`KEEP_DUAL`，AD-22 §10），证据 `tests/ctrl-l-repaint.test.mjs`。

### Tests

- 输入参考轨迹 **72 → 109 条**（只追加、0 条改写）；归属矩阵扩到 options question / filtering picker；
  新增 `surface-state-isolation`、`unicode-input-safety`、`ctrl-l-repaint`、`borrowed-field-caret` 等专项。
- `scripts/input-freeze-audit.mjs` 新增 `composer history` 写入类与 `historyGuards` 检查（注释剥离后判定）。
- **`scripts/tui-paste-probe.mjs`（新，真 PTY，CI 默认腿 + Windows）**：单行粘贴进 Composer、多行粘贴
  只插入不提交、Ctrl+U 清空、4 kB 粘贴不崩、粘贴在 Screen / picker 后面不漏也不落进 Composer、
  粘贴里的 `\x1bq` 保持字面不关 Screen、**结束标记跨 read 切开后 Esc 仍然生效**；关掉 paste 分帧即判红。
- `tui-unmeasured-probe` 的竞态修复：应答链路上 link chip 本来就是**两帧**（引导帧 `○○○○ 未测` → 测量帧
  `●●●● 7ms`），探针此前取第一帧并断言测量值，于是在慢机器上误报。现在按本 leg 关心的状态等待并打印
  这一跳；反向验证（把 `probed` 强制 false）仍判红。

### Release Hardening

- **首次安装向导**成为 CI 阻塞门（默认腿 + `test-windows`）：真实 PTY/ConPTY、未配置 home、**括号粘贴
  API Key**（掩码、原始字节不含密钥）、保存后无需按键返回工作区、二次启动不再进向导、resumed 首启保存。
- **发布产物冒烟**（`scripts/artifact-smoke.mjs`）：`npm pack` → 包内清单 → 用 **tarball**（不是 `link:`）
  装进仓库外的临时 home → 解析路径证明 → 在安装产物上跑向导与工作区探针。
- **升级冒烟基础设施**（`scripts/upgrade-smoke.mjs`）：同版本互换会明确拒绝，真正的升级是 bump 后的必跑项。

---

## 0.8.3 — 2026-10-13（`latest` + `next`）

发版说明：[`docs/release-notes-0.8.3.md`](docs/release-notes-0.8.3.md)。
**紧急修复**：三个缺陷都是 0.8.2 把首启向导改成 Screen 时引入的，全部在"首次安装 / `/setup`"这条路上。

### Fixed

- **首启向导 / `/setup` 的粘贴**：终端粘贴（Ctrl+V / Cmd+V / 右键，即括号粘贴）此前落到 Screen
  *背后*的工作区草稿里——向导字段一个字都收不到，读者只能手敲 API Key。现在粘贴归字段所有：字段步骤
  直接落进字段（行尾换行折叠掉，多行按分隔拼接成一行），没有字段的步骤（模型多选、确认）不接收，
  两种情况下草稿都不再被改写。
- **走完向导没有退回工作区**：保存成功后 Screen 仍然占着屏，要随便按一个键才退得出去（那个键的兜底
  才是真正的退场）。现在**保存本身就是退场**，与 Esc 对称；保存失败则**保留向导与错误**（此前错误写在
  一个立刻被丢弃的状态上：Screen 留着、错误没了、填好的答案也没了）。完成语改为转写行，回到工作区
  仍可读到。
- **一次读取里的多个按键**：`text\r` 这样的读取会收下文字却丢掉回车，步骤停住不动。现在按 composer
  一直以来的规则拆开（转义序列完整、CRLF 一个回车、控制字节各自成键、可打印文本连成一段）。
- **Screen 打开时的 composer 编辑键**：`Enter` / `Backspace` / `Ctrl+H` / `Ctrl+U` / `Ctrl+K` /
  `Ctrl+A` / `Ctrl+E` / `Ctrl+R` / `Ctrl+T` 不再作用于 `/diag`、`/status`、diff 全览等 Screen 背后
  那个看不见的草稿（此前 `Enter` 会把草稿当消息发出去，`Ctrl+U` / `Ctrl+K` 会清空或截断它）。
- **Screen 里的 `Ctrl+L`**：任意 Screen（不只是向导）都能整屏重画，用于清理花屏的终端；此前只有向导认这个键。

---

## 0.8.2 — 2026-10-05（`latest` + `next`）

发版说明：[`docs/release-notes-0.8.2.md`](docs/release-notes-0.8.2.md)；候选版说明保留在
[`docs/release-notes-0.8.2-rc.1.md`](docs/release-notes-0.8.2-rc.1.md)。
本版由 **0.8.2-rc.1**（2026-10-04，只上 `next`）沉淀一周后转正，**内容与候选版相同**，
下列变更即候选版以来累积的全部变更。

> `dsh-ssh-tui` is now presented as DSH Relay. The npm package name and the install command
> have not changed. —— `dsh-ssh-tui` 现在以 DSH Relay 为产品名展示；包名与安装命令没有变化。

B2（"what deserves to exist"）的六个阶段 B2.1 – B2.6 已完成并通过最终审计，本节汇总用户能看到的
部分。详细证据与冻结记录见 [`docs/checkpoints.md`](docs/checkpoints.md) 与
[`docs/decisions/b2-architecture-decisions.md`](docs/decisions/b2-architecture-decisions.md) §20。

### Added

- **报告是 Screen**：`/status`、`/help`、`/doctor`、`/subagents`、`/diag` 等报告不再写进转写、
  不再改变历史窗口，翻页只重画正文区，Esc 回到原处。
- **计划 artifact 投影**：计划模式下的待办与评审从会话日志折叠出来；一份计划一行引用、一个 dock、
  一个评审 Surface，resume 后身份一致。
- **工具卡片的审批状态**：卡片自己拥有 `waiting / approved / rejected / unknown`（以及来源：
  live / policy / durable / inferred）；不再有独立的审批行。
- **首启向导是 Screen**：9 步向导不再是"借工作区 composer 的对话框"，中途 detach/reattach 不丢步骤，
  也不再清空读者已经打了一半的草稿。
- **`npm run freeze`**：一条命令跑完 B2 的八条冻结不变量与七条退役路径扫描（CI 在 Linux 与
  Windows 两条腿上各跑一次）。
- **`npm run bench`**：五个动作（流式 delta / 等待时钟 / 报告翻页 / 菜单移动 / 向导打字）的性能基线，
  并断言这五个动作都不整屏重画。

### Changed

- **反馈分流**：控制面的确认去页脚（echo，最低优先级，直到下一次输入），警告/失败去身份行（notice），
  只有会改变历史的事实才进转写（[`docs/checkpoints.md`](docs/checkpoints.md) B2.3b）。
- **`/copy` 语法**：`/copy` 或 `/copy reply` 复制模型最后一条回复（默认）；`/copy highlight` 复制焦点卡片；
  `/copy error` 复制最新的错误/诊断行。复制键保留"取不到焦点就退回回复"的语义。
- **工作区在方向键后的停留**：resume 进来不再从窗口中间开始滚动，直接停在最新内容。

### Fixed

- **工具卡内容有多行代码时会窜到输入区**。`bash` 的摘要就是命令行原文，所以 heredoc 会带着换行进入
  卡片标题行；而单行裁剪器（`truncateToWidth`）保留 LF/CR，于是一"行"里含多个换行 —— 终端会因此换行，
  而按绝对行号定位的帧随后把下面每一行都写错位，卡片内容落到输入框和页脚上，还会出现两段文字拼在同一行。
  实测：31 行的一帧里有 11 行含裸换行；修复后为 0。
- **Windows Terminal 下输入法的预输入字符不再在处理中卡片那一行的最右边闪烁**。终端把 IME 预输入画在
  光标处，而写一行会把光标留在该行文本末尾；跑一轮时实时区域每 tick 重画、且位于输入框上方，于是光标停在
  处理中卡片上、预输入就闪在那里。现在除光标自己所在行外，每写一行都把光标交还输入框。
- **命令提示不再一直占着位置**：确认（"已复制 412 字"）与警告（命令失败）显示 6 秒后自动让位、恢复原来的
  遥测行（提交仍会立即清掉）；**"将在下个步骤生效"的排队提示例外** —— 它显示到那条消息真正被提交为止，
  因为它是"你有话在排队"的唯一标记。
- **全新安装不再跳过配置向导**。前端拉起后台 Host 时永远带 `--resume=<id>`（连它刚生成的新 id 也带），
  而首启判定把 `resume` 当成"这台机器配置过"，于是**新机器永远不会自动出现向导**，也没有任何提示。
  判定现在只看凭据存不存在。
- **裸 400 现在会说明它是什么**：网关拒收的是请求本身（不是 key），并给出这一族的上游记录与绕法
  （`/effort off` 或换 messages 风味路线）；**不自动重试**（实测这类失败成串出现，重发由读者决定）。
- 流式输出不再每个 tick 整屏重画（B2.2：live 区是投影，不是转写行）。
- 高亮的工具卡片不再把内容画进相邻卡片；处理中卡片遇到长内容不再折断成一行。
- 计划卡不再吃掉输入法的预输入字符（dock 高度不得超过工作区一半，光标行永远在屏）。
- resume 的历史回放不再逐帧重画（20k 事件从 51 帧 / 1.2 s 降到一次重建）。
- 部分命令执行后没有任何提示（页脚放不下的确认现在退到身份行显示）。
- 待办未收尾的提醒不再伪装成一条"计划转写引用"（B2 最终审计：`plan-row` → `plan-notice`）。
- **resume 进入时不再有一段黑屏（1–3 秒）**：前端先在备用屏打出"正在载入历史会话…"，relay 接入时
  宿主又写了一次 `?1049h` —— 终端已在备用屏时这个序列会**清屏**，而回放期间按 B2.4 不合成任何帧，
  于是读者面对的是一块空白，直到日志重建完（实测 20k 事件：9.1 s 清屏、12.6 s 首帧，中间 3.5 s 全黑）。
  这条"进屏"序列现在搭在第一帧上发出，与它要清出来的内容同一个 tick；没有东西要等的 reattach 行为不变。
  （上一版试过相反的做法 —— 加载期间由宿主补画一行 —— 结果写进了 relay 的测速窗口，那版已回退。）
- **思考卡片的文字不再发白**：`reasoning` 角色是 `2;3`，只有属性 —— "暗"完全靠 faint，不实现 faint 的
  终端（报告的 256 色终端）就退回**默认前景色**，与旁边的回复一样亮。四个调色板现在各自给出 muted 颜色
  （default `90`，catppuccin / gruvbox 用各自 `md-muted` 的色，mono 仍然只用属性），属性保留给支持的终端。
- **状态行不再把"绘制节奏"当成"链路延迟"**：终端不回 `CSI 6n` 时（现场 `/diag`：Linux + xterm-256color
  + SSH，`探测 未知`），这一格显示的是**回退的绘制节奏** 160ms，读者无法分辨它和真实延迟。现在改为
  `SSH ○○○○ 未测` / `n/a`；测到过的链路照旧显示测量值，绘制节奏仍留在 `/diag` 那一行（写明是"绘制"）。
- **`q` / `Q` 真的能关掉报告**：`inspectClosesOn` 一直声明接受它们（"全屏报告理应响应 q"），
  但可打印字符的提示分支在它之前返回，于是这两个键只会打印"这是报告视图，按 Esc 返回"。

### Docs

- [`docs/release.md`](docs/release.md) 新增"发布前人工门槛"：Windows 实机清单、fresh-home 首启探针命令、
  以及 `npm run freeze` / `npm run bench` 两条发版自检。
- [`docs/decisions/b2-architecture-decisions.md`](docs/decisions/b2-architecture-decisions.md) §20 记录 B2 冻结：
  八条不变量、七条退役路径、以及"表示的分类必须与它包裹的行一致"这条规则。

### Internal

- **链路验收补齐"带历史的 resume"**：`scripts/tui-rtt-probe.mjs` 现在有两个阶段——新会话（先慢后快的
  链路）与**带历史的 resume**（探针自己写一份 20k 事件的持久化日志，回放期间不合成帧）。后者同时断言
  三件事：读者画面上出现过加载行之后**不得再变空**、转写落地、chip 落在真实测量值而不是 `○○○○ 160ms`
  占位。两条断言都做过变异校验（改回"接入即写"报 4 秒黑屏；关掉 RTT 应用报 chip 停在占位）。
- **`verify-batch.mjs` 不再把 SKIP 说成 PASS**：有步骤跳过时收尾为 `RESULT: INCOMPLETE`（exit 2），
  与 `FAIL`（exit 1）分开；`link` 已加入验收步骤表（`--only link` 可单跑）。
- 表示管线：每条转写行都带 durability / class / destination；审计对未分类行、未知 destination、
  live 源行与重复 primary 表示各自计数，四个数字都必须为 0。
- 退役并在 CI 上禁止复活：`dedicated` Surface 角色、onboarding 的对话框渲染路径、
  `upsertPlanRow`（计划行的第二个写入者）、`ask_user_question` 的通用工具卡。
- **Windows 实机轮（2026-10-03）修掉五处探针缺陷，产品代码未改**：`verify-batch` 在 Windows 上
  因 `spawn('npm')` 必然 `ENOENT`（改用 `$npm_execpath`）；`tui-route-probe` 的 `/tmp` 字面量
  （改 `os.tmpdir()`）与目录符号链接（Windows 改 junction）；`footer-windows-probe` 补了**未测量
  链路**档案并逐格断言时长槽（`未测` 而非 `160ms`）；`tui-mock-probe` 的鼠标坐标改由真实终端网格
  给出（此前从字节流解析 `ESC[<row>;1H`，ConPTY 下拼出伪行，拖选看起来偏了两格——**是探针缺陷，
  不是选择缺陷**）。
- **新增 `scripts/tui-unmeasured-probe.mjs`**（管道父进程，进 `verify-batch` 与 CI）：ConPTY 自己回
  `CSI 6n`，所以"终端不回 DSR"这一格在 Windows 本机摸不到，而这个形状正是读者报过两次的那个。两条腿
  分别断言 `SSH ○○○○ 未测`（绘制节奏只留在 `/diag`）与 `SSH ●●●● <n>ms`。
- **ConPTY 盲区改为显式 `SKIP:`**（不再是"读错就判红"）：`tui-cut-probe` 的静默半场、
  `tui-rtt-probe` 的慢链路半场、`tui-setup-probe`/`--line-mode` 的字节形状检查。SKIP 仍收尾
  `INCOMPLETE`。真实 home 未配置时（会进配置向导）同样 `SKIP:` 而不是超时报红；
  `verify-batch --home <dir>` 可把读 profile 的三步指向自建 home。

### 已知问题

- **0.8.2-rc.1 → 0.8.2 无代码变更**：转正只改版本号与发版材料，包内 `lib/` 与候选版逐字节相同
  （候选版沉淀期间未收到新的回归报告）。
- Windows / ConPTY **实机人工验收已完成**（2026-10-03，维护者逐条走过 12 项清单，结论见
  [`docs/checkpoints.md`](docs/checkpoints.md)「Windows 实机轮」）：可自动化的部分由 `verify-batch --home
  <dir>` 覆盖（12 PASS · 2 SKIP · 0 FAIL），**没有自动化、只能人眼的两目（输入法组合、多行中文粘贴）
  已确认通过**。两处 `SKIP` 是覆盖边界、不是通过：ConPTY 自己回 `CSI 6n`，"慢链路"与"静默但没断连"
  这两个形状它扮演不了（这两个形状在 Linux 腿上真跑）。
- fresh-home 首启有两条探针覆盖（`scripts/tui-setup-probe.mjs` 断言向导自动出现 + 第二次启动不再出现；
  `scripts/probe-onboarding.mjs` 供工作区探针识别"这是首启"并 `SKIP:` 而不是误报），命令在
  [`docs/release.md`](docs/release.md)。只读 pnpm store 的沙箱建不出 home，那是环境限制，不是覆盖缺口。
- ~~`scripts/tui-drop-probe.mjs` 约 1/7 概率因自身的 `/status` 重试竞态误报~~ —— **本版已修**：
  改为一次请求在飞、按每次请求的输出判定、并按"当前是否真有 Screen"决定关闭，连跑 20 次无失败。
- 打包：`npm pack --dry-run` 实测 **243 个文件 / 1.4 MB（tarball）/ 解包 4.2 MB**，CHANGELOG 随包发布；
  无凭据、无 home、无 sqlite、无 scratch。

---

## 0.8.1 — 2026-09-30（`latest` + `next`）

发版说明：[`docs/release-notes-0.8.1.md`](docs/release-notes-0.8.1.md)。

### Fixed

- 没有终端的进程（桌面版 Electron-as-Node、管道、cron）不再抛错退出，而是保持惰性：不取锁、
  不装定时器、不查更新，记一行说明，退出码 0。

### Added

- `DSH_TUI_DISPLAY=stdio`（或 `--display stdio`）：宿主自带终端控件时可以把 TUI 当子进程用，
  画面走 stdout、按键走 stdin、尺寸由 `CSI 8 ; rows ; cols t` 报告。

---

## 0.8.0 — 2026-09-29（`next`，随后提升为 `latest`）

发版说明：[`docs/release-notes-0.8.0.md`](docs/release-notes-0.8.0.md)。基线切到上游 `0.2.0-rc` 线
（桌面版 Harness 的基线），兼容窗口与 CI 腿随之上移。
