Skip to content

Releases

v0.3.16

Choose a tag to compare

@github-actions github-actions released this 06 Oct 15:49

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.16

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.16/dsh-rehearsal-0.3.16.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.16.tgz.sha256 校验 / verify with the attached .sha256。)


变更

  • npm 发布通道迁移到 OIDC trusted publishing:publish.yml 不再读取 NPM_TOKEN。npm 已开始限制 bypass-2FA 的 granular token(发布时的官方提示原文:"npm tokens that bypass 2FA are being restricted for account changes and direct publishing"),该 secret 属于被限类别。发布改由 GitHub Actions 的 OIDC 身份直接授权,npm 包侧把 wuwaka/dsh-rehearsal 的 publish.yml 登记为受信发布方;依赖该 secret 的 gate 前置任务一并移除,publish 前升级 npm 以满足 OIDC 客户端要求(≥ 11.5.1)。NPM_TOKEN secret 保留作回退通道——恢复 publish 步骤的 NODE_AUTH_TOKEN 环境变量即可退回。

Changed

  • The npm publishing channel moves to OIDC trusted publishing: publish.yml no longer reads NPM_TOKEN. npm has started restricting bypass-2FA granular tokens (the official notice, verbatim: "npm tokens that bypass 2FA are being restricted for account changes and direct publishing"), and that secret is in the restricted class. Publishing is now authorized directly by GitHub Actions' OIDC identity, with wuwaka/dsh-rehearsal's publish.yml registered as the trusted publisher on the npm package; the gate job that depended on the secret goes with it, and npm is upgraded before publish to satisfy the OIDC client requirement (>= 11.5.1). The NPM_TOKEN secret stays as a fallback — restoring the NODE_AUTH_TOKEN env on the publish step reverts to the old channel.

完整历史 / Full changelog: v0.3.15...v0.3.16

v0.3.15

Choose a tag to compare

@github-actions github-actions released this 06 Oct 12:49

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.15

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.15/dsh-rehearsal-0.3.15.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.15.tgz.sha256 校验 / verify with the attached .sha256。)


变更

  • npm 包内文档与仓库对齐:README 安装 pin 更新到 v0.3.15(0.3.14 包内的 pin 停在 v0.3.13,照抄会把 GitHub tag 安装指到旧版本),安全摘要补上 URL userinfo 凭据剥离;docs/architecture 双语在写回合抑制第 2 层记录 --dump-config fail-closed 前置校验。CHANGELOG 底部链接补齐 0.3.13/0.3.14/0.3.15 三个缺失定义,[Unreleased] compare 区间重置。本版不含代码变更——发布它就是为了这件事。

Changed

  • In-package docs catch up with the repository: the README install pin moves to v0.3.15 (the 0.3.14 package still pinned v0.3.13, pointing tag installs at an older release), the security summary gains the URL-userinfo credential line, and the architecture docs record the --dump-config fail-closed pre-check in suppression layer 2. The changelog's bottom link definitions gain the missing 0.3.13 / 0.3.14 / 0.3.15 entries and the [Unreleased] compare range resets. No code changes in this release — it exists to make that true.

完整历史 / Full changelog: v0.3.14...v0.3.15

v0.3.14

Choose a tag to compare

@github-actions github-actions released this 06 Oct 12:09

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.14

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.14/dsh-rehearsal-0.3.14.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.14.tgz.sha256 校验 / verify with the attached .sha256。)


修复

  • run 期间收到 SIGINT/SIGTERM/SIGBREAK/SIGHUP 不再遗留影子目录:清理此前只依赖 finally 块,而阻塞型 spawnSync 期间到达的信号会直接终止进程——明文会话副本留在磁盘上,正是 SECURITY.md『每条退出路径都会删除』的保证没有覆盖到的那一条。现在信号处理器先删除影子 home(与安装前缀)再退出;此外每次 run 启动时按 ownership 标记清扫遗留的 dsh-rehearsal-home-* 目录(名字相似从不清删,只认本工具的标记)。
  • 写回合对工具抑制改为 fail-closed(src/lib/shadow.js):writeReplayPatch 此前不检查 --dump-config 是否成功,抑制 0 行只体现为一行日志。dump 命令失败、输出解析不出任何行、或请求抑制却匹配到 0 个执行器行时,写路径直接中止——阶段详情报告 replay patch fail-closed (<原因>),不再带着未经验证的执行器继续;coverage.writeRounds.toolSuppression 记录校验结果。
  • 写入补丁的每个 id 都经过 JSON.stringify——disable 行此前裸拼 id,与 P2-7 起就对会话派生行加引号的规则不一致。
  • 环境剥除覆盖 URL 内嵌凭据:http://user:token@host/ 形态的代理与 registry 值此前能穿过名字过滤原样传给子进程。名字过滤保留的值现在会剥掉 userinfo 部分。名字过滤的"误删"方向(AUTH 同时匹配 XAUTHORITY)有意保留——错误方向是给孩子更少,绝不更多;SECURITY.md 的保证措辞已改为与实现精确一致。

变更

  • release.yml 的 tag 改经环境变量传入 shell,不再用 ${{ }} 插值;三个 workflow 的 actions/checkout 与 actions/setup-node 全部按 commit SHA 锁定,persist-credentials: false 让用不到 git 凭据的 job 不再持有驻留凭据。
  • test/fixtures/ 新增 README,说明两个 .asar 是手工构造、仅包裹事实性包清单(名称与版本号)的容器,不含官方应用的任何代码、二进制或素材——再分发疑虑就此了结。回归锁:测试数 129 → 140。

Fixed

  • SIGINT/SIGTERM/SIGBREAK/SIGHUP during run no longer leave the shadow home behind: cleanup used to live only in a finally block, which a signal arriving during a blocking spawnSync outflies — the process died with the plaintext session copies still on disk, the one exit path SECURITY.md's every-exit-path-deletes guarantee did not cover. The signal handler now removes the shadow home (and the prefix) before exiting; in addition, every run sweeps leftover dsh-rehearsal-home-* directories at startup, gated on this tool's ownership marker (a name that merely looks ours never authorises a delete).
  • The write round is fail-closed about tool suppression (src/lib/shadow.js): writeReplayPatch used to parse --dump-config output without checking that the command succeeded, and zero suppressed rows was visible only as a log line. A failed dump, a dump that parses to no rows, or a suppression pass matching zero executor rows now aborts the write path — the stage details report replay patch fail-closed (<reason>) instead of continuing with unverified executors; coverage.writeRounds.toolSuppression records the outcome.
  • Every id written into the replay patch is JSON.stringify'd — disable rows previously interpolated the id bare, inconsistent with the session-derived rows quoted since P2-7.
  • Environment scrubbing covers URL-embedded credentials: a proxy or registry value like http://user:token@host/ used to pass the name filter untouched and reach the child. Values that survive the name filter now have their userinfo stripped. The name filter's over-removal side (AUTH also matches XAUTHORITY) is kept deliberately — the error direction is giving a child less, never more — and SECURITY.md's guarantee now states exactly what is and is not covered.

Changed

  • release.yml passes the tag into the shell through the environment instead of ${{ }} interpolation; all three workflows pin actions/checkout and actions/setup-node by commit SHA, and persist-credentials: false keeps git credentials from standing in jobs that never need them.
  • test/fixtures/ gains a README stating that the two .asar archives are hand-built containers around a factual package manifest (names and versions), holding no code, binary or artwork from the official application — settling the redistribution question. Regression locks: tests 129 → 140.

完整历史 / Full changelog: v0.3.13...v0.3.14

v0.3.13

Choose a tag to compare

@github-actions github-actions released this 05 Oct 08:49

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.13

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.13/dsh-rehearsal-0.3.13.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.13.tgz.sha256 校验 / verify with the attached .sha256。)


修复

  • 候选安装的 npm 过程改在剥除凭据的环境下运行:开启 --run-scripts 时,依赖生命周期脚本此前继承完整宿主环境——授予脚本执行的逃生门顺带重新暴露了宿主凭据。现在与候选运行同规则剥离全部凭据形状变量。
  • CLI 旗标统一到一份契约(src/lib/args.js):每个 --dashed-flag 同时以连字符与 camelCase 两种拼写存储——--shadow-dir、--prefix-dir 与 --skip-write 从命令行传入时此前被静默忽略(解析器存一种拼写、命令代码读另一种)。开关类旗标(--run-scripts、--allow-tools、--keep、--skip-write、--yes、--full)显式接受 =true/=false,其余取值直接报错,且不再吞掉下一个参数——--yes=false 不再被读作"已确认"。
  • clean 的无标记兼容路径改为结构判定:.dsh-rehearsal 布局只有在每个生成子目录携带自己的报告(report.json/report.md)或被中断运行为空目录时才可清理。

变更

  • README 中指向 npm 包外维护者文档(PUBLISHING、AUDIT)的相对链接改为 GitHub 绝对地址,随包 README 不再有失效相对链接。
  • 生产代码注释的最后一批评审/日期残留清除:注释只陈述"为什么必须如此",审计轨迹留在 AUDIT.md 与本文件。回归锁:测试数 125 → 129。

Fixed

  • The npm install of the candidate now runs under a credential-stripped environment: with --run-scripts, dependency lifecycle scripts used to inherit the full parent environment, so the escape hatch that grants script execution also re-exposed host secrets. It now strips every credential-shaped variable, same rule as the candidate's own runs.
  • CLI flags parse under one contract (src/lib/args.js): every --dashed-flag is stored under both its dashed and camelCase spelling — --shadow-dir, --prefix-dir and --skip-write from the command line used to be silently ignored because the parser stored one spelling while the command code read the other. Switches (--run-scripts, --allow-tools, --keep, --skip-write, --yes, --full) accept =true/=false explicitly, reject any other value, and never consume the next argument — --yes=false no longer reads as "confirmed".
  • clean's pre-marker fallback now checks structure, not only naming: a .dsh-rehearsal layout is cleanable only when each generated child carries its report (report.json/report.md) or is an interrupted run's empty directory.

Changed

  • README relative links that pointed at maintainer documents outside the npm tarball (PUBLISHING, AUDIT) are absolute GitHub URLs, so the shipped README has no dead relative links.
  • The last review/date residue in production comments is gone; comments state why a rule holds, the audit trail stays in AUDIT.md and this changelog. Regression locks: test count 125 → 129.

完整历史 / Full changelog: v0.3.12...v0.3.13

v0.3.12

Choose a tag to compare

@github-actions github-actions released this 05 Oct 08:26

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.12

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.12/dsh-rehearsal-0.3.12.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.12.tgz.sha256 校验 / verify with the attached .sha256。)


修复

  • 版本参数在命令边界校验(--candidate/--current/--to):实测 check --candidate nonsense 曾以 exit 0、upgrade-ok 收场——比较根本没执行,结论从零拼出;现在非法版本直接报错(exit 3),且发生在任何安装与产物写入之前。
  • clean 增加 ownership 与危险路径守卫:只删除带本工具标记的产物目录(或旧版默认布局);任意目录、HOME、工作目录、文件系统根即便带 --yes 也一律拒绝。
  • profile-local 运行时标记与桌面描述符同规则三态:存在但不可用(损坏、非 semver)记 untrusted、current 保持未知——不再回落到机器级 bundle 以另一套安装的版本作答。
  • --writeRounds 与 --preset-mode 严格校验(正整数 / skip|patch):非数字预算曾变成 NaN 使上限失效、写回合无界执行;未知模式值曾静默落入默认。
  • 脱敏 invariant 结构化:privacy.redactionGapCount 记录漏网数,扫描覆盖全部字段(含 warnings),gap 警告不再回显泄漏的 token 本身。
  • 单段 POSIX 绝对路径(/tmp、/etc)纳入脱敏与 invariant 检查;“任意 POSIX 绝对路径”现在字面成立。
  • --shadow-dir/--prefix-dir 写入前需 ownership:空目录接管并标记,非空且无标记的目录拒绝使用。

新增

  • npm tarball 边界测试(test/pack.test.js):用户文档随包(SECURITY 双语在内),维护者文档(AUDIT、PUBLISHING、内部方案)被明确排除。
  • dsh-rehearsal --help 现在列出 clean 命令及其 ownership 行为。

变更

  • 生产代码注释改为陈述“为什么必须如此”,不再记录改动出自哪一轮评审;审计轨迹留在 AUDIT.md 与本文件。回归锁:测试数 117 → 125。

Fixed

  • Version-valued options are validated at the command boundary (--candidate, --current, --to): measured, check --candidate nonsense used to exit 0 with upgrade-ok — the comparison never ran and the verdict was assembled from nothing. An invalid version now fails with a readable error (exit 3) before any install or artifact write.
  • clean gained ownership and dangerous-path guards: it removes only artifact directories bearing this tool's marker (or the pre-marker default layout); arbitrary directories, the home, the working directory and filesystem roots are refused even with --yes.
  • Profile-local runtime markers follow the same three-state rule as desktop descriptors: a marker that exists but is unusable (corrupt, non-semver) resolves to untrusted and current stays unknown — it no longer falls through to a machine-level bundle answering with another install's version.
  • --writeRounds and --preset-mode are validated (positive integer / skip|patch): a non-numeric budget used to become NaN, which disabled the cap and let the write round run unbounded; an unknown mode used to fall through to the default silently.
  • The redaction invariant is structured: privacy.redactionGapCount records the surviving-token count, the scan now covers every field (warnings included), and the gap warning no longer echoes the leaked tokens themselves.
  • Single-segment POSIX absolutes (/tmp, /etc) are scrubbed and invariant-checked; "any POSIX absolute path" now holds literally.
  • --shadow-dir / --prefix-dir require ownership before anything is written: empty directories are adopted and marked, non-empty unmarked directories are refused.

Added

  • An npm-tarball boundary test (test/pack.test.js): user documentation ships with the package (SECURITY included, both languages), maintainer documents (AUDIT, PUBLISHING, internal plans) are pinned out.
  • dsh-rehearsal --help now lists the clean command and its ownership behaviour.

Changed

  • Production comments state why a rule must hold instead of which review round introduced it; the audit trail lives in AUDIT.md and this changelog. Regression locks: test count 117 → 125.

完整历史 / Full changelog: v0.3.11...v0.3.12

v0.3.11

Choose a tag to compare

@github-actions github-actions released this 05 Oct 07:49

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.11

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.11/dsh-rehearsal-0.3.11.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.11.tgz.sha256 校验 / verify with the attached .sha256。)


修复

  • 报告脱敏收口(评审第五轮 P1-1/P1-2):home 路径规则此前在空格处截断,C:\Users\John Smith\.dsh 会漏出姓氏,干净 home 路径也会留下整段尾巴(~\AppData\Local\Temp\run-1,均实测);现在 home 字段按字段边界整段归一(干净路径仍归一为 ~,含空格的字段升级为 <abs-path>)。writeReport() 同时改为 fail-closed:invariant 仍发现 path-shaped 文本时拒绝写盘(此前先警告再照写,与"落盘前已脱敏"的承诺相矛盾)。
  • 运行时证据补全(P2-1):描述符存在但校验不过的 untrusted 标记进入 b1 证据的 currentRuntime.untrusted 与 coverage.host.runtimeUntrusted,"current 为什么是 null"可诊断。
  • 非字符串 peer 范围(null、数字、对象)产出 peer-range-unparseable 警告,不再被读作"无约束"(P2-2);真缺席(undefined、空白串)语义不变。
  • 收紧:looksLikeDshHome 要求 dsh.profile.bundles 数组(P2-5);candidate 版本不可读时 adoption-gate 拒绝打补丁而不是猜测备份基准(P2-4);README、--help 与 SECURITY 写明 --shadow-dir/--prefix-dir 不被自动清理、也不归 clean 管(P2-3)。
  • 上述每项修复都带回归锁(测试数 114 → 117):含空格 home 的尾巴、fail-closed 拒写、untrusted 进入报告、带类型的 peer 范围、版本未知时的闸门。

Fixed

  • Report redaction closes its last two gaps (review round 5, P1-1/P1-2): the home-path rules stopped at whitespace, so C:\Users\John Smith\.dsh leaked the surname and even an unspaced home kept everything after it (~\AppData\Local\Temp\run-1 — both measured); home fields now consume to the field boundary with no tail (a clean home still normalises to ~, a spaced field escalates to <abs-path>). And writeReport() is now fail-closed: when the invariant still finds path-shaped text it REFUSES to write (the earlier behaviour warned and wrote the leak anyway, contradicting the sanitised-before-disk promise).
  • Untrusted runtime markers reach the report (P2-1): a descriptor that exists but fails validation is listed under currentRuntime.untrusted in the b1 evidence and coverage.host.runtimeUntrusted, so a null current explains itself.
  • Peer ranges that are not strings (null, numbers, objects) produce the peer-range-unparseable finding instead of reading as "no constraint" (P2-2); truly absent ranges (undefined, blank strings) stay unconstrained.
  • Hardening: looksLikeDshHome requires the dsh.profile.bundles array (P2-5); the adoption-gate patch refuses to run when the candidate version is unreadable rather than guessing which backup is valid (P2-4); README, --help and SECURITY spell out that --shadow-dir / --prefix-dir are never auto-cleaned and are not covered by clean (P2-3).
  • Regression locks for each item above (test count 114 → 117): spaced-home tails, the fail-closed refusal, untrusted propagation into the report, typed peer ranges, and the unknown-version gate.

完整历史 / Full changelog: v0.3.1...v0.3.11

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 05 Oct 06:16

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.1

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.1/dsh-rehearsal-0.3.1.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.1.tgz.sha256 校验 / verify with the attached .sha256。)


修复

  • 桌面 bundle 探针的平台过滤失效:平台门读取的是不含该字段的对象,任何平台上都会探测全部宿主的安装路径(macOS 上会先试 Windows 路径)。现在按条目自身的平台过滤,并有"darwin 下不得泄漏 win32 路径"的回归测试。
  • 官方 macOS 探针多拼一层 resources(Contents/Resources/resources/app.asar),真实布局永远探不到,macOS 用户稳定得到 current = null 与保守高的噪音。探针改为按平台声明档位置(archive),含 darwin 命中与"双拼必须 miss"两组测试。
  • 官方回退探针(档内 dsh/node_modules/@deepseek-ai/dsh/package.json)是死代码:所有 asar 探针都被当描述符解析。探针新增 kind:描述符缺失时回退到档内 package.json;描述符存在但校验不过时保持未知并记入 untrusted——此处回退会绕过描述符的完整性交叉校验。
  • writeReport() 不再把 privacy.scrubbed 当跳过令牌:每次落盘都重新 finalize()。实测缺口:finalize 之后被追加的字段会原样入库,而脱敏标志仍声称干净。
  • 非法 peer 范围不再读作"两侧都不满足"的既有失配:新增 peer-range-unparseable 警告发现项说明真实原因;satisfies 包装的兜底分支返回 false 而不是 true。
  • --home=(空值)报可读错误,不再静默落到自动发现;home 门禁要求 profile manifest 带 harness 的 dsh 字段(无关项目的 package.json 不再算数);--prefix-dir 跨 candidate 复用时 adoption-gate 备份按版本重播种;npm 前缀探测的契约(仅 npm_config_prefix 存在时生效)写进代码与测试。
  • 上述每项修复都带回归锁(测试数 106 → 114):跨平台探针泄漏、darwin 命中与双拼 miss、描述符缺席回退与不可信不回退、finalize 后追加字段、非法 peer 范围、空 --home。

Fixed

  • Desktop bundle probes were not platform-filtered: the gate read a platform field off an object that does not carry one, so every platform probed every host's install paths (on macOS the Windows paths would be attempted first). The gate now filters catalog entries themselves, with a regression test that fails if win32 roots leak under a darwin platform.
  • The official macOS probe joined an extra resources segment (Contents/Resources/resources/app.asar) and could never hit the real Contents/Resources/app.asar layout, leaving macOS users with current = null and conservative-high noise. Probe entries now declare their archive segments per platform, with darwin hit and doubled-path miss tests.
  • The official fallback probe (dsh/node_modules/@deepseek-ai/dsh/package.json inside the archive) was dead code: every asar probe was parsed as a descriptor. Probes now declare a kind: a missing descriptor falls back to the in-archive package.json, while a descriptor that exists but fails validation stays unknown and is listed under untrusted — falling back there would bypass the descriptor's integrity cross-check.
  • writeReport() no longer treats privacy.scrubbed as a skip token: it re-runs finalize() on every write. Measured gap: a field appended after a previous finalize reached disk unscrubbed while the flag still claimed clean.
  • Unparseable peer ranges no longer read as a settled "excluded by both versions": a dedicated peer-range-unparseable warn finding says what is actually wrong, and the satisfies wrapper returns false on its belt-and-braces path instead of true.
  • --home= (blank) now fails with a readable error instead of silently falling through to auto-discovery; the home gate requires the harness dsh field in a profile manifest (an unrelated project's package.json no longer qualifies); the adoption-gate backup re-seeds when a reused --prefix-dir gets a different candidate version; the npm-prefix probe's contract (only when npm_config_prefix is present) is stated in code and tests.
  • Regression locks for each fix above (test count 106 → 114): cross-platform probe leakage, the darwin hit and the doubled-path miss, descriptor-absent fallback versus untrusted no-fallback, post-finalize mutation, unparseable peer ranges, and a blank --home.

完整历史 / Full changelog: v0.3.0...v0.3.1

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 05 Oct 03:54

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.3.0

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.3.0/dsh-rehearsal-0.3.0.tgz
(用本 Release 附带的 dsh-rehearsal-0.3.0.tgz.sha256 校验 / verify with the attached .sha256。)


新增

  • 桌面宿主兼容:check 与 run 无需 --home 即可发现官方 DeepSeek Harness Desktop 与社区桌面(anywhere-labs DSH Desktop、dataelement DSHDesktop)的 home——--home 与 DSH_HOME 缺省、默认 home 不存在或不是真实数据时,按登记顺序逐宿主探测并验证(必须存在 profile manifest 或真实会话日志);报告以 target.homeOrigin 标签记录来源,不写路径。
  • 版本探测走探测表:官方运行时整树在 resources/app.asar 档内,由零依赖只读读取器读取 dsh/desktop-runtime.json(sharedPackages 为数组,取 @deepseek-ai/dsh 条目并与 release.version 交叉校验);桌面来源的 home 只信自己宿主的内置运行时,共享 home 上多宿主版本冲突返回 null 并以 currentAmbiguous 列出各宿主的版本,npm 全局前缀只在其他来源全部落空时参与。
  • 桌面来源的 run 预演附带范围警告与 coverage.host(desktopRuntimeTested: false):判定覆盖 npm 依赖闭包与会话数据格式,不覆盖桌面应用自身的更新通道;纯桌面歧义(无有效默认 home 且 ≥2 个桌面 home 验证通过)时 run 要求显式 --home,check 全自动。
  • 发现、探测与范围判定附带 25 条回归锁:从探测表顺序漂移锁定、真实工具生成的 asar 夹具,到双宿主版本冲突用例(测试数 81 → 106)。

Added

  • Desktop-host compatibility: check and run discover the homes of the official DeepSeek Harness Desktop and community desktops (anywhere-labs DSH Desktop, dataelement DSHDesktop) without --home — when neither --home nor DSH_HOME is set and the default home is absent or not a real home, catalog candidates are probed and validated in registered order (a profile manifest or real session logs must exist); reports record the origin as a target.homeOrigin label, never a path.
  • Version detection goes through the catalog: the official runtime lives inside resources/app.asar, read by a zero-dependency read-only asar reader from dsh/desktop-runtime.json (the sharedPackages array is searched for @deepseek-ai/dsh and cross-checked against release.version); a desktop-origin home trusts only its own host's bundle, conflicting bundled versions on a shared home resolve to null with the contenders listed as currentAmbiguous, and the npm global prefix only fills in when every other source misses.
  • Desktop-sourced run rehearsals carry a scoping warning and a coverage.host block (desktopRuntimeTested: false): verdicts cover the npm dependency closure and the session data format, not the desktop app's own update channel; with pure-desktop ambiguity (no valid default home and ≥2 validating desktop homes) run demands an explicit --home, while check proceeds automatically.
  • Discovery, probing and scoping come with 25 regression locks, from the catalog order drift-lock to a real-tool asar fixture and a dual-host version-conflict case (test count 81 → 106).

完整历史 / Full changelog: v0.2.2...v0.3.0

v0.2.2

Choose a tag to compare

@github-actions github-actions released this 04 Oct 16:10

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.2.2

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.2.2/dsh-rehearsal-0.2.2.tgz
(用本 Release 附带的 dsh-rehearsal-0.2.2.tgz.sha256 校验 / verify with the attached .sha256。)


文档、徽章与安装元数据,外加一处内部常量收敛。check 与 run 的行为没有任何改动。

变更

  • 假设的模型上下文窗口 256000 从两处魔数(extractRoutes 造默认模型条目、影子 settings 序列化的兜底)收敛为 util.js 的命名常量 ASSUMED_CONTEXT_WINDOW_TOKENS,并加回归锁:该字面量只允许出现在常量定义处(测试数 80 → 81)。
  • SECURITY.md 补充工具抑制名单(TOOL_ROW_NAME_PREFIXES)的失效方向:名单缺了新工具家族只会让抑制不完整,不构成放行路径——写回合只回放会话录制中出现且全部通过只读白名单的调用,--allow-tools 默认关闭仍是最外层闸门。引用断言同步加入文档测试。
  • README 首屏正面陈述核心差异:迁移成功不等于写回(含"读侧静态检查无法判定该类损坏"的依据,
    及七个同类工具逐项对照的链接);新增「为什么是独立 CLI,而不是插件」;使用场景由反问改为直陈;
    删除硬编码的测试数;report 与 clean 两个命令显名。
  • SECURITY.md 同一边界只说一次:删除重复段落与拟人表述。PUBLISHING.md 收敛为发布操作手册,
    维护者知识(目录投稿调查、仓库图片、文档治理、新增签名的步骤)移入新增的 docs/MAINTAINING.md;
    docs/FAILURE_MODES.md 的「新增一条签名」一并移入,正文收敛为纯 reference。
  • README 安装节增加 npm registry 路径(dsh-rehearsal@0.2.1 已于 2026-10-03 发布);徽章区新增
    npm 版本徽章与 listed in awesome-deepseek-harness 收录徽章(Dominic789654/awesome-deepseek-harness#579 已合并)。
  • npm keywords 移除 dsh-plugin,与 GitHub topics 的口径对齐(生态反爬虫清单会剔除蹭该标签的非插件)。

Documentation, badges and install metadata, plus one internal constant consolidation. The behaviour of check and run is unchanged.

Changed

  • The assumed model context window 256000 is consolidated from two magic literals (the default entry in extractRoutes and the fallback in the shadow settings serializer) into one named constant, ASSUMED_CONTEXT_WINDOW_TOKENS in util.js, with a regression lock: the literal is allowed only at the constant's definition (test count 80 → 81).
  • SECURITY.md now states the failure direction of the tool-suppression list (TOOL_ROW_NAME_PREFIXES): a list missing a new tool family leaves suppression incomplete but opens no execution path — the write round only replays tool calls that appear in the session's own recording and all passed the read-only allowlist, and --allow-tools (off by default) remains the outermost gate. A citation assertion backs it in the docs test.
  • The README states its differentiators up front: a successful migration does not prove write-back (with the reason read-side static checks cannot decide this class, and a link to the seven-tool comparison); a new "why a standalone CLI" section; use-case questions rewritten as statements; the hard-coded test count removed; report and clean named.
  • SECURITY.md states each boundary once: duplicate paragraphs and anthropomorphic phrasing removed. PUBLISHING.md is narrowed to the release runbook, with maintainer knowledge (the catalogue investigation, repository images, documentation governance, the add-a-signature procedure) moved into the new docs/MAINTAINING.md; the procedure moved out of docs/FAILURE_MODES.md, which is now pure reference.
  • The install section gains the npm registry path (dsh-rehearsal@0.2.1 was published on 2026-10-03); the badge row gains the npm version badge and a listed in awesome-deepseek-harness badge (Dominic789654/awesome-deepseek-harness#579 merged).
  • The npm keywords drop dsh-plugin, aligning with the GitHub topics convention (anti-spam crawlers strip non-plugins carrying that tag).

完整历史 / Full changelog: v0.2.1...v0.2.2

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 03 Oct 06:25

安装 · Install

npm install -g github:wuwaka/dsh-rehearsal#v0.2.1

也可锁定到字节 / or pinned to bytes: npm install -g https://github.com/wuwaka/dsh-rehearsal/releases/download/v0.2.1/dsh-rehearsal-0.2.1.tgz
(用本 Release 附带的 dsh-rehearsal-0.2.1.tgz.sha256 校验 / verify with the attached .sha256。)


文档与发布可核验性。check 与 run 的行为没有任何改动。

变更

  • README 从 247 行压到约 130 行:只保留定位、安装、快速开始、真实输出示例、报告、覆盖范围、
    安全摘要、兼容性、限制。移出的内容进入新增的 docs/architecture.md。
  • 首页不再承担"为什么值得存在"的论证:外部 CLI 的理由、与同类工具的分工表、写回合三层抑制的
    实现细节、多帧 zstd 的测量数字,全部下沉到 architecture 与 SECURITY。
  • 新增一句核心边界:迁移成功不等于迁移后的会话还能写回。
  • "全程无需 API 键"改为准确表述:写回合走 @deepseek-ai/dsh-llm-replay 的录制回放路径,
    不发起真实模型请求。
  • 术语统一:预检 / 预演 / 迁移 / 写回(pre-flight / rehearsal / migration / write round);
    状态词统一为 Tested / Inferred / Not tested / Unsupported / Not covered。
  • 删除"由报告自证""逐条核对对方源码"这类审计腔措辞。
  • SECURITY.md 重排为:代码保证 / 显式危险选项 / 报告是敏感数据 / 范围之外 / 自查方法 / 上报方式。
  • AUDIT.md 标注为历史基线文档(基线 7c374bc),新增逐条状态总览表;FIXES.md 并入其
    "修复与验证"一节后删除,避免与 AUDIT / CHANGELOG / git 历史三处重复。
  • PUBLISHING.md 改为清单优先,事故叙述移出。
  • 全部文档双语对;test/docs.test.js 断言对开存在、小节数一致、file:line 引用与 issue 号与
    提交哈希集合一致、语言切换行指向真实文件、无第一人称(测试数 61 → 68)。
  • 新增仓库海报 assets/poster.jpg 与 assets/social-preview.jpg。

修复

  • a-inventory 的 details 原先把 DSH_HOME 原值拼进字符串,靠 finalize() 的正则遮罩。该正则识别
    C:\Users\<n>、/home/<n>、/Users/<n> 与任意盘符路径,但相对路径、UNC 共享、以及
    /srv/users/<n> 这类非标准 Unix 家目录会原样进入报告
    (A/B 实测:修复前 home=dsh-home 泄漏,
    修复后为 home=custom)。该字段改为只写形状,路径不再进入字符串。

  • report.tool.version 硬编码为 0.1.0,已与 package.json 脱节;现改为从 package.json 读取。

  • 回归锁:homeShape 的返回值不得含路径分隔符;端到端用相对 --home 跑 check,断言该路径
    不出现在报告任何位置(测试数 68 → 70)。

  • 上一条只是让 home 这一个调用点不再经过滤器,scrubText 本身的缺口仍在:/root/.dsh(容器与
    root 运行时的默认家目录)、/var/lib/<服务名>、/srv/<团队>、/tmp/<影子目录>、UNC 共享与 ../
    相对路径全部原样穿过。本轮按类修:过滤器补齐这些形状(URL 与仓库相对路径各有测试保证不被误遮);
    scrubValue 原先只清值不清键,以路径作键会整体绕过,现已一并清;finalize() 增加不变量,用同一
    检测器复扫完整报告,任何漏网的 path-shaped 文本写入 warnings[](redaction gap: …),于是将来新
    阶段拼出新式路径时报告自己承认,而不是安静发布。测试数 70 → 73。

  • privacy.scrubbed: true 原先写在 newReport() 里,等于构造时就宣称已脱敏;而 redaction-gap
    不变量在 finalize() 内部,所以"某阶段绕过 finalize()"这一场景并未被覆盖(评审指出,判断正确)。
    现在该字段由 finalize() 依据不变量结果写入:没扫干净就是 false。同时新增 writeReport()
    作为唯一落盘入口,未 finalize 的报告会被就地补做,绕不过去。

  • check 不带 --candidate 时,0 newly-broken high 是空转出来的数字却按结果呈现。现在该阶段判
    warn、details 写明"comparison NOT exercised"、并写入一条 warnings[],退出码为 1 而非 0。

  • defaultHome() 在 USERPROFILE 与 HOME 同时缺失时(裸容器)会走到
    path.join(undefined, '.dsh') 抛 TypeError;现回退到 os.homedir() 再到 cwd,不再抛。
    顺带修掉一处同源漂移:homeShape() 自己重算默认位置,与加固后的 defaultHome() 得出不同结果,
    会把真实默认值判成 custom;现由调用方传入单一事实源。测试数 73 → 78。

  • 文档里的行号引用会随代码移动而失效,且此前不可检测。本轮修掉四处真实失效:SECURITY 引用的
    src/lib/report.js 的第 136 行在 finalize() 上移后指向无关代码(实为第 199 行);作为"不该被误遮"示例写出的 src/lib/x.js(第 12 行)指向不存在的文件;docs/FAILURE_MODES 里 src/lib/drill.js 的第 311-313 行差一行
    (应为 312-314);指向 gating-hub 第 875 行的那条外部引用与本仓库自己的同名文件撞名,读者无从分辨归属,现已带上 owner 前缀。

  • 新增两条断言(测试数 78 → 80):活文档引用的每个仓内路径必须存在、外部引用必须在同一行标明归属;
    每个仓内 file:line 引用都必须配一条"该行确实写着被引用的东西"的断言,没有断言的新引用会让测试失败。
    AUDIT.md 有意排除——它描述的是自己声明的基线提交,拿 HEAD 去断言它的行号会在两个方向上出错。


Documentation and release verifiability. The behaviour of check and run is unchanged.

Changed

  • The README was cut from 247 lines to roughly 130, keeping only positioning, install, quick start, a real output sample, reports, coverage, a safety summary, compatibility and limitations. Everything moved out went into the new docs/architecture.md.
  • The front page no longer argues for its own existence: the external-CLI rationale, the comparable-tools table, the three-layer write-round internals and the multi-frame zstd measurements now live in the architecture and security documents.
  • Added the boundary the whole tool turns on: a successful migration does not prove the migrated session can still be written to.
  • "No API key required" was made precise: the write round replays through @deepseek-ai/dsh-llm-replay and issues no live model request.
  • Terminology unified (pre-flight / rehearsal / migration / write round); status vocabulary fixed to Tested / Inferred / Not tested / Unsupported / Not covered.
  • Removed audit-voice phrasing such as "self-evidenced by the report" and "verified line by line against their source".
  • SECURITY.md restructured into: guarantees, explicitly dangerous options, reports are sensitive data, out of scope, self-check procedure, reporting.
  • AUDIT.md is now marked as a historical baseline document (baseline 7c374bc) with a per-finding status overview; FIXES.md was folded into it as a remediation section and deleted, removing the overlap with AUDIT, this changelog and git history.
  • PUBLISHING.md became a checklist first, with the incident narrative moved out.
  • Every document is a bilingual pair. test/docs.test.js asserts the pair exists, section counts match, file:line citations, issue numbers and commit hashes agree, language switch lines resolve, and no document drifts back into first person (test count 61 → 68).
  • Added repository images assets/poster.jpg and assets/social-preview.jpg.

Fixed

  • The a-inventory details string interpolated the raw DSH_HOME and relied on the finalize()
    regexes to mask it. Those regexes cover C:\Users\<n>, /home/<n>, /Users/<n> and any
    drive-rooted path, but a relative --home, a UNC share, or a Unix home outside /home such as
    /srv/users/<n> reached the report verbatim
    (measured A/B: home=dsh-home leaked before the
    change, home=custom after). The field now records a shape, so no path enters the string.

  • report.tool.version was hard-coded to 0.1.0 and had drifted from package.json; it is now read
    from package.json.

  • Regression locks: homeShape must never return a value containing a path separator, and an
    end-to-end check with a relative --home asserts that the path appears nowhere in the report
    (test count 68 → 70).

  • The change above only kept one call site away from the filter; the gap in scrubText itself
    remained. /root/.dsh (the default home for root, and the normal case in containers),
    /var/lib/<service>, /srv/<team>, /tmp/<shadow>, UNC shares and ../ relative paths all passed
    through untouched. Fixed as a class this time: the filter now covers those shapes, with tests
    pinning that URLs and repository-relative text are not over-masked; scrubValue redacted values but
    not object keys, so a path used as a key bypassed redaction entirely and now does not; and
    finalize() gained an invariant that re-scans the whole report with the same detector and records
    any surviving path-shaped text in warnings[] (redaction gap: …), so a future stage that composes
    an unknown style admits it instead of publishing the path silently (test count 70 → 73).

  • privacy.scrubbed: true was set in newReport(), i.e. the report claimed to be scrubbed at
    construction time. The redaction-gap invariant lives inside finalize(), so the scenario raised in
    review — a stage that bypasses finalize() — was not covered by it. The field is now written by
    finalize() from the invariant's own result, so a report that did not fully pass reports false,
    and writeReport() became the single writer that finalizes an un-finalized report on the way to disk.

  • check without --candidate printed 0 newly-broken high as if it were a result. That number is
    now labelled: the stage reports warn, its details say the comparison was not exercised, a
    warnings[] entry says the same, and the exit code is 1 rather than 0.

  • defaultHome() reached path.join(undefined, '.dsh') when both USERPROFILE and HOME are absent
    (a bare container), throwing a raw TypeError; it now falls back to os.homedir() and then the
    working directory. Fixing it exposed a drift in the same area: homeShape() recomputed the default
    location itself and disagreed with the hardened defaultHome(), labelling a genuine default as
    custom; the caller now passes one source of truth in (test count 73 → 78).

  • Line citations in documentation go stale as code moves, and until now nothing could detect it.
    Four real failures fixed this round: SECURITY pointed at line 136 of src/lib/report.js, which was
    unrelated code after finalize() moved (it sits at line 199 now); the "must not be over-masked"
    example was written as line 12 of src/lib/x.js, a file that does not exist; the
    docs/FAILURE_MODES range on src/lib/drill.js was 311-313, off by one (312-314); and a citation of
    line 875 of the gating-hub changelog collided with the repository's own file of that name, so it now
    carries the dsh-plugin-gating-hub/ owner prefix.

  • Two assertions added (test count 78 → 80): every path cited by a living document must either exist
    in this repository or be qualified with its owner on the same line, and every in-repo file:line
    citation must be backed by an assertion that the cited line really contains what the docs claim it
    for — a new unasserted citation fails the suite rather than drifting silently. AUDIT.md is
    deliberately excluded: it describes the baseline commit it names, so checking its numbers against
    HEAD would be wrong in both directions.


完整历史 / Full changelog: v0.2.0...v0.2.1