dsh-completion-guard 0.8.0 → 0.8.2

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,10 +1,66 @@
1
1
  # Compatibility
2
2
 
3
- Compatibility is pinned to exact host package sets. A nearby version or a partial package match is not treated as supported.
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.8.0: DSH 0.1.7-rc.2 only
5
+ ## 0.8.2: DSH >=0.2.0-rc.2 and official Desktop
6
6
 
7
- Current metadata and the production selector accept exactly `0.1.7-rc.2`, with Cordis `4.0.4`. The sole cohort is `dsh-0.1.7-rc.2-core-v1`: 46 exact package identities, backed by published-tarball SHA-256, SRI and installed module/manifest and actual dependency-path checks in `manifests/rc017-rc2-byte-audit.json`. A higher version is unregistered, not supported. Old cohorts exist only as historical test data.
7
+ 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.
8
+
9
+ The reviewed host baseline is DSH `0.2.0-rc.2` / Cordis `4.0.4`, with 46 package identities and published implementation digests in `manifests/rc020-rc2-byte-audit.json`, regenerated from the published `0.2.0-rc.2` tarballs (upstream commit `639ed015397290b3745d163aafe02ffee4aa3f84`). Compared with rc.1, only six cohort packages carry real `lib` changes in rc.2 (`dsh`, `dsh-commands`, `dsh-goal`, `dsh-llm` typert tables; `dsh-tool-bash`/`dsh-tool-pwsh` tool descriptions); every other package differs only in its `package.json` dependency pins. Native acceptance of the final Guard artifact on each platform remains a separate gate; no native validation of a future host is claimed.
10
+
11
+ ### Official Desktop (CG-RC2-002)
12
+
13
+ The application owns the `desktop` profile (`dsh-profile-desktop`). Its CLI carrier permits plugin management for that profile but refuses CLI boot and `--dump-config`. Use the carrier installed with the app for installation, and Guard's `dump-desktop` command for boot-free composition. See the [Desktop upgrade steps](HOST_LOCK_UPGRADE.md#official-desktop-profile).
14
+
15
+ Guard identifies the profile by its manifest name. A Desktop profile contains the Web bundle, so bundle presence alone cannot identify the running surface. For macOS, Guard verifies the app's Developer ID signature and DeepSeek team/identifier; for Windows, it verifies the executable's Authenticode status and DeepSeek publisher. It then compares the ASAR header with the integrity value embedded in the signed carrier. A detached archive or a self-reported digest table cannot establish carrier identity.
16
+
17
+ Desktop's bundled pnpm 11.7 produces a physical hoisted plugin tree with a JSON `.modules.yaml` index and no package map. Guard verifies the index against the actual tree, then applies the same published-byte and dependency-route checks to local critical peers. Missing, unlisted, duplicate, escaped or changed critical packages are refused. A supported package-map layout remains accepted when present; malformed maps never fall back to the physical-tree path.
18
+
19
+ The archive is read in place. The registry baseline closes the executable/JSON inventory of each critical package, including scripts outside `lib`. Its bytes must match the acquired official tarball digests. The signed archive metadata authenticates the packager's rewritten manifests; executable files have no rewrite exception. Nested critical packages, unlisted code and changed dependency routes are refused. The same fresh route and byte audit also checks critical peers selected from the physical profile.
20
+
21
+ The lock binds the canonical archive, signed header, runtime manifest and metadata, carrier bytes, installed Guard manifest, profile manifest, map and lockfile. Inject and runtime revalidation use one evaluation path, including foreground renderers and default-workdir providers. Changed inputs refuse the injected lock. Receipts stay under physical, contained profile directories; directory links cannot redirect them elsewhere.
22
+
23
+ `hostLockProfile: "desktop"` is preserved through composition and readback. Guard refuses Desktop restart with `host_capability_request_unsupported`; the graphical app owns its lifecycle. Exact-artifact backend acceptance, graphical-shell acceptance and real-model behavior are separate gates. Their results belong to the matching Release annexes.
24
+
25
+ ### 0.8.2 中文说明
26
+
27
+ 0.8.2 延续 0.8.x 的任务、证书与数据协议,主要适配 DSH RC.2、增加 Desktop 宿主锁并修复退出证据判定。最低 DSH 版本升至 `0.2.0-rc.2`;请先升级宿主,再安装 Guard、重新注入锁并回读。版本准入没有上限,但版本号相符仍不足以证明实现兼容。Cordis 的独立要求为 `>=4.0.4`。
28
+
29
+ Desktop 按应用自有的 `dsh-profile-desktop` 名称识别。安装须使用应用附带的 CLI;该 CLI 允许管理 Desktop 插件,但拒绝通过 CLI 启动 Desktop 或执行 `--dump-config`。Guard 的 `dump-desktop` 使用应用内同一套配置组合 API,不启动宿主。具体操作见[Desktop 升级步骤](HOST_LOCK_UPGRADE.md#official-desktop-profile)。
30
+
31
+ Desktop 自带 pnpm 11.7 生成平铺插件目录,安装索引为 JSON 格式的 `.modules.yaml`,不含 package-map。Guard 核对索引与实际目录,再对本地关键 peer 执行相同的官方字节与依赖路由认证。关键包缺失、未登记、重复、越界或发生改写时均拒绝准入;若存在受支持的 package-map,则使用该布局,损坏的 map 不会回退到平铺目录路径。
32
+
33
+ Guard 先核验 macOS 的 DeepSeek Developer ID 签名或 Windows 的 DeepSeek Authenticode 发布者,再将 ASAR 头与签名载体内的摘要比对。随后原位读取归档,按独立获取的官方 tarball 清单核验关键包内全部可执行/JSON 文件,包括 `lib` 外的脚本。签名归档的元数据只用于认证打包器改写的 manifest;新增代码、嵌套关键包、错误依赖路由及本地被改动的关键 peer 均拒绝。宿主锁同时绑定应用、载体、profile、安装映射与锁文件;注入和运行时复验采用同一链路,并核验 shell 渲染器及默认工作目录提供者。
34
+
35
+ Desktop 应用重启仍由应用自行管理,Guard 不提供该能力。最终制品的后端生命周期、图形界面和真实模型验收分别记录在对应 Release annex 中。定时提醒及超时问题的晚到答案仍不授予根指令权限;退出标记被后续 prose 遮挡时,结果保持 `unknown`,不再误判成功。
36
+
37
+ ### RC.2 message sources (CG-RC2-004 / CG-RC2-005)
38
+
39
+ RC.2 delivers scheduled reminders as `user/message` events with `source.kind === 'schedule'` and late answers to timed questions as `source.kind === 'user-question-reply'`. Neither is root user input: neither activates Guard, counts as real root input, creates work units, or is scanned for instructions. The authority for a schedule is the real user turn that created it, recorded in the durable log; the framing of a scheduled message (rc.2 renders it as "from the user") does not change that classification. A late answer belongs to its question/answer contract, never to a new instruction. Only `source.kind === 'user'` carries root authority, and unknown future source kinds fail closed the same way.
40
+
41
+ ### Consumer prerelease semantics
42
+
43
+ The plain npm/node-semver expression `>=0.2.0-rc.2` excludes later-tuple prereleases by default. The installed DSH plugin compatibility check (`dsh-app-boot`'s `evaluatePluginCompatibility`) uses `semver.satisfies(..., { includePrerelease: true })`, so a `>=0.2.0-rc.2` peer declaration admits `0.2.1-rc.1` and later RCs on the same tuple, and refuses below-floor values. `benchmarks/incidents/acceptance/semver-matrix.json` records the verified matrix for the new floor. pnpm's peer helper behaves the same way; package installation is not a version-admission proof — Guard's own floor check rejects a below-floor host independently.
44
+
45
+ ## 0.8.1: DSH >=0.2.0-rc.1
46
+
47
+ Version admission uses strict SemVer precedence, including later-tuple RCs and ignoring build metadata. The floor is `0.2.0-rc.1`, with no upper limit. 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.
48
+
49
+ The reviewed host baseline is DSH `0.2.0-rc.1` / Cordis `4.0.4`, with 46 package identities and published implementation digests in `manifests/rc020-rc1-byte-audit.json`. Real installed-graph source entry measurements exist for that baseline. Native acceptance of the final Guard artifact on each platform remains a separate gate; no native validation of a future host is claimed.
50
+
51
+ A newer compatible installation can be rebound with `--rebind-registry`, without adding an internal version row. The generator checks exact official registry metadata, archive SRI, installed manifests/modules and both CJS/ESM routes.
52
+
53
+ Qualification binds ordered entry-selection fields (`exports`, `main`, `imports`, package type and dependency declarations) as well as the reviewed ECMAScript programs. A changed entry or dependency cannot inherit qualification merely because the old file remains unchanged. `guard-host-contract/v2` probes use actual bare package resolution in separate ESM and CJS processes, including the acquired dependencies. Critical adapter entries must resolve to the same authenticated target in both lanes; auxiliary libraries may have separate authenticated lane implementations. Changed compatible entries can qualify without a version row; incompatible API, Session or guarded-effect behavior fails the contract.
54
+
55
+ A deterministic per-profile receipt binds all qualified bytes, dependency identities and actual Node startup conditions. Old v1 receipts require rebinding. If Node cannot execute an ESM package through `require`, the receipt explicitly records resolution-only CJS coverage; it does not claim CJS behavior was executed. Runtime and pre-install inspection verify the binding and recheck loading routes; a verified download or self-reported compatibility cannot establish qualification.
56
+
57
+ An unqualified optional Goal implementation disables only Goal integration and reports `host_contract_goal_qualification_required`; independent core work stays available. Different dependency package versions are allowed when their individual identities and routes agree. New graph/module expectations create a new digest, so prior certificates cannot transfer. See [rebinding](HOST_LOCK_UPGRADE.md#rebinding-compatible-package-versions).
58
+
59
+ The plain npm/node-semver expression `>=0.2.0-rc.1` excludes later-tuple prereleases by default. The installed DSH `0.2.0-rc.1` plugin manager and market discovery explicitly include prereleases: input probes accept `0.2.1-rc.1` and `0.3.0-rc.1`, and reject below-floor values without exemptions. pnpm 11.22.0's peer helper uses `includePrerelease: true`, and isolated version-form registry fixtures resolve those RCs. In the tested install mode it also resolved a below-floor peer despite strict-peer flags; package installation is therefore not a version-admission proof. The DSH and Guard floor checks independently reject that version. Other consumers must opt into equivalent semantics; plain npm matching is not the runtime version rule.
60
+
61
+ ## 0.8.0: DSH 0.1.7-rc.2 (historical fact, unchanged)
62
+
63
+ 0.8.0 metadata and its production selector accepted exactly `0.1.7-rc.2`, with Cordis `4.0.4`, cohort `dsh-0.1.7-rc.2-core-v1`, manifest `manifests/rc017-rc2-byte-audit.json`. That historical support scope is a property of the released 0.8.0 and is not rewritten by the 0.8.1 adaptation.
8
64
 
9
65
  Missing, duplicated, mixed, escaped or modified critical packages fail closed. A matching version or `allow-version` cannot bypass host identity. `auditedPlatforms: []` remains empty: local graph/module verification is separate from native acceptance of a frozen Guard tgz. See the [A01–A16 record](DSH_0_1_7_RC2_ACCEPTANCE.md).
10
66
 
@@ -61,7 +117,7 @@ Version 0.5.2 advertises only DSH `0.1.5-rc.2` and `0.1.5-rc.1`, with rc.1 retai
61
117
  ## Historical compatibility cohorts
62
118
 
63
119
  These are verification records, not support entries. An installed runtime built
64
- from any of them fails closed under the 0.8.0 policy.
120
+ from any of them fails closed under the 0.8.0–0.8.1 policy.
65
121
 
66
122
  - DSH `0.1.1-rc.2` + dshmarket `1.36.0` + Cordis `4.0.1` is a retained, published-line cohort.
67
123
  - DSH `0.1.2-alpha.2` + dshmarket `1.38.1` + Cordis `4.0.2` is the published 0.3.2 cohort checked natively on macOS and Windows.
@@ -73,7 +129,7 @@ from any of them fails closed under the 0.8.0 policy.
73
129
 
74
130
  ## Rejection rules
75
131
 
76
- The sole current core graph is recorded in [`../manifests/supported-host.v1.json`](../manifests/supported-host.v1.json); older graphs remain only in historical test fixtures. All core rows and actual critical dependency routes must match the current graph. Missing, mixed, duplicate, unknown or integrity-drifted core rows reject certification.
132
+ The reviewed baseline core graph is recorded in [`../manifests/supported-host.v1.json`](../manifests/supported-host.v1.json); older graphs remain only in historical test fixtures. For the baseline lock all core rows must match that graph. For a registry rebind, exact individual identities and qualified module expectations bind the new graph. Mixed dependency versions are allowed; missing required, duplicate, untrusted or integrity-drifted identities and wrong critical routes reject certification.
77
133
 
78
134
  Market versions do not select a core cohort. Market restart has its own protocol and loaded-instance checks; an unavailable adapter does not disable the core or erase pending restart work. Changing the actual core graph changes its digest and invalidates earlier certificates.
79
135
 
@@ -93,7 +149,7 @@ The plugin accepts an `activation` configuration value of `opt-in` or `always`.
93
149
 
94
150
  Before the Guard can certify work, generate and verify the host lock from the active DSH runtime and profile. Use the packaged `dsh-completion-guard-host-lock inspect|inject|verify-dump` flow in the README. The default patch has no `hostLockPackages`, so the Guard fails closed until this flow succeeds.
95
151
 
96
- Since 0.4.3, the generator injects `hostLockPolicy: dsh-core/v1`, the runtime/profile source roots, `hostLockPackages`, `hostLockPlatform`, and `hostLockProfile` together. Replay rechecks those actual graph sources; legacy configuration without the policy and roots reports `host_lock_migration_required`. Each critical package row records the exact resolved version and registry tarball integrity. The Guard does not infer a missing identity from a nearby lockfile: missing, duplicate, multi-version, or drifted rows fail closed. The audited identities are defined in [`../manifests/supported-host.v1.json`](../manifests/supported-host.v1.json).
152
+ Since 0.4.3, the generator injects `hostLockPolicy: dsh-core/v1`, the runtime/profile source roots, `hostLockPackages`, `hostLockPlatform`, and `hostLockProfile` together. Mount and protected entries recheck those actual graph sources; ordinary replay uses the mount result; legacy configuration without the policy and roots reports `host_lock_migration_required`. Each critical package row records the exact resolved version and registry tarball integrity. The Guard does not infer a missing identity from a nearby lockfile: missing, duplicate reachable instances, untrusted, or drifted rows fail closed. The audited identities are defined in [`../manifests/supported-host.v1.json`](../manifests/supported-host.v1.json).
97
153
 
98
154
  ### Capability groups
99
155
 
@@ -123,17 +179,16 @@ The ordinary runtime packages are host-provided peers:
123
179
  - `@deepseek-ai/dsh-session`; and
124
180
  - `@deepseek-ai/dsh-tools`.
125
181
 
126
- Goal support uses two exact optional peers as one capability. `@deepseek-ai/dsh-goal` owns Goal state, while `@deepseek-ai/dsh-tool-goal` owns the audited `update_goal` name, schema, and arguments. Both host-graph rows and the live Goal service and tool must agree. A profile without this complete pair can still load, but Goal-dependent integration stays inactive.
182
+ Goal support uses two identity-bound optional peers as one capability. `@deepseek-ai/dsh-goal` owns Goal state, while `@deepseek-ai/dsh-tool-goal` owns the audited `update_goal` name, schema, and arguments. Both host-graph rows and the live Goal service and tool must agree. A profile without this complete pair can still load, but Goal-dependent integration stays inactive.
127
183
 
128
- Version 0.5.2 publishes `0.1.5-rc.2 || 0.1.5-rc.1` in top-level
184
+ The historical 0.5.2 artifact publishes `0.1.5-rc.2 || 0.1.5-rc.1` in top-level
129
185
  `engines.dsh`, nested `dsh.engines.dsh`, and every DSH peer dependency. Cordis
130
186
  is versioned independently and remains `^4.0.2`. Plugin markets and package
131
187
  managers therefore see the same two exact host releases as the host-lock
132
188
  registry; neither an unregistered stable release nor a future version is
133
189
  implicitly admitted.
134
190
 
135
- The development dependencies retain exact `0.1.5-rc.1` pins as the build
136
- baseline. Historical peer declarations belong to their own release sections
191
+ That historical artifact retained exact `0.1.5-rc.1` development pins. The current build pins DSH `0.2.0-rc.1` while public DSH peers declare the floor range. Historical peer declarations belong to their own release sections
137
192
  above and are not part of the 0.5.2 contract.
138
193
 
139
194
  ## Terminal outcome contract
@@ -0,0 +1,85 @@
1
+ # Completion Guard:DSH RC.2 与 Desktop 开发任务
2
+
3
+ 本任务在 `dsh-context-guard` 仓库内独立完成。公开仓库及 npm 产品名是 `dsh-completion-guard`,Cordis entry id 仍为 `context-guard`。目标是把最低支持版本提高到 DSH `0.2.0-rc.2`,支持官方 Desktop,并在本次适配中完成全仓审阅、修复已复现的功能、性能和安全问题。实现完成后交给另一个 Codex 线程独立验收;本文件不是已经通过的实现或发布证明。
4
+
5
+ ## 1. 基线与工作边界
6
+
7
+ 2026-09-30 的调查基线是 `b18d31dda7fdecae5c6496446f33238ea945a93a`、插件 `0.8.1`,调查开始时工作区干净。启动开发时重新读取 HEAD、分支、dirty paths、AGENTS 和工具链,保留非本任务改动。基线变化不自动改变本文件的功能要求。
8
+
9
+ 最低版本是固定策略 `>=0.2.0-rc.2`,最新实际测试宿主暂定 RC.2;构建依赖和测试 runtime 则使用精确 RC.2。三者分别记录。未来升级不自动追随 registry `latest` 提高下限;高于下限的宿主不能因为未列入测试清单而被拒绝。实际 API、完整性或行为不合格仍必须拒绝相应能力。
10
+
11
+ 本轮准备已把本机 Web runtime 升至 RC.2,官方 Desktop 也为 RC.2。现有 Guard 保留安装但暂时禁用;旧 RC.1 host lock 保留用于恢复,不能直接用于 RC.2。当前状态及私有回读在 codex-sync 的 RC.2 准备记录中,不能当成新插件验收。
12
+
13
+ 本仓库自行设计、实现、检查和交付,不依赖 Session Insights 的进度或发布。开发 harness 不修改另一个插件、codex-sync 的消费者 pins、日常 runtime 或 Desktop app bundle。需要消费者适配时返回明确的适配要求。不要发布 npm、创建 tag/Release、推送、迁移日常 profile 或启用日常插件;这些是后续独立操作。分支采用 `codex/` 前缀,按平台权限执行。
14
+
15
+ ## 2. 已核实的上游与源码事实
16
+
17
+ - [官方 RC.2 发布页](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.2.0-rc.2),tag `dsh-v0.2.0-rc.2`,发布关联提交 `639ed01`。相关变化包括 Desktop 官方 dsh 命令、图形启动的登录 shell 环境、PowerShell 完成状态识别、定时消息语义及实验性异步问答。
18
+ - RC.2 官方 `dsh-app-boot` 的 `evaluatePluginCompatibility()` 使用 `includePrerelease: true` 检查 DSH peers。必须用这个真实消费者及市场消费者验证范围,不能只测普通 node-semver。
19
+ - 现有 `src/domain/host-version.ts` 已把最低版本与 `HOST_VALIDATED_VERSIONS` 分离;`host-lock.ts`、`host-trust.ts`、`host-resolver.ts` 和 `host-contract-program.ts` 已有 graph-derived registry rebind 路径。保留它,不能退回“每个新版本加一行才支持”的实现。
20
+ - `HostProfileKind` 只有 `web | headless`;profile 识别、目标图、lock 注入和 native 工具均没有正式 Desktop 分支。`resolveActiveProfileHostLock()` 用 Web bundle/market 推断 profile,Desktop 也包含 Web app bundle,不能沿用该推断。
21
+ - 现有源码测试基线(RC.1 测试依赖):`pnpm test` 为 169 个文件通过、1 个文件跳过;2812 个测试通过、7 个跳过。只建立现有源码基线,不建立 RC.2、Desktop、新 tgz 或新模型行为证据。
22
+
23
+ ## 3. 本次问题登记
24
+
25
+ | ID | 级别与状态 | 定位与影响 | 结案要求 |
26
+ | --- | --- | --- | --- |
27
+ | CG-RC2-001 | 必须实现;已确认 | package.json 的双层 engines/DSH peers,`host-version.ts`、RC.1 manifest/dev pins:下限仍为 RC.1 | 所有当前准入面统一 RC.2 下限;RC.1 拒绝,后续 RC/stable 接受版本准入;历史记录保持原事实 |
28
+ | CG-RC2-002 | 必须实现;已确认 | `host-lock.ts`、`host-resolver.ts`、`config.ts`、bin、native scripts:Desktop 缺失且可被误识别为 Web | 显式 Desktop 身份、正确官方 CLI/Node/包图、独立 profile-bound lock 和生命周期证据 |
29
+ | CG-RC2-003 | P2;强制测量后结案 | `runtime.ts` 的 `rebuild()`、`sync()`,`session-events.ts` 与 private-ledger:反复全日志投影;host audit 是同步 I/O | 测事件数/entry 次数/文件读取/耗时和峰值资源;可复现回退必须修复。不得凭猜测新增跨 entry 信任缓存 |
30
+ | CG-RC2-004 | 语义适配;强制设计与复现 | RC.2 schedule 产生 `source.kind=schedule` 的 user message;`derive.ts` 对 root input 只接受 `kind=user` | 明确定时指令/用户授权继承策略,覆盖真实生产路径;不能简单把所有 schedule 或 role=user 都升级成 root authority |
31
+ | CG-RC2-005 | 审阅风险;待复现 | RC.2 异步问答、late answer、取消、resume、子代理通知与 Stop/Goal/boundary 状态交互 | 无提前结案、重复 capture、错误暂停或旧证书复用;实验功能关闭/开启分别检查适用行为 |
32
+
33
+ CG-RC2-004 的合成对照已在提交的 dist/domain 运行:相同 user-role 文本,`source.kind=user` 得到 `realRootInputSeen=true`,`kind=schedule` 得到 false。它证明现行来源分类差异,尚不证明新的授权策略应当如何实现。必须核对实际定时任务记录、用户授权与宿主投递关系,再决定适配或保留限制并给出理由。
34
+
35
+ 对于新增发现:先建立最小复现和稳定 ID,记录影响、共同原因、修复与回归。不能把猜测写成已确认漏洞,也不能以“这只是审阅”略过已复现的本次范围内问题。低价值重构和新产品功能可列 backlog,必须说明边界。
36
+
37
+ ## 4. 设计与实现要求
38
+
39
+ ### 版本准入与宿主资格
40
+
41
+ 1. 同步顶层 `engines.dsh`、`dsh.engines.dsh`、各 DSH peer 最低值、运行时 floor、支持 manifest、生成工具、当前 README/兼容性/迁移文档及 fixture identity。dev pins 和实际测试 runtime 精确绑定 RC.2;Cordis 单独验证,不因 DSH 版本一起随意放宽。
42
+ 2. 版本向量至少含:RC.1、RC.2、RC.3、0.2.0 stable、0.2.1-rc.1、0.3.0-rc.1、1.0.0、带 build metadata 的 RC.2、非法值。未来版本仅做消费者/生产准入合成测试,不谎称真实宿主验收。
43
+ 3. RC.2 关键包从官方 archive/SRI 重新研究,报告实际 API/程序/依赖与 RC.1 差异。保留旧 manifest 的历史用途;新的资格证明必须绑定所有实际选中 executable/JSON inventory、ESM/CJS 路由、Node conditions 和依赖身份。
44
+ 4. 验证“新但兼容的程序经生产 rebind 可以资格化”和“API/行为/字节/路由破坏被拒绝”。不能用测试 seam、复制已签信任、仅换版本字串或只扩 cohort 表来替代。
45
+ 5. 核对 Goal、jobs、shell、fs、session flush 的必要/可选能力边界;缺可选 Goal 时只按既定策略禁用 Goal,不把整套 core 误报支持或全部瘫痪。
46
+
47
+ ### Desktop
48
+
49
+ 1. 使用官方 app 的命令 carrier 与 bundled Node/pnpm。Web/Headless 仍使用显式管理的 CLI runtime。PATH 上同名 dsh、系统 Node、临时 npm CLI 均不是 Desktop 身份替代物。
50
+ 2. 读取 app/runtime/host/primary metadata、profile bundles、实际 import graph 和真实解析路由。app.asar/安装型图没有 pnpm `.package-map.json` 时设计真实适配器;不能伪造 map,也不能把 app bundle 解包后当作官方运行图。
51
+ 3. Desktop profile 身份独立进入 digest、trust receipt、lock、config schema 和 native annex。Web lock 或证书不得复制到 Desktop;app 或 profile 路径别名、同名包 shadow、混合图、错误 Node startup conditions 均需负例。
52
+ 4. 扩展 repository-owned host-lock/native 工具:显式选择 Desktop,不要求 CLI 启动桌面 UI;通过官方图形启动/退出处理生命周期,安装前检查主程序及 host children 已退出,尤其 Windows 原生模块占用。
53
+ 5. 升级与重装保留模型/MCP、bundles、禁用偏好、skins、日常数据和 account state;备份、atomic apply、失败恢复及第二次严格 no-op。不要改 app.asar 或绕过 Desktop 保留 profile 管理。
54
+
55
+ ### 全仓审阅与性能
56
+
57
+ 至少逐项覆盖:root capture/附件及引用授权、work units/supersession、evidence/target/locator/digest、checkpoint/closure/Stop、Goal、recovery/compaction/replay、private ledger/损坏恢复、external operations/jobs/用户暂停、release reservation/settlement、shell/pwsh/fs/native adapters、host version/graph/trust/rebind、CLI/安装/迁移、公开隐私、双语文档、pack inventory/CI。包含提交的 dist、manifests、tests、scripts、bin 和 npm 文件表;文档里的宣称也要对照实际执行入口。
58
+
59
+ 提交覆盖表:模块/阅读位置/生产入口/现有测试/新增复现/结案或残余风险。审阅不是给所有目录标一个“看过”。特别检查 RC.2 PowerShell 末尾空格/退出码、unknown tool outcome 不能成为成功或确定失败、late user answer 不能串 turn、历史工具文本不能创建 authority。
60
+
61
+ 性能至少对 0、100、1000、10000 个事件和短/长私有账本测量,包含长 tool output;同一宿主同一环境各 5 次,报告中位数与 p95、物理读取次数/字节、投影次数和峰值 RSS。性能 harness 的 synthetic/source/native 分类必须明确。修复重复解析/无界输入/泄漏时保留新鲜的 pre-effect host validation、durability 与 fail-closed;无可复现回退可用有依据的“无需变更”结案。
62
+
63
+ ## 5. 开发、打包与验收
64
+
65
+ 先关闭复现问题,再做完整 candidate gate。按 AGENTS 的完整矩阵:typecheck、lint、Vitest、release-pack tests、stats tests、build、pack dry run、文档 audit 及其测试、`git diff --check`;build 后核对 dist 无意外漂移。选择器和 repair-families 可用于修复阶段,不代替 freeze 矩阵。
66
+
67
+ 最终按仓库干净源码要求提交一个本任务候选 commit(若接收线程的实际权限允许);不要混入 unrelated changes。使用 `scripts/release-pack.mjs` 生成唯一 tgz、SHA256SUMS 和 release-artifact。新版本原暂建议 0.9.0;独立复核确认未改变任务、证书或数据协议,按维护者的版本连续性要求采用 0.8.2;不占用已发布版本。不在不同平台重打包,不提前发布。
68
+
69
+ | Gate | 独立验收要检查的事实 |
70
+ | --- | --- |
71
+ | G1 源码与准入 | RC.2 floor、真实 DSH/market 消费者、未来版本合成向量、Core/Goal 资格与拒绝路径;全仓问题登记结案 |
72
+ | G2 portable/CI | repository-owned 实际生产入口、RC.2 契约、跨 OS/Node 矩阵;不将 fixture pass 报成原生通过 |
73
+ | G3 制品 | 全 commit、tgz SHA256、嵌入 gitHead、安装文件 inventory、clean source、dist 同步 |
74
+ | G4 macOS native | 同一 tgz 的 Web、Headless、官方 Desktop 安装、strict no-op、lock/字节/路由、启动/取消/重启/恢复、卸载/清理与状态还原 |
75
+ | G5 Windows native | 独立执行同样三种宿主;Desktop 真 app、pwsh/shim/原生模块占用,不用 macOS 或 CI 代替 |
76
+ | G6 行为与页面 | 非空真实生产路径的 capture→checkpoint→Stop,未满足拒绝、满足允许、暂停/等待/Goal/compaction;Desktop 实际设置和插件状态;必要的模型批次单独绑定来源和结果 |
77
+ | G7 文档 | 中英文 README/CHANGELOG/兼容性/升级操作清晰且事实一致;最终字节 cold review,公开面无私有路径/真实会话 |
78
+
79
+ 初始开发验收至少完成 G1–G3 和可用平台的 G4/G5;缺少平台或模型能力必须保留 pending,不能整体标“支持 Desktop 已验收”。独立 Codex 验收最终关闭所需平台/模型/UI gates,输出逐项结果,不把发布或消费者 apply 混入开发结论。真实模型沿用现有登录,不因隔离 HOME 重做登录;未运行的部分明确给出 owner 和 resume event。
80
+
81
+ ## 6. 返回给独立验收线程
82
+
83
+ 交付一个聚合 handback:候选 commit/dirty 状态与任务 diff;稳定问题 ID、复现及修复解释;全仓审阅覆盖与性能数据;源码/CI/制品/native/模型/UI 各自的命令、结果和 subject identity;唯一 tgz 与 checksum/inventory;final reader-review;公开可用的迁移说明;仍待验收项、未执行外部操作和恢复方法。使用 `agent-handoff/v1`,不要返回真实会话或原始凭据日志。
84
+
85
+ 独立 Codex 线程先阅读这个 handback、检查 subject 和差异,再对缺失或失效的 gate 验收。修复回合只重跑受影响 gates,重复同类失败时审查共同原因及所有入口,不重复无关通过项。
@@ -0,0 +1,148 @@
1
+ # Historical incident coverage
2
+
3
+ Verification date: 2026-09-28 (two evidence rounds). The adjudication round
4
+ ran its working tree on the `1e88176` lineage and the four adaptation cases it
5
+ introduced were first committed in `f4a9497`; the review-repair round added the
6
+ scope-aware auditor fix, the 040 compaction/restore chain and the 042 A–E
7
+ authorization-continuation chain on top; the third repair round fixed the
8
+ core-v2 action-evidence mismatch (a Git operation can no longer satisfy a
9
+ different same-repository action, and same-root clauses bind only their own
10
+ evidence) and made the fully observed 042 chain certify. This document therefore binds each
11
+ row to the NAMED CASE CONTENT and to the commit that first contained it — a
12
+ bare base-commit number is never the evidence. The release candidate commit is
13
+ a later, separate fact and is never referenced from packaged documentation.
14
+
15
+ ## Method and verdict vocabulary
16
+
17
+ Every one of the 28 records gets its own row and one of four verdicts. A
18
+ verdict is never inherited from a file-level or family-level green run.
19
+
20
+ - `executed_pass` — the DSH adaptation of the record's failure family is
21
+ pinned by named `it()` cases with named assertions, and those cases pass at
22
+ the base commit. Family members may share one case; the case is named for
23
+ each member.
24
+ - `not_applicable` — the incident surface does not exist in DSH (product
25
+ boundary). The row must still name the positive/negative controls that pin
26
+ the analogous invariant DSH does keep.
27
+ - `analogue_only` — the input surface exists in DSH but the original expected
28
+ behavior is intentionally different. The row must name the tests that prove
29
+ DSH's actual path in both directions plus the documented difference.
30
+ - `pending` — no replayable DSH evidence exists yet. The row must list the
31
+ missing minimal events, trigger steps, and observation conditions.
32
+
33
+ ## Library binding
34
+
35
+ - Historical evidence lives in the maintainer's sanitized historical
36
+ regression set, kept outside this repository; raw records, private session
37
+ material and machine-local mappings are never copied into public files.
38
+ The per-record table below is a historical producer statement for a former
39
+ 28-record subset and is superseded for acceptance purposes by the current
40
+ full-library adjudication (56 cases / 45 active — 29 Codex, 16 DSH — plus a
41
+ frozen 16-record legacy lineage), whose per-case verdicts, execution lanes
42
+ and candidate binding are tracked in that sanitized set.
43
+
44
+ ## New adaptation tests added for this adjudication
45
+
46
+ 1. `tests/v6-recovery-feedback.test.ts` — "a legal correction after the armed
47
+ follow-up ends the turn safely with the work still pending" (014/023 full
48
+ chain, see row).
49
+ 2. `tests/runtime.test.ts` — "keeps the protocol correction message
50
+ fixed-size regardless of session debt" (020/029).
51
+ 3. `tests/domain/v030-manifests.test.ts` — "routes simulation variants through
52
+ the same stateful mutation lane as the real mutation" (019/028).
53
+ 4. `tests/runtime.test.ts` — "a cleanup request never carries mutation
54
+ authority for product repair" (012).
55
+
56
+ Review-repair round additions:
57
+
58
+ 5. `tests/v6-recovery-feedback.test.ts` — "an answered explicit question is
59
+ not re-injected after compaction and restore while the open one stays
60
+ current" plus the conversational-phrasing boundary control (040).
61
+ 6. `tests/native-file-v2.test.ts` — the CGI-2026-042 A–E describe: one root
62
+ commit-and-push authorization across five edit/commit shapes, with the
63
+ fully observed chain certifying through the registered checkpoint tool (042).
64
+ 7. `tests/native-file-v2.test.ts` — the action-mismatch review block: a Git
65
+ operation cannot satisfy a different same-repository action, and a compound
66
+ root satisfied by only one action keeps the other clause insufficient.
67
+
68
+ ## Per-record verdicts
69
+
70
+ | ID | Original oracle (sanitized) | DSH production path / adapter | Regression evidence (exact case + assertion) | Verdict |
71
+ | --- | --- | --- | --- | --- |
72
+ | CGI-2026-009 | A-tier high-risk action (tag/release creation) observed with no pre-action decision and no ticket | `authorizeMutationFromProjection` fail-closed chain; every stateful mutation request needs an exact pending root-owned item | `tests/runtime.test.ts` "authorizes a mutation only for the exact pending root-owned action and target" asserts `mutation_contract_item_missing` when no item exists, plus revision/action/target mismatch denials; `tests/runtime.test.ts` it.each "rejects incomplete %s root authority before mutation" denies `publish`/`push` with incomplete root targets; `tests/v081-production-entry-drift.test.ts` "charges one validation to the checkpoint entry and one to the whole publish entry, and refuses drift between entries" pins real production entries to fresh validation | executed_pass |
73
+ | CGI-2026-010 | Declared deferred disposition overrode observed authorized remaining work; disposition was not validated against its owner | `decideTurnBoundary` takes no assistant text at all; declared dispositions are bounded diagnostics only; a typed boundary needs an immutable root qualification | `tests/domain/v030-stop-boundary.test.ts` "keeps completion prose diagnostic-only and protocol decisions metamorphic"; `tests/domain/v030-stop-boundary.test.ts` "accepts user_wait only from a current immutable wait authorization"; `tests/runtime.test.ts` "steers exactly once for root persistence and yields to an active armed Goal" | executed_pass |
74
+ | CGI-2026-011 | Quoted/annotated text was treated as a root correction superseding a prior requirement | Supersession requires an explicit mechanism: identical re-statement, or an explicit rebind confirmation with a proposal id; wrapped/misplaced control is ambiguous | `tests/domain/core.test.ts` "derives distinct IDs and supersedes identical re-statements" (R001 superseded only by an identical re-statement, `supersededBy` pinned); `tests/domain/v050-confirm.test.ts` "a valid control line that is not the first line is ambiguous, never applied" and "two different proposals in one message stay ambiguous without partial effect"; `tests/domain/v061-conservative-interpretation.test.ts` "a verbatim concrete instruction supersedes an unresolved clause (review repro: clarification lane)" names the only legal supersession lane | executed_pass |
75
+ | CGI-2026-012 | Authorized cleanup scope silently continued into new product repair without separate authorization | Cleanup grants no mutation authority; a repair needs its own pending root-owned item with a matching semantic action and target | `tests/runtime.test.ts` "a cleanup request never carries mutation authority for product repair" — `authorizeMutationFromProjection` denies `modify` citing a cleanup item; `tests/domain/v062-capability-and-layers.test.ts` "only dependency_free enters the removal set" and "a clean tree or an empty worktree list never proves \"no dependants\"" bound the cleanup scope itself; `tests/v6-recovery-feedback.test.ts` "a cleanup request keeps the dependency-free condition at every budget and view state" | executed_pass |
76
+ | CGI-2026-013 | Every prompt chained a child work unit; historical items kept entering Stop gating | Units open only from delegation-marked roots; a task switch opens a sibling; stale siblings never join the current view | `tests/domain/v060-unit-closure.test.ts` "an ordinary task switch opens a sibling that never blocks the newer unit"; `tests/domain/v060-unit-closure.test.ts` "the delegation vocabulary is closed: a subagent mention without an act never opens a unit"; `tests/v6-recovery-feedback.test.ts` "a stale pending sibling-unit record does not join the current recovery rows" | executed_pass |
77
+ | CGI-2026-014 | Checkpoint gap re-triggered visible continuations far beyond one bounded correction | Checkpoint rejection arms one bounded follow-up; repeats dedup; a legal correction ends the turn safely; unfinished work is never marked complete | `tests/v6-recovery-feedback.test.ts` "invalid-proof: reminders do not repeat after a persisted continue and the same rejection" and the `failed-flush` twin (0 after 3 rejections); `tests/v6-recovery-feedback.test.ts` "a legal correction after the armed follow-up ends the turn safely with the work still pending" — full chain: reject → one injection → real successful host test → `observed` checkpoint → zero follow-ups → `handleGuardTurnStopping` returns `safe_yield_pending_preserved`, steers nothing, no certificate exists, item stays `pending`; `tests/domain/v051-host-loop.test.ts` "disarms the armed goal and stops further rounds and model calls" (real host loop: two production decisions then the bounded stop, zero further model calls) | executed_pass |
78
+ | CGI-2026-015 | Declared user_wait/deferred were judged mismatched against an observed external_wait and each produced a visible continuation | Dispositions are strictly typed against their qualification source, not lexically compared: external_wait needs a live trusted-adapter operation, user_wait needs a root wait authorization | `tests/tools/boundary-integration.test.ts` "round-trips live jobs readback through derive, boundary tool, and persisted replay" (only a real `running` operation qualifies `external_wait`); it.each "maps pinned ctx.jobs status %s to %s without parsing output text"; `tests/runtime.test.ts` "live-requalifies every external_wait job immediately before effectuation" — a completed job yields `boundary_pre_effect_failure`, never a continuation; `tests/domain/v030-stop-boundary.test.ts` "requalifies a live external operation before yielding or disarming" | executed_pass |
79
+ | CGI-2026-016 | hooks.json attached a statusMessage to every allow event and injected receipts on normal prompts | No DSH counterpart: DSH has no hooks.json surface and no statusMessage writer (`grep statusMessage src/` = 0 hits). Allow-path silence is pinned by controls. The one additional-context producer is the bounded read-only shell-workdir observation on bash/pwsh (`src/runtime.ts` workdir receipt), an evidence channel, not an allow-path status writer | Controls: `tests/v6-recovery-feedback.test.ts` "T0 stays silent; the first root carries the boundary once; …"; `tests/domain/v062-capability-and-layers.test.ts` "an ordinary business tool call gains no Guard approval requirement" and "a pending obligation can end silently without being reported as complete"; `tests/host-workdir-v070.test.ts` "records the same passive notice through the real Cordis tool waterfall" (the bounded receipt's exact scope) | not_applicable |
80
+ | CGI-2026-017 | A-tier mutations always demanded an exact ticket even though no release contract was ever adopted | Release class needs an adopted contract AND the protected release surface; non-release stateful mutations need only root authority; adoption is explicit and durable | `tests/tools/v060-release-chain.test.ts` "publishes under a real adopted contract, reserves, settles, and reconciles" (the only allow path); `tests/domain/v060-release-migration.test.ts` "a keyword, a Skill or an installation never adopts a contract" and "a contract naming an unprotectable operation is refused at adoption"; `tests/domain/review-counterexamples.test.ts` "R2: missing observed repository/ref and invented readiness must not grant" (`releasePreEffectDecision` denied) | executed_pass |
81
+ | CGI-2026-018 | Command classifier accepted any token whose basename matched git/gh, so echo/search arguments became tier-A/B actions | Whitelisted single-command parser: only the executable position is consulted; quoted/argument command words never become executables | `tests/domain/core.test.ts` "parses shell commands quote-aware (P0-2 / P1-2)" asserts `parseShellCommand('echo "ignored; pnpm test"').executables` is exactly `['echo']` and wrappers fail closed; "does not let quoted text invent an executable method (P0-2 negative)" and "does not let echo-only bash close a create requirement (P0-1 negative)" pin the denial side | executed_pass |
82
+ | CGI-2026-019 | Explicit no-side-effect variants (`npm publish --dry-run`) consumed real-mutation authorization (false deny without recourse) | DSH deliberately has no simulation lane: the dry-run spelling classifies as the same stateful `publish` action. The verified boundary is the classification lane; the authorization/reservation/effect behavior beyond it is governed by the named release surfaces, not asserted here | `tests/domain/v030-manifests.test.ts` "routes simulation variants through the same stateful mutation lane as the real mutation" (`npm publish --dry-run` → `publish`, `git push --dry-run origin main` → `push`, both `isStatefulAction`, identical to the real spellings); prose-mention control: `tests/domain/v051-instruction-semantics.test.ts` "explaining a command is not executing it (0.6.1: unresolved, closable only via the interpretation route)" asserts no `publish` obligation from the explanation probe; the release-side denial controls live in `tests/domain/review-counterexamples.test.ts` (R1–R3: identity kind mismatch, invented readiness, failed-without-readback all denied) | analogue_only |
83
+ | CGI-2026-020 | Stop correction message appended every requirement/acceptance id in the session, far beyond the 240-char budget | The real correction message is a fixed notice handed to the model by the production turn-stopping entry; its size is independent of open-item count | `tests/runtime.test.ts` "keeps the protocol correction message fixed-size regardless of session debt" — with 60 extra open items the steered message is byte-identical to the 1-item message, equals `PROTOCOL_CORRECTION_NOTICE`, ≤240 chars, and contains no item ids; packet budgets are a separate, existing surface (`tests/tools/v042-feedback.test.ts` "T08 reserves rules and next steps even after an oversized item") | executed_pass |
84
+ | CGI-2026-021 | MCP thread-read alias set matched only the short name, so the real event never bound a readback subject | No DSH counterpart: DSH has no MCP thread-read tool or alias table (`grep read_thread\\|THREAD_READ src/` = 0 hits). Subject binding happens only through structured native-observation metadata and known adapters | Controls: `tests/domain/v030-capture-targets.test.ts` "$action captures root identity and rejects adapter target substitution" (it.each); `tests/native-file-v2.test.ts` "certifies an observed edit without a Guard execution qualification or resolution call" asserts a text-only or tampered state row yields `insufficient`/`incomplete` — echoed text can never bind as state evidence | not_applicable |
85
+ | CGI-2026-022 | Reproduced supersedes CGI-2026-013 (same work-unit lifecycle family) | Same production path as CGI-2026-013 | Same three named cases as CGI-2026-013 | executed_pass |
86
+ | CGI-2026-023 | Reproduced supersedes CGI-2026-014 (checkpoint failure cascade family) | Same production path as CGI-2026-014 | Same named cases as CGI-2026-014, plus `tests/runtime.test.ts` "steers exactly once for root persistence and yields to an active armed Goal" pinning `protocol_correction_already_issued` on the second attempt at the same boundary | executed_pass |
87
+ | CGI-2026-024 | Reproduced supersedes CGI-2026-015 (disposition subclass family) | Same production path as CGI-2026-015 | Same named cases as CGI-2026-015 | executed_pass |
88
+ | CGI-2026-025 | Reproduced supersedes CGI-2026-016 (allow-path status/ receipt family) | Same product boundary as CGI-2026-016 | Same controls as CGI-2026-016 | not_applicable |
89
+ | CGI-2026-026 | Reproduced supersedes CGI-2026-017 (release machinery without adoption family) | Same production path as CGI-2026-017 | Same named cases as CGI-2026-017 | executed_pass |
90
+ | CGI-2026-027 | Reproduced supersedes CGI-2026-018 (executable-position family) | Same production path as CGI-2026-018 | Same named cases as CGI-2026-018 | executed_pass |
91
+ | CGI-2026-028 | Reproduced supersedes CGI-2026-019 (simulation classification family) | Same production path and verified classification boundary as CGI-2026-019 | Same named cases as CGI-2026-019 | analogue_only |
92
+ | CGI-2026-029 | Reproduced supersedes CGI-2026-020 (unbounded Stop feedback family) | Same production path as CGI-2026-020 | Same named cases as CGI-2026-020 | executed_pass |
93
+ | CGI-2026-030 | Reproduced supersedes CGI-2026-021 (thread readback binding family) | Same product boundary as CGI-2026-021 | Same controls as CGI-2026-021 | not_applicable |
94
+ | CGI-2026-040 | An answered question was replayed into the recovery view after resume; the unit stayed active | Recovery injection consumes the current confirmed view: closed/answered work is not re-injected, unchanged packets dedup, re-injection needs real content change | Full compaction/restore chain: `tests/v6-recovery-feedback.test.ts` "an answered explicit question is not re-injected after compaction and restore while the open one stays current" — question A captured and answered in its own turn, question B captured and left open, then `compaction/summary` and a strict `Session.fromRestore` into a new session; the resumed registered pre-step injects nothing containing A and the restored contract keeps A `answered` while B stays `pending`. Input boundary controls, same file: "the original conversational question phrasing stays outside the contract entirely" (the original record's bare question is conversational in DSH and never becomes an obligation) and the existing resume/dedup lane "injects nothing for an observed ordinary closure after resume", "injects the unmet view after resume, dedups repeats, and follows real changes", `tests/runtime.test.ts` "does not re-arm recovery from a historical compaction summary". The original private question texts are not reproduced; the chain uses structure-preserving sanitized fixtures, so this row is the DSH adaptation of the failure family, not a claimed precise replay of the original inputs | executed_pass |
95
+ | CGI-2026-041 | A mixed update+cleanup request collapsed to cleanup-only and the patch was denied | Mixed requests keep every execution obligation through prepare and the authorizer; answered information ranges are not re-listed | `tests/tools/v063-host-materialization.test.ts` "a mixed request keeps its execution obligations through prepare and the authorizer" — the prepared list keeps both execution items and each commit/push obligation is denied only for the real reason (missing authority), never collapsed; `tests/domain/v063-holdout-round35.test.ts` "an agreeing pair is inherited whole" / "a conflicting pair leaves only the branch open" pin clause-level preservation | executed_pass |
96
+ | CGI-2026-042 | Ordinary host edit/commit/push forced re-authorization when the observer missed edit provenance; insufficient observation still denied | Authorization identity comes from the root contract items and never re-arms; each clause is satisfiable only by observations of its OWN semantic action (`src/core-v2/session.ts` evidence-applicability gate); certification tracks the shared-core closure | `tests/native-file-v2.test.ts` CGI-2026-042 describe, it.each over the five original shapes (A python-recorded edit/direct shell commit, B observed edit/direct commit, C explicit file edit/direct commit, D python-recorded edit/commit, E recognized edit/text-only result; the Python shapes are session-recorded adaptation forms, not native Python-process runs): ONE root message authorizes modify+commit+push, all three items share `sourceMessageId`, and `authorizeMutationFromProjection` authorizes the commit and push from those same root items with no new root input in every shape. The fully observed B chain certifies through the REGISTERED `context_guard_checkpoint` tool with per-clause bindings, each citing exactly its own effect+state ids; A/C/D/E keep the edit (and, for D, the wrapper commit) insufficient and refuse any certificate naming only `current_closure_unmet`, never the push binding. Supporting surfaces: "certifies an observed edit without a Guard execution qualification or resolution call" (tampered/missing observation → `insufficient`, `certifiable: false`), "reads back a native commit and push from fixed Git queries after persisted results" (wrong branch → `incomplete`; unbound amend output → `unavailable`), `tests/host-workdir-v070.test.ts` "does not retrospectively grant old calls that lack a call-time receipt". The same file pins the action-mismatch family directly: a Git operation cannot satisfy a different same-repository action (cross observations rejected, matching actions accepted) and a compound root satisfied by only one action keeps the other clause insufficient with the closure uncertifiable | executed_pass |
97
+ | CGI-20260913-codex-archive-043 (archive 043) | Report-level (Windows 0.12.1): repeated authorized-commit denials after real commits | Analogue surface exists (`tests/native-file-v2.test.ts` commit/push readback; `tests/domain/v051-target-identity.test.ts` refused push targets) but the record itself has no replay | Missing minimal events: (1) the root message binding commit-and-push intent, (2) the real `git commit` in both the compound and independent forms, (3) the denial event with its exact reason code per push attempt, (4) the persisted projection showing the commit evidence at denial time. Trigger steps: fresh Windows rc.2 host, current candidate, ordinary repo, one explicit authorization, edit→commit→push via both command forms. Observation conditions: full hook/session log with reason codes; no private repo content in the record; native Windows only — CI or synthetic hosts do not qualify A cold/warm first-open measurement does NOT produce any of these events and is not acceptance for this record; remaining input: a dedicated native commit/push denial run (owner: coordinator native batch). | pending |
98
+ | CGI-20260913-codex-archive-044 (archive 044) | Report-level (Windows 0.12.1): an unnecessary supersession clarification on an ordinary follow-up | Analogue surface exists (`tests/domain/v061-conservative-interpretation.test.ts` conservative supersession) but the record has no replay and its own pure probes did not reproduce | Missing minimal events: (1) the prior durable state with ≥2 unfinished requirements, (2) the exact follow-up prompt, (3) the emitted clarification event (or its absence) with reason code, (4) a current-version pure-probe run for contrast. Trigger steps: rebuild the two-open-requirement chain on a current host, send the follow-up, compare legacy-state vs pure-probe event streams. Observation conditions: durable session logs on both runs; same version/platform; the comparison, not either run alone, is the evidence A cold/warm first-open measurement does not exercise this chain; remaining input: the paired legacy-state/probe run (owner: coordinator native batch). | pending |
99
+ | CGI-20260913-codex-archive-045 (archive 045) | Report-level (Windows 0.12.1): a generated private diagnostic control was rejected as malformed, with no successful diagnosis | No DSH analog can be named without the control grammar; the record explicitly omits the raw control and the rejecting event is unresolved | Missing minimal events: (1) the regenerated control value with its documented grammar, lifetime and wrapper, (2) the emitting tool/event identity, (3) the exact rejection event with reason code, (4) one accepted-control run for contrast. Trigger steps: on a current host invoke the diagnostic lane with a valid current control and invalid controls; capture accept/reject per input. Observation conditions: rejection captured from the session log; no real private control value archived; the accepting run must show the bounded diagnosis the record never observed A cold/warm first-open measurement exercises none of this; remaining input: regenerated control grammar + paired accept/reject run (owner: coordinator native batch, after the grammar is recovered). | pending |
100
+
101
+ ## Denominator and totals
102
+
103
+ - `executed_pass`: **19** (009, 010, 011, 012, 013, 014, 015, 017, 018, 020,
104
+ 022, 023, 024, 026, 027, 029, 040, 041, 042)
105
+ - `not_applicable` (Codex-only surface, with controls): **4** (016, 021, 025, 030)
106
+ - `analogue_only` (documented intentional difference, both directions proven): **2** (019, 028)
107
+ - `pending` (report-level, no replay conditions met): **3** (043, 044, 045)
108
+
109
+ Only the Codex Python/runtime suites of the private library were treated as
110
+ upstream evidence; no row above counts a Codex-runtime pass as a DSH pass.
111
+
112
+ ## Regression suite runs used for this adjudication
113
+
114
+ - Adjudication round (working tree at `1e88176`, cases first committed in
115
+ `f4a9497`): batch 1 — `tests/v6-recovery-feedback.test.ts`,
116
+ `tests/runtime.test.ts`, `tests/domain/v030-manifests.test.ts`: 3 files,
117
+ 105 passed; batch 2 — the 23 remaining evidence files named in the table:
118
+ 23 files, 448 passed, 1 skipped (pre-existing platform skip), 0 failed.
119
+ - Review-repair round: reviewer repro patches verified RED at `b1ae3b6`
120
+ (4 negative scope cases + the full `revalidateCoreLock` entry), then GREEN
121
+ after the scope-aware auditor fix; `tests/domain/host-dependency-audit.test.ts`
122
+ 20 passed; rc017-adaptation family 143 passed / 3 skipped; upgrade,
123
+ target-identity and qualification families 246 passed; full matrix and CI at
124
+ `a0bf01f` green.
125
+ - Action-mismatch repair round: reviewer patch verified RED at `a0bf01f`
126
+ (2 failed / 2 passed), then GREEN after the evidence-applicability fix in
127
+ `src/core-v2/session.ts`; `tests/native-file-v2.test.ts` 16 passed;
128
+ rc017-adaptation 143 passed / 3 skipped, qualification 172, target-identity
129
+ 168, upgrade 82; mirror/conformance/portable-semantics/081 entries
130
+ 207 passed / 1 skipped. Full deterministic matrix, CI, and packaging stay
131
+ governed by the candidate freeze record; this page pins per-case evidence
132
+ only.
133
+
134
+ ## Explicit gaps carried forward
135
+
136
+ 1. 043–045 stay pending on their own listed minimal events. A cold/warm
137
+ first-open latency measurement produces none of those events (no
138
+ commit/push denial chain, no legacy-state clarification chain, no
139
+ diagnostic-control grammar), so it is not an acceptance vehicle for them;
140
+ each row names its remaining input and owner.
141
+ 2. 019/028 remain an intentional architectural difference at the verified
142
+ classification boundary: DSH classifies simulation spellings as their real
143
+ stateful mutation. If DSH ever grows a simulation lane, the family needs a
144
+ dedicated regression before release.
145
+ 3. 016/021/025/030 are Codex-product-only surfaces; they cannot regress on
146
+ DSH and stay recorded for cross-product audits, with the controls named in
147
+ their rows re-checked if DSH grows an allow-path status writer or an MCP
148
+ thread-read adapter.
@@ -1,6 +1,20 @@
1
1
  # Upgrading the core host lock
2
2
 
3
- Version 0.8.0 requires DSH `0.1.7-rc.2` and Cordis `4.0.4` only. Its 46 critical packages must match the registered identities, implementation bytes and actual dependency paths. Guard's exact DSH core is separate from optional market versions.
3
+ Version 0.8.2 requires DSH `>=0.2.0-rc.2` and qualified Cordis `>=4.0.4`. Upgrade order and what each step produces:
4
+
5
+ 1. Stop the host, upgrade DSH to `0.2.0-rc.2` or a later version, then install this Guard version.
6
+ 2. Rebuild the host lock for each Guard profile by running `inspect`, `inject` and `verify-dump` from an accepted package or matching source checkout:
7
+ `node bin/dsh-completion-guard-host-lock.mjs inject --runtime-root <DSH runtime> --profile-root <profile>` — then verify with `... verify-dump --dump-config <file>`. A successful rebuild reads back `supported` with `audit_provenance` stating how the graph was established.
8
+ 3. Start each Web/Headless profile when needed so it reads the rebuilt lock. The checks above do not require a running host.
9
+
10
+ Failure readbacks distinguish these cases:
11
+
12
+ - `host_lock_migration_required`: the configuration lacks the policy or source roots. Supply `--runtime-root` and `--profile-root` when rebuilding the lock.
13
+ - `host_lock_version_below_minimum`: DSH is older than `0.2.0-rc.2`. Upgrade DSH first.
14
+ - `host_lock_version_mismatch`: the installed graph differs from the reviewed baseline in version or integrity. For a later compatible version, use `--rebind-registry` to acquire and qualify the published graph. For the baseline, restore the recorded identities.
15
+ - `host_lock_installed_graph_drift`: installed bytes or routes changed after the audit. Inspect the change before rebuilding the lock.
16
+
17
+ The floor is `>=0.2.0-rc.2` with no upper bound. Passing the version check does not establish native validation; validated versions are recorded separately. Guard's exact DSH core is separate from optional market versions.
4
18
  A normal market update no longer changes the core digest. A plugin that changes
5
19
  which core packages actually resolve still invalidates the lock.
6
20
 
@@ -31,45 +45,43 @@ dsh --profile web --dump-config | "$GUARD_HOST_LOCK" verify-dump --runtime-root
31
45
 
32
46
  **Run this block after the runtime is already on the target DSH version, not
33
47
  before.** `inject` records the absolute runtime and profile roots and binds the
34
- graph it finds there, and runtime replay re-reads those same roots. Injecting
35
- against the old runtime therefore writes a lock that describes a graph the new
36
- runtime no longer has, and it will fail on the next replay. Order: upgrade the
37
- runtime, restart it, then inspect/inject/verify.
48
+ graph it finds there, and each session mount validates those same roots once,
49
+ with every security-sensitive entry validating them again at its own decision.
50
+ Injecting against the old runtime therefore writes a lock that describes a graph
51
+ the new runtime no longer has, and it will fail at the next mount or the next
52
+ protected entry. Order: stop the host, upgrade DSH and install Guard, inspect/inject/verify each profile, then start it when needed.
38
53
 
39
54
  `inject` **writes to `<profile>/cordis.patch.yml`** — it replaces or adds Guard's
40
55
  managed block in that file. Back the file up first. The same file is the one
41
56
  `docs/LOCAL_ACCEPTANCE.md` tells you to preserve.
42
57
 
43
- **Read the verdict from the JSON body, not from the exit status.** All three
44
- commands print a JSON object whose `status` is the verdict — `supported`,
45
- `unsupported` or `unavailable` — together with `cohort_id`, `host_lock_digest` and
46
- `audit_provenance`. Note that `inspect`, `inject` and `verify-dump` exit **0** even
47
- when that status is `unsupported`; only `inspect-graph` exits non-zero on an
48
- unsupported graph, and only a thrown error produces `status: "unavailable"` with a
49
- `reason_code` on stderr and exit 1. So a shell check of `$?` alone will not tell
50
- you whether the graph was accepted.
58
+ **Check both the JSON verdict and the exit status.** Accepted commands print `status: "supported"`. A missing graph, drift, incompatible implementation or untrusted registry description reports a specific `reason_code` on stderr and exits 1. `inspect-graph` is a pre-install graph check; it does not grant runtime authority.
51
59
 
52
- For Headless, use its profile path and `--profile headless`. On Windows, use the
60
+ For Headless, use its profile path for the host-lock commands and `dsh --profile headless --dump-config` for the dump. On Windows, use the
53
61
  installed `.cmd` launcher and Windows absolute paths. A strict repeat leaves
54
62
  the package and profile contents unchanged. Restarting or enabling a daily
55
63
  profile remains a separate user action.
56
64
 
57
65
  ## Check a Headless profile before installation
58
66
 
59
- A DSH `0.1.7-rc.2` Headless profile can have no external dependencies and no private `node_modules` or lockfile. From an accepted package or matching source checkout, `node bin/dsh-completion-guard-host-lock.mjs inspect-graph --runtime-root <runtime> --profile-root <profile>` checks that state without initializing or launching the profile.
67
+ A DSH Headless profile can have no external dependencies and no private `node_modules` or lockfile. From an accepted package or matching source checkout, `node bin/dsh-completion-guard-host-lock.mjs inspect-graph --runtime-root <runtime> --profile-root <profile>` checks that state without initializing or launching the profile.
60
68
 
61
- This narrow case requires exactly the installation-owned `dsh-base` and `dsh-headless` bundles, a complete audited runtime core, and matching bundle versions, package-map origins and patch files. Declared but uninstalled dependencies, partial map/lock pairs, unexplained local modules and foreign parent-module fallbacks are rejected. Existing profiles with both graph files retain their active-importer checks; damaged files are not treated as an empty graph.
69
+ This narrow case requires the installation-owned `dsh-base` and `dsh-headless` bundles, with the RC.2 `dsh-web-app` bundle allowed between them, a complete audited runtime core, and matching bundle versions, package-map origins and patch files. Declared but uninstalled dependencies, partial map/lock pairs, unexplained local modules and foreign parent-module fallbacks are rejected. Existing profiles with both graph files retain their active-importer checks; damaged files are not treated as an empty graph.
62
70
 
63
71
  The result labels `inspection_scope: pre_install_target` and `profile_graph.state: dependency_free_headless`, with the manifest hash and bundle identities. Its package rows describe the verified runtime core used for this installation target, not a private profile importer or a live boot. After installing Guard, the `inspect`, `inject` and runtime replay checks still require the profile's package map, lockfile and installed plugin binding. This pre-install result cannot replace those checks.
64
72
 
65
73
  ## What changes in the lock
66
74
 
67
75
  The generator writes `hostLockPolicy: dsh-core/v1`, the actual runtime/profile
68
- source roots, platform/profile kind and the complete 46-row core graph. The
69
- core manifest is version 2. Runtime replay re-reads those graph sources and
70
- requires the same exact core before using certificate authority.
76
+ source roots, platform/profile kind and the actual core package graph (46 rows in the reviewed baseline). The
77
+ core manifest is version 2. Each session mount validates those graph sources
78
+ exactly once; ordinary replay (resume, compaction, step and command refresh)
79
+ consumes that result without rescanning, and every entry that grants
80
+ certificate authority — completion certificates, mutation authorization,
81
+ release pre-effect decisions and Goal/Stop boundaries — validates the lock
82
+ freshly at the moment of its own decision.
71
83
 
72
- Version 0.8.0 registers only `dsh-0.1.7-rc.2-core-v1`. Runtime checks authenticate the mapped files and verify that each critical dependency resolves to the mapped instance. Installation imports use native Node resolution; Profile imports use rc.2's local-first routing and installation fallback only when no local package is selected. A nearer shadow, missing edge, wrong export target or escaped path is rejected even when the recorded versions match.
84
+ Version 0.8.2 registers `dsh-0.2.0-rc.2-core-v1` as the audited baseline cohort and derives graph cohorts for compatible hosts above the version floor (see the compatibility guide). Runtime checks authenticate the mapped files and verify that each critical dependency resolves to the mapped instance. Installation imports use native Node resolution; Profile imports use the host's local-first routing and installation fallback only when no local package is selected. A nearer shadow, missing edge, wrong export target or escaped path is rejected even when the recorded versions match.
73
85
 
74
86
  The manifest's `registry-derived-pending-native-audit` provenance and empty `auditedPlatforms` list describe its immutable source audit, which is part of the lock digest. Native acceptance belongs to each exact artifact's separate Release annexes; it does not rewrite that digest. Inspection, injection and dump verification report `audit_provenance` alongside the cohort and digest.
75
87
 
@@ -88,9 +100,31 @@ that matters for deciding whether you are migrating or just drifting:
88
100
  a DSH upgrade, and both are cured by re-running inspect, inject and verify against
89
101
  the new runtime rather than by editing the lock.
90
102
 
91
- Historical requirements and session records are retained; old certificates do not become certificates for the new lock. Historical host cohorts are test data only and are not accepted by 0.8.0.
103
+ Historical requirements and session records are retained; old certificates do not become certificates for the new lock. Historical host cohorts are test data only and are not accepted by 0.8.2.
92
104
  The shared digest-v3 encoder and its upstream fixtures are unchanged.
93
105
 
106
+ ## Official Desktop profile
107
+
108
+ Stop the Desktop app before installing or rebuilding its lock. Use the CLI carrier shipped with that app: `Contents/Resources/runtime/cli/bin/dsh` on macOS, or `resources\runtime\cli\bin\dsh.cmd` in the Windows installation. A separately installed `dsh` CLI cannot manage the reserved Desktop profile.
109
+
110
+ Install Guard through that carrier with `plugin --profile desktop add dsh-completion-guard@0.8.2`. Use the profile's own host-lock tool and the app's physical `app.asar` as `--runtime-root`. The default profile is `$DSH_HOME/profiles/desktop`, or `.dsh/profiles/desktop` under the user's home when `DSH_HOME` is unset. This POSIX example starts after installation:
111
+
112
+ ```sh
113
+ DSH_DESKTOP_ASAR=/absolute/path/to/DeepSeek-Harness.app/Contents/Resources/app.asar
114
+ DSH_DESKTOP_PROFILE=/absolute/path/to/.dsh/profiles/desktop
115
+ GUARD_DESKTOP_LOCK="$DSH_DESKTOP_PROFILE/node_modules/.bin/dsh-completion-guard-host-lock"
116
+ "$GUARD_DESKTOP_LOCK" inspect --profile desktop --runtime-root "$DSH_DESKTOP_ASAR" --profile-root "$DSH_DESKTOP_PROFILE"
117
+ "$GUARD_DESKTOP_LOCK" inject --profile desktop --runtime-root "$DSH_DESKTOP_ASAR" --profile-root "$DSH_DESKTOP_PROFILE"
118
+ "$GUARD_DESKTOP_LOCK" dump-desktop --profile desktop --runtime-root "$DSH_DESKTOP_ASAR" --profile-root "$DSH_DESKTOP_PROFILE" > desktop-composed.yml
119
+ "$GUARD_DESKTOP_LOCK" verify-dump --profile desktop --runtime-root "$DSH_DESKTOP_ASAR" --profile-root "$DSH_DESKTOP_PROFILE" --dump-config desktop-composed.yml
120
+ ```
121
+
122
+ On Windows use the `.cmd` host-lock launcher and the installation's `resources\app.asar` path. `dump-desktop` authenticates the carrier and uses the app's bundled configuration APIs to compose the same bundle/profile/home layers, without starting a host. It writes the profile's empty loader anchor as the official dump API does. Preserve any composed output privately because user configuration may contain secrets; it is not a Release attachment.
123
+
124
+ Check `supported` on inspect, inject and verify-dump. Keep Desktop stopped until all checks pass, then open the app when needed. Guard never edits the app archive or restarts the graphical app.
125
+
126
+ Desktop 升级顺序相同:先停止应用并升级宿主,再用应用附带的 CLI 安装 Guard。普通外部 CLI 无法管理保留的 Desktop profile。以应用的 `app.asar` 和实际 Desktop profile 路径执行 `inspect`、`inject`、`dump-desktop`、`verify-dump`,确认三项 JSON 回读均为 `supported` 后再打开应用。`dump-desktop` 不启动宿主;配置输出可能包含私人信息,请留在本机。Guard 不修改应用归档,也不负责应用重启。
127
+
94
128
  ## Market and restart
95
129
 
96
130
  Core compatibility does not certify the optional market restart adapter.
@@ -120,4 +154,20 @@ exact artifact and platform; publication is recorded on its GitHub Release.
120
154
 
121
155
  ## Historical 0.5.1 evidence
122
156
 
123
- Version 0.5.1 registered DSH `0.1.5-rc.1` and `0.1.5-rc.2` with 33 critical packages. Its macOS and Windows results belong only to that artifact and those hosts; see the [0.5.1 release annexes](https://github.com/GreenLv/dsh-completion-guard/releases/tag/v0.5.1). These are historical records, not installation targets for 0.8.0.
157
+ Version 0.5.1 registered DSH `0.1.5-rc.1` and `0.1.5-rc.2` with 33 critical packages. Its macOS and Windows results belong only to that artifact and those hosts; see the [0.5.1 release annexes](https://github.com/GreenLv/dsh-completion-guard/releases/tag/v0.5.1). These are historical records, not installation targets for 0.8.2.
158
+
159
+ ## Rebinding compatible package versions
160
+
161
+ For a newer compatible installation, add `--rebind-registry` to `inspect-graph`, `inspect`, `inject` and `verify-dump` in the upgrade example above. This acquires the exact official archives and qualifies their consumed API contract. Changed programs run bounded probes in an isolated Node process; the command does not start DSH or install packages. A successful result binds a new lock. Keep the backup until dump verification succeeds.
162
+
163
+ The version floor admits later releases and RCs by SemVer precedence. A new version does not by itself prove that Guard can read its events or authorize its effects. Rebinding separates published installation identity from adapter qualification:
164
+
165
+ - Published identity is acquired from the official npm registry for each exact installed `name@version`. The registry integrity must agree with the installed lock, and the downloaded archive must reproduce that integrity. The archive supplies the manifest and module digests; local manifests and local lockfile SRI alone never establish provenance.
166
+ - Qualification is independent of version rows. Comments and formatting can retain reviewed program identity; unrelated unconsumed modules are allowed. Equivalence also checks ordered entry-selection fields and the consumed dependency graph. Changing `exports`, `main`, `imports` or an active dependency requires qualification of the actual selected entry, even when the old file remains intact. Changed programs must pass `guard-host-contract/v2` API and Session V4 behavior checks using actual bare package resolution in separate ESM/CJS Node processes. These check immutable, contiguous event snapshots, restore preservation/refusal, fork recovery and unknown tool outcomes, plus consumed service APIs. A contract failure refuses the affected implementation. Optional Goal failures disable Goal integration while independent core work remains available.
167
+ - The probe uses verified archives and exact installed dependency identities in a temporary directory. It receives no user environment or credentials, cannot write files or launch child processes, and has its network entrypoints disabled. It has bounded time/output and does not boot a host, run installation scripts or contact model providers. This is a finite contract check of official code, not certification of every possible host behavior.
168
+ - CJS and ESM behavior results are recorded separately. Critical adapter routes must agree on one authenticated target; auxiliary dependencies may use separately authenticated CJS/ESM files. When Node lacks ESM-through-`require` execution, CJS resolution is checked and its behavior remains explicitly unavailable.
169
+ - The generator stores a deterministic qualification receipt under the declared profile's `.dsh-completion-guard/host-contracts/` directory and puts its binding in managed configuration. The receipt binds exact package/module bytes and Node startup conditions; a package compatibility declaration or a descriptor without its issued receipt cannot establish qualification. Earlier v1 receipts are refused; run the same rebind commands to issue v2 receipts. Pre-install `inspect-graph` uses the same qualifier and byte/route audit. Inspection and authorization recheck the mixed-version graph, qualified bytes and both CJS/ESM routes in one fresh audit session; they do not repeat the behavioral probes.
170
+ - Route checks use actual startup conditions from command-line flags and `NODE_OPTIONS`, including custom conditions, disabled addons and `module-sync` availability. Changing these inputs creates a new binding. Custom loaders or ambiguous configuration are refused rather than approximated.
171
+ - A changed graph or trust description creates a new lock identity. Existing completion certificates and private authority records retain their old digest and cannot transfer. Reinject the lock, restart the profile under the user's control, and obtain new evidence.
172
+
173
+ Rebinding writes only its qualification receipt and, for `inject`, the managed lock configuration. It does not start DSH, install packages, publish, or mutate session history. Foreground/default-workdir interpretations retain their narrower reviewed-byte qualification. Native acceptance of a later DSH version remains separate from this source-level compatibility rule.