dsh-completion-guard 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  # Session activation migration / 会话启用模式迁移
2
2
 
3
- 0.9.0 makes `always` the default for **new unseeded root sessions**. It preserves each old session's pre-upgrade effective mode using a write-once private binding. Mode is independent of `standard` policy, execution/publication authority and completion certificates. Empty old sessions belong in the inventory too. Recorded off/on continues to control enablement; neither configuration nor adoption re-signs history.
3
+ This guide covers upgrades to **0.11.0**, including upgrades from **0.10.0** and earlier supported lines. Since 0.9.0, `always` has been the default for **new unseeded root sessions**. A write-once private binding preserves each old session's pre-upgrade effective mode. Mode is independent of `standard` policy, execution/publication authority and completion certificates. Empty old sessions belong in the inventory too. Recorded off/on continues to control enablement; neither configuration nor adoption re-signs history.
4
4
 
5
- 0.9.0 将**新建无继承根会话**的默认模式改为 `always`,旧会话通过不可覆盖私有绑定保留升级前有效模式。模式独立于 `standard` 策略、执行与发布权限及完成证书。旧空会话也必须清点,已记录的 off/on 继续控制启用状态;配置及 adoption 都不重签历史。
5
+ 本指南用于升级到 **0.11.0**,包括从 **0.10.0** 及更早支持线升级。自 0.9.0 起,**新建无继承根会话**的默认模式为 `always`,旧会话通过不可覆盖私有绑定保留升级前有效模式。模式独立于 `standard` 策略、执行与发布权限及完成证书。旧空会话也必须清点,已记录的 off/on 继续控制启用状态;配置及 adoption 都不重签历史。
6
6
 
7
7
  ## Prepare before changing the installed version / 升级前准备
8
8
 
@@ -10,16 +10,16 @@ Stop the relevant Web, Headless and Desktop session writers. Preserve their inst
10
10
 
11
11
  先停止相关 Web、Headless、Desktop 会话写者,在升级前保留旧安装包身份及有效配置回读。可从独立准备的候选工具目录运行新工具,此时旧 Guard 仍安装在原位。不能把升级后的新缺省当作旧模式,不得在回读中包含凭据或会话正文。
12
12
 
13
- Prepare an operator-owned JSON file in the following format. `previousPackage.sha256` identifies the preserved old package bytes; `sourceSha256` hashes the relevant sanitized, pre-upgrade source readback. Cohort names describe that verified source. If all relevant cohorts have one known mode, that uniform mode can cover the inventory. If modes differ, each session needs an explicit `sessionIds` mapping based on verified old provenance; absent or contradictory mappings stay `pending`. Profile paths, dates, event counts and `on` markers cannot supply that mapping. A checksum checks integrity; it is not an issuer signature or proof that an operator's asserted mapping is correct.
13
+ Prepare an operator-owned JSON file in the following format. `previousPackage.sha256` identifies the preserved old package bytes; `sourceSha256` hashes the relevant sanitized, pre-upgrade source readback. Cohort names describe that verified source. If all relevant cohorts have one known mode, that uniform mode can cover the inventory. If modes differ, each session needs an explicit `sessionIds` mapping based on verified old provenance; absent or contradictory mappings stay `pending`. Profile paths, dates, event counts and `on` markers cannot supply that mapping. A checksum checks integrity; it is not an issuer signature or proof that an operator's asserted mapping is correct. Use the verified old mode in the example; package version alone does not establish whether it is `opt-in` or `always`.
14
14
 
15
- 准备以下格式的操作者 JSON 文件。包摘要指向保留的旧包字节,来源摘要指向相关的脱敏升级前回读。来源组名描述已核验来源。所有相关来源模式一致时可覆盖库存;模式不同则必须提供基于已核验旧来源的 `sessionIds` 映射,缺失或冲突保持 `pending`。不能用 profile 路径、日期、事件数量或 on 标记替代来源映射。摘要核验完整性,不是发行签名,也不能证明操作者的映射断言正确。
15
+ 准备以下格式的操作者 JSON 文件。包摘要指向保留的旧包字节,来源摘要指向相关的脱敏升级前回读。来源组名描述已核验来源。所有相关来源模式一致时可覆盖库存;模式不同则必须提供基于已核验旧来源的 `sessionIds` 映射,缺失或冲突保持 `pending`。不能用 profile 路径、日期、事件数量或 on 标记替代来源映射。摘要核验完整性,不是发行签名,也不能证明操作者的映射断言正确。示例中的 `opt-in` 应按已核验的旧模式填写,不能仅按包版本判断。
16
16
 
17
17
  ```json
18
18
  {
19
19
  "schema": "dsh-activation-prior-modes/v1",
20
20
  "previousPackage": {
21
21
  "name": "dsh-completion-guard",
22
- "version": "0.8.4",
22
+ "version": "0.9.0",
23
23
  "sha256": "<64 lowercase hex characters>"
24
24
  },
25
25
  "sourceSha256": "<64 lowercase hex characters>",
@@ -27,6 +27,10 @@ Prepare an operator-owned JSON file in the following format. `previousPackage.sh
27
27
  }
28
28
  ```
29
29
 
30
+ The 0.11.0 toolkit accepts verified prior-mode records for predecessor versions `0.0.x`–`0.10.x`, including `0.10.0`. It refuses `0.11.0` as a prior package.
31
+
32
+ 0.11.0 工具接受前驱版本 `0.0.x`–`0.10.x` 的已核验旧模式来源,包括 `0.10.0`;不能把 `0.11.0` 本身作为旧包。
33
+
30
34
  ## Official old-format refusals and an explicit readable subset / 官方旧格式拒绝与显式可读子集
31
35
 
32
36
  The official persistence reader may reject an older session with `SessionFormatUnsupportedError`. This names a host format-support boundary; it does not by itself prove corruption or a Guard regression. Do not delete, rewrite, rename or repair the raw log to force acceptance. Preserve it, the old package and its verified effective-mode source. `inventory` can record this **specific official open refusal** as pending. Other failures (corruption, permissions, missing files, unknown errors, list/stat failure or drift) abort; they are not automatically skipped. Default `inspect/adopt/verify` still requires the whole inventory to be readable.
@@ -91,16 +95,16 @@ When a later official host supports the pending format, use its **read-only** pe
91
95
 
92
96
  ### Copyable migration prompts / 可复制迁移提示词
93
97
 
94
- > Help me migrate session activation to DSH Completion Guard 0.9.0. Lifecycle constraint: [fill in which writers may be stopped and whether restart is allowed]. Reuse scope, write and lifecycle authorization already supplied in this conversation; ask only for missing or materially changed decisions. First report the current host/persistence/compression settings, preserved 0.8.x package identity and sanitized pre-upgrade effective-mode sources. If they cannot be verified, keep affected sessions pending. Do not replace packages, stop/restart processes or write bindings before that lifecycle and mutation authority is established. Run the packaged read-only inventory command; show total/readable/official-format-refused counts and a local pending report. Use my existing explicit selection, or ask me to choose the included scope if none was supplied; do not silently expand it or treat readability alone as authorization. Bind that explicit selection through inspect/adopt/verify, detect all inventory changes, preserve raw logs and old sources, and never infer modes/origin/cuts from paths, dates or event counts. No log bodies, credentials or private IDs leave my machine. Once the scope and writes are covered by my authorization, adopt, repeat to check no-op, and verify; report selected completion and remaining pending separately. For unsupported rows, give the future official-reader/re-inventory/source-validation route; without a recoverable source, keep pending or use a new session. Do not treat old certificates as new authority.
98
+ > Help me migrate session activation to DSH Completion Guard 0.11.0. Lifecycle constraint: [fill in which writers may be stopped and whether restart is allowed]. Reuse scope, write and lifecycle authorization already supplied in this conversation; ask only for missing or materially changed decisions. First report the current host/persistence/compression settings, preserved predecessor package identity (for example 0.9.0) and sanitized pre-upgrade effective-mode sources. If they cannot be verified, keep affected sessions pending. Do not replace packages, stop/restart processes or write bindings before that lifecycle and mutation authority is established. Run the packaged read-only inventory command; show total/readable/official-format-refused counts and a local pending report. Use my existing explicit selection, or ask me to choose the included scope if none was supplied; do not silently expand it or treat readability alone as authorization. Bind that explicit selection through inspect/adopt/verify, detect all inventory changes, preserve raw logs and old sources, and never infer modes/origin/cuts from paths, dates or event counts. No log bodies, credentials or private IDs leave my machine. Once the scope and writes are covered by my authorization, adopt, repeat to check no-op, and verify; report selected completion and remaining pending separately. For unsupported rows, give the future official-reader/re-inventory/source-validation route; without a recoverable source, keep pending or use a new session. Do not treat old certificates as new authority.
95
99
 
96
- > 帮我迁移到 DSH Completion Guard 0.9.0 的会话启用模式。生命周期约束:[填写允许停止的写者及是否允许重启]。沿用本会话已给出的范围、写入及生命周期授权,仅询问缺失或实质变化的决定。先报告现有宿主、持久化目录/压缩配置、保留的 0.8.x 包身份及脱敏的升级前有效模式来源;不能核验就将受影响会话保持 pending。取得明确生命周期和写入权限前,不替换包、不停/重启进程、不写绑定。运行打包工具的只读 inventory,报告总数/可读/官方格式拒绝数量并保存本地 pending 报告;沿用我已明确选择的范围,尚未选择时再请我决定;不静默扩大范围,也不把可读性本身当作授权。让显式 selection 贯穿 inspect/adopt/verify,检测全部库存变化,保留原日志和旧来源,不按路径、日期、事件数猜模式/origin/cut。正文、凭据、私有 ID 不离开本机。范围和写入已有授权覆盖后 adopt、重复检查 no-op,再 verify,分别报告选中行完成及剩余 pending。被拒绝项给出未来官方读取器支持后重盘点、核验身份/旧来源的方案;没有可恢复来源就保留 pending 或改用新会话。旧证书不当作新权限。
100
+ > 帮我迁移到 DSH Completion Guard 0.11.0 的会话启用模式。生命周期约束:[填写允许停止的写者及是否允许重启]。沿用本会话已给出的范围、写入及生命周期授权,仅询问缺失或实质变化的决定。先报告现有宿主、持久化目录/压缩配置、保留的前驱包(如 0.9.0)身份及脱敏的升级前有效模式来源;不能核验就将受影响会话保持 pending。取得明确生命周期和写入权限前,不替换包、不停/重启进程、不写绑定。运行打包工具的只读 inventory,报告总数/可读/官方格式拒绝数量并保存本地 pending 报告;沿用我已明确选择的范围,尚未选择时再请我决定;不静默扩大范围,也不把可读性本身当作授权。让显式 selection 贯穿 inspect/adopt/verify,检测全部库存变化,保留原日志和旧来源,不按路径、日期、事件数猜模式/origin/cut。正文、凭据、私有 ID 不离开本机。范围和写入已有授权覆盖后 adopt、重复检查 no-op,再 verify,分别报告选中行完成及剩余 pending。被拒绝项给出未来官方读取器支持后重盘点、核验身份/旧来源的方案;没有可恢复来源就保留 pending 或改用新会话。旧证书不当作新权限。
97
101
 
98
102
 
99
103
  ## Full-inventory inspect, adopt, verify / 整库清点、采纳、核验
100
104
 
101
- The entry `node /absolute/prepared-package/bin/dsh-completion-guard-activation.mjs` below uses the independently prepared 0.9.0 toolkit; it does not assume a new command is installed on PATH while the old Guard remains installed. The tool mounts only the official JSONL persistence service, without starting the agent loop, UI or model. `--runtime-anchor` is a file in the physical official runtime; the tool resolves its real path before loading dependencies. `--persistence-root` and optional `--compression none|zstd` must match the active persistence configuration. No storage path or encoding is guessed. Inspection uses public `list`, read-only `open`, exact header/inherited-cut metadata and revision readback; it outputs no event bodies. Keep writers stopped through the sequence.
105
+ The entry `node /absolute/prepared-package/bin/dsh-completion-guard-activation.mjs` below uses the independently prepared 0.11.0 toolkit; it does not assume a new command is installed on PATH while the old Guard remains installed. The tool mounts only the official JSONL persistence service, without starting the agent loop, UI or model. `--runtime-anchor` is a file in the physical official runtime; the tool resolves its real path before loading dependencies. `--persistence-root` and optional `--compression none|zstd` must match the active persistence configuration. No storage path or encoding is guessed. Inspection uses public `list`, read-only `open`, exact header/inherited-cut metadata and revision readback; it outputs no event bodies. Keep writers stopped through the sequence.
102
106
 
103
- 下方使用独立准备的 0.9.0 工具入口 `node /absolute/prepared-package/bin/dsh-completion-guard-activation.mjs`,不假定旧 Guard 仍安装时新命令已在 PATH。工具只挂载官方 JSONL persistence 服务,不启动 agent loop、界面或模型。runtime anchor 必须是官方 runtime 中的文件,加载依赖前先解析物理路径。持久目录及可选压缩格式必须匹配实际配置,不推测目录或编码。清点使用公开 list、只读 open、精确 header/cut 元数据及 revision 回读,不输出事件正文。整个操作期间保持写者停止。
107
+ 下方使用独立准备的 0.11.0 工具入口 `node /absolute/prepared-package/bin/dsh-completion-guard-activation.mjs`,不假定旧 Guard 仍安装时新命令已在 PATH。工具只挂载官方 JSONL persistence 服务,不启动 agent loop、界面或模型。runtime anchor 必须是官方 runtime 中的文件,加载依赖前先解析物理路径。持久目录及可选压缩格式必须匹配实际配置,不推测目录或编码。清点使用公开 list、只读 open、精确 header/cut 元数据及 revision 回读,不输出事件正文。整个操作期间保持写者停止。
104
108
 
105
109
  The following example is for a POSIX shell. Run `inspect` before replacement; run `adopt` and `verify` before starting the upgraded host. Keep the prepared toolkit path explicit throughout.
106
110
 
@@ -140,9 +144,13 @@ Missing/corrupt/changed records invalidate cached projections and certification.
140
144
 
141
145
  缺失、损坏或变化的记录使缓存投影和认证失效。根据具名原因诊断,再使用保留且已核验的收据采纳同一缺失旧身份与模式。损坏或冲突的 final 拒绝自动修复,请保留诊断;无可信旧来源时保持 unknown,在新合格会话中建立新工作。不删除历史,也不触发无穷纠正。fork 需核验父绑定并继承父模式;精确 cut 由官方 Session/persistence 合同提供及验证,不由前缀长度推断模式。
142
146
 
143
- A fresh 0.9.0 creation that leaves `.pending` has no general recovery command in this toolkit. `inspect` accepts preserved pre-0.9.0 sources, and `adopt` requires a verified legacy migration receipt; neither permits inventing such a receipt for a fresh creation. Without an existing trusted legacy receipt, keep the mode unknown, diagnose the retained state, or continue new work in another qualified fresh session. The exported same-value writer is a programmatic controlled recovery primitive, not an operator CLI. Do not delete `.pending` merely to make the final readable.
147
+ A qualified fresh creation that lost a brief writer-lock race now retries itself: the runtime re-attempts the SAME creation, while the startup intent is still provable, for a bounded budget (at most 8 attempts within 60 seconds of attach), and then reports the explicit `activation_writer_unavailable` status. The retry is idempotent (same-value) and never applies to a session that was ever successfully created, to resume/late attach, or to a deleted binding — those keep the unknown/diagnosis rules below. This automatic retry is not a recovery command and does not need one.
148
+
149
+ A fresh creation that leaves `.pending`, including a fresh 0.11.0 session, has no general recovery command in this toolkit. `inspect` accepts verified pre-upgrade predecessor sources (`0.0.x`–`0.10.x`, including `0.10.0`), but `adopt` still requires a verified migration receipt for the same old session identity and mode. Predecessor support does not authorize treating a failed fresh creation as a legacy migration or inventing a receipt to repair it. Without an existing trusted legacy receipt, keep the mode unknown, diagnose the retained state, or continue new work in another qualified fresh session. The exported same-value writer is a programmatic controlled recovery primitive, not an operator CLI. Do not delete `.pending` merely to make the final readable.
150
+
151
+ 合格新会话因短暂写锁竞争而失败的首次创建会自行重试:运行时在首创意图仍可证明时,按有界预算(attach 后 60 秒内至多 8 次)重试同一创建,随后返回明确的 `activation_writer_unavailable` 状态。重试是同值幂等的,绝不适用于曾成功创建的会话、resume/迟挂载或被删除的绑定——那些仍按下面的 unknown/诊断规则处理。该自动重试不是恢复命令,也不需要恢复命令。
144
152
 
145
- 新的 0.9.0 会话创建留下 .pending 时,本工具没有通用恢复命令。inspect 只接受已保留的 0.9.0 前来源,adopt 需要核验过的旧迁移收据,不能为新建会话编造旧收据。没有既有可信旧收据时,保持模式 unknown、诊断保留状态,或在另一合格新会话中继续新工作。导出的同值 writer 是程序受控恢复原语,不是操作者 CLI;不能为了让 final 可读而删除 .pending。
153
+ 新建会话(包括 0.11.0 新会话)留下 .pending 时,本工具仍没有通用恢复命令。inspect 可使用已核验的旧版本模式来源(`0.0.x`–`0.10.x`,包括 `0.10.0`),但 adopt 仍需针对同一旧会话身份与模式的已核验迁移收据。支持这些前驱版本不意味着可以把失败的新建会话当作旧会话迁移,或编造收据来修复它。没有既有可信旧收据时,保持模式 unknown、诊断保留状态,或在另一合格新会话中继续新工作。导出的同值 writer 是程序受控恢复原语,不是操作者 CLI;不能为了让 final 可读而删除 .pending。
146
154
 
147
155
  For rollback, stop writers, retain the receipt and bindings, and select the previous mode explicitly in each old profile before reinstalling the old Guard. A pre-0.9.0 Guard does not read these bindings; mixed-mode inventories need separate correctly mapped profiles or remain unsuitable for rollback. Keep host-lock and certificate identities separate: re-inspect the actual installed host as required, and never re-sign old certificates merely to change mode. Cross-machine transfer includes only verified bindings/receipts, with owner permissions restored; it transfers no host lock, credentials or native authority.
148
156
 
@@ -16,27 +16,30 @@ Context Guard does not own Goal, Todo, Compaction, or continuation. It intervene
16
16
  ## Call-time Host working-directory evidence
17
17
 
18
18
  For an ordinary named `npm test` or `pnpm test` Host call that omits `workdir`,
19
- the Guard captures a read-only working-directory receipt before execution and
20
- defers its provider-visible plugin context until the host has persisted the
21
- complete tool-result batch. This is a call-time derivation from the original Session header, the scoped sandbox
22
- policy, the active shell service, and exact audited DSH `0.1.5-rc.2` producer
23
- bytes. It is **not** a working directory returned by the Host process. The
24
- notice binds the original call ID, sequence, turn, arguments digest, root
25
- source, Session digest, Host-lock digest, physical directory, and policy root.
26
- On replay it is accepted only after the matching result and before the next
27
- assistant step, with the same source and Host identity. A legacy notice between
28
- a call and result is not upgraded. The observer always lets the Host tool proceed;
29
- it grants no ordinary mutation or execution qualification.
30
-
31
- The Bash producer chooses the scoped policy workspace root, or the Session
32
- header cwd when no policy is mounted; this candidate only certifies the
33
- audited policy route when its physical root equals the immutable header cwd.
34
- PowerShell uses the immutable header cwd under its separately audited local
35
- executor. An explicit `workdir` is checked on its own merits. Missing or
36
- ambiguous provider identity, a lexical filesystem alias, absent physical
37
- directory, changed policy or graph bytes, background execution, or missing
38
- call-time notice leaves target attribution insufficient. Historical logs
39
- without such a notice cannot be upgraded by reading today's Host config.
19
+ Guard observes the proposed default directory before execution. The observation
20
+ binds the original Session header, committed cwd epoch, scoped policy and
21
+ `WorkingDirectoryService`, active shell service, and audited DSH `0.2.1-rc.2`
22
+ implementation bytes and dependency routes. Its provider-visible context is
23
+ deferred until the host has persisted the complete tool-result batch. It is
24
+ not a directory returned by the executed process.
25
+
26
+ Bash and PowerShell obtain their default from the host's asynchronous
27
+ `workingDirectory.ensure()`. That service can recover a missing directory after
28
+ `tool/call`. Guard therefore withholds the receipt if the current service readback
29
+ disagrees or the directory history changes while the call is in flight. The
30
+ ordinary call still proceeds; its cwd-dependent result stays unconfirmed and
31
+ retains the call-epoch target. An explicit absolute workdir or file target is
32
+ bound independently; a relative shell workdir resolves against the call epoch only under the epoch reader. Historical logs with no cwd-change events retain the exact 0.9.0 projection under the same host binding and its frozen evidence/digests, including relative workdir spelling. The reader version is chosen from effective epochs committed through the result, so a future change cannot rewrite a completed legacy fact.
33
+
34
+ A receipt binds call ID, sequence, turn, arguments digest, root source, Session
35
+ and host-lock digests, physical directory and policy root. Replay accepts v1
36
+ only in unchanged header history. V2 additionally binds the governing epoch
37
+ and the original cwd supplied by the actual Session header, and refuses
38
+ in-flight directory changes and transplanted histories. Neither version
39
+ creates permission to execute or proves resource cleanup. Missing or ambiguous
40
+ provider identity, a lexical filesystem alias, background execution or an absent
41
+ receipt leaves the omitted-workdir completion shortcut unavailable. Historical
42
+ logs cannot acquire a missing receipt from today's configuration.
40
43
 
41
44
  ## Durable state model
42
45
 
@@ -2,9 +2,67 @@
2
2
 
3
3
  Guard binds each accepted installation to its exact package identities, implementation bytes and dependency routes. Version admission and implementation qualification are separate checks; a matching version alone does not establish compatibility.
4
4
 
5
+ ## 0.11.0: DSH >=0.2.1-rc.3
6
+
7
+ Upgrade DSH to `0.2.1-rc.3` or later before installing Guard 0.11.0. The package declares the same minimum in `engines.dsh`, `dsh.engines.dsh` and its DSH peers; Guard enforces that floor independently at runtime. There is no upper version bound, but every later graph must still pass package, byte, route and contract qualification. Cordis keeps its separate `>=4.0.4` range.
8
+
9
+ The current reviewed baseline and default cohort are DSH `0.2.1-rc.3` / Cordis `4.0.5` (`dsh-0.2.1-rc.3-core-v1`). The rc.2 audit files, distribution pins and prior acceptance records remain historical evidence; they do not admit an rc.2 runtime into this release. Existing session and Guard data protocols are preserved, while changed host locks require fresh checks. The official app-boot admission tests and [`semver-matrix-v110.json`](../benchmarks/incidents/acceptance/semver-matrix-v110.json) bind the new floor; the older matrix remains unchanged for 0.10.0.
10
+
11
+ The rc.3 registry and Desktop implementation records below describe their own source qualification. A new Guard package still needs its own CI, exact-artifact native, model and UI/performance evidence; raising this floor does not transfer an earlier package's acceptance.
12
+
13
+ 安装 Guard 0.11.0 前,请先将 DSH 升级到 `0.2.1-rc.3` 或更高版本。包顶层、嵌套 DSH 声明和 DSH peer 范围使用同一下限,Guard 运行时也独立核对;没有版本上限,后续宿主仍须逐项核验包身份、实现字节、依赖路由和接口。Cordis 继续单独要求 `>=4.0.4`。
14
+
15
+ 当前已审查基线及默认 cohort 为 DSH `0.2.1-rc.3` / Cordis `4.0.5`。rc.2 的审计文件、分发行身份与旧验收记录原样保留,但不再作为本版运行准入。旧会话及 Guard 数据协议保持兼容,宿主锁变化后仍须重新核验;新包的 CI、精确制品原生验收、模型及 UI/性能结果分别记录,不从旧包继承。
16
+
17
+ ## 0.10.0: DSH >=0.2.1-rc.2
18
+
19
+ 0.10.0 raises the host floor to `0.2.1-rc.2` (upstream release `dsh-v0.2.1-rc.2`, commit `687f282e8625c6b8d11ff58211a90524be2e4317`, cumulative over `0.2.1-rc.1`). There is no upper bound: later RCs on any tuple, stable and future releases pass VERSION ADMISSION and must still pass the graph, byte, route and contract audits. `0.2.0-rc.2`, `0.2.0` and `0.2.1-rc.1` keep their recorded-evidence rows but are refused as below the floor. Cordis keeps a separate `>=4.0.4` peer range and qualification (the reviewed baseline moved to Cordis `4.0.5` with the same range).
20
+
21
+ The reviewed host baselines are DSH `0.2.1-rc.2` and DSH `0.2.1-rc.3` (both over Cordis `4.0.5`), with 47 package identities and published implementation digests in `manifests/rc021-rc2-byte-audit.json` and `manifests/rc021-rc3-byte-audit.json` (cohort ids `dsh-0.2.1-rc.2-core-v1` and `dsh-0.2.1-rc.3-core-v1`). The rc.3 manifest was regenerated from the published `0.2.1-rc.3` tarballs (upstream `dsh-v0.2.1-rc.3`, commit `1f81c047fc48fa190a683e469daa699857e9afe8`); the rc.2→rc.3 cohort study verified per-package registry SRI and found ZERO executable-byte changes across the 47-name core cohort — the rc.3 functional commits touch only UI/model-listing packages outside this cohort — with manifest diffs limited to version and dependency-field rewrites. Host trust acquisition selects the equivalence baseline by the acquired graph's version and accepts a loading/modules match from either reviewed state. Native acceptance of the final Guard artifact on each platform remains a separate gate; no native validation of rc.3 is claimed.
22
+
23
+ ### Official Desktop distribution bytes
24
+
25
+ Official `0.2.1-rc.3` Desktop distributions for macOS arm64 and Windows x64 have independent registered identities, verified using vendor signatures, signed ASAR headers and official updater archive digests. The rc.2 pins are not reused. Distribution registration does not establish Guard installation, lifecycle, real-model or UI performance acceptance; those remain separate gates. An unregistered distribution still fails closed.
26
+
27
+ The official Desktop `0.2.1-rc.2` distribution retains generated `lib/types/invariant.js` companions that the npm packages no longer contain. Guard does not load these companions. Desktop qualification additionally checks the exact released archive identities and eight critical-package file tuples in [`desktop-distribution.v1.json`](../manifests/desktop-distribution.v1.json). Each program was independently reproduced from the fixed upstream source before its removal; the manifest keeps that public source pin separate from the application's declared build identity. The local ASAR hash table cannot authorize extra code. The carrier must pass vendor-signature verification, the authenticated ASAR header must match a registered platform distribution, and registry bytes and active dependency routes must still pass their existing audits. Unknown files, changed bytes, versions, headers or routes are refused. Ordinary registry runtime qualification is unchanged. A new Desktop build requires qualification of its own bytes even when its version string is unchanged.
28
+
29
+ Desktop's physical hoisted profile reader accepts the observed pnpm `11.7.0` and `11.28.5` JSON layouts only when the profile's manager agrees with the verified carrier. Duplicate keys, unsupported YAML, linked or escaped locations and invalid dependency routes are refused. The `dsh-desktop-bound/v2` contract is unchanged: Guard's second single-package add must preserve all tracked bytes and its complete package tree; only object-key order in `.modules.yaml` may differ in the later multi-package add. Qualification and read-only preflight do not establish installation, no-op, lifecycle or real-model acceptance.
30
+
31
+ `0.2.1-rc.3` 的 macOS arm64 与 Windows x64 官方 Desktop 分发行已分别登记厂商签名、签名绑定的 ASAR 头和官方更新源归档摘要,不复用 rc.2 pin。分发行登记不代表 Guard 安装、生命周期、真实模型或 UI 性能已验收;这些仍是独立门槛。未登记分发行继续按失败关闭拒绝。
32
+
33
+ 官方 Desktop `0.2.1-rc.2` 分发包保留了 npm 包已移除的 `lib/types/invariant.js` 编译产物,Guard 不加载这些伴随插件。Desktop 另行核对固定发行包身份和八个关键包的精确文件清单;每份程序均由删除前的固定上游源码独立编译复现,公开源码 pin 与应用声明的构建标识分开记录。ASAR 自带哈希表不能授权额外代码:仍须通过官方签名、已登记平台的 archive header、registry 字节和实际依赖路由核验。未知文件、改字节、错版本、错 header 和错路由均被拒绝,普通 registry runtime 的闭合规则不变。同版本重新构建的 Desktop 也须重新核验其分发字节。
34
+
35
+ Desktop 平铺安装索引只接受已观察的 pnpm `11.7.0`、`11.28.5` JSON 布局,版本必须与已验证的 carrier 一致;重复 key、未知 YAML、链接或越界目录、错误依赖路由仍会被拒绝。v2 两步 no-op 合同不变:Guard 单包第二次 add 要求全部跟踪文件及包树字节不变;后续多包 add 仅容许 `.modules.yaml` 的对象 key 顺序变化。资格核验及只读 preflight 不等于安装、no-op、生命周期或真实模型验收通过。
36
+
37
+ ### Host-surface changes Guard 0.10.0 actually handles
38
+
39
+ - **Session V4 catalog adds `job/registered`, `job/settled`, `working-directory/change`.** Job registrations and settlements are durable lifecycle facts, not completion evidence: a `job/settled` record with `status: "completed"` refines the external-wait view only when the producer itself reported fulfilment (`cause: "producer"`, `producerReported: true`); killed and failed settlements are explicit failures, and an unreported completion is unconfirmed. A settlement never certifies resource cleanup, file readback or the completion of a user obligation. Only a validated registration/settlement pair owned by the current session may refine its wait; supplied tool/root identities must match the original persisted invocation. The host writes lifecycle records best effort, so a well-formed orphan settlement remains audit-only. Missing or malformed identity, time or optional fields and conflicting repeats fail closed. A forked history never transfers the original owner.
40
+ - **Working directory is switchable inside a session.** The immutable Session header keeps the original project; each committed `working-directory/change` opens a new cwd epoch. Captured targets, paths and receipts keep the meaning of the epoch they were bound in — a later change never re-interprets an older relative path. A cwd-dependent call keeps its call-epoch target; a directory change before its result makes execution unconfirmed, including recovery by the host after dispatch. Absolute explicit execution targets remain independently bound. Drive-root and complete Windows UNC directories preserve their original spelling. Host default-workdir receipts gained a v2 shape that binds the governing epoch and the original project; receipts replayed next to different directory history are refused. Root-locator digests bind the epoch each root was captured in. Historical logs without `working-directory/change` preserve the 0.9.0 frozen projection under the same host binding, and preserve its evidence fields and digests, including the original spelling of explicit relative shell workdirs. The epoch reader applies only once a committed effective epoch is visible through that result; it resolves relative shell workdirs against the call epoch and keeps ambiguous Windows workdirs unconfirmed. Later events never reinterpret an already completed legacy fact.
41
+ - **Plugin records exist (`appendPluginRecord`/`pluginRecordOf`, `plugin:` namespace).** They are ignorable, never model-visible, and retained on a best-effort basis across format migrations; the upstream gate restricts production callers to its own experimental packages, so this API is not a stable third-party persistence interface. Guard does NOT migrate its private hash-chained ledger onto plugin records; the ledger keeps its own storage, writer lock and loss model. Foreign plugin records are retained-and-skipped: they never trigger capture, never authorize anything, and never break seq-driven call/result pairing.
42
+ - **Session append gained a publication-reentrancy check and per-listener exception isolation.** Guard's synchronous `snapshotEvents()` reads remain valid on the pinned local Session implementation; the existing flush-before-control and boundary durability flows are unchanged.
43
+ - **The invariant companion plugin and the `./invariant` exports were removed upstream.** Guard never imported them and adds no substitute. The official Desktop distribution's retained compiled files require the separate qualification above.
44
+ - **Subagents and Teams.** The subagent tool name `subagent` stays in Guard's delegation allowlist: a subagent result remains bounded evidence and never closes a parent obligation. Team delivery moved to direct inbox acceptance (the old outbox retry/dedupe path is gone upstream); `team/message/delivered` records reception only — reception is not execution, and neither is completion. Waiting for a subtask, a plan-review end turn, or a Goal pause does not consume or fabricate a completion.
45
+ - **Search/Fetch APIs and new models** are ordinary host tools: their success is non-authoritative evidence, never proof that a user task is complete.
46
+
47
+ ### 升级、临时禁用与恢复(0.10.0 中文说明)
48
+
49
+ 最低宿主为 DSH `>=0.2.1-rc.2`,没有隐式上限。升级顺序不变:先停写者、保留旧模式来源,升级宿主到 `0.2.1-rc.2` 或更高,安装 Guard,重新注入宿主锁并回读(见[宿主锁升级](HOST_LOCK_UPGRADE.md))。已审查基线为 DSH `0.2.1-rc.2` 与 `0.2.1-rc.3`(Cordis 均为 `4.0.5`;cohort `dsh-0.2.1-rc.2-core-v1` / `dsh-0.2.1-rc.3-core-v1`,各 47 包,见 `manifests/rc021-rc2-byte-audit.json` 与 `manifests/rc021-rc3-byte-audit.json`,上游提交分别为 `687f282e8625c6b8d11ff58211a90524be2e4317` 与 `1f81c047fc48fa190a683e469daa699857e9afe8`;rc.3 核心图可执行字节经逐包比对与 rc.2 完全一致)。
50
+
51
+ 新宿主事件语义:`job/settled` completed 不证明资源释放,只有本会话所有、注册与结算身份一致且工具根调用匹配的配对记录,在 producer 自己报告完成(`cause: "producer"` 且 `producerReported: true`)时才把外部等待标记为完成;合法孤立结算仅保留为审计事实,畸形或冲突记录拒绝;killed/failed 是显式失败,未报告的 completed 保持未确认。`working-directory/change` 开启新的 cwd 纪元:此前捕获的目标与证据保留原含义,不会随当前目录重新解释;调用与结果之间若发生目录变化(包括宿主自动恢复),默认或相对目录的执行保持未确认;显式绝对目标独立绑定。Windows 完整 UNC 和 drive-root 路径保留拼写,drive-relative/root-relative 拒绝。没有 `working-directory/change` 的日志在同一宿主绑定下保留 0.9.0 冻结投影,并保留其证据字段与摘要,包括显式相对 shell workdir 的原始拼写。新读法只在该结果之前已有实际生效的提交纪元时使用;后来追加的事件不能重新解释已经完成的旧证据。`plugin:` 记录一律忽略且不触发捕获;Guard 私有账本不迁移到 plugin records。子代理结果仍是有界证据;Team 直投 Inbox 的接收成功不等于执行完成;Goal 等待与计划审阅的结束等待不算完成。
52
+
53
+ 临时禁用与恢复:升级窗口内可在 profile 配置中把 Guard 从 bundles 移除或保持不加载(临时禁用是独立状态,不影响 `activation=always` 与完整原有 config 的保留)。禁用期间会话事件不被捕获;重新启用时按既有规则恢复——新建无继承根会话回到默认模式,旧会话沿用 write-once 私有绑定的原模式。宿主锁在禁用期间不变质;重新启用后若宿主或 profile 图未变,原锁继续有效,若变化则按 `--rebind-registry` 流程重建。市场兼容卡片显示"兼容"不等于 Guard admission 已通过;插件加载成功也不等于审计通过。
54
+
55
+ ### Consumer prerelease semantics
56
+
57
+ The plain npm/node-semver expression `>=0.2.1-rc.2` excludes later-tuple prereleases by default. The installed DSH plugin compatibility check (`dsh-app-boot`'s `evaluatePluginCompatibility`) reads the TOP-LEVEL `engines.dsh` first and ignores the DSH peers entirely when it exists; it uses `semver.satisfies(..., { includePrerelease: true })`, so the declaration admits `0.2.1-rc.3` and later RCs on any tuple, and refuses below-floor values. Both shipped layers (`engines.dsh` and `dsh.engines.dsh`) carry the same range so consumers reading either layer agree; peers keep the same range for peers-only consumers. `benchmarks/incidents/acceptance/semver-matrix.json` records the verified matrix for the new floor, and `tests/v100-app-boot-admission.test.ts` pins the real consumer's decisions. Package installation is not a version-admission proof — Guard's own floor check rejects a below-floor host independently.
58
+
59
+ The default-workdir shortcut additionally authenticates the published `dsh-working-directory` implementation, its dependency routes and the scoped `WorkingDirectoryService`. Missing, substituted or modified providers emit no trusted receipt. A v1 receipt is valid only before any directory-change event; v2 replay binds its origin to the actual Session header supplied by derivation, rather than trusting the receipt's own origin field. A pre-execute receipt is refused if directory history changes before the result; a pre-execute observation does not prove that `ensure()` later executed in that directory.
60
+
61
+ 默认目录快捷证据还核验 `dsh-working-directory` 的发布字节、依赖路由和当前 scoped 服务身份。服务缺失、替换或修改时不发可信回执。v1 只能用于调用前没有目录变化的历史;v2 的 origin 必须绑定派生器从实际 Session header 取得的原始目录,不能只信回执自报。调用后目录发生变化时,执行前回执不再证明实际执行目录。
62
+
5
63
  ## 0.8.2–0.9.0: DSH >=0.2.0-rc.2 and official Desktop
6
64
 
7
- 0.9.0 retains the host admission and Desktop support introduced in 0.8.2. Each release still requires its own artifact acceptance.
65
+ 0.9.0 retained the host admission introduced in 0.8.2 with the floor `0.2.0-rc.2`; 0.10.0 supersedes it. Historical description:
8
66
 
9
67
  Version admission uses strict SemVer precedence, including later-tuple RCs and ignoring build metadata. The floor is `0.2.0-rc.2`, with no upper limit. `0.2.0-rc.1` keeps its recorded-evidence row but is refused as below the floor. Below-floor and malformed versions are refused. Cordis has a separate `>=4.0.4` peer range and qualification; a DSH version does not establish arbitrary Cordis compatibility.
10
68
 
@@ -0,0 +1,123 @@
1
+ # Dependency advisory gate / 依赖告警门禁
2
+
3
+ The repository runs a fail-closed dependency advisory gate (`scripts/audit_dependencies.py`,
4
+ required CI job `dependency-scan`). This page is the maintenance contract for that gate.
5
+
6
+ 本仓库通过失败关闭的依赖告警门禁(`scripts/audit_dependencies.py`,必需 CI job
7
+ `dependency-scan`)检查依赖公告。本文是该门禁的维护说明。
8
+
9
+ ## Policy / 策略
10
+
11
+ - Any `high` or `critical` advisory — production or development chain — fails the gate.
12
+ A test-chain finding is still an unaccepted high/critical finding.
13
+ - `moderate` and `low` advisories are printed by the gate but do not block. They stay
14
+ visible in CI logs; fixing them is encouraged, not gated.
15
+ - The scan must complete: a network failure, registry outage, or malformed `pnpm audit`
16
+ output fails the gate (`exit 2`). A missing scan never reads as "zero vulnerabilities".
17
+
18
+ - 任何 `high`/`critical` 公告(无论生产链还是开发链)都会使门禁失败。
19
+ 开发链的 high/critical 同样是未接受的高危发现。
20
+ - `moderate`/`low` 公告会被打印但不阻断;修复值得鼓励,但不作为门禁条件。
21
+ - 扫描必须完成:网络失败、registry 不可用或 `pnpm audit` 输出不可解析时门禁失败
22
+ (退出码 2)。扫描缺失绝不会被解读为“零漏洞”。
23
+
24
+ ## Classification and reachability / 分类与可达性
25
+
26
+ `pnpm audit` reports scanner severity, not product severity. This package ships no
27
+ runtime dependencies beyond the audited DSH host cohort; advisories historically land in
28
+ the development chain (vitest/vite/tinypool/source-map-js and their transitive graphs).
29
+ Before acting on a finding, check where the module sits (`pnpm why <module>`) and whether
30
+ the advisory's precondition is reachable in this repository's usage — for example, the
31
+ tinypool advisories require attacker-controlled worker options, and the vitest mocker
32
+ advisories require untrusted mock inputs. Reachability decides priority; it never
33
+ converts a blocking advisory into a silent pass.
34
+
35
+ `pnpm audit` 报告的是扫描器严重性,不是产品严重性。本包除受审计的 DSH 宿主队列外
36
+ 没有运行时依赖;历史告警均落在开发链(vitest/vite/tinypool/source-map-js 及其传递
37
+ 依赖)。处理发现前先确认模块位置(`pnpm why <module>`)及其前置条件在本仓库用法中
38
+ 是否可达——例如 tinypool 公告需要攻击者可控的 worker 选项,vitest mocker 公告需要
39
+ 不可信的 mock 输入。可达性决定优先级,但绝不把阻断级公告变成静默通过。
40
+
41
+ ## Fixing and upgrading / 修复与升级
42
+
43
+ 1. Prefer a coordinated upgrade of the affected chain that stays inside the dependents'
44
+ declared ranges (`pnpm update`, then `pnpm-workspace.yaml` `overrides` floors only when
45
+ the fixed version is otherwise unreachable). Verify `pnpm install`, the full local
46
+ matrix, and record the mapping advisory → version in the change log.
47
+ 2. Never hide an incompatibility behind a blind force, and never delete lockfile entries
48
+ to silence a scanner.
49
+ 3. Dropping an override floor requires the dependents' own minimums to cover the fixed
50
+ version.
51
+
52
+ 1. 优先协调升级受影响链条,并保持在依赖方声明范围内(先 `pnpm update`;只有当修复
53
+ 版本无法通过范围解析时才在 `pnpm-workspace.yaml` 用 `overrides` 设下限)。验证
54
+ `pnpm install` 与完整本地矩阵,并在变更日志记录“公告 → 版本”映射。
55
+ 2. 不得用盲目 force 掩盖不兼容,也不得删除 lockfile 条目让扫描器闭嘴。
56
+ 3. 只有当依赖方自身的最低版本覆盖修复版本后,才可移除 override 下限。
57
+
58
+ ## Exceptions / 例外
59
+
60
+ Accepting a blocking advisory requires a matching entry in the machine-readable table
61
+ `scripts/dependency-scan-exceptions.json` (validated by the gate: expired, mismatched or
62
+ malformed entries leave the advisory blocking) plus the summary record below: advisory id,
63
+ affected module and version, why the advisory's precondition is unreachable here, the
64
+ owner, and an expiry date after which the exception must be re-justified or the chain
65
+ upgraded.
66
+
67
+ 接受阻断级公告必须同时在机器可读表 `scripts/dependency-scan-exceptions.json` 登记
68
+ (由门禁校验:过期、不匹配或损坏的条目仍保持阻断)并在下表登记摘要:公告 ID、受影
69
+ 响模块与版本、前置条件在本仓库不可达的原因、责任方、到期日;到期后必须重新论证或
70
+ 完成升级。
71
+
72
+ ### Explicit temporary risk acceptance for 0.11.0 / 0.11.0 明确的临时风险接受
73
+
74
+ For the three Undici 8.11.2 findings added below, the maintainer explicitly accepted the disclosed residual risk and waived the ordinary unreachability eligibility requirement for this 0.11.0 validation. This is a specific exception to eligibility, not a finding that the whole host is unreachable or safe. The signed host remains unfixed, and a TLS 1.2 process-crash denial of service cannot be excluded. The cache and TLS-callback inspections narrow particular paths only; they do not establish whole-host isolation. Changing a development override would not repair signed-host bytes.
75
+
76
+ 这次 0.11.0 验收新增的三条 Undici 8.11.2 例外,由维护者明确接受已披露的剩余风险,并对通常要求“前置条件不可达”的例外准入作一次特批。这不是“整个宿主不可达”或“已经安全”的结论。签名宿主仍未修复,TLS 1.2 导致进程崩溃的拒绝服务风险不能排除;cache 和 TLS callback 的静态检查只缩小部分路径,不能证明整个宿主隔离。修改开发依赖 override 也不会修复签名宿主中的代码。
77
+
78
+ Acceptance covers only scanner IDs 1243472, 1243474 and 1243477 with the exact advisory IDs and Undici version below. It expires on **2026-11-05 inclusive**, according to the runner's existing date semantics; from **2026-11-06**, the unchanged gate rejects the expired table and blocks again. Other findings, versions and release checks are not waived. The two older exceptions retain their original scope and expiry. Expiry blocks CI qualification and subsequent acceptance checks; it does not fix upstream code, disable an installed 0.11.0 instance, or withdraw a published package.
79
+
80
+ 接受范围仅限 scanner ID 1243472、1243474、1243477 与下列精确公告 ID、Undici 版本的组合。有效期**包含 2026-11-05 当日**,沿用 runner 现有日期语义;自 **2026-11-06** 起,未改动的门禁会拒绝过期表并恢复阻断。其他发现、版本及发布检查不在豁免范围内;原有两条例外的范围和到期日保持不变。到期阻断的是 CI 资格和后续验收,不会自动修复上游、禁用已安装的 0.11.0 实例或撤回已发布的包。
81
+
82
+ The advisory id in the exception table is the scanner's numeric id; the GitHub
83
+ advisory it resolves to is recorded alongside it. Earlier drafts of this page
84
+ mistakenly wrote the numeric id as a GHSA code — the real identifiers are:
85
+
86
+ | Advisory (GitHub) | Scanner id | Module@version | Severity | Rationale (summary) | Owner | Expires |
87
+ | --- | --- | --- | --- | --- | --- | --- |
88
+ | [GHSA-mrhx-c7xc-m3w5](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5) | 1243066 | zod@4.4.3 | high | Dev-chain only: exact-pinned transitive dep of the pinned `@deepseek-ai` host devDependencies (test replica of the audited cohort). Nothing ships in the npm package; the advisory needs attacker-controlled oversized schema input, which offline deterministic tests never provide. The verified rc.3 host manifests still exact-pin zod 4.4.3, so upgrading the host does not lift this. Re-evaluate at the next host cohort bump that carries zod ≥4.6.6. | GreenLv | 2027-01-31 |
89
+ | [GHSA-xjj6-f33q-929c](https://github.com/advisories/GHSA-xjj6-f33q-929c) | 1243112 | undici@8.11.2 | high | Dev-chain only: exact-pinned transitive dep of `@deepseek-ai/dsh-http-proxy` under the pinned host devDependencies. Nothing ships in the npm package; the advisory needs an attacker-controlled server sending crafted Content-Encoding stacks, which offline tests never contact. The verified rc.3 host manifests still exact-pin undici 8.11.2, so upgrading the host does not lift this. Re-evaluate at the next host cohort bump that carries undici ≥8.12.2. | GreenLv | 2027-01-31 |
90
+ | [GHSA-4w7w-5xrc-9h26](https://github.com/nodejs/undici/security/advisories/GHSA-4w7w-5xrc-9h26) | 1243472 | undici@8.11.2 | high | Explicit temporary risk acceptance: cache/redirect composition was not found in the inspected factory; whole-host/plugin configurations remain unknown. 明确临时接受 cache/redirect 剩余风险,不声称全宿主不可达。 | GreenLv | 2026-11-05 (inclusive) |
91
+ | [GHSA-2m5v-pch6-74hx](https://github.com/nodejs/undici/security/advisories/GHSA-2m5v-pch6-74hx) | 1243474 | undici@8.11.2 | high | Explicit temporary risk acceptance: application-specific TLS callbacks may be lost; the inspected factory lacks that callback, but other configurations are unknown. 明确临时接受 TLS callback 检查绕过风险,其他配置仍未知。 | GreenLv | 2026-11-05 (inclusive) |
92
+ | [GHSA-qrxm-fqhp-jwvm](https://github.com/nodejs/undici/security/advisories/GHSA-qrxm-fqhp-jwvm) | 1243477 | undici@8.11.2 | high | Explicit temporary risk acceptance: TLS 1.2 renegotiation can crash the client; reachability cannot be excluded and the signed host is unfixed. 明确临时接受可能可达的进程崩溃风险,签名宿主未修复。 | GreenLv | 2026-11-05 (inclusive) |
93
+
94
+ ## Recorded upgrades / 已记录的升级
95
+
96
+ The advisory state is whatever the gate prints for the lockfile under review; the
97
+ exception table above is the only durable record of accepted findings. Upgrades this
98
+ gate has already carried: the vitest 3.2.7 mocker path-traversal and tinypool 1.1.1
99
+ prototype-pollution/RCE chains were closed by moving to vitest 4.1.12 (which drops the
100
+ vulnerable tinypool 1.x pool) with `vite >=7.3.7 <8` and `source-map-js ^1.2.2` floors
101
+ inside the dependents' declared ranges. The vitest 4 migration seams for this repository
102
+ (manifest wrapper modules, the clean-startup test setup file, mock placement) are
103
+ described in the 0.11.0 change log.
104
+
105
+ 门禁打印的告警状态始终针对被检查的 lockfile;上表是已接受发现的唯一持久记录。该
106
+ 门禁已承载的升级:vitest 3.2.7 mocker 路径穿越与 tinypool 1.1.1 原型污染/RCE 链
107
+ 通过迁移到 vitest 4.1.12(随之移除带漏洞的 tinypool 1.x pool)并设定
108
+ `vite >=7.3.7 <8`、`source-map-js ^1.2.2` 范围内下限关闭。本仓库 vitest 4 迁移的
109
+ 接缝(manifest 包装模块、清空启动参数的测试 setup 文件、mock 摆放位置)见
110
+ 0.11.0 变更日志。本仓库的 vitest 4 迁移注意事项(manifest 包装
111
+ 模块、清空启动参数的测试 setup 文件、mock 摆放位置)见 0.11.0 变更日志。
112
+
113
+ ## Upstream references and follow-up / 上游参考与后续更新
114
+
115
+ - [DSH public dependency discussion](https://github.com/deepseek-ai/deepseek-harness/discussions/10847) records concerns about exact-pinned vulnerable dependencies. It does not establish that DSH maintainers have responded or scheduled a repair.
116
+ - [Undici 8.12.2 release](https://github.com/nodejs/undici/releases/tag/v8.12.2) lists the upstream fixes for these three advisories. That release does not replace code in an already signed DSH app. The reviewed rc.3, rc.4 and alpha.2 host manifests still pin Undici 8.11.2.
117
+
118
+ - [DSH 公开依赖讨论](https://github.com/deepseek-ai/deepseek-harness/discussions/10847)记录了精确锁定受影响依赖的担忧;不能据此声称 DSH 维护者已回应或已排期修复。
119
+ - [Undici 8.12.2 发布记录](https://github.com/nodejs/undici/releases/tag/v8.12.2)列出了这三条公告的上游修复,但该发布不会替换已有签名 DSH 应用内的代码。本次核对的 rc.3、rc.4 和 alpha.2 宿主 manifest 仍锁定 Undici 8.11.2。
120
+
121
+ Once an official compatible host carries the fixed dependency chain, recheck its actual signed/installed bytes and advisory result, validate the changed inputs, then update this disclosure and remove or reassess only the matching exceptions. Until then, the residual risk remains accepted only within the recorded scope and expiry; other acceptance gates stay in force.
122
+
123
+ 后续官方兼容宿主带入修复链后,应重新核对实际签名及安装字节、公告扫描结果和受影响输入,再更新披露,并仅移除或重新评估相符的例外。在此之前,剩余风险只在已记录的范围和期限内被接受,其他验收门禁继续有效。
@@ -0,0 +1,110 @@
1
+ # Installation and first load / 安装与首次载入
2
+
3
+ [English README](../README.md) · [中文 README](../README.zh-CN.md)
4
+
5
+ ## Before installation
6
+
7
+ Use the profile you actually run: Web, Headless or Desktop. Stop the relevant host/session writers first. If this installation has old Guard sessions, preserve the old package and effective mode sources, then prepare a frozen inventory and migration receipt using [the migration guide](ACTIVATION_MIGRATION.md) **before replacing DSH or Guard**. Empty old sessions count too. The 0.11.0 migration toolkit can run from a separately prepared package directory while the old package stays installed.
8
+
9
+ With no old Guard sessions, there is no old-mode adoption step. Upgrade the host to DSH `>=0.2.1-rc.3` if necessary, install Guard, and complete the installation checks before startup. Requires Node.js `>=22`, pnpm `>=11` and a qualified Cordis `>=4.0.4` installation. Do not load both `dsh-context-guard` and `dsh-completion-guard` in one profile; the internal entry ID remains `context-guard`.
10
+
11
+ ## 安装前
12
+
13
+ 先确认实际使用的 Web、Headless 或 Desktop profile,并停止相应宿主与会话写者。如果已有旧 Guard 会话,替换 DSH 或 Guard **之前**,按[迁移指南](ACTIVATION_MIGRATION.md)保留旧包、核验有效模式来源,冻结会话库存并准备迁移收据。旧空会话也需要清点。0.11.0 迁移工具可以从另行准备的包目录运行,旧包此时仍留在原安装位置。
14
+
15
+ 没有旧 Guard 会话时,不需要旧模式 adoption。先按需将 DSH 升级到 `>=0.2.1-rc.3`,再安装 Guard,完成安装核验后启动。需要 Node.js `>=22`、pnpm `>=11` 及通过资格验证的 Cordis `>=4.0.4`。同一 profile 不要同时加载 `dsh-context-guard` 和 `dsh-completion-guard`,内部条目 ID 仍是 `context-guard`。
16
+
17
+ ## Web installation / Web 安装
18
+
19
+ Keep the host stopped through these steps. Substitute the actual absolute runtime/profile paths. Back up the profile's `cordis.patch.yml` before `inject`, which writes the lock into that file. The three host-lock checks—`inspect`, `inject` and `verify-dump`—must each return `status: "supported"`; a nonzero exit or another status stops this path. This status requirement does not apply to `dsh plugin add`.
20
+
21
+ 以下步骤期间保持宿主停止,将目录替换为实际绝对路径。`inject` 会把锁写入 profile 的 `cordis.patch.yml`,执行前先备份。`inspect`、`inject` 和 `verify-dump` 三条宿主锁检查都须返回 `status: "supported"`;非零退出或其他状态都不能继续启动。该状态要求不适用于 `dsh plugin add`。
22
+
23
+ ```sh
24
+ dsh plugin --profile web add dsh-completion-guard@0.11.0
25
+
26
+ DSH_RUNTIME_ROOT=/absolute/path/to/.dsh-runtime
27
+ DSH_PROFILE_ROOT=/absolute/path/to/.dsh/profiles/web
28
+ GUARD_HOST_LOCK="$DSH_PROFILE_ROOT/node_modules/.bin/dsh-completion-guard-host-lock"
29
+
30
+ "$GUARD_HOST_LOCK" inspect --runtime-root "$DSH_RUNTIME_ROOT" --profile-root "$DSH_PROFILE_ROOT"
31
+ "$GUARD_HOST_LOCK" inject --runtime-root "$DSH_RUNTIME_ROOT" --profile-root "$DSH_PROFILE_ROOT"
32
+ dsh --profile web --dump-config | "$GUARD_HOST_LOCK" verify-dump --runtime-root "$DSH_RUNTIME_ROOT" --profile-root "$DSH_PROFILE_ROOT" --dump-config -
33
+ ```
34
+
35
+ The reviewed baseline is DSH `0.2.1-rc.3` / Cordis `4.0.5`. A later compatible host requires `--rebind-registry` on the three lock commands; it checks official archives and qualifies changed programs before rebuilding the lock. See [compatible-version rebinding](HOST_LOCK_UPGRADE.md#rebinding-compatible-package-versions). Changes to DSH, Guard or the profile location require fresh checks. An ordinary market-only update does not require reinjection; installing or removing the Desktop market does.
36
+
37
+ 已审查基线为 DSH `0.2.1-rc.3` / Cordis `4.0.5`。更新的兼容宿主需要在三条锁命令中添加 `--rebind-registry`,核对官方归档并验证变化的程序后重建锁,见[兼容版本重绑定](HOST_LOCK_UPGRADE.md#rebinding-compatible-package-versions)。DSH、Guard 或 profile 路径变化后需要重新检查。仅 market 的普通更新不需重新注入,Desktop 市场的安装或移除则需要。
38
+
39
+ ### Windows, Headless and Desktop / 其他入口
40
+
41
+ - **Windows Web:** run the same lock subcommands through `node_modules\.bin\dsh-completion-guard-host-lock.cmd` inside the actual Web profile directory, with Windows absolute paths. Use your shell's variable syntax; the block above is POSIX shell syntax.
42
+ - **Headless:** use the Headless profile and its own installed lock tool throughout, including `--profile headless` on DSH commands. See [the host-lock guide](HOST_LOCK_UPGRADE.md) for the profile-specific flow.
43
+ - **Desktop:** use the app's bundled CLI for installation and `--profile desktop` when building the lock. Bind the app archive and actual Desktop profile. Its CLI has no `--dump-config`; run `dump-desktop` and verify that newly generated output. The complete commands are in [official Desktop setup](HOST_LOCK_UPGRADE.md#official-desktop-profile). After installing or removing `dshmarket`, repeat `inspect`, `inject`, `dump-desktop` and `verify-dump` on the new output.
44
+
45
+ 中文对应路径:
46
+
47
+ - **Windows Web**:通过实际 Web profile 下的 `node_modules\.bin\dsh-completion-guard-host-lock.cmd` 运行相同锁子命令,使用 Windows 绝对路径和当前 shell 的变量语法;上方示例是 POSIX shell。
48
+ - **Headless**:全程使用 Headless profile 及其安装的锁工具,DSH 命令选择 `--profile headless`,完整流程见[宿主锁指南](HOST_LOCK_UPGRADE.md)。
49
+ - **Desktop**:使用应用附带 CLI 安装,以 `--profile desktop`、应用归档和实际 Desktop profile 建锁。该 CLI 没有 `--dump-config`,要用 `dump-desktop` 生成新配置,再核验这份输出。[官方 Desktop 步骤](HOST_LOCK_UPGRADE.md#official-desktop-profile)给出完整命令。安装或移除 `dshmarket` 后重新执行 `inspect`、`inject`、`dump-desktop`,并对新输出执行 `verify-dump`。
50
+
51
+ ## Finish an upgrade before startup
52
+
53
+ A host lock verifies the installation, not old session modes. While writers remain stopped, use the frozen pre-upgrade receipt for `adopt` and `verify`. Start the host only after installation/lock checks and the intended migration scope pass. Unknown old sources, missing bindings and conflicts stay pending; do not fill them with the upgraded `always` default.
54
+
55
+ If the official persistence reader refuses old formats, preserve those logs and mode sources. The [readable-subset flow](ACTIVATION_MIGRATION.md) freezes the whole report, then a user-reviewed selection of exact readable IDs. All three migration commands carry the same `--selection`; exclusions remain pending even when selected rows succeed. A zero exit or `selected_complete` does not establish whole-inventory completion. Corruption, permissions and other errors abort rather than becoming exclusions. The guide also contains [copyable migration prompts](ACTIVATION_MIGRATION.md) and recovery steps.
56
+
57
+ ## 升级核验完成后再启动
58
+
59
+ 宿主锁核验安装环境,不会迁移旧会话模式。保持写者停止,用升级前冻结的收据完成 `adopt` 和 `verify`。安装、锁核验及目标迁移范围全部通过后才能启动;旧来源未知、绑定缺失或冲突时保持待处理,不能用升级后的 `always` 默认值填补。
60
+
61
+ 官方 persistence 若拒绝旧格式,保留原日志和模式来源。按[可读子集流程](ACTIVATION_MIGRATION.md)先冻结全库报告,再明确选择精确的可读 ID。三个迁移命令都携带同一 `--selection`,选中行通过后排除项仍待处理。零退出或 `selected_complete` 不代表整库完成;损坏、权限等其他异常会中止,不会转成排除项。指南还提供[可复制迁移提示词](ACTIVATION_MIGRATION.md)和恢复步骤。
62
+
63
+ ## First load and status
64
+
65
+ When you open or restore a session that already has history, DSH loads that history and Guard reconstructs its saved state. You may see “载入历史” (loading history); wait for loading to finish before continuing. A later visit can still wait.
66
+
67
+ 0.9.0 reuses completed history checks only when it can verify that the history is unchanged and the results are safe to reuse. Each operation still checks the current mode and performs the required fresh checks of Goal state, private records and the host environment. It does not modify the official host's history-view lifecycle or decode cache and does not guarantee an instant first opening or subsequent visit.
68
+
69
+ Once loading finishes, run `/context-guard status`. With the default configuration, a new empty root session reports `armed`, waiting for the first real input; Guard has written no session events yet. DSH may have written its own initialization events. Images and attachments count as real input, blank messages do not. An explicit `activation: opt-in` instead requires `/context-guard on`. In an old session, check the retained mode and any binding diagnosis. Protection does not grant new authority; the default policy remains `standard`.
70
+
71
+ ## 首次载入与状态
72
+
73
+ 打开或恢复已有历史的会话时,DSH 载入历史,Guard 重建已保存的状态。界面可能显示“载入历史”,等加载结束后再继续;再次进入也可能需要等待。
74
+
75
+ 0.9.0 只在确认历史未变、检查结果可安全复用时,复用已经通过的历史检查。每次操作仍核对当前模式,并按需要重新核验 Goal 状态、私有记录和宿主环境。它没有修改官方宿主的历史视图生命周期或解码缓存,不能保证首次或后续打开立即完成。
76
+
77
+ 加载结束后执行 `/context-guard status`。使用默认配置的新建空根会话显示 `armed`,等待首条真实输入,此前 Guard 没有写入会话事件;DSH 可能已记录自身的初始化事件。图片、附件算真实输入,纯空白不算。显式配置的 `activation: opt-in` 则需要执行 `/context-guard on`。旧会话查看保留模式和可能的绑定诊断。保护不增加权限,默认策略仍为 `standard`。
78
+
79
+ ## Choose the default for new sessions
80
+
81
+ Profiles that omit `activation` already use `always` for new roots. To adopt that default while retaining old modes, complete the old-session migration first, back up `cordis.patch.yml`, then remove the `activation` field from the existing `context-guard` entry's `config`. Keep the entry, injected host-lock fields and all other settings. Do not replace the old field with an explicit `activation: always`: an explicit setting applies when reading existing bindings too and reports `activation_mode_conflict` if they disagree. Omitting the field lets new roots use `always` while old sessions use their bound initial modes. Forks inherit their parent's bound mode.
82
+
83
+ If you want future new roots to remain opt-in, keep `activation: opt-in`; any existing bindings must agree with that explicit setting. To choose a different initial mode, use a new root session. `/context-guard on` and `off` change the saved enabled state of the current session without changing its bound initial mode.
84
+
85
+ ## 新会话默认模式
86
+
87
+ profile 未填写 `activation` 时,新建根会话已默认采用 `always`。要采用新默认值并保留旧模式,先完成旧会话迁移、备份 `cordis.patch.yml`,再删除原 `context-guard` 条目 `config` 下的 `activation` 字段。保留整个条目、注入的宿主锁字段及其他配置。不要直接替换为显式 `activation: always`:读取已有绑定时也会核对显式配置,矛盾时报告 `activation_mode_conflict`。省略该字段,才能让新根会话使用 `always`,旧会话沿用绑定的初始模式。分叉会话继承父会话绑定的模式。
88
+
89
+ 若希望后续新根会话仍需手动开启,保留 `activation: opt-in`,但已有绑定也须与这一显式设置相符。需要不同的初始模式时应新建根会话。`/context-guard on`、`off` 改变当前会话保存的启用状态,不改变绑定的初始模式。
90
+
91
+ Default settings paths / 默认配置路径:
92
+
93
+ | System / 系统 | Profile | Settings / 配置 |
94
+ | --- | --- | --- |
95
+ | macOS / Linux | Web | `$HOME/.dsh/profiles/web/cordis.patch.yml` |
96
+ | macOS / Linux | Headless | `$HOME/.dsh/profiles/headless/cordis.patch.yml` |
97
+ | macOS | Desktop | `$HOME/.dsh/profiles/desktop/cordis.patch.yml` |
98
+ | Windows | Web | `%USERPROFILE%\.dsh\profiles\web\cordis.patch.yml` |
99
+ | Windows | Headless | `%USERPROFILE%\.dsh\profiles\headless\cordis.patch.yml` |
100
+ | Windows | Desktop | `%USERPROFILE%\.dsh\profiles\desktop\cordis.patch.yml` |
101
+
102
+ Use a custom `DSH_HOME` instead of the default `.dsh` directory when configured. Restart the appropriate host after the edit, once the required lock and migration checks have passed. Guard `on`/`off` controls this session's protection, not its DSH standard/minimal/custom preset.
103
+
104
+ 设置了自定义 `DSH_HOME` 时,使用该目录而非默认 `.dsh`。修改后在必要的锁及迁移核验通过时重启相应宿主。Guard 的 `on`、`off` 控制当前会话保护,不改变 DSH 的标准、极简或自定义 preset。
105
+
106
+ Copyable configuration prompt / 可复制配置提示词:
107
+
108
+ > Use dsh-completion-guard 0.11.0's default always mode for future new root sessions while preserving old modes. Find the cordis.patch.yml for the Web, Headless or Desktop profile I actually use. First verify that old-session mode migration is complete for the authorized scope; keep exclusions and unknown sources pending. Back up the file, then remove only the activation field from the existing context-guard config, or leave it absent. Preserve bindings, all other settings and host-lock fields. Do not rewrite bindings or restart DSH. Show the path and exact diff, and report any lock or migration checks remaining before restart.
109
+
110
+ > 让后续新根会话使用 dsh-completion-guard 0.11.0 的默认 always,保留旧模式。找到我实际使用的 Web、Headless 或 Desktop profile 的 cordis.patch.yml;先确认授权范围内的旧会话模式迁移已通过,排除项和来源未知项继续待处理。备份配置后,仅删除原 context-guard config 下的 activation 字段;原本没有该字段则保留不填。保留绑定、其他配置和宿主锁字段,不重写绑定,不重启 DSH。报告文件路径、精确差异,以及重启前尚缺的锁或迁移核验。