# Changelog

本项目的所有重要变更都会记录在此文件。
格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)，版本号遵循[语义化版本](https://semver.org/lang/zh-CN/)。

## [0.2.41] - 2026-09-05

### 修复（docx 工具）

- 整段合并与逐节点模式下，类别统计不再把共享计数 Map 的历史累计重复相加
  （此前报告 email/addr/name 约为实际 2 倍）；计数按每次调用前后差值累加。
- 整段合并模式下不再做节点级二次处理，避免占位符被二次包裹/统计虚高。
- 引擎公司规则不再为“会被合并丢弃的重叠候选”预先分配占位符：
  单个公司名不再被统计为 2 次、编号不再无故跳号（docx 验收复现后修复）。

### 新功能（docx 工具）

- CLI 支持 `--config <json>`：键与 README 配置表一致（如 `{ "redactNames": false }`），
  按任务需要关掉会干扰推理的类别，避免过度脱敏；新增配置化测试。
- CLI 支持批量：一次传入多个 .docx（配合 `--out-dir`）逐个生成脱敏副本；
  `--report <json>` 输出每份文件的遮罩统计/失败原因报告。

### 界面与误伤

- 卡片新增：生效配置摘要（当前生效类别与保留类别）、“复制状态”按钮；
- 卡片新增姓名/公司/机关/案号/出生日期五个独立开关，可精细调整而非只能一键全开全关；
- 修复源码/产物“插件版本行”漂移：版本常量回到 client-src 并由 accuracy 测试强制同步；
- 误伤语料扩充 12 条，并修复无名「社区/政务…服务中心」被当公司/街道的问题。
- 新增纯文本脱敏 CLI `tools/redact-text.mjs`（支持 `--config`，统计从输出占位符推导）。

### 可靠性

- 卡片开关新增“点击级”自动断言：逐个执行按钮 onClick，校验写入字段、翻转值与
  全面脱敏一键写三字段，防止按钮与数据层失联；
- docx 批量报告为默认模式条目标注 `crossRunNotChecked: true`，
  明确提示未做跨 run 复核，避免报告看似完整实则漏遮。
- docx CLI 新增 `--html-report <汇总.html>`：批量结果生成可浏览器打开的表格汇总
  （输入/输出/文本节点/命中类别/风险标注），纯本地生成。
- 宿主升级防护：启动即打印「适配检查」（llm/settings/模块表条目/sessionController 可见性）
  并明确列出降级项；设置命名空间与展示层还原的安装均以 try/catch 包裹，
  失败只降级、不让 dsh web 因插件启动失败。

### 安全（M3 第一版：离境硬门禁）

- `nonTextPolicy: allow` 不再默认原样透传：未显式设置 `allowRawMedia: true` 时，
  图片/文件等非文本内容会被拒绝（提示先本地 OCR/脱敏）——落实“凡离境必先脱敏”；
- 新增 `allowRawMedia`（默认 false）作为显式承担风险的开关；新增 M5/M5b 回归
  （reliability 138 → 139），README 配置与已知限制同步。

## [0.2.40] - 2026-09-05

### docx 工具打磨

- 占位符编号改为**整个文档单调递增**（此前每个文本节点重新编号，出现重复 EMAIL_1）；
- 新增可选 `--whole-paragraph`：按段落合并全部 Word run 后整体识别，
  解决“邮箱被拆到两个文本节点漏遮”的问题；结果写入首 run、其余 run 保留结构与样式；
  默认关闭（避免把整段格式并入首 run），开启时 CLI 会提示用 Word 抽查。
- docx 测试新增跨 run 合并识别 + 编号单调用例。

## [0.2.39] - 2026-09-05

### 新功能：docx 本地脱敏（MVP）

- 新增纯本地 docx 脱敏（lib/docx.js + tools/redact-docx.mjs）：
  - 只改写正文/页眉页脚/脚注/批注里的 Word 文本节点，样式、媒体、关系等原样保留；
  - 输出“脱敏副本”，不修改原文件；
  - 零第三方依赖（Node 内置 zlib + 手工 zip/crc32）。
- 已知边界：不跨 Word 文本分段识别被拆开的敏感值（工具与 README 均已注明）。
- 新增 test/docx-test.js，并接入 CI 与 prepublishOnly；npm 包 files 增加 tools/。

## [0.2.38] - 2026-09-05

### 界面与策略

- 隐私保护卡片新增两行：适配 dsh 版本范围（官方 npm 0.1.0-rc.6+ 与 0.1.2 开发线，
  功能随宿主能力自动降级）与简版责任声明（启发式脱敏不保证零漏检，完整版见 README）
- 策略提示：`redactToolMeta` 保持默认开启（schema 含敏感值也在上云前遮罩）；
  若担心遮罩影响模型对工具用途的理解，可显式设 false——在 README 配置表已注明取舍

### 文档

- README 新增「责任与边界」「版本适配与升级策略」章节
- README 明确文件脱敏边界：当前仅处理文本/文本块，Word/PDF/图片为规划中的独立功能，
  未内置前不声明支持（避免“看似支持实则不遮”）
- README 展示边界补充 sessionController 不可见组合的占位符行为（与已知限制一致）

## [0.2.37] - 2026-09-04

### 修复（第四十四轮：泛指误伤语料扫射）

- 街道规则排除「前方路口/十字路口/三岔路口/这个路口」等泛指路口（不再当街道名）；
- 机构与公司规则排除「新开了一家律师事务所」「这家医院」「一家公司叫…」等
  数量/动作引导的泛指（真实机构如「北京大成律师事务所」仍正常脱敏）；
- accuracy 误伤防回归新增 路口/新开律师事务所/一家公司 用例。

## [0.2.36] - 2026-09-04

### 修复（第四十三轮：地址规则误伤/漏网）

- 街道规则不再把「在小区门口等我」「家门口的路」「翠湖小区门口」等生活场景当街道名
  （validator 排除 门口/楼下/屋里/家里/村里）；
- 地址链（省市区+街道）后紧跟的道路此前会漏遮罩（如「粤海街道科技园路」只遮到街道，
  第二轮被占位符左边界挡住）——链规则现对占位符后紧跟的道路做续扫补遮；
- accuracy 误伤防回归新增小区门口/家门口，地址链测试新增道路续扫回归。

## [0.2.35] - 2026-09-04

### 修复（第四十二轮：还原未命中统计）

- 入站还原未命中计数不再把同一占位符在 text-delta 与 block-end 各计一次：
  改为只在权威的 block-end 与流尾收尾统计，日志/事件里的“未命中数量”不再虚高；
- 新增 V5 回归（reliability 137 → 138），断言 count=1 且样例含该占位符。

## [0.2.34] - 2026-09-04

### 修复（第四十一轮：userinfo 误伤面）

- `mailto:user@example.com` 不再被 userinfo 规则拆成 `mailto:user:[KEY]@example.com`
  （会残留邮箱域名）：mailto 整地址规则在 userinfo 之前全量遮罩；
- 裸 userinfo 密码字符集排除反斜杠、起点排除冒号前导，避免 Windows 路径
  （`C:\users\alice@example.com`）与 `mailto:/tel:` 形态被当作凭据；
- accuracy 凭据矩阵新增 mailto 整体遮罩回归。

### 验证

- 真机（0.2.33）确认：用户消息按设计以占位符落盘/展示（已知限制），
  模型回显占位符经入站还原后在界面显示原文邮箱（mailto 链接）。

## [0.2.33] - 2026-09-04

### 修复（第四十轮：0.2.32 启动卡死）

- **0.2.32 启动 100% CPU 卡死**：展示层探测里对 loader entry 的 fiber 上下文做递归下钻，
  会在 apply 期触发未就绪 include entry 的材料化死循环（实测复现）。已改回当前 loader
  的线性枚举（0.2.30 行为），启动恢复正常；递归下钻仅保留注释警示。
- 0.2.32 已发布但含此缺陷，建议执行 `npm deprecate dsh-privmask@0.2.32` 提示升级 0.2.33。

## [0.2.32] - 2026-09-04

### 文档（第三十九轮：真实环境回归）

- 真实回归又发现并修复：非 ASCII 密码/主机（如 `admin:密码ABC123@内网主机`）此前因
  userinfo 规则要求 ASCII 主机前瞻而漏网；现改为「@ 后至少一个非空白字符」即整段遮罩，
  中文主机凭据不再残留（accuracy 回归）
- 真实回归又发现并修复：URL 密码含原始 `@` 时（畸形但存在），旧规则只遮到首个 `@`，
  密码片段会残留在日志与出站内容中；userinfo 规则现吞到主机名前的最后一个 `@`
  （带主机形态前瞻），路径中的普通 `@` 不误伤；accuracy 新增多 @/路径 @ 回归
- 真实环境回归确认：部分 dsh 组合下插件 host 上下文探测不到 `sessionController`
  （注册在 web-app 内层 include），展示层还原不生效，用户消息在界面与日志中一致为占位符。
  已在 README「已知限制」与机制条目如实记录该场景及启动日志告警字样。
- 浏览器端替代方案调研结论：聊天显示走 `uiConversation`/`remote.session`，包装可行，
  但浏览器拿不到 host 内存中的占位符映射，需新增 host→browser 的映射 RPC（新架构缝），
  暂不自行实现，建议向 dsh 官方申请会话读取/改写缝。
- 展示层探测增强：新增 loader 树递归探测与诊断（告警带 loader 条目数/session-controller 可见性）；
  实测确认该组合下 session-controller 不在插件可达的 loader 树（147 个 entry 无该 id）

## [0.2.30] - 2026-09-04

### 修复（第三十九轮：URL 凭据盲区）

- **URL/连接串 user:password@ 凭据盲区**：特殊字符密码此前会被邮箱规则部分漏出；
  新增 scheme 与裸 userinfo 两条规则整段脱敏密码（accuracy 凭据矩阵回归）。
- 规则起点加负向后顾避免在无 `://` 的长文本上 O(n²) 重扫（200KB 字母数字保持约 6ms）；
- 密码字符集排除方括号，保证首轮替换后的占位符不会被第二轮规则再次包裹（幂等；
  fuzz 原 18 例幂等失败全部回归通过）

### 测试

- accuracy 凭据矩阵新增 url-userinfo / bare-userinfo 用例，断言密码不泄漏且只替换一次

## [0.2.29] - 2026-09-04

### 修复（第三十八轮：代码审查整改）

- **请求形态守卫与 __proto__ 字段安全**：`messages` 缺失/非数组时给出明确拒绝（不再裸 TypeError）；
  对象拷贝改用 `defineProperty` 写入，避免字段名为 `__proto__` 时触发原型 setter 导致字段丢失/污染。
  新增 T16 回归（可靠性 136 → 137）
- **超长无空白 ASCII 连续串守卫**：约 8MB 单 token 会让 V8 正则栈溢出（RangeError）；
  引擎现对 >4MB 的连续无空白 ASCII 运行直接给出明确拒绝，accuracy 性能测试覆盖
- **恢复流收尾冲刷**：流在没有 block-end 时结束且尾部残留疑似占位符前缀，
  不再静默丢弃，按原类型冲刷（不完整占位符不含原值，无泄漏风险）
- **结构化工具参数遮罩**：`tool-call.arguments` 若为对象/数组（而非 JSON 字符串），
  出站递归遮罩其中的字符串（原实现会静默跳过，构成潜在泄漏面）；入站还原同步支持
  `restoreJson` 对结构化参数递归还原。新增 T14/T15 回归（可靠性 134 → 136）
- **高危：中文实体替换的 O(n²) 字符串重建**：姓名/机构/地址/自定义词规则原先逐条
  `slice+concat` 重建整串、且姓名扫描反复从「当前位置+1」重扫尾部并对每个命中线性查覆盖，
  长文档（84 万字符含 4 万角色词）实测约 13s。已改为：ctx 扫描线性推进、覆盖判定二分、
  全部替换点统一单遍切块 join（84 万字符降至约 0.34s，16 万密集角色词 4.5s→25ms）
- **高危：邮箱正则灾难回溯**：`[A-Za-z0-9._%+-]+@...` 在长串无分隔符字母数字上呈 O(n²)
  （实测 200KB ≈ 18s，可能拖垮宿主进程）。已加本地部分起始负向后顾，
  200KB 降至约 5ms，识别行为不变；accuracy 性能测试增加防回归断言
- **高危：字符串 content 消息被整体清空**：`walkBlocks` 原先假定 content 为块数组，对字符串逐字符
  按“非文本块”处理，默认 `strip` 策略会把整条消息删成空数组（可复现）。现改为字符串直接走文本脱敏，
  字符串进、字符串出，并新增 T12/T13 回归（出站消息与工具结果均不丢文本）
- **展示层还原与 `persistMapping` 的依赖关系文档化**：`restoreInbound: true + persistMapping: false`
  时流内实时还原正常，但历史展示层无法还原已落盘占位符；配置表说明 + 启动时打印告警
- **浏览器卡片 `waitReady` 竞态**：订阅可能在赋值前同步触发、超时定时器可能残留；
  改为 settled 一次性放行（resolve/reject 与清理均只执行一次）
- **复制命令兜底检测返回值**：`execCommand('copy')` 返回 false 时不再误报“已复制”，改为提示手动输入
- **还原性能**：`restoreChunkText` 改为按会话编译一次占位符正则单遍替换（长占位符在前），
  并避免“还原值恰好含占位符形态文本”时被二次替换（防嵌套展开）

### 文档

- README 新增「环境与安装排查」：镜像源滞后、pnpm 最小发布期白名单、重启与令牌、
  LaunchAgent/后台环境、非 web profile 的能力降级
- README 新增「诊断与统计」章节（控制台前缀、privmask/stats 事件、还原未命中格式、诊断文件）
- package.json 清理：合并重复的 `keywords` 键（此前存在两份，解析器只保留后者）
- README 已知限制补充内存上界说明（200 会话上限、极端规模内存可能较大）
- README 可靠性计数 132 → 134（新增 T12/T13）

### 测试与可观测性

- 入站还原未命中日志/事件增强：统计时携带 sessionId，并附最多 3 个未命中占位符样例，
  便于区分「映射被逐出」与「模型改写」两类场景
- 新增客户端数据层无 DOM 单测（并入既有测试块）：加载 lib/client.js 产物驱动
  list/describe/update，覆盖卡片注册信息、settingsScope 读取/写入/未知命名空间拒绝/写入未生效报错
- 卡片迷你首帧渲染断言（无 DOM）：驱动组件钩子与 JSX 桩渲染首帧，
  校验顶部状态、版本号、复制按钮、常用开关提示与作者/仓库/Issues 署名链接
- 性能阈值放宽为数量级哨兵并注释（拦截二次方/灾难回溯回归，避免 CI 抖动误报）

### 界面

- 隐私保护卡片底部新增署名与反馈入口：作者 JunyuZhan、GitHub 仓库链接、Issues 链接

## [0.2.28] - 2026-09-04

### 修复（第三十七轮：文档与面板一致性）

- 修正 package.json 简介与 lib 头注释：原「本地会话日志保留原文/日志不受影响」与实际机制矛盾，
  实际是用户输入与工具结果落盘前遮罩为占位符、模型回复经入站还原以真值落盘与显示
- README 澄清“日志保持占位符”仅适用于用户消息：模型回复与工具调用参数在日志中为真值
  （此前特性与机制条目表述未限定主语，与安全模型/已知限制冲突）
- 「日志不落明文」改为“原则上不落明文”，并链接已知限制中的 dsh 内部事件原文副本例外

### 界面

- 卡片顶部插件状态改用「插件已启用/未启用」措辞，与下方配置项“总开关（已开启/已关闭）”区分，
  避免关闭总开关后顶部仍显示“已开启”的歧义
- 「全面脱敏」在姓名/公司/机关部分开启时显示「部分开启」，按钮文案改为「全部开启」/「关闭」
- 删除正文中多余空格；卡片说明与注册 locale 不再各自维护一套文案（移除未使用的 desc/update/on/off 键）
- 卡片底部补充提示：此处为常用开关，案号/出生日期/严格模式等其余选项在配置文件中调整
- 自定义敏感词输入支持一次添加多个：以分号/逗号/顿号/换行分隔，自动去重并忽略空项
- 卡片新增「复制更新命令」按钮：一键复制 `dsh plugin --profile web update dsh-privmask` 到剪贴板，
  并提示重启 dsh web 生效（dsh 未提供网页端一键更新的远程接口，故以复制命令方式替代）

## [0.2.27] - 2026-09-04

### 修复（第三十六轮：跨版本兼容官方包）

- **修复官方 npm 包安装后插件依赖缺失**：官方 dsh（npm 最新 0.1.1-rc.2，含 npx 缓存中的 0.1.0-rc.6）
  的网页端模块表没有 `@deepseek-ai/dsh-api-settings-controller`（0.1.2-alpha.1 才引入），
  此前 `dsh.client.inject` 声明了对它的依赖，用户安装后在启动/插件列表看到「依赖缺失/等待依赖」类提示。
  已移除该声明；现在只声明官方 0.1.0-rc.6、0.1.1-rc.2 与 0.1.2-alpha.1 模块表都有的行
  （client-connection / client-runtime / api-remotes / client-ui-settings / client-locale）。
- **浏览器端改用跨版本共有的 `settingsScope` 服务**：卡片原先使用 0.1.2 才提供的
  `remote.settings` 读写命名空间，旧官方包没有该服务会导致客户端停在 PENDING（表现为「等待依赖」）。
  现改为两线（官方 0.1.0-rc.6+ 与 0.1.2 开发线）都由 `dsh-client-ui-settings` 提供的
  `settingsScope.bind({ namespace: 'privmask' })` 作用域读写，启停状态、全面脱敏档、地址/凭据开关、
  自定义敏感词编辑等功能全部保留；读写失败/版本冲突仍以可见错误提示。
- 运行 `dsh web` 的浏览器端不再因官方包版本偏旧而加载失败；host 端出站脱敏主链路不受影响。

### 兼容性说明

- 官方 npm `@deepseek-ai/dsh`（0.1.0-rc.6 / 0.1.1-rc.2）：完整可用（核心脱敏、日志遮罩、卡片开关）。
- 本地 0.1.2-alpha.1 开发线：完整可用；`tools/ptc-dispatch-log`（run_code 子派发日志遮罩）
  仅在 dsh ≥ 0.1.2 提供该事件的宿主上自动启用，旧官方版无此事件属宿主能力差异，不视为插件功能缺失。

### 测试

- accuracy-test 新增 客户端 manifest 不依赖 0.1.2 专属模块 回归（防止未来误加回
  `@deepseek-ai/dsh-api-settings-controller` 依赖）

## [0.2.26] - 2026-08-30

### 修复（第三十五轮：卡片版本号）

- 隐私保护卡片新增「插件版本：vX.Y.Z」展示，用户可确认当前运行的插件版本
- 新增一致性测试：lib/client.js 的 PLUGIN_VERSION 必须与 package.json 相同，
  防止发版时版本号漂移

### 测试

- accuracy-test 新增 客户端卡片版本号与 package.json 一致 回归

## [0.2.25] - 2026-08-30

### 修复（第三十四轮：复姓识别）

- 复姓表补全：司马/诸葛/上官/慕容/东方/独孤/夏侯/皇甫/公孙/司徒/司空/尉迟/长孙/
  宇文/令狐/端木/申屠/澹台/拓跋/赫连/呼延/完颜/富察/爱新觉罗 等（首字不在单姓表的复姓
  此前漏脱敏，如「原告司马光、诸葛亮、上官婉儿」只识别了欧阳娜）
- 复姓同样支持尾词剥离、判决主文重扫与顿号并列

### 测试

- accuracy-test 新增 复姓组回归（顿号并列/尾词/判决主文/幂等）

## [0.2.24] - 2026-08-30

### 修复（第三十三轮：USCC 小写）

- 明确标注（统一社会信用代码/USCC/营业执照号等）下的 18 位编码支持小写字母：
  「统一社会信用代码 12345678901234567x」此前明文漏出
- 泛化标签（编号）与裸值仍保持严格：校验位不合法或小写裸值不触发（避免误伤普通编号）

### 测试

- accuracy-test「USCC 上下文」新增 小写 x 明确标注脱敏、泛化标签小写不误伤 回归

## [0.2.23] - 2026-08-30

### 修复（第三十二轮：USCC 标注词扩展）

- USCC 明确标注词扩展：统一社会信用代码/社会信用代码/信用代码/USCC/uscc/
  营业执照号/营业执照注册号 引导的 18 位编码始终脱敏（不依赖校验位）
- 确认设计边界：合法 USCC 在「编号/订单号」等泛化标签下仍被无上下文严格规则脱敏；
  校验位不合法且无明确标注的码保留（避免误伤普通编号）

### 测试

- accuracy-test「USCC 上下文」扩展：USCC/营业执照号/营业执照注册号/社会信用代码 上下文
  与「编号+合法码仍脱敏」回归

## [0.2.22] - 2026-08-30

### 修复（第三十一轮：USCC 上下文）

- 带「统一社会信用代码/信用代码」上下文的 18 位编码始终脱敏，不依赖校验位
  （与身份证上下文修复同一逻辑）；裸「编号/订单号」不作触发词，避免误伤普通编号
- 无上下文的 18 位编码仍保持严格校验（校验位合法才脱敏）

### 测试

- accuracy-test 新增 USCC 上下文：校验位非法仍脱敏、裸编号不误伤 回归

## [0.2.21] - 2026-08-30

### 修复（第三十轮：住所无冒号地址缺口）

- 无冒号的「住所」在紧跟地域词（省/市/自治州/地区/盟/区/县）时视为地址前缀：
  「住所贵州省毕节市七星关区碧阳大道12号」此前地址不脱敏（仅姓名脱敏），现可完整脱敏；
  「住所证明文件/变更登记/无固定场所/经营场所」等普通名词短语仍不触发（不误伤）
- 带冒号「住所：」行为不变

### 测试

- accuracy-test 新增 住所无冒号+省/道路 脱敏覆盖 与 住所证明/变更登记/无固定场所 误伤回归

## [0.2.20] - 2026-08-30

### 修复（第二十九轮：真实场景漏脱敏）

- 带「身份证号/证件号码/身份证/证件号/身份证明号码」上下文的 18 位号码**始终脱敏**，
  不再依赖校验位：校验位不合法但被作者明确标注为证件号的号码此前在严格模式
  （strictId18=true，默认）下明文漏出（实测场景「身份证号 522421199001011234」）
- 无上下文的号码仍保持严格校验（校验位合法才脱敏），避免误伤订单号等；
  「号码 12345678901234567X」等非证件上下文不受影响

### 测试

- accuracy-test「PII 校验位」新增 上下文+校验位非法 仍脱敏 回归

### 修复（第二十八轮：脱敏覆盖）

- 法律服务机构/羁押场所补全：公证处/鉴定所/看守所/拘留所 纳入机关词表
  （「北京市公证处」「深圳市看守所」此前漏脱敏；「去公证处」「在看守所」等泛指不受影响）

### 测试

- accuracy-test 新增 公证处/鉴定所/看守所/拘留所 回归

### 修复（第二十七轮：脱敏+还原双向可靠性）

- 还原层补全字符串 content 路径：消息 content 或 tool-result content 为字符串
  （非块数组）时占位符不再残留（此前仅还原块数组结构，历史记录/兼容格式漏还原）

### 测试

- reliability 新增 P4/P5：字符串 content 与 tool-result 字符串 content 还原回归
  （131 项）；还原专项探针 12 项（相邻占位符/编号不串位/工具参数/块数组/wireData/
  历史记录/未知占位符/miss 统计/往返闭环/2 字符流式分片/切占位符）全部通过

### 修复（第二十六轮可靠性强化）

- 机构后缀补全：中心（政务服务中心/检测中心/鉴定中心等）、管理局/管理委员会/管委会
- 「大型购物中心」「在市中心」「这个中心」等泛指不再误脱敏
  （奥莱国际购物中心/深圳市政务服务中心等真实机构保留）；
  介词剥离放宽到 2 字前缀（「在市中心」→ 保留「在」，span 级泛指针检查拦截）

### 测试

- accuracy-test 新增 政务服务中心/检测中心/城市管理局/管理委员会/市中心 回归

### 修复（第二十五轮可靠性强化）

- 合同/票据/知识产权角色词补全：买受人/出卖人/保管人/被背书人/背书人/出票人/承兑人/
  著作权人/专利权人/商标权人/被许可人/受托人/中介人/行纪人
- 社会团体后缀：协会/基金会/联合会/商会/学会 纳入机构词表
  （「中国律师协会」「中华全国工商业联合会」此前漏脱敏）
- 「参加/加入」动词：参加协会活动 等泛指不再误脱敏，参加中国律师协会 等真实机构保留动词并脱敏

### 测试

- accuracy-test 新增 买受人/被背书人/著作权人/中国律师协会/慈善基金会/商会/
  参加协会/参加中国律师协会 回归

### 修复（第二十四轮可靠性强化）

- 执法人员角色词补全：执行法官/承办法官/法官助理/法官/民警/法警/代理律师/辩护律师/
  委托律师/律师（「派出所民警王五」「执行法官李四」「法官助理王五」此前漏脱敏；
   「委托代理人陈志明律师」后置姓名不受影响，「律师执业证号」等上下文不误伤）

### 测试

- accuracy-test 新增 民警/执行法官/法官助理/代理律师 回归

### 修复（第二十三轮可靠性强化）

- 行政/刑事文书角色词补全：被处罚人/违法行为人/行为人/犯罪嫌疑人/嫌疑人/在逃人员/
  被拘留人/被羁押人（「犯罪嫌疑人」置于「嫌疑人」之前避免拆词；
   「犯罪嫌疑人及其辩护人」等无姓名场景不受影响）

### 测试

- accuracy-test 新增 被处罚人/违法行为人/犯罪嫌疑人/嫌疑人/在逃人员 回归

### 工程（第二十二轮）

- CI 补跑 accuracy-test.js（此前 GitHub Actions 只跑 self/reliability/fuzz，
  准确性回归（23 项）未纳入自动检查）

### 修复（第二十一轮可靠性强化）

- 专门法院词表：铁路运输法院/互联网法院/知识产权法院/金融法院/海事法院/军事法院
  （「北京铁路运输法院」此前被街道规则误当「铁路」路名；其余专门法院漏脱敏）

### 测试

- accuracy-test 新增 铁路运输/互联网/知识产权/金融/海事法院 回归

### 修复（第二十轮可靠性强化）

- 起诉状/刑事文书角色词补全：具状人/起诉人/被告人/原告人/申诉人/被害人/受害人/
  举报人/控告人/报案人（「具状人：王五」「附带民事诉讼原告人王五」此前漏脱敏；
   「被告人」「原告人」置于「被告」「原告」之前避免拆词）

### 测试

- accuracy-test 新增 具状人/被告人/原告人/被害人/举报人 回归

### 修复（第十九轮可靠性强化）

- 基层组织/职务角色词补全：主任/副主任/书记/村长/组长/会计/出纳
  （「村民委员会主任王五」「村党支部书记李四」此前漏脱敏；
   「书记」置于「书记员」之后避免拆词；「主任办公会」等泛指不受影响）

### 测试

- accuracy-test 新增 村委会主任/支部书记/会计/出纳 回归

### 修复（第十八轮可靠性强化）

- 诉请返还/支付短语补全：立即返还/立即支付/立即/应返还/返还
  （「判令被告李小红立即返还借款」「被告李小红应返还」此前漏脱敏）

### 测试

- accuracy-test 新增 立即返还/应返还 回归；执行裁定书+判决书端到端
  （报告财产/高消费/失信/加倍/逾期/经本院合法传唤）幂等/还原/零泄漏 验证通过

### 修复（第十七轮可靠性强化）

- 判决主文利息/履行短语补全：加倍支付/加倍/逾期未付款/逾期未履行/逾期未/逾期/
  经本院合法传唤（「被告王五加倍支付迟延履行期间的债务利息」此前吞「加倍」或漏脱敏）

### 测试

- accuracy-test 新增 加倍支付/逾期未履行/逾期未付款/经本院合法传唤 回归

### 修复（第十六轮可靠性强化）

- 执行/失信阶段短语补全：报告财产/高消费/纳入失信被执行人名单/无财产/无可供执行财产/
  采取限制消费措施/应当/迟延履行/履行（「责令被执行人王五报告财产」「限制高消费」等此前漏脱敏）
- 修复「行」单字虚词把「王五有履行能力」裁成「王五有履」的问题（补「履行」整词尾词）

### 测试

- accuracy-test 新增 报告财产/高消费/纳入失信/有履行能力/迟延履行 回归

### 修复（第十五轮可靠性强化）

- 广谱误伤扫描（50 句日常文本）发现并修复：
  「华南区/华北区/大湾区」等宏观区域不再被当街道名（「西南路/华北路」等真实路名不受影响）；
  「乡村振兴」政策短语不再被当乡村地址链
- 「雄安新区」等国家级新区仍按地址处理（与南山区/浦东新区同类，属刻意取舍）

### 测试

- accuracy-test 新增 华南区/大湾区/乡村振兴 误伤回归；
  50 句广谱扫描仅剩 1 句（雄安新区）为刻意取舍

### 修复（第十四轮可靠性强化）

- 机关规则同步代词/介词剥离：「冻结其在毕节市公安局七星关分局」不再把「其在」吞进占位符
- 代词剥离保护：本/贵/各/双 仅在紧跟机构后缀词时剥离，修复「贵州茅台」「本溪钢铁」
  「贵州省高级人民法院」被拆成「州茅台」「溪钢铁」的问题；「该公司为/本公司系」仍正确保留系动词
- 行业词补全：钢铁/煤炭/煤业/石油/天然气/水泥/玻璃/陶瓷/造纸（「本溪钢铁公司」此前漏脱敏）

### 测试

- accuracy-test 新增 贵州茅台/贵州高院/本溪钢铁 回归；
  混合压力文档幂等/还原/零泄漏 持续验证通过

### 修复（第十三轮可靠性强化）

- 公司名前缀句法成分剥离：执行类动词（冻结/查封/扣押/划拨/扣划/变卖/拍卖）、
  代词「其」、单字介词（在/去/从/到）不再被吞进公司占位符；
  修复「冻结其在中国工商银行深圳南山支行」两轮脱敏不一致的幂等问题
  （此前支行 span 覆盖银行 span 被合并丢弃，第二轮才补脱敏）
- 「小明在学校」「爸爸在银行」等泛指判定不受影响（先判定后剥离）

### 测试

- accuracy-test 新增 冻结其在银行/在招商银行 回归；
  混合实体压力文档（保全裁定+公司+地址+证件）幂等/还原/零泄漏 验证通过

### 修复（第十二轮可靠性强化）

- 裸「欠」动词纳入姓名尾词（「被告王五欠原告李四货款」中的王五此前漏脱敏；
  尚欠/欠付/欠款等长词不受影响）
- 流式还原抽查：占位符按 3 字符网络分片切碎后跨分片重组还原正常

### 测试

- accuracy-test 新增 欠（动词）回归

### 修复（第十一轮可靠性强化）

- 保全/担保/权利类角色词补全：申请保全人/保全人/抵押权人/抵押人/质押权人/质押人/
  出质人/质权人/留置权人/保证人/权利人/义务人（「申请保全人王五」此前漏脱敏）

### 测试

- accuracy-test 新增 申请保全人/抵押权人/质押权人/保证人/权利人 回归

### 修复（第十轮可靠性强化）

- 座机号支持空格分隔（0755 12345678 / 010 12345678），与横线/无分隔格式统一脱敏；
  超长数字串不截断（010 123456789 保持原文）

### 测试

- accuracy-test 新增 空格座机/无分隔座机 回归；B2B平台/3M口罩/AB测试/IBM电脑/VIP会员
  等拉丁泛指误伤探测通过

### 修复（第九轮可靠性强化）

- 户口所在地 纳入地址上下文与姓名尾词（「被告李小红户口所在地：浙江省杭州市」
  无逗号场景此前姓名与市级地址均漏脱敏）

### 测试

- accuracy-test 新增 户口所在地 回归

### 修复（第八轮可靠性强化）

- 机关词补全：分局/人民法庭 纳入词表；机关前缀最短长度放宽到 2 字
  （「深圳市公安局南山区分局」「碧阳派出所」「碧阳人民法庭」此前漏脱敏；
   「在派出所」等泛指仍保留）

### 测试

- accuracy-test 新增 区分局/派出所独立/人民法庭 回归

### 修复（第七轮可靠性强化）

- 拉丁字母/数字组合字号识别：「3M中国有限公司」「IBM中国」「B2B公司」「华为Mate60公司」
  此前漏脱敏（含 ≥2 拉丁字母或字母+数字组合的前缀视为专名字号）

### 测试

- accuracy-test 新增 拉丁字号公司/IBM中国/数字字母公司 回归

### 修复（第六轮可靠性强化）

- 亲属关系链补全：「被告王五的丈夫李四」「被告王五的妻子李四」中的
  的丈夫/的妻子/的儿子/的女儿/的父亲/的母亲/的配偶 后的姓名继续识别

### 测试

- accuracy-test 新增 的丈夫/的妻子/的父亲/的配偶 回归

### 修复（第五轮可靠性强化）

- 居住地字段补全：户籍所在地/经常居住地/实际居住地 纳入地址上下文与姓名尾词
  （「被告李小红，户籍所在地：浙江省杭州市」此前姓名可脱敏但市级地址漏脱敏）
- 仲裁院 纳入机关词表（「深圳国际仲裁院」此前未脱敏）

### 测试

- accuracy-test 新增 户籍所在地/实际居住地/仲裁院 回归

### 修复（第四轮可靠性强化）

- 庭审到庭/出庭/当庭短语补全：到庭参加诉讼/出庭应诉/当庭出示/当庭提交/到庭/出庭/当庭
  纳入姓名尾词（「原告王小明到庭参加诉讼」此前漏脱敏）

### 测试

- accuracy-test 新增 到庭参加诉讼/出庭应诉/当庭出示/出庭作证 回归；
  完整起诉状/判决书端到端（脱敏→幂等→还原往返）验证通过

### 修复（第三轮可靠性强化）

- 权属/行为动词补全：出具/持有/所有/所在地 纳入姓名尾词
  （「被告王五出具的证明」「原告王小明所有的房产」此前吞词）
- 又名/别名/曾用名 纳入姓名上下文（「被告王五（又名王老五）」中的别名同样脱敏）
- 修复「强」字被单字虚词裁剪：三字名以「强」结尾（李二强/张三强）此前被裁成两字，
  导致「（别名李二强）」拆出残留「强」；「李强认为/强调/主张」等仍正确保留动词

### 测试

- accuracy-test 新增 出具/持有/所有/所在地、又名/别名/曾用名、三字名以强结尾 回归

### 修复（第二轮可靠性强化）

- 亲属关系链：被告张三之父王大明 / 原告李小红之母刘芳 中「之父/之母/之妻/之夫/之子/之女」
  后的姓名继续识别，不再只脱第一个当事人
- 答辩/质证/出庭短语补全：认可/不认可/无异议/有异议/同意/不同意/无正当理由/
  当庭陈述/陈述/经合法传唤 纳入姓名尾词（「被告李小红认可该欠款事实」此前漏脱敏）
- 区级地址链补全：缺少市级前缀的「天河区体育西路123号」「住在朝阳区建国路88号」
  不再漏脱敏（街道规则被汉字前缀阻断的缺口），且「位于/住」等介词保留在原文

### 测试

- accuracy-test 新增 之父/之母链、认可/不认可/无异议/同意/当庭陈述/经合法传唤、
  区级地址链 回归

### 修复（可靠性强化轮）

- 姓名字段标签边界：住址/户籍/出生日期/身份证号/联系电话/微信/QQ/银行卡号/执业证/常住/住所等
  标签不再被吞入姓名占位符（此前「张三住址」整体脱敏会破坏后续地址/证件规则的上下文识别）
- 姓名尾词多轮剥离：修复「张三生日是」漏裁（裁掉「是」后暴露「生日」仍被吞）与
  「王小明住在」吞「住」；新增 名下/之父/等人/尚欠/欠付/应于/应支付/经传票传唤/下落不明/
  辩称 等法律文书高频尾词
- 「被告（李小红）」括号姓名、「被告张三及李四」并列连接（及/和/与）、
  姓名后直接跟年份数字（「张三2024年」）纳入识别
- 地址链带门牌号（「…碧阳大道12号」）不再被数字阻断；常住/居住/家住/现住/住 引导的地址链纳入脱敏
- 地址链链首介词剥离：「住广东省…」「位于上海市…」「我住在…」的介词/代词保留在原文，
  不再整句被吞；修复「粤海街道」被截成「粤海街」残留「道」字
- 泛化机构误伤：在学校/这所学校/在银行/那家酒店/这家医院/上个月学校/去工厂 等泛指不再脱敏；
  招商银行/清华大学/协和医院/人民银行/中央戏剧学院 等真实机构保留
- 机构后缀补全：中学/小学/幼儿园/门诊部/诊所/卫生院/卫生室/分行/支行；
  修复「平方米）出租给圣柏俐医疗美容门诊部」中句子级右括号与「出租给」被吞入公司名
- 泛指机构前缀补全：「附近有一所医院」「深圳有一所医院」「北京的医院」「两所学校」等
  不再误脱敏（招商银行/深圳市第一人民医院等真实机构不受影响）
- 村镇/街道泛指误伤：我们村/本村/全村/隔壁村/回村/去镇上/住在村里/他在街道上 不再当地址链；
  王家村/碧阳街道 等真实地址保留
- 街道误伤：大街小巷/走街串巷/街头巷尾/工业园区/该小区/高速公路 不再被当街道名
- MAC 地址纳入脱敏（此前被「MAC地址」上下文误当住址生成 ADDR 占位符）
- 机关补全：全国人大常委会/中央人民政府；「公安分局」完整识别不再只脱「公安局」
- 案件角色补全：监护人/案外人/异议人/利害关系人/当事人；「被告方王五」剥离角色词缀「方」
  （方姓姓名如「原告方明」不受影响）

### 测试

- accuracy-test 新增「泛化机构/村镇与真实机构并存」回归（脱敏覆盖、误伤、幂等、介词保留、
  平方米前缀不吞）
- accuracy-test 误伤防回归新增 20+ 泛指/成语/街道样本（学校/银行/酒店/医院/村/镇/园区等）
- 端到端验证：毕节奥莱租赁合同风格文书 脱敏→幂等→还原往返 全通过，金额/日期/条款保留

### 修复

- 「住所：」地址前缀纳入脱敏（法律文书高频写法，此前整段地址明文漏出）
- 含拉丁字母/数字的公司名可识别（如「奥莱国际Fmall购物中心」「3M中国」），
  购物中心/商场纳入公司后缀词表
- 公司名识别补强：常见城市名（广州/杭州/毕节等）、行业词（制药/保险/证券/矿业/化妆品等）、
  知名品牌（腾讯/百度/华为/字节跳动等）纳入佐证词表，覆盖此前漏脱敏的真实公司
- 「户籍地址」等长上下文词优先匹配，修复地址前缀错位
- 省市区+道路的完整地址链（「贵州省…七星关区碧阳大道」）纳入脱敏，且要求区县级
  避免「深圳市分行南山路」误吞
- 「被告一/被告二/被告1」编号被告、顿号分隔的连续姓名（张三、李四、王五）纳入脱敏
- 「实际控制人/控股股东/一致行动人」纳入姓名上下文
- 姓名边界词补强：认为/以为保留、诉称/借款纠纷等法律高频动词短语识别，
  修复「李强民间借贷纠纷」漏脱敏与「李强认为」吞词
- 机关全称完整脱敏：法院/检察院/公安分局+派出所不再被街道规则拆散，
  相邻机关重叠 span 去重避免占位符错位；「中华人民共和国」等含「和」前缀不再截断
- 「公司为/公司系/公司由」系动词保留，前置公司名不再被吞入后续公司占位符；
  公司后缀重叠（科技公司+控股）去重
- 姓名补充脱敏：同一文档中已通过角色词识别的当事人姓名，在判决主文等无上下文
  位置重复出现时仍脱敏（如「判决如下：一、李强于…偿还张伟…」）
- 姓名边界补全：「上诉人/被上诉人/原审原告/再审申请人」角色词、
  「一案」动词短语、「因」保留边界词，修复「李强因」「李强一案」吞词/漏检
- 「原告X诉被告Y」诉讼格式：X 后紧跟「诉」直接识别（保留「诉」）
- 长案由短语（民间借贷纠纷一案/买卖合同纠纷/劳动争议纠纷/物业服务合同纠纷等）
  按最长尾词优先剥离，修复「合同纠纷」抢先吞掉「买卖/服务/民间」等问题
- 公司规则补强：组合后缀（集团有限公司/股份有限公司/控股有限公司）按前缀含强词识别；
  括号公司名（腾讯科技（深圳）有限公司）纳入前缀回溯；
  「申请/申请执行人」不再被动词裁剪吞掉
- 角色词补全：欠款人/今欠/今借到/被继承人/继承人/遗赠人/受遗赠人
- 银行卡：有「收款账户/银行卡号」等上下文时 16-19 位即脱敏（不再要求 Luhn 合法）
- 移除歧义动词型姓名上下文（今欠/借到/收到），修复「今欠是方言」「借到钱不容易」误伤；
  欠条/借条仍通过落款「欠款人/借款人」覆盖
- 角色词补全：转让方/受让方/居间人/寄件人/投保人/被保险人/受益人/买方/卖方/甲方/乙方等；
  案由短语补全：赡养/探望权/相邻关系/散伙清算/股权转让协议/居间合同纠纷等
- 姓名虚词过滤：候选名含「的/了/与/和」等虚词时拒绝（修复「王芳的联」误吞）
- 动词型姓名上下文（查询/检索/搜索/了解/介绍）支持，误伤「查询功能」等已防
- IPv6 完整匹配（8 段全写及含「::」压缩），不再误伤 MAC/时间/C++ 作用域/命名空间/裸冒号
- 带空格/横线分隔的手机号（138 0013 8000 / 138-0013-8000）纳入脱敏
- 地址链支持「位于/在/名下」等介词引导（如「查封被申请人名下位于广州市天河区体育西路」）；
  镇/乡/街道/村结尾后跟道路字时不再截断（修复「中关村大街」被截成「中关村」）
- 「XX律师」职业词、金融借款合同纠纷等案由短语纳入姓名/案由识别
- 机关词补全：街道办事处/居民委员会/村民委员会/村委会/居委会（修复「中关村街道办」误吞为地址链）

### 测试

- accuracy-test 新增「法律文书高频地址/含拉丁公司名」覆盖与「住所证明/大型购物中心/苹果公司」误伤回归
- accuracy-test 新增地址链与多姓名、机关全称、公司系动词与重叠后缀三组回归
- accuracy-test 新增判决书主文回归（当事人姓名无上下文重复出现仍脱敏、金额/案由保留、幂等）
- accuracy-test 新增常见案由/角色/欠条借条/括号公司回归（含案由短语保留断言）
- accuracy-test 新增动词型姓名上下文、更多角色词/案由、IPv6/分隔手机号三组回归
- accuracy-test 新增介词引导地址链与律师/金融借款案由回归
- 真实 dsh web 会话日志核对：user/message 落盘遮罩、assistant/message 入站还原均符合预期；
  确认 `agent/inbox/spliced` 事件保留原文属 dsh 平台行为（无插件改写缝），已记入已知限制

## [0.2.18] - 2026-08-30

### 新增

- 隐私保护卡片新增「自定义敏感词」编辑：随时添加/删除当事人姓名、别名、机构简称，live 生效并持久化（复用 settings 命名空间）

### 测试

- 可靠性测试 129 项（新增词表热更新回归）

## [0.2.17] - 2026-08-30

### 新增

- 中国即时通讯/执业标识脱敏（上下文识别，防误伤）：微信号、QQ 号、律师执业证号

### 质量

- 展示层/设置诊断日志仅在 `logRedactions` 开启时输出（消除单测噪音）
- README 测试计数同步；清理诊断文件

### 测试

- accuracy-test 新增微信/QQ/执业证标识与误伤回归

## [0.2.16] - 2026-08-30

### 修复

- 卡片开关写入改用 dsh 官方 `settings.mutate` 操作（此前用 update，可能与客户端远程签名不匹配导致点击不生效）
- 卡片开关语义清晰化：状态文本（已开启/已关闭）+ 动作按钮（关闭/开启），避免“开”是状态还是动作的歧义
- 写入失败时显示错误信息（不再静默吞掉），便于定位

## [0.2.15] - 2026-08-30

### 修复

- 运行时设置改用官方 `ctx.inject(['settings'])` 软依赖访问（此前用 `ctx.settings.register` 直接访问，服务未注入时不可见，导致卡片开关在真实环境不可用）；服务缺失时优雅降级为配置文件模式

## [0.2.14] - 2026-08-29

### 修复

- 运行时设置命名空间惰性注册：settings 服务晚于插件加载启动时，首个请求后自动补注册（此前只在 apply 时尝试一次，真实环境导致卡片开关不可用）
- 服务解析改为非严格 get + 严格 get 双路径

### 测试

- 可靠性测试 128 项（新增 settings 惰性注册 2 项）

## [0.2.13] - 2026-08-29

### 新增

- 隐私保护卡片新增「全面脱敏（姓名/公司/机关）」开关：一键把事实类（姓名/公司/机关）纳入脱敏，涉案金额、日期、案号仍保留
- 本地脱敏对照工具 `npm run mask:preview -- <文件> [--redactFacts]`：输出原文 / 脱敏后（发往云端）/ 还原后三份对照，纯本地不发送数据

## [0.2.12] - 2026-08-29

### 变更

- 移除逐请求的还原诊断日志（定位完成）；保留启动配置摘要与「会话映射为空导致还原跳过」警告

## [0.2.11] - 2026-08-29

### 修复

- 诊断日志写入文件（`<dshHome>/privmask-restore.log`）：启动配置摘要 + 每次请求的还原决策（包装/跳过/映射条数），便于无终端访问时定位

## [0.2.10] - 2026-08-29

### 修复

- 入站还原与请求脱敏路径解耦：即使请求无需脱敏（早退路径），响应流也做占位符还原（原实现在该路径漏掉还原）
- 还原诊断升级：每次请求打印包装/跳过原因（rev 数量或映射为空），定位真实环境问题

### 测试

- 可靠性测试 123 项（新增早退路径还原）

## [0.2.9] - 2026-08-29

### 修复

- 入站还原诊断：当会话映射为空导致还原被跳过时打印原因（定位真实环境中占位符未还原的问题）

## [0.2.8] - 2026-08-29

### 新增

- 运行时设置：插件注册 `privmask` settings 命名空间（dsh-settings，`applies: live`），用户在界面开关后无需重启即生效（引擎重建）
- 隐私保护卡片升级为可交互：总开关 + 姓名/公司/机关/地址/凭据 类别开关，读写 dsh-settings 命名空间并持久化

### 工程化

- 客户端 bundle 构建改为一次性 /tmp 克隆（不修改 dsh 源码树），npm 包仍只携带自包含的构建产物

### 测试

- 可靠性测试 122 项（新增 settings 注册/live 开关 4 项）

## [0.2.7] - 2026-08-29

### 修复

- 客户端模块声明补 `dsh.client.platform: "web"`（缺失会导致 dsh web 启动失败）

## [0.2.6] - 2026-08-29

### 新增

- 浏览器 half（客户端模块）：在 设置 → 插件 注册「隐私保护」卡片，展示 dsh-privmask 启停状态、脱敏范围说明与更新/重启指引；模块由 dsh 的 modules 系统自动发现（`dsh.client` 声明），无需改 dsh 组合

### 工程化

- 客户端 bundle 使用 dsh 的 tsdown client 预设构建（`window.__ModuleLoader__` 格式），仅依赖预加载的 react externals；源码存于 `client-src/`，产物 `lib/client.js` 随 npm 包发布

## [0.2.5] - 2026-08-29

### 修复

- 展示层还原：sessionController 解析改为多路径探测（属性访问/严格 get/非严格 get/根上下文），并输出命中路径与 llm 控制探针——定位真实运行环境中的服务可见性问题

## [0.2.4] - 2026-08-28

### 修复

- 展示层还原补充 `sessionController.control` 流：界面主视图订阅的是 control（host 级实时状态），其 baseline 与 queue 帧中的用户消息同样按会话还原
- 安装诊断日志：成功/失败都会打印一行（定位服务不可用或加载顺序问题）
- 姓名识别补漏：姓氏库新增常见姓（詹/傅/萧/欧/区/柳/苗/康/易/童/路/舒/解/樊/鲁/乐/单等）；2 字姓名后紧跟动词（离婚/起诉/上诉/签订/结婚/借款/抚养/继承/经营等）与「诉」现在视为自然边界——修复「原告詹永飞与被告李丽离婚纠纷」漏检
- 流式 delta 跨分片重组：占位符被网络切成两半时，尾部缓冲跨 delta 还原，流式显示不再残留 `[REDACTED_…` 前缀
- 还原未命中可见性：`restoreMisses` 统计 + 日志，映射被逐出或模型改写占位符时不再静默
- 配置校验：`apply()` 统一走 schema（schemastery 调用式校验），默认值单一来源，`nonTextPolicy` 改为 literal union，非法配置响亮失败、字符串布尔拒绝
- 自定义词表 `customTerms` 与白名单 `preserveValues`：用户可补充当事人姓名/别名/机构简称（精确子串匹配），误报值可标记放行
- 引擎请求上下文线程化：移除共享 `req` 单槽，所有状态经显式 rctx 传递，消除未来异步化时的跨请求串映射隐患
- 性能：H1 阈值收紧（150KB < 1000ms）+ 纯文本快速路径断言；结构化事件缝 `privmask/stats`（emit，消费方异常不影响主链路）

### 工程化

- 单文件拆分为 `lib/rules.js`（规则表/校验器）、`lib/engine.js`（引擎）、`lib/restore.js`（还原工具）、`lib/index.js`（插件接线）
- 测试迁移 `node:test`（结构化报告、退出码语义）；新增版本/载荷兼容矩阵（value 型工具决策、reject、旧版 sessionController、emit 缝）

### 测试

- 可靠性测试 118 项（新增 control 还原、詹姓/离婚/诉边界、Config 校验、词表/白名单、delta 重组、兼容矩阵、emit）

## [0.2.3] - 2026-08-28

### 新增

- 展示层还原：包装 `sessionController.page/follow`，浏览器读取会话时按会话映射还原占位符——界面显示原文（含用户自己的消息），落盘日志保持占位符；`restoreInbound: false` 时关闭

### 测试

- 可靠性测试 103 项（新增展示层还原 page/follow/开关 4 项）

## [0.2.2] - 2026-08-28

### 变更（隐私分类重构）

- `redactFacts` 拆分为 `redactNames` / `redactCompanies` / `redactOrgs` / `redactCaseNumbers` / `redactDob`
- **默认行为变更**：姓名、公司名称、机关/单位名称默认脱敏（能唯一锁定对象的信息）；案号、出生日期默认保留（公开案件标识 / 非唯一信息）

### 新增

- 日志脱敏（方案2）：`agent/pre-step` 改写用户消息、`tools/post-execute` 改写工具结果，两者在写入会话日志前遮罩为占位符；与 `llm/stream` 共用会话映射，编号一致
- `nonTextPolicy: block` 下，图片/文件块在 `agent/pre-step` 直接拒绝步骤（不落盘不上云）
- `tools/ptc-dispatch-log` 落盘遮罩（dsh ≥ 0.1.2）：run_code 子派发的 `tool/code-dispatch` 事件单独走此缝，同样在落盘前遮罩；`block` 策略下以安全标记替换日志副本

### 修复

- 严格模式（`strictUnknown` 默认开）下，嵌套的非普通对象（Buffer/Date/Map/类实例等）不再静默透传，改为拒绝请求，杜绝序列化字节绕过脱敏上云
- 单类别占位符超过内存上限（2000 个）后编号不再复用：改为逐出最旧条目，编号单调递增，保持同会话占位符语义唯一
- 公司识别补充常见大公司：`集团`/`控股`/`事务所` 等强后缀无需地区/行业词佐证，`技术` 等行业词纳入识别
- 姓名识别补充角色词（委托人/证人/鉴定人/经办人等）与「是/为/系」系动词衔接，覆盖「委托人是张三」「法定代表人是张三」等高频句式
- 地址/街道规则左边界把占位符结尾视为汉字，修复公司/机关脱敏开启后第二轮产生新匹配的幂等性破坏
- 入站还原性能：排序每条流只做一次，无占位符的 chunk 快速短路
- 无效的 `nonTextPolicy` 配置现在打印告警（不再静默回退）

### 清理

- 删除姓名排除判断中的死代码（`NAME_EXCLUDE.startsWith`）
- 删除 `redactText` 中重复的 `longTokens` 判断与 `NAME_TAILS` 中已被单字裁剪覆盖的死条目

### 测试

- 可靠性测试 69 → 103 项：新增嵌套非普通对象拦截、编号单调、集团/技术公司识别、方/任姓氏回归、空格/系动词姓名识别、案号/出生日期策略、交叉规则幂等、日志遮罩（pre-step/post-execute/ptc-dispatch-log/映射一致性）、展示层还原（page/follow/开关）

## [0.2.1] - 2026-08-28

### 文档

- 按开源规范重写 README（目录/特性/安装/快速开始/配置/脱敏机制/安全模型/已知限制/测试与 CI/贡献/发布/许可证）
- 修复文档中误入的占位符样式文本
- 新增 CHANGELOG.md；package.json 补齐 repository/homepage/bugs/engines 元数据

## [0.2.0] - 2026-08-28

### 新增

- 类别级脱敏策略：`redactCredentials`（凭据）、`redactAddress`（地址）、`redactFacts`（事实类）
- 律师模式默认：凭据与地址脱敏，事实类（姓名/案号/出生日期/公司/司法机关）保留

### 变更

- **默认行为变更**：事实类默认不再脱敏，保证云端模型可基于真值做金额核算、管辖判断等精确工作；涉案金额本就不脱敏

## [0.1.9] - 2026-08-28

### 新增

- 入站还原 `restoreInbound`（默认开）：云端返回的占位符在本地还原为原值（响应显示、工具执行），下次出站重新脱敏

## [0.1.8] - 2026-08-28

### 新增

- 身份证严格校验开关 `strictId18`（默认开）：仅校验位合法的 18 位号码脱敏；关闭后日期段合理或带「身份证号」上下文的号码也脱敏

> 注：0.1.8 未单独发布，其变更并入 0.2.0。

## [0.1.7] - 2026-08-28

### 修复

- `inject` 声明 `llm` 服务依赖，修复拦截钩子在 llm 服务就绪前静默不注册的问题

## [0.1.6] - 2026-08-28

### 修复

- 声明 `dsh.bundle` 并随包携带 `cordis.patch.yml`，插件真正挂载进 profile 层栈

> 注：0.1.6 未单独发布，其变更并入 0.1.7。

## [0.1.5] - 2026-08-28

### 变更

- 非文本内容默认策略由拒绝改为剥离（`nonTextPolicy: strip`），图片字节不出本地、请求照常处理

## [0.1.4] - 2026-08-28

### 变更

- 图片/文件等非文本块默认拦截（`nonTextPolicy: block`）

> 注：0.1.4 未单独发布，其变更并入 0.1.5。

## [0.1.3] - 2026-08-28

### 新增

- 严格模式默认开启：`failClosed`（脱敏异常拒绝请求）与 `strictUnknown`（未检查字段拒绝请求）

## [0.1.2] - 2026-08-28

### 新增

- 非文本内容策略 `nonTextPolicy`：block / strip / allow

## [0.1.1] - 2026-08-28

### 新增

- 跨请求占位符一致性 `persistMapping`（默认开）：同一会话内同值同号
- `redactToolMeta`：工具描述/参数 schema 脱敏可配置
- AWS 密钥格式识别（`aws_secret_access_key` 等）
- 公司/机关规则动词不吞（查询/委托/向等）

### 修复

- 姓名识别吞字与三字名漏检
- 银行卡上下文规则与 17/18 位防误伤

## [0.1.0] - 2026-08-28

### 新增

- 首个版本：llm/stream 出口拦截、密钥/PII/中文实体脱敏、占位符映射、防误伤、自测脚本
