@awiki/dsh-pap 0.0.0-stage → 0.1.1

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.
Files changed (64) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +184 -2
  3. package/README.zh-CN.md +271 -0
  4. package/cordis.patch.yml +15 -0
  5. package/docs/verification.md +217 -0
  6. package/lib/auth-challenge.d.ts +19 -0
  7. package/lib/auth-challenge.js +136 -0
  8. package/lib/browser-client.js +81 -0
  9. package/lib/browser-client.js.map +6 -0
  10. package/lib/callback-handoff.d.ts +55 -0
  11. package/lib/callback-handoff.js +33 -0
  12. package/lib/client/controller.d.ts +107 -0
  13. package/lib/client/controller.js +106 -0
  14. package/lib/client/index.d.ts +6 -0
  15. package/lib/client/index.js +28 -0
  16. package/lib/client/views.d.ts +5 -0
  17. package/lib/client/views.js +57 -0
  18. package/lib/client.d.ts +108 -0
  19. package/lib/client.js +833 -0
  20. package/lib/cooldown.d.ts +11 -0
  21. package/lib/cooldown.js +88 -0
  22. package/lib/credential-history.d.ts +33 -0
  23. package/lib/credential-history.js +109 -0
  24. package/lib/delegation.d.ts +16 -0
  25. package/lib/delegation.js +59 -0
  26. package/lib/discovery.d.ts +8 -0
  27. package/lib/discovery.js +227 -0
  28. package/lib/errors.d.ts +14 -0
  29. package/lib/errors.js +17 -0
  30. package/lib/file-secrets.d.ts +14 -0
  31. package/lib/file-secrets.js +148 -0
  32. package/lib/host-secrets.d.ts +16 -0
  33. package/lib/host-secrets.js +22 -0
  34. package/lib/host.d.ts +83 -0
  35. package/lib/host.js +1 -0
  36. package/lib/index.d.ts +21 -0
  37. package/lib/index.js +13 -0
  38. package/lib/keyring.d.ts +10 -0
  39. package/lib/keyring.js +64 -0
  40. package/lib/management-remote.d.ts +13 -0
  41. package/lib/management-remote.js +69 -0
  42. package/lib/network.d.ts +23 -0
  43. package/lib/network.js +91 -0
  44. package/lib/plugin.d.ts +75 -0
  45. package/lib/plugin.js +473 -0
  46. package/lib/product-api.d.ts +89 -0
  47. package/lib/product-api.js +25 -0
  48. package/lib/product-operations.d.ts +16 -0
  49. package/lib/product-operations.js +120 -0
  50. package/lib/protocol-adapter.d.ts +90 -0
  51. package/lib/protocol-adapter.js +75 -0
  52. package/lib/remote.d.ts +3 -0
  53. package/lib/remote.js +17 -0
  54. package/lib/store.d.ts +14 -0
  55. package/lib/store.js +128 -0
  56. package/lib/strict-json.d.ts +2 -0
  57. package/lib/strict-json.js +111 -0
  58. package/lib/tools.d.ts +5 -0
  59. package/lib/tools.js +29 -0
  60. package/lib/types.d.ts +202 -0
  61. package/lib/types.js +1 -0
  62. package/lib/util.d.ts +17 -0
  63. package/lib/util.js +66 -0
  64. package/package.json +156 -4
@@ -0,0 +1,271 @@
1
+ # DSH PAP:DeepSeek Harness 的 PAP 0.3 客户端
2
+
3
+ [English](README.md) | 简体中文
4
+
5
+ 本项目让 DSH 中的 Personal Agent 使用**一套可复用的本地身份**连接外部 PAP Company。用户创建并发布身份、授权插件和业务操作后,Agent 无需在每个服务重复创建自己的密钥和身份;但 Company 的准入策略、权限检查与需要账户时的用户授权仍然有效。
6
+
7
+ ## 与 ANP、MCP 的关系
8
+
9
+ | 协议 | 采用的身份认证方式 | 组件 |
10
+ | --- | --- | --- |
11
+ | ANP | `did:wba` 身份 + 逐请求 HTTP 签名 | [dsh-anp](https://github.com/agent-network-protocol/dsh-anp) |
12
+ | MCP | CIMD/JWKS + `private_key_jwt` + `client_credentials` | [DSH MCP Host](https://github.com/AgentConnect/dsh-harness-identity) |
13
+ | **PAP 0.3** | 本地身份签发 Delegation,使用 `Poppy-Session`;账户授权单独处理 | **本仓库** |
14
+
15
+ 共享的是本地身份和签名底座,**不是**同一个可在三种协议间复用的 Token。Agent/Delegation/DPoP 私钥由本地 [ANP Identity](https://github.com/agent-network-protocol/anp-identity) 管理,不托管在本插件或远端服务。
16
+
17
+ ## 快速安装
18
+
19
+ 要求 Node.js `^22.19.0 || >=24.0.0`、兼容 DSH Host、已发布的身份,以及在 ANP Identity 中批准 `@awiki/dsh-pap/plugin` 这一精确消费者。
20
+
21
+ ```sh
22
+ pnpm dsh plugin --profile <profile> add @awiki/dsh-pap@0.1.1
23
+ ```
24
+
25
+ 源码构建:
26
+
27
+ ```sh
28
+ git clone https://github.com/AgentConnect/dsh-pap.git
29
+ cd dsh-pap
30
+ npm ci --ignore-scripts
31
+ npm run typecheck
32
+ npm run build
33
+ npm test
34
+ ```
35
+
36
+ 安装后插件默认不启用。需要在 Host 的 Cordis 配置中显式开启并配置本地加密状态目录和身份政策:
37
+
38
+ ```yaml
39
+ - id: pap
40
+ name: '@awiki/dsh-pap/plugin'
41
+ config:
42
+ enabled: true
43
+ stateRoot: /absolute/private/dsh/profile/pap
44
+ policyRef: approved-c-policy-id
45
+ keyringService: org.agentconnect.dsh-pap
46
+ ```
47
+
48
+ Linux 默认使用 Secret Service;其他平台或没有可用 Keyring 时,可以显式使用 `secretStore: local-file` 和独立的绝对路径 `secretsRoot`。两种存储不会自动降级或迁移。配置细节见下方完整技术说明。
49
+
50
+ ## 线上演示:不需要账户登录的 PAP Session
51
+
52
+ 已部署示例:[Service Agent](https://agent.agent-network-protocol.com/ready)、[PAP Company 元数据](https://agent.agent-network-protocol.com/.well-known/poppy.json)、[官网公开帖子](https://agent-network-protocol.com/zh/posts)。
53
+
54
+ 1. 打开 DSH 的 **PAP Company 连接**设置,选择已发布的共享身份。
55
+ 2. 发现域名 `agent.agent-network-protocol.com`,连接 **signed-out Session**。
56
+ 3. 由用户显式启用发现结果中的 `protocol_list`、`protocol_get` 或 `post_create` 操作。
57
+ 4. 在 Agent 中通过 `pap_status`、`pap_operations` 查询已授权操作,再使用实际返回的操作引用调用:
58
+
59
+ ```text
60
+ pap_request({
61
+ "operationRef": "<已批准的 post_create 操作引用>",
62
+ "body": { "content": "Hello from DSH via PAP" }
63
+ })
64
+ ```
65
+
66
+ 这是**无需浏览器、无需用户账户授权服务器的 Session 示例**;不等于获取了远端用户账户权限。若 Company 需要账户权限,必须由用户在管理界面主动发起 Direct Sign-In 并完成授权,Agent 不能自行打开授权页面或提取授权码。
67
+
68
+ 下面保留本项目已有的详细实现、安全与测试记录,便于进一步集成和核验。
69
+
70
+ ---
71
+
72
+ ## 详细设计、接口与验证记录
73
+
74
+ ### 原始技术 README(PAP 0.3)
75
+
76
+ Apache-2.0-licensed DSH Host plugin and PAP client. The protocol baseline is
77
+ [the fixed 0.3 spec](https://github.com/personal-agent-protocol/personal-agent-protocol/blob/6fb46d381ac1b94265795132af13848ec442b6f6/content/versions/0.3/spec.mdx),
78
+ Git blob `01e9dc34bacb73ef0a740cc3bae77d82f0be0d37`.
79
+
80
+ 源码以 [Apache-2.0](LICENSE) 公开。包名为 `@awiki/dsh-pap`,声明 DSH bundle;发布必须经过显式授权和发布前验证。安装 bundle 默认不启用签名或网络请求,仍需配置身份、用途策略和秘密后端。
81
+
82
+ ## 已实现路径
83
+
84
+ - Company discovery:HTTPS 受限重定向,DNS 解析与实际连接绑定,地址、大小、时间、请求数限制;根 PRM 与精确 issuer 双向关联;无 AS、账户和 disabled 分开。网络错误保留已知 issuer,Company Identifier 改变后隔离原命名空间。
85
+ - 随机且私有的 Company User/Agent ID、独立匿名身份、sid 和加密事务状态。匿名 Session 禁止账户 Token。Agent ID 不改变 User ID。新账户 slot 使用新 Session。
86
+ - 通过 C 的 `./protocol-client` 调用 A 本地 custody:临时 P-256 key、身份 Delegation、逐请求 Session、独立 DPoP key、客户端断言和重启后 handle 恢复。F 不打开 NativeStore,不持有或导出这些私钥,不调用远程 signer。
87
+ - 每个实际资源请求重新签 `Poppy-Session`,绑定实际 htm/htu,带账户 Token 时才有 ath。发现、描述和 OAuth 请求不携 Session;禁止调用者注入认证 Header;凭据重定向停止。
88
+ - Direct Sign-In:显式用户入口、state、issuer、43 字符 S256 PKCE verifier、已发布 callback 校验、标准账户 Token、可选 RFC 9449 DPoP 和按 AS/资源分离的 nonce。
89
+ - 独立 PAP account store:scope/resource 约束、refresh single-flight/CAS、轮换 Token 原子替换、丢回执标为 uncertain、退出撤销及 revocation_pending。持久 account slot epoch 同时约束登录事务、refresh 和发送前检查;退出取消 pending/exchanging 登录,迟到 Token 只保留撤销信息。并发资源调用会等待同一刷新代次。
90
+ - `invalid_session` 停止,`session_ended` 新 sid 后最多重发一次,仅 GET/HEAD/OPTIONS 的 Token 错误可刷新后最多重发一次;副作用 API 的认证 challenge 不自动重放。网络超时或丢回执不自动重发副作用请求。429 持久保存 Retry-After fence,原请求不重放,后续显式请求在窗口前不签名或发送。
91
+
92
+ Device 为后续独立阶段,当前返回 `unsupported_sign_in` 并且不广告。Browser Join、Mediated Sign-In、PS384、Web Bot Auth operator signature、自动账户合并均未实现。PAP 不复用 MCP machineToken、Mcp-Session-Id 或 0.2 Session grant。
93
+
94
+ ## Host 接入
95
+
96
+ `@awiki/dsh-pap/plugin` 提供实际 Cordis `pap` 服务;bundle 同时挂载用户管理 `./management-remote`、模型工具 `./tools` 和根 package 的 client declaration marker。根 `@awiki/dsh-pap` 保留 Host 库 exports,作为 Cordis row 时仅是无能力 marker;不提供第二个 pap 服务、不注入 C 或 credentials。真实 consumer 始终是唯一的 `@awiki/dsh-pap/plugin`。默认 `enabled: false`,没有 Company、identity 或 policy 时不执行网络发现、创建凭据或签名。用户仍可读取 disabled/unconfigured 状态。启用需要 Host 的明确 profile 配置,不再读取 `DSH_PAP_*` 环境变量或接受自报 binding:
97
+
98
+ ```yaml
99
+ - id: pap
100
+ name: '@awiki/dsh-pap/plugin'
101
+ config:
102
+ enabled: true
103
+ stateRoot: /absolute/profile/pap
104
+ policyRef: approved-c-policy-id
105
+ keyringService: org.agentconnect.dsh-pap
106
+ ```
107
+
108
+ C 的真实 Loader consumer 必须是精确 `@awiki/dsh-pap/plugin`。Host 在 C 管理面预批准相应身份、profile、target 和 scopes;Remote 只选择 `{storeId, identityId, did}`,不能提交 owner、client_id、policy、verified metadata 或 targetRef。F 捕获插件构造时的真实 Context;不会将随 Cordis Service 调用关联变化的 `this.ctx` 当作签名调用者。
109
+
110
+ C 服务需实现 `bindProtocolConsumer(actualInstalledContext)` 与 `bindPapHostConsumer(actualInstalledContext)`。后者返回同进程 capability,`resolveBinding(identityRef, policyRef, profile)` 从当前已发布身份与政策得出 binding,`callbackManagementFor({identityRef,policyRef,targetRef})` 只返回 register/claim 两个受限操作。F 的 `ProtocolIdentityHost` 通过 C 真实 `registerValidatedTarget` 得到 opaque target,callback adapter 从加密事务重建相同 issuer/resource/scope 后取得该目标;不接受用户或模型提交的 opaque 引用。C factory 不可用时拒绝操作,不以组件 fixture 补位。失效 capability 永不复活;status/工具不会自动重绑,仅用户显式 identity/select 或插件重载从实际 Context 重新取得当前许可。
111
+
112
+ 用户管理 namespace 为 `papManager`:`status()`、`operations()`、`manage(request)`。仅安装的 `@awiki/dsh-pap/management-remote` Context 可以取得管理 facade,部署必须把该 namespace 留在已认证的用户管理 Gateway,不接入 Agent 的 Remote/MCP 通用工具。闭合管理动作如下:
113
+
114
+ | action | 作用 |
115
+ |---|---|
116
+ | `identity/select` | 选择 C 已批准的已发布 identity reference |
117
+ | `company/discover` | 按用户指定域执行安全发现;Company 不由包预造 |
118
+ | `session/connect` / `session/disconnect` | 建立 signed-out 或明确 account slot 的 Session/断开 |
119
+ | `operation/enable` / `operation/disable` | 将已发现 operation 绑定到用户选定的 Session 与 scope,或撤销 |
120
+ | `account/sign-in` | 选定 operation/resource 和 scopes,使用实际已发布的 HTTPS callback 发起 Direct |
121
+ | `account/collect` / `account/refresh` / `account/sign-out` | 原设备一次领取后换码/显式刷新或退出指定账户 slot;不接受 grantRef、resource、scope 或 Token |
122
+
123
+ `account/sign-in` 的授权 URL 只返回给上述用户管理调用,需由真实用户 UI 打开。state、code、PKCE、callbackRef、claim secret、Token、key handle 不进入模型工具。包内 `./client` 现提供最小 settings.section“PAP 连接”:只从 C 的公开 listIdentities/publicationStatus 选择已发布且支持 PAP Session 的 reference,发现 Company、建立连接、明确批准操作及其账户权限、显式发起浏览器登录/领取、刷新、退出和断开。登录链接只由用户点击,带 noopener/noreferrer,不由模型自动打开。默认 disabled、C 未 ready、缺秘密后端和 legacy history 门禁均有安全状态,不切 fallback。UI 只调用用户 Remote,不持有 Host secret、C signer capability、DeviceAccess 或 callback proof。Desktop owner 负责最终正式 profile/renderer 装入和产品验证。
124
+
125
+ `package.dsh.client` 使用现有 Web/Settings/Remote 依赖,`./client` 指向独立 `lib/browser-client.js`。Host 核心仍在 `lib/client.js`,不被 browser build 覆盖;实际 client-modules 通过根 marker 找到并服务 browser export。
126
+
127
+ 模型只有 `pap_status`、`pap_operations`、`pap_request` 三个工具。`pap_request` 输入只含本地 `operationRef`、已声明 path/query 参数及可选 JSON body,不接受 URL、method、Header、resource、scopes、account slot 或认证 metadata。method/destination/resource/session 来自本地已发现描述与用户授权。每次启用产生新的持久授权 generation,撤销后重新启用也不能让旧的在途调用越过发送前 fence。操作输出只给有界业务 JSON/状态,不透传响应 Header。除凭据字段和 JWT 模式外,实际发送前只在 Host 内存捕获本次 Session/DPoP/access/refresh 等值,任意 JSON key/value 或嵌入消息中的同值也遮盖;自动 refresh 后即使 sign-out 清空 Store,迟到 response 也不能回显新凭据。当前工具是 HTTP operation adapter;MCP 描述不会被当成已经实现的 PAP MCP transport,机器 MCP 不作 PAP 回退。
128
+
129
+ 状态 key 的 namespace 包含 PAP purpose、规范化 profile stateRoot 摘要以及 identity/owner/client binding 摘要;不同 profile 不复用同一 item。移动 profile 目录需要受控迁移其 protected item,不能只拷密文后创建新 key。状态根密钥默认使用 Linux Secret Service,也可显式选择下面的跨平台文件存储。受信 Host 仍可通过同进程 `papHost.secrets` 提供 `HostSecretStore`;显式指定 `secretStore` 时,以插件配置为准。密钥后端之间不会自动回退或迁移。
130
+
131
+ ### 跨平台文件密钥存储
132
+
133
+ ```yaml
134
+ - id: pap
135
+ name: '@awiki/dsh-pap/plugin'
136
+ config:
137
+ enabled: true
138
+ stateRoot: /Users/your-name/.dsh/profiles/pap-test/pap
139
+ policyRef: approved-c-policy-id
140
+ secretStore: local-file
141
+ secretsRoot: /Users/your-name/.dsh/secrets/pap
142
+ ```
143
+
144
+ 两个路径都使用本机绝对路径;Windows 可用 `C:/Users/your-name/...`。`secretsRoot` 与 `stateRoot` 必须是彼此独立、互不包含的目录。不同 profile 和身份通过 namespace 派生各自的密钥文件名。
145
+
146
+ 文件后端保存随机 32 字节的 PAP 状态加密密钥:macOS/Linux 设置目录 `0700`、文件 `0600` 并检查当前用户所有权;Windows 使用系统 PowerShell 设置当前用户 SID 的 DACL、移除继承权限,不依赖 chmod。临时文件写入并刷盘后,通过不覆盖已有目标的原子 hard link 发布;并发创建复用胜出的文件。需要支持这些文件权限和 hard link 的本地文件系统(例如 APFS、NTFS)。Windows 刷新文件,不尝试打开目录执行 fsync。
147
+
148
+ PAP 状态继续加密保存,Agent/Delegation/DPoP 私钥仍由 ANP Identity 托管。文件权限保护边界是当前 OS 用户账户;同用户进程和管理员仍可能访问。已有密文找不到对应密钥或密钥文件损坏时返回 `credential_unavailable`,不会为已有密文生成替代密钥。备份及迁移需同时保留匹配的状态与密钥,并在目标系统重设权限。
149
+
150
+ 独立 Host 集成也可从根包或 `./file-secrets` 导入 `FileSecretStore`;`./host-secrets` provider 同样接受 `secretStore: local-file` 和 `secretsRoot`。保留 keyring 时,Linux 仍需要可用的 `secret-tool`。本次未改变默认后端。
151
+
152
+
153
+ 生产网络默认 `SafeHttpsTransport`。受信 Host 的 `papHost.transport` 仅用于显式部署连接策略和组件验证,Remote/Tools 不能覆盖。`privateOrigins`、`portOverrides` 和自定义 DNS 仅适用于明确配置的隔离部署/组件;TLS 始终验证,连接映射只改变 TCP 端口,Host 与 Session htu 保持逻辑 URL。
154
+
155
+ 账户 callback 固定为当前实际发布 CIMD 中的 HTTPS URI。F 不取得管理 DeviceAccess,C 保留 exact-device credential/checkpoint/proof;只提交 state/claim 的独立 SHA-256 摘要与一次领取 secret。verifier、PAP User/Agent ID、sid、第三方 Token 均不交给 callback 服务,完整领取引用只在加密 Store。C 逐次检查当前调用者、政策、publication、provider、manager 以及目标 issuer/resource。
156
+
157
+ 底层 Host engine 保留显式独立 loopback lane(127.0.0.1 或 [::1] literal、合法显式 port、固定 path、无 query/fragment/userinfo/dot segment),它与默认 HTTPS handoff 分开,不能作为后者失败后的回退。本产品管理 adapter 首先只提供默认 HTTPS handoff,其他 lane 不广告为可用 UI。
158
+
159
+ ## 本地状态与生命周期
160
+
161
+ 产品将 Company/Session/operation 授权保存在每个 identity binding 独立目录;`selected-identity.json` 仅保存三字段公开 reference(0600、原子替换),每次恢复仍需 C 重新批准 binding。`pap-state.enc` 以 AES-256-GCM 加密,AAD 绑定 schema 和 identity/owner/client 命名空间;目录 0700、文件 0600。跨进程锁内使用 fsync + rename 原子提交;公开映射、Delegation、Token、PKCE 和 callback 领取状态均不明文落盘。状态目录备份与 Host secret store 备份应分别保管。Cordis Context disposer 会关闭 engine、取消在途资源请求并 dispose C facade;输出前仍检查原 engine/selection 与调用 Context,忽略 abort 的旧 transport 也不能交出迟到结果。Keyring provider 的 locksRoot 须使用独立目录,不能与 PAP stateRoot 使用同一个锁目录。
162
+
163
+ 恢复后重新经 C 获取目标许可并复核 key handle;持久 handle 本身不授予签名权。中断的 refresh 标为 uncertain,换码中断要求重新授权。委托默认一小时且校验最大二十四小时;自动/显式轮换保持 User ID/sid,并保存旧 key 的停用重试引用。每次 key 创建先持久预留 attempt;创建回执未知时复用原幂等 operation,已停用的失败 attempt 则不会再用;退休未确认时先完成清理再创建下一把 key。外部 Company 可缓存 Delegation 到 exp,本地停止签名不等于立即全网撤销。
164
+
165
+ 元数据五分钟过期后自动重新发现;发现失败直接停止,不降级无 AS。没有 expires_in 的 Token 保持未知远端寿命,仅施加本地二十四小时使用上限,不猜测 opaque Token 内容。账户 sign-out 停止本地 Token 使用;未确认撤销保留最小加密重试信息。普通 `disconnectPap` 停止该连接,不隐式退出其他共用账户 Session。
166
+
167
+ ## 构建、测试和依赖来源
168
+
169
+ 当前插件面向 Harness `0.2.2-rc.1`,使用 Cordis `4.1.0` 与 Loader `1.1.0`。Remote 描述符使用该版本的延迟 `create()` codec 接口;不再声明兼容 Harness `0.1.5`。
170
+
171
+ ```bash
172
+ npm ci --ignore-scripts
173
+ npm run typecheck
174
+ npm test
175
+ npm run build
176
+ npm pack --ignore-scripts --pack-destination .artifacts
177
+ ```
178
+
179
+ 生产依赖固定 `proper-lockfile@4.1.2` 和 `zod@4.6.2`(严格管理 DTO);JOSE 验证使用 Node crypto。Cordis 固定 `4.1.0`,可选 Host peer 为 typert/tools `0.2.2-rc.1`;依赖 integrity 在 package-lock.json 固定。C/A 的新 PAP API 尚未发布到 registry,因此本阶段依赖实际 Host capability 结构绑定,不能宣称已通过新 API 的 registry 安装验证或正式发行门槛。此阶段不将未发布本地源码写作正式 SDK lock 来源。
180
+
181
+ `npm test` 是本仓库单位/隔离组件检查,不启动产品 E2E、System Test 或远程部署。`tests/fixture.ts` 的 in-memory ECDSA custody 仅供测试,和生产 C/A 路径分开。`tests/vectors/local-signer-v2.json` 来自 A 的真实本地 native 公有测试向量,独立 Node 验签;没有私钥。它证明 wire 兼容,不替代实际 C/A Host 接入。
182
+
183
+ G 在隔离 HTTPS/PG 环境提供合成用户和 fixture CIMD 时,可执行:
184
+
185
+ ```bash
186
+ npx tsx scripts/frontvia-component.ts /absolute/path/to/handoff.json --account
187
+ ```
188
+
189
+ 此 driver 验证 F→G 的真实 Rust Session/对象/账户路径,显式读取 G 的合成 fixture identity key;不用于运行时,不打包进产品,不把该 custody 计为 A/C 原生验收。`--account` 仅在 G 明确开启测试 OTP/consent 模式时运行,受其 OTP 冷却限制。
190
+
191
+ 详细边界和本轮实际证据见 [安全与验收记录](docs/verification.md)。
192
+
193
+ ## 新增真实模块链入口
194
+
195
+ 默认 fixed HTTPS relay 的 F/C/B 链:
196
+
197
+ ```bash
198
+ npm run test:callback-component -- /absolute/C/test/helpers/managed-callback-fixture.ts /absolute/user-service /absolute/venv/bin/python
199
+ ```
200
+
201
+ 该入口使用 C 的真实批准创建/A native 设备 proof、B 实际 factor 注册/Registry/SQL/PAP 发布和生产 ASGI callback handlers,验证 F handoff 登记、公共 callback、原设备一次领取及拒绝路径。B 使用隔离临时 MySQL,邮件投递是 capture;URL 是逻辑 HTTPS 的 ASGI 模块调用,不计远程 TLS 部署。
202
+
203
+ C/A 本地 custody 与 G 实际账户组合链:
204
+
205
+ ```bash
206
+ npm run test:native-account-component -- /absolute/C/test/helpers/native-protocol-fixture.ts /absolute/public-materials.json https://agent.test:29443
207
+ ```
208
+
209
+ 进程打印 `public_materials_ready` 后保持存活;将文件交给 G 的 `--materials-file` public-only fixture,用同一端口开启 fresh OTP 窗口,再在该进程 stdin 输入 G handoff.json 的绝对路径。输入通道应保持打开。它只导出 C 确认的原始 CIMD/JWKS 字节,G 不接收 Agent private key;F 不读 `identity_key`,不使用 FixtureHost,所有 Agent identity/delegated/DPoP 签名均通过真实 C/A。实际 loopback listener 接收 callback,并验证 Direct、DPoP 重启恢复、委托轮换、refresh、revoke 与 signed-out。完成后双方精确清理。
210
+
211
+ 上述两条独立链保留其历史边界;后续默认 HTTPS relay 与同一 native 账户已通过下面的新联合入口。宿主 keyring 配置、产品 UI/E2E、System Test 和 registry 发行仍不因此自动通过。
212
+
213
+ ## 实际 Secret Service 模块验证
214
+
215
+ `npm run test:keyring-container` 在唯一任务镜像中安装 libsecret-tools/gnome-keyring/dbus,使用真实 F 私有包,不安装宿主软件。运行阶段 network none、根文件系统只读、非 root、有限 tmpfs/资源和独立 DBus/XDG/control;密码只在 stdin/内存。已验证创建/读取、PapStore 加密、新 Node 进程恢复、daemon 重启、锁定拒绝、删除 item 后不重建/不改写既有密文,以及无明文回退。详见 `scripts/keyring-container/README.md`(源码内) 和 [验证记录](docs/verification.md)。
216
+
217
+ 这关闭了隔离容器内真实 Secret Service 的模块证据缺口;宿主仍没有配置该后端,原 `real_missing_backend_only` 结果保持。它不代表宿主 keyring 部署就绪,也不补齐产品 UI/E2E 或 registry 门槛。
218
+
219
+ ## HTTP 认证错误与持久冷却
220
+
221
+ 资源冷却按当前本地身份/owner Store 内的 Company+resource 隔离,OAuth endpoint 冷却按 Company+精确 AS issuer 隔离,二者即使同 origin 也不共用窗口。Retry-After 支持 delta-seconds 和 HTTP-date;绝对截止时间以精确整数字符串保存在加密状态中,不截短到 300 秒。缺失/非法值使用本地一秒 fence,不伪造远端 TTL。较短窗口可等待,较长窗口返回 `PapError.retryAfterSeconds` 并保持 fence;超大整数用十进制字符串返回。Host engine 的 `inlineCooldownWaitMs` 为 0–5000ms,默认1500ms,只约束本次愿意等待多久,不缩短服务器窗口。
222
+
223
+ close、断开和账户退出可取消等待;这些动作不清除共享 fence。等待后重新检查当前 scope、账户 epoch、连接、generation 和 C lease。实际发送的持锁 callback 在等待 Store 锁/secret resolver 后再次检查真实 C Session/DPoP lease,随后同步完成本地 CAS 并启动 HTTP,不能使用撤销后的旧签名发出请求。
224
+
225
+ 401/403 优先解析标准 Bearer/DPoP WWW-Authenticate,支持多 challenge、quoted comma/escape,重复或歧义参数拒绝。`PapError.authHint` 只可能包含固定 scheme、当前 Company 已广告的合法 scope 和当前 resource 的精确标准 PRM URL;realm、error_description、任意 URL/query 或远端秘密不会进入提示/日志。提示不触发 metadata fetch、resource 切换、Token 请求或扩权。非标准 Session/旧登录错误不能通过 OAuth challenge 触发新 sid 或副作用重放。
226
+
227
+ 定向回归入口:`npm run test:p22`。该入口仅 owning client/storage/HTTP 检查,不运行 System Test 或产品 E2E。
228
+
229
+ ## 默认 HTTPS relay 与同一 native 账户联合入口
230
+
231
+ ```bash
232
+ npm run test:relay-native-account-component -- /absolute/C/test/helpers/managed-callback-fixture.ts /absolute/user-service /absolute/venv/bin/python /absolute/public-materials.json https://agent.test:29443
233
+ ```
234
+
235
+ 脚本以真实 C 批准/A native/B 注册、Registry 和 PAP 发布建立同一身份,重新打开相同 native Store 安装显式 PAP consumer policy,导出原始 B CIMD/JWKS 公材料;不导出 provider、lease、Token 或 Agent private key。它打印 `public_materials_ready` 和精确的 `callbackForward` 后等待 stdin。G 使用 `--materials-file <file> --fixture-port 29443 --callback-forward <listener URL> --handoff-only` 开启独立 fresh 账户窗口,再将其 handoff.json 的绝对路径输入该进程。
236
+
237
+ 该 lane 始终注册 `https://agent.test:29443/user-service/v1/pap-callback` 并使用显式 `handoff`。G 只对这个精确 HTTPS GET 转发原 query 到 Node 的 127 listener,不转 caller auth/cookie/DPoP/Session,也不记录 query/code;Node 只转发到 `helper.fetch` 的真实 B public callback,不自行保存或领取 code。随后 F `DeviceCallbackHandoff` 经真实 C 原设备 proof 领取,由原本地 PKCE verifier 兑换 G 的实际 code。没有 fake callback、没有以 RFC8252 loopback URI 替代默认 relay。内部 127 HTTP 仅为隔离 HTTPS publisher 到 B ASGI 的测试转发路径。
238
+
239
+ 实际同一链已通过真实 HTTPS 公材料/AS code→B receive→C device claim→PKCE/DPoP account→restart key restore→delegation rotation→refresh→revoke→signed-out。生产执行 lineage 为 `7325b80`,测试脚本之后单独入库;双方精确清理,只有隔离 master 和外部邮件投递 capture 的已声明边界。它是源级真实模块证据,不是已安装 DSH 产品、外部短信/邮件投递、宿主 keyring 配置或 registry 发布 gate。
240
+
241
+ ## S15 凭据历史与 legacy 门禁
242
+
243
+ AT/RT 的脱敏不限于一次请求或当前 grant:有效 AS response 在返回解析前先归档到现有 AES-GCM PapStore 的私有 credentialVault,替换、刷新和清除前也在同一事务保存旧值。vault 与协议授权分离,只用于防止已知凭据从任意业务 JSON key/value、Company 名称、operation 路径、公开状态或错误字段回显;它不构成 grant 或恢复签名权。运行内已知寿命使用单调时钟并 pin 在途响应;重启后的私有 tombstone 保守按未知剩余寿命保留,不凭本地24h使用上限猜测 AS/RT 期限。上限4096值/4MiB,容量不足锁闭输出,不驱逐仍可能有效值。不能把旧 AT 从当前 grant 消失当作脱敏完成。
244
+
245
+ 当前 state/verifier/claim/sid 等映射与本次真正发送的材料也会过滤;只有明确用户 account/sign-in 的 authorizationUrl 字段保留正常 OAuth state/challenge。跨请求及跨重启的持久历史承诺专指已观察 AT/RT,不宣称无限重构已删除的旧协议 nonce 或未知过去值。
246
+
247
+ 新 vault 有完整性标记。老加密状态没有 vault,但存在任意 grant、account slot、登录事务(包括 cancelled/failed)、AS nonce 或 DPoP retirement 迹象时,迁移为 legacy_incomplete;seed 当前已知 Token 不等于补全历史。Agent 请求及动态 Company/catalog/status 输出停止,只有固定迁移码。用户只见 Host 产生的账户引用与封闭状态,可尝试正常撤销当前账户;退出/latest revoke 不会自动把历史标为完整。旧纯 NoAS 状态仅在无账户处理迹象时可迁移 complete。加密数据、epoch、cooldown fence 都保留,不自动 wipe、新建 key 或放开权限。
248
+
249
+ 本轮没有“confirmed:true”、重置按钮或普通 Remote 恢复入口。处理 legacy 需要独立受信 Host 运维证据:对应 issuer/client/resource 的全部旧凭据已撤销事实,并保留审计来源;不能让模型或普通业务请求声明已确认。既有未知旧值无法重构,不把它们写成已覆盖。
250
+
251
+ ## 实际产品模块与默认秘密后端组件
252
+
253
+ `scripts/product-native-component.ts` 使用真实 fresh C approval/B strict 注册发布→同 store C Host 重开→实际 F plugin/manager/tools 与实际 DSH ToolRuntime,向独立 HTTPS NoAS verifier 发送2条实际 Delegation/Session;批准前0请求、卸载后0后续请求、Company Token0。F 只注入隔离网络 transport,秘密存储走默认 KeyringSecretStore。Host 进程中的私有 secret-tool shim 固定本地 Docker socket 和 inspected container ID,访问任务专属容器真实 DBus/gnome-keyring;不装宿主软件、不读用户 keyring、不改 HOME,所有 key/password 仅 stdin/内存。此为实际 factory/default backend 模块证据,不是 GUI 产品 E2E。
254
+
255
+ 侧车入口 `scripts/secret-service-sidecar-component.ts` 单独验证当前加密 vault 的真实 backend create/get、daemon 重启、新 Host Node 进程恢复和无明文;镜像复用已核验 fea7c2…,不是把整个 C/Python 仓库搬入容器。原始宿主缺后端记录仍成立,容器后端不代表宿主已配置。
256
+
257
+ 新实际账户入口 `scripts/product-account-component.ts` 已实际通过:使用新 C factory 与 user Remote、固定 B HTTPS relay、G 实际 OAuth/DPoP 及默认 backend;显式当前 A runtime aliases,并核实际加载冻结 native FFB。它不是旧直接 PapClient/managed-callback helper 的替代计数,完整来源见验证记录。
258
+
259
+ ## npm scope and existing source profiles
260
+
261
+ The published package is `@awiki/dsh-pap`. Its identity consumer is
262
+ `@awiki/dsh-pap/plugin`; manager and tool entries use the same package scope.
263
+ Install with `pnpm dsh plugin --profile <profile> add @awiki/dsh-pap@0.1.1`.
264
+
265
+ Earlier unpublished source profiles used `@agentconnect/dsh-pap`. They are not
266
+ silently aliased or granted access under the new consumer. Configure the new
267
+ installed consumer explicitly in ANP Identity's allow list and protocol policy,
268
+ then approve it. Keep the existing identity Store and keys unchanged. Start the
269
+ new PAP consumer with its own empty state root and matching secret namespace;
270
+ retain old encrypted PAP state and its keys separately rather than editing its
271
+ binding, overwriting keys, or attempting an unauthenticated in-place migration.
@@ -0,0 +1,15 @@
1
+ # Explicit opt-in configuration is owned by the profile Host. No implicit environment binding.
2
+ - insert:
3
+ - id: pap-client-declaration
4
+ name: '@awiki/dsh-pap'
5
+ - id: pap
6
+ name: '@awiki/dsh-pap/plugin'
7
+ config:
8
+ enabled: false
9
+ # To select file storage explicitly, also set stateRoot and policyRef.
10
+ # secretStore: local-file
11
+ # secretsRoot: /absolute/private/dsh/secrets/pap
12
+ - id: pap-manager
13
+ name: '@awiki/dsh-pap/management-remote'
14
+ - id: pap-tools
15
+ name: '@awiki/dsh-pap/tools'
@@ -0,0 +1,217 @@
1
+ # F 模块验证与安全边界
2
+
3
+ 本仓库为私有源码,当前没有 push、发布、产品 E2E、System Test 或远程服务部署。
4
+
5
+ 本轮通过的 owner 检查:`npm run typecheck`、`npm test`。测试覆盖发现分类/issuer 失效保留、disabled、协议版本、私有与匿名身份、重启、加密与损坏拒绝、委托/Session 独立 ECDSA 验签、逐请求 method/URL/ath、轮换、Direct state/issuer/PKCE/标准 Token、DPoP、refresh single-flight/丢回执/退出竞态、Session 错误、429/redirect/撤销/断开,以及 Device 不广告。具体最终数量和最终组件命令见文档末尾执行记录。
6
+
7
+ `tests/native-vector.test.ts` 消费 A 生成的 `local-signer-v2-vector.json` 公有向量并用 Node crypto 独立验证四种 JWT,字段与协议基线一致。向量来自本轮 A worktree `bindings/node/test/fixtures/`,未包含私钥。实际 A 最终 native 候选 `anp-identity.linux-x64-gnu.node` 的提供方 SHA-256 为 `e2c4b86a0b3622aaefa70b44d3dc31cdab579b1237a4418d349bd294c52663ef`。静态向量不替代运行证据;本轮后续真实 C/A→F→HTTPS 结果见执行记录。
8
+
9
+ 安全检查的主要信任边界如下:
10
+
11
+ | 边界 | 约束与证据 |
12
+ | --- | --- |
13
+ | Company 网络输入 | HTTPS、DNS pin、地址过滤、精确私网例外、五次 discovery redirect、64 次请求/30s/4MiB 总预算;携凭据的请求不转发 redirect |
14
+ | 目标许可 | F 仅从验证过的路由构造实际 URL,C Context/管理 policy 授权,注册精确 allowedEndpoints;普通 consumer JSON 不充当 targetRef |
15
+ | 本地持钥 | F 仅保存 A key handle、公钥与 generation;C 重新授权/restore;无 NativeStore 或远程 signer 调用 |
16
+ | 本地状态 | Host secret store 根密钥、AES-GCM、AAD、0700/0600、进程锁、fsync/rename;秘密缺失时不创建替代根密钥 |
17
+ | 签名用途 | 身份→Delegation,委托→Session,独立 DPoP key;ES256、typ、thumbprint、请求绑定、ath 分开核验 |
18
+ | OAuth | 非空且不提升 scope、精确 issuer、独立 state/43字符PKCE、固定已发布 callback;token endpoint 不接收 Session/User/sid |
19
+ | 并发与退出 | refresh single-flight/CAS;丢回执 uncertain;退出立即停止账户请求;迟到 refresh 仅保留待撤销秘密而不复活登录态 |
20
+ | 用户与模型 | 管理状态不含Token/JWT/key;授权链接仅用户UI;没有模型tool/Remote通用签名入口 |
21
+ | MCP 隔离 | 独立 PAP schema 与 OAuth account grants;没有machineToken导入、client_credentials或协议回退 |
22
+
23
+ 当前剩余发行/启用门槛:实际 Host Secret Service 配置与恢复(隔离容器正向已补证);产品管理 UI、产品 E2E 和受影响 System Test;发布后的 registry SDK pin/lock 验证。真实 C/A native 账户组合和 F/C/B exact-device callback 模块链已补证,边界见末节。Device 为另阶段,当前不广告。测试 custody 的成功不能抵消这些未验证范围。
24
+
25
+ ## 执行记录
26
+
27
+ - 2026-11-06:初始 15 项 owner 检查与真实本仓库隔离 HTTPS Session 组件通过;增加 refresh 竞态、B relay mapper、A 公有向量及秘密丢失检查后,20 项 owner 检查通过。
28
+ - F→G `pap03_d4f27aa3b9e5`:真实 HTTPS discovery、同 sid Session、委托轮换通过。测试 custody;账户未执行。
29
+ - F→G `pap03_5e01b509d095`:`npx tsx scripts/frontvia-component.ts <该隔离 handoff.json> --account` 通过 Session/委托轮换、对象 create/read、真实合成用户 OTP/consent、F Direct PKCE/state/issuer、标准 Token、DPoP account、refresh、revoke 和退出后 signed-out。该窗口 binary 的 discovery 仍有 G 随后修正的旧未知字段;F 使用标准 AS scopes_supported,不按旧字段解释。最终 0.3 discovery 证据以修订 binary 重跑为准。
30
+ - 实际联调发现 F 早期 PKCE verifier 长度为 37,已改为 32 随机字节 base64url(43 字符),补 owner 回归并在真实账户组件成功。初始生成向量的 access_token=null,独立验签测试已按 signed-out 规则检查 ath 缺失;该失败属于测试断言修正。
31
+
32
+ - 最终 owner 检查:`npm run typecheck && npm test`,26/26 通过。新增 fatal UTF-8、BOM、重复 JSON(含转义等价 key)、深度/大小、JWT canonical base64url、JSON media type、IPv6 `2001::/23`/文档地址,以及 OAuth 路由即使被 API 声明也不发 Session、DPoP key 丢失不降 Bearer。
33
+ - 最终 G binary:`npx tsx scripts/frontvia-component.ts /home/ecs-user/awiki-space/worktrees/20261104-dsh-shared-agent-identity/frontvia-pap/platform/.local/pap03/pap03_51205459476f/handoff.json --account` 通过。该候选已修正 auth.scopes、HTTP 400 Session 错误、登录路由范围和 code/refresh 最终事务到期检查。测试 custody;没有冒充 A/C 的账户持钥证据。
34
+ - 真实 C/A native:`npx tsx scripts/native-component.ts /home/ecs-user/awiki-space/worktrees/20261104-dsh-shared-agent-identity/anp-identity/packages/dsh-anp-identity/test/helpers/native-protocol-fixture.ts` 通过。三次真实 HTTPS Session 请求、C Context/target/scope 许可、A native 持钥和委托签名、F dispatcher、独立 Node 验签、委托轮换、重启后 restorePapKey 与 sid 连续。C publication 仍为显式 accepted fixture,状态根密钥为隔离测试 master;不提供 B 设备注册或系统 keyring 证据。
35
+ - A native 早期 ef32 候选在最终格式化/能力广告重编译后被 f123 候选替换;先执行哈希检查并暂停消费,A/H 核对完整候选 manifest 后固定 f123 继续。该制品不是 registry 包。
36
+ - 安全复核已关闭本轮发现的 PKCE 长度、UTF-8/重复 JSON/BOM/media type、IPv6 special-use、OAuth 目的地重叠和 refresh/sign-out 竞态问题。正式发行/启用仍受上面的未验证范围约束。
37
+ - 最终 G component manifest 的 binary SHA-256:`35f6265876ef98daa69e8780f055ed2e6f164468494f1241b711dd2e7be09444`。
38
+ - 最终补充匿名结束清除映射、可选 Agent 共享相同 Company User/account slot 的 owner 回归;`npm run typecheck && npm test` 最终 26/26。
39
+
40
+ ## 交叉审查后的最终修订
41
+
42
+ G 只读交叉审查实复现了三项缺口:登录换码与退出竞态可能恢复账户;第二个资源调用未等待正在进行的 refresh;首次委托签发失败并退休 key 后复用了原幂等 key 创建 operation,导致恢复永久失败。初始提交及 26 项通过记录不能证明这三条边界。
43
+
44
+ 本轮修复增加持久 account slot epoch,退出原子取消 pending/exchanging 事务并清除 verifier/领取引用。Token HTTP 启动前再次检查该 epoch;已经发出的换码响应迟到时只保留空 accessToken 的 revocation_pending grant,不恢复账户。资源 dispatcher 对 refreshing grant 合并等待,并在同一 account epoch 与后续 grant generation 重读;退出或刷新失败后停止本次账户调用,不改成 signed-out 重发。
45
+
46
+ Delegation 创建改为先持久预留 attempt,再执行幂等创建/签发。失败 key 已退休后下一尝试使用新序号;创建回执未知时保留原操作恢复;退休失败保留加密清理引用,完成清理后才创建下一把 key。自动轮换失败仍可使用尚有效且获准的旧委托,sid/User ID 不变。
47
+
48
+ - `npm run typecheck && npm test`:最终 **35/35** 通过,新增跨客户端 pending/exchanging 退出、迟到换码、等待刷新、等待期间退出、signer 挂起后取消、委托失败后重启恢复、自动轮换恢复、create 丢回执和退休失败边界。
49
+ - G 原复现脚本 `node --import tsx <G .local/review/f-races.mjs>`:P1 返回 revocation_pending,迟到换码后 activeGrants=0;P2 第二请求成功且只进行同一轮刷新;P3 `[delegation_blocked, ok, ok]`,创建两把 key、只剩一把 active。G 独立只读复测也确认三项关闭。
50
+ - 真实 C/A 组件 fresh Node 进程再次通过,native pin 更新为 e2c4 候选,三请求、轮换与重启恢复均通过。A 的该次改动为 publication candidate 的冻结 baseEvidence,PAP 签名契约未改;f123 是被其替换的历史候选,不是最终包或 registry 依赖。
51
+
52
+ 截至该次并发修复提交,B callback、系统 keyring、native 账户组合、产品 E2E/System Test 和 registry 门槛仍未执行;后续模块补证见下节。
53
+
54
+ ## 真实 callback 与 native 账户组合补证
55
+
56
+ 本轮不再以 mapper mock 或 FixtureHost 代替这两条链。F 的 callback Host seam 已缩为闭合 register/claim DTO 与两个 execute overload,实际兼容 C 的受限 driver。F 同步 B/C 独立 loopback 正负向配置向量,公开材料/资源 URL 的 HTTPS 限制没有放宽。
57
+
58
+ 1. `npx tsx scripts/callback-component.ts <C test/helpers/managed-callback-fixture.ts> <B source> <Python>` 通过。真实 C 批准 E1 创建、A native 设备签名、B factor 注册/owner/ready-admin Registry 与实际 PAP account 发布后,经 `DeviceCallbackHandoff` 完成 register、公共 callback 和原设备一次领取;未 ready、state 伪装领取秘密、issuer 不匹配、重复领取均拒绝;access_denied 的 state/iss 保留。该检查只替代邮件投递和隔离 master,B 为生产 ASGI handlers + 临时真实 MySQL;逻辑 fixed HTTPS relay,不是远程 TLS 部署。未冒称 Web native 管理全链。
59
+ 2. `scripts/native-frontvia-component.ts` 与 G `pap03_0c7c24406ada` 窗口通过。所有 Agent identity/delegated/DPoP key 由 A 本地 custody 经真实 C Context 使用,F 与 G 不读取/接收 Agent private key。C 的公材料以原始字节挂接 G,实际 HTTPS GET 与 C 确认字符串逐字节相等;metadata SHA-256 `5fe653513cc2180e5ad1043b10f27819910851ba936c8c92990cebd7f4a40c71`,JWKS `3f66193cf6011226c349179644338792a2e0b23d16f8b00ad4f21f345945e7a0`,G 独立计数两份材料各 GET 11 次并核对相同摘要。
60
+ 3. 上述 native 账户链包含真实 127.0.0.1 HTTP listener、Direct/PKCE、state/issuer 负例、标准 Token、DPoP 资源调用、重启后 native key restore、委托轮换不触发账户刷新、显式 refresh、revoke 与退出后 signed-out。Token endpoint 仅两次(code + refresh),revocation 一次。仍明确保留 C publication acceptance fixture 和隔离状态 master;它与第 1 条默认 HTTPS relay 是分别验证的模块链。
61
+ 4. `npm run typecheck && npm test`:**36/36 通过**,包含新增 B/C 共同 loopback 正负向向量。A native pin 仍为 `e2c4b86a0b3622aaefa70b44d3dc31cdab579b1237a4418d349bd294c52663ef`;G binary 仍为 `35f6265876ef98daa69e8780f055ed2e6f164468494f1241b711dd2e7be09444`。
62
+
63
+ 首个 native 账户编排在进入任何网络前因 stdin/TTY 与 readline close 顺序失败,已修复后重新生成 native fixture/public materials 并执行成功窗口;失败不计作通过。两次 G 窗口均已核对 DB/role=0、进程停止,独占 PG 27432 停止;F listener、C native 临时状态、PAP 状态 master、公材料文件和 callback 管理 fixture 已精确清理。没有 Token、code、JWT、claim secret 或私钥进入日志/结果。
64
+
65
+ A owner 另对当前 host 做真实缺后端 keyring 检查:缺少 secret-tool/gnome-keyring-daemon,独立无 activation DBus/private XDG 中 F KeyringSecretStore get/create/PapStore.transaction 均 credential_unavailable、无文件 fallback。此项只能记为 real_missing_backend_only;Secret Service 正向 create/restart/locked/missing-item 未执行。
66
+
67
+ ## 隔离容器真实 Secret Service 正向补证
68
+
69
+ 2026-11-06 在任务专用 Docker 镜像/容器内直接导入 F 实际私有包的 KeyringSecretStore/PapStore,9 项检查全部通过;没有替代 secret-tool/Secret Service,没有 Agent private key,也没有修改生产实现。输入私有包为 aa4241089027bc003d18b2a36080d4780a7fccff 的候选,SHA-256 `1db4804f23af43ffcad4a094ded981e2f7f8a5b8df624a28ee9f6eed2db2b30b`;三份相关源文件 SHA 在结果中记录且与运行后仓库完全相同。
70
+
71
+ 实际检查:真实 create/get、PapStore 加密事务、新 Node 进程取 key/恢复状态、gnome-keyring-daemon 重启、Lock 后 get 不返回 key/create 和 PapStore read 拒绝且密文不变、带 stdin 密码启动新 daemon 后恢复同一 key/state、clear item 后既有状态 read/transaction 均 credential_unavailable 且不重建/不改写,以及私有普通文件中没有明文 key/password/marker 或 fallback。
72
+
73
+ - 入口:`node scripts/keyring-container/run.mjs`,只运行该真实模块验证,没有重跑完整 owner/System/E2E 套件。
74
+ - 成功 run:`worktrees/20261104-dsh-shared-agent-identity/.artifacts/keyring-verification/secret-service-container/run-20261105t185044615-a3063167/`。
75
+ - 基镜像:`node:22.23.1-bookworm-slim@sha256:6c74791e557ce11fc957704f6d4fe134a7bc8d6f5ca4403205b2966bd488f6b3`,实际 Node v22.23.1。
76
+ - 最终任务镜像 digest:`sha256:8a56b828b5f50bae4eaac282304a223653f40d2c9a8ca19a4b3b2f478b4020e5`;tag `dsh-pap-secretservice-check:run-20261105t185044615-a3063167`,没有 push。
77
+ - 实际包版本:libsecret-tools `0.20.5-3`、gnome-keyring `42.1-1+b2`、dbus `1.14.10-1~deb12u1`;完整依赖版本在 result.json。
78
+ - 结果 `output/result.json` SHA-256:`56bdaaea832b17129c3ad901dfc36a671e9e9caac964b1dcf7f59df2bcfb56d4`。
79
+
80
+ 运行时使用 --rm/network none/read-only root、非 root、cap-drop ALL/no-new-privileges、有限 pids/memory/CPU、私有 tmpfs、仅任务 evidence 可写路径。私有 DBus 不配置 activation 服务目录,XDG/control/state 独立,不改 HOME、不接宿主 DBus/keyring。Secret Service、DBus、私有状态清理均核实 true,容器无残留;失败尝试的专属 image tag 已删除,只保留最终镜像供核对。
81
+
82
+ 前期 harness 断言曾误用成功 read 之前的密文摘要(read 会推进 generation),另有 host log stream 收尾和运行中 CLI unlock 假设的问题;修正验证编排后重新执行,旧失败结果保留且不计通过。锁定后的恢复采用真实 daemon 重启并从 stdin 提供同一密码,不冒称 headless in-place CLI unlock 成功。
83
+
84
+ 原宿主 negative result 完整保留。结论是 isolated_container_real_secret_service,不是“宿主已配置 keyring”。另已核对 C clean `481ac1707b2287b03a08725141ce81d983dcda6a` 与前述两真实组件执行时的 7 个关键源文件完全同字节;可绑定 C481/Bf2/G242 的已测来源,不再只停在 dirty source 描述。
85
+
86
+ ## P22 实际客户端缺口修复与 P06 fixture 回归
87
+
88
+ 只读 P01–P28 快照位于统一 `.artifacts/completion-audit/pap.json`,保留当时 P22 partial 的事实;后续最新总审计由 H 合并,未把其他缺口静默改成通过。本轮增加持久加密 resource/AS 冷却命名空间,Retry-After 精确 deadline(delta 与三种 HTTP-date)、跨实例/新进程恢复、短窗等待/长窗剩余提示、取消与重新授权检查;429 不自动重放原请求,也不以 cap300 提前发出。标准 Bearer/DPoP challenge 优先于 JSON,并只提供严格校验后的 scope/PRM 管理提示;无 metadata fetch 或 Token/resource 自动跳转,不记录远端描述。
89
+
90
+ H 指出的发送窗口也已关闭:签名后若因 Store 锁/secret resolver 挂起,恢复后的持锁 callback 会重新 await 实际 C Session/DPoP lease.assertActive,再同步复核本地 generation/epoch 到 HTTP start。受控 resolver 挂起→撤销 fixture lease→恢复的直接回归观察到一条签名、**零 physical request**,没有输出 JWT。
91
+
92
+ 实际命令:`npm run typecheck && npx tsx --test tests/cooldown-challenge.test.ts tests/client.test.ts tests/network-store.test.ts`,最终 **48/48** 通过;原生 TAP 为 ignored `.artifacts/p22-owner.tap`。其中新文件18项(含 P06 fixture),client26项和storage/network4项。没有跑 System Test、产品 E2E 或其他全量套件。
93
+
94
+ 直接证据包括:真实 HTTPS 的一秒窗口与两个显式并发 client、签名/物理请求零提前;HTTP-date fence 在新 Node 进程恢复且 signer/network 均0;3601秒窗口不截短;disconnect/signout/close 取消且保留fence;scope/epoch/lease复查;同origin AS/resource互不阻塞;AS429并发等待一致返回rate_limited而不误报reauth;challenge-only/空JSON、header优先、quoted challenge、多scheme、重复参数、unsafe URL/scope丢弃、无副作用重放、非标准Session错误不能触发OAuth重试。AS时间/错误矩阵使用明确FixtureTransport边界,不冒充新真实G限流运行。
95
+
96
+ 新增 P06 client unit/fixture:已持有效标准grant后重新发现disabled=true、issuer不变,即使scope广告省略也允许按本地grant/C许可向AS实际refresh;new sign-in拒绝;AS返回invalid_grant后本地reauthorization_required,Company仍disabled/issuer,不降无AS、不转CC/JWT Session grant。此项不替代 H/G 的真实disabled服务专项。
97
+
98
+ 旧 client 回归原来在429后立即检查许可撤销,现因持久fence先返回rate_limited,已用显式测试时钟走过该窗口再隔离检查permission_denied;不是清除生产fence。
99
+
100
+ 此前容器SecretService正向测试仍绑定旧输入包/Store源码;本轮Store只加cooldowns的加密schema默认值/迁移,cipher/atomic/key逻辑未改,keyring实现未改。最新focused storage regression通过,但不把旧container Store整文件hash称为当前相同;宿主未配置的边界不变。
101
+
102
+ P22 收尾补充:AS 冷却期间也复查本地 code transaction.expiresAt;窗口尚未结束但交易已到期时,不签新的客户端断言、不发送 code。追加真实短时间窗回归,并重跑 P06 与 delayed-signer 取消用例:`npx tsx --test --test-name-pattern='P22 an expiring|P06 fixture|cancelled code exchange' tests/cooldown-challenge.test.ts tests/client.test.ts`,**3/3** 通过。此为前述48项之外一项新expiry场景及两项复验,不把重叠用例重复累加为一轮全量结果。
103
+
104
+ ## 最终 production 7325 的最小真实重绑与默认 relay 联合链
105
+
106
+ 生产保持 `7325b80a2b5c4b4b5e5e80d1ff1304921c9d1bb7`,没有修改 src 或 package-lock;此前更旧源码的 positive 没有直接冒充本轮。
107
+
108
+ - 当前 7325 私有包 `5fcaca0d98fa857433a1af0e8786f33ce545595136fcd4763a46fcc98cb7a255` 输入新 Secret Service source layer,真实 **9/9** 通过;source 三文件及 compiled JS 与当前文件逐SHA一致。新镜像 `sha256:fea7c2a0f03570a8bc636c1d3c19505a79964bb0b7f573363d7473fe039aa72c`;结果 `run-20261105t200941309-2cad8afb/output/result.json` SHA `6b764c884c6c57689211c580b85afda8496ce7ce9ff9abda58a3a60bfa7c9350`,daemon/DBus/private state清理均true、--rm无容器。该结论仍是隔离容器,不是宿主已配。
109
+ - 旧 callback component 以 C95c5f5/B04fe 重新通过一次。C当时全仓dirty仅无关test helper,31个 production src+managed helper实际执行文件全部匹配HEAD blob且pre/post无变,未虚写全仓clean;B clean且pre/post无变。F `.artifacts/rebind-7325/summary.json` SHA `37fc0078f14e5ccf02b201bc8ecd939ddc040e7ed12cbe38152c2c4008aa6d8e`。
110
+
111
+ 默认 HTTPS relay + same-native 账户联合新入口 `scripts/relay-native-frontvia-component.ts` 已在 G `pap03_9ba25075199a` 实际通过。它直接使用 B 扩展的 `createManagedCallbackFixture` 完整显式 policy tuple,实际 C 批准/E1 native/B factor 注册/Registry/PAP publication,C public material 是 B 原始 GET bytes。所有 Agent identity/delegated/DPoP key 仅经 C/A 本地 custody;不是 FixtureHost,也不是 publication acceptance mock。隔离 master、测试邮件投递 capture 与 G 保留 OTP身份范围仍明确。
112
+
113
+ 实际请求次序为:F startSignIn真实登记→G AS真实consent/code→真实TLS `https://agent.test:29443/user-service/v1/pap-callback`→G精确路径代理→Node只`helper.fetch`实际B callback→F DeviceCallbackHandoff 原设备一次领取→本地PKCE换标准Token→DPoP账户→重启DPoP restore→委托轮换(Token请求数不变)→显式refresh→revoke→signed-out。callback forwarded/received=1,Token endpoint仅2次(code+refresh)。Node proxy没有parse/store/claim code,G ledger只固定path不含query;不能把内部127转发称为AS loopback callback lane。
114
+
115
+ 原生consumer结构stdout保存 `.artifacts/default-relay-native-7325/consumer-result.json`,SHA `fe02de620a06de33c7d0c88a51e8bb519550d6ae65e3d31f999d025d7bec981c`;与 G 原生 `pap03_9ba25075199a/result.json`(SHA `f601ccef6c5711e5512af342f08f4911399e84ca6738143898808dea143c241c`)配对。最终 summary SHA `23b97c3feb4e2e79543cf1838514aa34225a46388089f594753c3d84dd5b7b98` 是初始 summary27d 加最终 producer blob绑定后的版本,consumer/G结果没有改动。
116
+
117
+ G独立核对 metadata/JWKS各11GET,原始bytes SHA分别 `1ca906fee0216195d57244b35f7108f1b27a4acd8f0a553cf1e421e1a19a6fcd` / `ad5c33829caba2ee7a4bb371aefc7df9fffa339b17a433f1c59be23fb5f6fcaa`,固定callback forwarded1/non-success0,DB/roles0、process stopped、PG27432停止。F listener、native/PAP临时状态、master、公材料与B临时MySQL fixture清理完成,process exit0。
118
+
119
+ 执行时 C managed helper17d737/B bridgec857 pre/post逐SHA相同,并分别与最终 C commit `fddc8a3e1bb81409ef9eb06ed5e6bbdda8bdd735` / B commit `6dcf839c0d2eff1f63d881695c20cc80445cc7ac` 的blob逐字节匹配。实际生产仍native e2c4、G binary35f626;H/G/E在同一生产7325上另行运行P01/P28,不以此账户链代替MCP回归,也未让此test-only入库改动抢占其HEAD guard。
120
+
121
+ 本轮没有重复 full owner suite、System Test、产品E2E或依赖发布检查。测试脚本已typecheck并实际运行,后续只提交脚本/说明,生产src/lock继续与7325同字节。
122
+
123
+ H/G/E 的 P01/P28 联合已完成并释放 F HEAD guard:原生工具结果结构化归档为 `cimd-oauth-server/ts/.local/verification/shared-protocol-final-20261106.json`,SHA `fcd4f93190bf787a1e7e93caf4455b0bc3b71f99b2c6a64cce74fa3fc2392ea9`。实际绑定 F7325/Daf6/C helperd193/nativee2:PAP NoAS真实C/A→HTTPS、Token0,关闭engine/实际PAP Context/lease/server,随后同DID/CIMD在新独立MCP Context完成陌生client CC双工具、真实等待8.5s DB expiry后再次CC双工具,Token2且均CC、无callback/authorize/refresh。PG owner与私有/tmp/cimd-pg.rvezGbFr已EXIT删除。该结果来自已完成tool25276 stdout归档与guard后source复核,不是本轮F另跑,也不是新test-only HEAD的执行来源。
124
+
125
+ ## PAP installed Host 管理与受限工具(新增候选)
126
+
127
+ 本轮针对只读产品接入审计发现的缺口,仅修改 F 仓库。bundle 默认 disabled,不再隐式从 DSH_PAP_* 环境变量取得 binding;enabled 但配置不全时返回 unconfigured,正常装载且没有网络或 key 创建。实际插件 Context 固定为 `@awiki/dsh-pap/plugin`;独立用户 Remote 与工具 row 分别为 `@awiki/dsh-pap/management-remote`、`@awiki/dsh-pap/tools`,通过真实 Loader entry/fiber 校验。用户管理不再依赖调用者提供的 `assertAuthorizedUserAction` 空泛回调。产品 Host 必须将 Typert 管理 namespace 限定在真实已认证用户 Gateway;本模块没有新建公开 HTTP listener 或把管理能力注册成模型工具。
128
+
129
+ 新增 `PapHostConsumer` 是 C 真实安全 factory 的结构合同,不是 F 自实现授权:F 仅给出实际 installed Context、三字段身份 reference 和 Host 固定 policyRef;binding/HTTPS redirect 从当前 C publication/policy 得出。callback 逐次从加密事务还原 Company/resource/scope,先走真实 ProtocolIdentityHost 获取 C opaque target,再索取 register/claim 闭合 capability 并在 finally dispose。F 没有 DeviceAccess、NativeStore 或 generic HTTP/signer 入口。C factory 在本轮 F 单位测试中是明确替身;未把此前直接 new PapClient 的真实 native 结果当成此新入口的 C/A 集成通过。真实 C factory owner 通知 ready 后才补必要模块验证。
130
+
131
+ 模型只注册 `pap_status`、`pap_operations`、`pap_request`。用户先通过管理 Remote 选择 identity、发现 Company、创建 Session、显式启用本地 operation;工具只提交 operationRef 与已声明 path/query/JSON body,不能自报 URL/method/Header/resource/scopes/account/verified metadata。权限存入加密 Store,每次启用有新 generation;签名期间撤销再启用同一操作,旧调用在最终持锁 guard 拒绝,实际 HTTP 为零。工具不自动发起账户登录或 browser/callback action。标准 challenge 的安全 PRM/scope 提示仅在用户 status 出现,不把 URL/远端描述送给工具。
132
+
133
+ Secret Store 复用真实 KeyringSecretStore;namespace 额外隔离 PAP purpose 与规范化 profile stateRoot 摘要。实际状态 key 仍为 OS secret store 产生的独立随机32bytes,不从身份私钥或普通 credentials/env 派生。可选受信 papHost.secrets 支持其他平台;后端不可用/锁定/既有 item 丢失继续 credential_unavailable,没有明文、RootKey 或 env fallback。既有 SecretService 容器9项仍只证明其对应源码和容器平台,不能宣称宿主已配;此次 keyring.ts/store.ts/host-secrets.ts 的生产密钥/密文实现未改。
134
+
135
+ 实际定向验证:
136
+
137
+ - `npm run typecheck && npm run build && npx tsx --test tests/product.test.ts`:12/12。正式 registry `@deepseek-ai/cordis-plugin-loader@1.0.3` 入口与真实 Cordis 生命周期;C/publication/callback backend 和加密 root key 为单位替身。覆盖 disabled/unconfigured、精确 installed caller、仅用户管理、NoAS Token0、路径/URL/Header/query 拒绝、Direct target handoff、秘密不进工具、错误脱敏、权限 ABA race、Loader 重启恢复、工具禁用、profile namespace、blocked secrets、challenge 提示分离。
138
+ - 较早受影响回归 `npx tsx --test tests/product.test.ts tests/client.test.ts tests/cooldown-challenge.test.ts`:55/55(当时 product10项);新增2项后仅复跑 product12,不将重叠次数累加成新整轮57。没有跑其他全量或 System/E2E。
139
+ - `npx tsx scripts/tools-registry-component.ts <Desktop已安装dsh-tools/lib/index.js>`:真实 `@deepseek-ai/dsh-tools@0.1.5-rc.2` 注册三工具并经 ToolRuntime.execute 执行 disabled status、拒绝任意URL、未配置 operations。实际入口 SHA-256 `aaba52bf5d0149355407642b3965c06977d1e9143f5c61bc19429abbe6a11c5d` 前后相同;systemPrompt 仅替代注册 seam,无 LLM、Company、credentials 或 native 验收声明。
140
+
141
+ 依赖诊断纠正:起初误读 `lib/index.d.ts` 路径(实际为 `lib/types/index.d.ts`)并被 rg 默认忽略 lib 的结果误导,曾误报 registry Loader 缺入口。Root 与 owner 重新核对正式包 lib/index.js 存在、SRI一致;测试已完全改为正式包入口,删除源码编译辅助与所有 NoCheck 绕行。lock 虽来自 mirror,SRI `sha512-YNcHiH7TRFrgnRbQU7qdS1spABUFFHg04QpB9DdboPEjgKLTFfeEAvr6Y7qll3/nGgqywDQdk1tYshqKO0p1WQ==` 与 primary 制品逐字节相符。安装 dsh-tools dev 依赖曾因 ^rc2 解析到 rc3 的 peer 冲突停止,没有 force;运行时 peer仍固定rc2,实际 registry检查复用 Desktop 安装产物,不修改其依赖。
142
+
143
+ 此候选补齐 F 管理/工具 Host 源码,不代表 Desktop 默认 bundle/vendor/settings 已接入。Desktop/C/D 由对应 owner 修改;实际 Company 业务目标尚未决定时保留配置,不新造默认 Company。C factory 全链、真实产品 UI/启用流程、宿主 keyring 配置、System/E2E 和发行门槛分别保留其待验范围。
144
+
145
+ ### 产品入口安全复核 follow-up
146
+
147
+ A/H 只读 source review 在 7bd 候选发现实际生命周期缺口:仅定义 stop 不会触发 Cordis disposer。现 constructor 显式注册 ctx.effect cleanup,stop 幂等关闭 engine/abort resource HTTP/dispose C facade;工具响应后与 post-Store 公开结果前再次检查 installed tool Context、真实 C active capability 和原始 engine/selection。显式重选同一 identity 也会产生新 engine,旧结果不得借用新 active facade 返回。select 在 persistSelection 的 fsync/rename await 后再次检查 C active/stopped,不能在卸载之后发布新 client。
148
+
149
+ 同批关闭 opaque credential 回显空洞:不只按字段/JWT pattern 遮盖,还在实际 HTTP send 前持锁同步 capture 本次真正发送的 Session/DPoP/Authorization/access/refresh 值,仅供同进程 redaction set,不是 wire DTO/日志。合并调用前后私有值集,任意 JSON key/value/message 包含该值都遮盖,包含自动 refresh 的中间新 Token,不能假设响应后 Store 还留着它。输入 URI 经编码后的8KiB上限在签名前检查。C disposed generation 只在真实用户 identity/select 或插件重载时重获,工具/status 保持 fail-closed,不复活旧 target。
150
+
151
+ 当前 `npm run typecheck && npx tsx --test tests/product.test.ts`:18/18。新增直接断言包括实际 Loader unload 的 transport abort(honor/ignore两模式)、迟到结果不返、selection 持久化挂起时卸载后 next.close、自动 refresh→实际资源响应→dispatch返回挂起→用户 sign-out 清空新 Token→恢复后的未知 key/value/message 回显仍脱敏,以及同 identity/operation approval 不变时重选仍拒旧 engine 结果。C/protocol/callback 仍是明确单位替身;这些用例不冒充新 C factory/native 或产品 E2E。
152
+
153
+ 只读复核再收口同族只读入口:getStatus/catalog 在 protected-key/Store await 后也检查当前 engine/selection、真实 C active 与调用 Context;user/tool status facade 在 await 后复查,manager.execute 通用尾检避免慢管理动作返回卸载前结果。受控 key resolver 挂起期间实际 Loader 卸载,四种 user/tool status/operations 均拒返回旧 ready/catalog;另一次 provider generation 在挂起期间变化,恢复后拒绝旧 status。当前 `npm run typecheck && npx tsx --test tests/product.test.ts` 为 **23/23**。A 对最终源码只读安全复核未发现剩余确定阻塞,测试归 F owner 执行;不将其称为 C factory/产品全链审计通过。
154
+
155
+ ## 产品入口后续:S15 持久闭环、用户 settings 与真实默认 backend
156
+
157
+ 后续 Root 实际复核发现两个历史边界,均先复现:旧 AT 首请求401引发 refresh,下一请求 echo 仍有效旧 AT 时单请求 redaction set 不足;加 service 内历史后,实际 Loader disable/enable 创建新 engine 仍会漏旧值。两个失败结果不计通过。并纠正早先 owner“重启”用例只 update 相同 config 的不足:Loader 不会因此重启;现明确 disable/enable,assert 旧 stopped、新 engine 引用不同,才计恢复证明。旧2113与23项记录保留其当时范围。
158
+
159
+ 现在私有 AT/RT 历史在既有 AES-GCM PapStore credentialVault 内,不另建密钥服务或明文 vault。新AS response 在解析/提交 grant 前先持锁归档;发送 refresh/revoke、替换及清 Token 前也原子保留旧值。运行内已知寿命使用单调时间与所有在途响应 pin;跨重启剩余寿命无法证明的 tombstone 保守保留,不伪造24h AS/RT期限。4096值/4MiB预算满即持续 fail-closed,不驱逐仍可能有效项,也不因用户重选同identity清历史。所有 tool/user 动态状态、Company名称、operation路径和业务输出都做已知秘密过滤;当前pending state默认过滤,只有明确User account/sign-in的authorizationUrl字段局部保留正常state/challenge。AT/RT是持久历史范围,已删除的旧nonce/verifier/claim/sid不宣称无限追踪或重构。
160
+
161
+ Legacy规则由Root明确确认:无vault却有grant/slot、任意已处理或取消的账号tx、AS nonce/DPoP迹象,保守 legacy_incomplete;只 seed当前已知不等于补全未知。Agent请求和动态Company/catalog/status停止;user仅固定迁移状态、Host生成的account refs/闭合状态并可正常尝试revoke。最新logout/revoke不自动证明全部旧RT失效。无账号迹象的旧纯NoAS才迁移complete;fresh在首次AS请求前有complete marker。保留加密数据/epoch/cooldown,不wipe/newkey/弱confirmed参数;只记录独立受信Host运维的完整issuer/client/resource撤销事实前置,本轮没有新恢复UI或通用扫描器。
162
+
163
+ 用户明确的 account/refresh{accountSlot} 也已纳入闭合管理动作,输入无grantRef/URL/resource/scope/Token;核对当前binding/subject/Company/slot epoch/已有连接代次,调用既有真实refresh,再检查原Context、engine与C active。无RT或not-active拒绝,不自动重新授权;slow refresh期间实际Loader卸载不返回active。callback在Company discovery过期后先安全重新发现、检查namespace/tx,再重新获取真实C目标,不复活过期target。
164
+
165
+ 实际验证:
166
+
167
+ - 最后一次受影响 owner 合计 **94/94**(client26、P22 19、storage4、history5、product32、UI8);原生 `.artifacts/product-final-owner.tap`。此后新增hint一项仅复跑UI,不能把不同重叠轮次累加成整轮95。typecheck/build均通过,未执行fullsuite/System/E2E。
168
+ - settings DOM与browser制品:明确identity选择、Company发现、Session、operation批准/撤销、浏览器点击/collect、refresh/logout、disabled/Cwaiting/legacy/error安全提示、实际settings.section注册;C身份只能经公开list+publicationStatus得到published且papSession=true的refs,无C审批/Native/DeviceAccess。浏览器bundle与输入图不含Host/Node模块,Host `lib/client.js`不被覆盖;浏览器入口是`lib/browser-client.js`。
169
+ - 实际Desktop所装ClientModuleRegistry(entry SHA `a178c4b2d8adfb18d21e66337638aa66d08b57cc0f6325981678045aca380510`)完成root marker→locatePkgJson→browser export→serveBundle。marker没有pap/C/credentials能力;DOM与此gate分别记录,不当Desktop GUI已启动。
170
+ - `scripts/product-native-component.ts` 新真正入口 `.artifacts/product-native-entry/second-run.json`(SHA `5113b33c85a1c723d2b150bf61cfcaa6685332f92c613b14ba6e5c459ea9f44b`)exit0:fresh实际C批准/Bstrict注册发布→同store真实C/Native/credentials/manager重开→实际F三entry+真实ToolRuntime→独立实际TLS Nodecrypto NoAS verifier,2条Delegation/Session验签、jti2、Token0、公发现无auth、批准前physical0、卸载后0。F仅提供网络transport,默认Keyring实item32bytes已查证,无memorySecret。F Host与C src pre/post一致,实际加载native e2c;对应helper为旧49.../strict c74...,后继test-onlyoptional origin/profile不反标为本次来源。该结果早于M12 availability新native,保持历史。
171
+ - 上项首轮未显式A runtime aliases,freshpublication失败;原生结构输出保留first-run-failed.json且全清理。第二轮fresh Node用明确main/provider aliases→A bindings/node,Cordis/credentials仍official registry,唯一加载e2c。不是新API registry安装或署名remoteSigner。
172
+ - 默认backend sidecar复用image `sha256:fea7c2a0f03570a8bc636c1d3c19505a79964bb0b7f573363d7473fe039aa72c`;固定本机`unix:///var/run/docker.sock`,CLI最小env,shim固化inspected containerId+privateDBus+closedargv,无Host HOME/DBus/keyring mount。current Keyring/PapStore/vault real create/get、密文、daemon restart、新Host Node与vault恢复4项过;预取消/启动中取消也清理且task container inventory不变。该后端容器不是宿主已配置。所有key/pass只stdin/内存/捕获stdout,无日志。
173
+
174
+ 上述native默认backend链结束已核C/F state、TLS server、SecretService/DBus/private state/container/shim全清理,HOME不变。新actual account产品链另由 `scripts/product-account-component.ts` 准备,严格使用fresh C factory与实际user Remote、defaultbackend、B固定HTTPS relay、G真实OAuth/DPoP,不使用旧直接new PapClient/managed callback helper。其新C/A M12候选及运行结果尚需单独绑定;不以NoAS或旧账户组件冒充此层通过。Desktop profile/renderer最终产品gate仍由Root执行。
175
+
176
+ ## 最终 actual product-account:F43 / C M12 / A FFB / G35
177
+
178
+ 实际执行F源码为 clean `43aac767fa1c73ecdb7a60e1f263c1ec06155d8f`。命令为 `npx tsx --tsconfig .local/tsconfig.product-native.json scripts/product-account-component.ts <C test/helpers/product-host-fixture.ts> <B source> <Python> <public-only-materials.json> <Desktop installed dsh-tools/lib/index.js> ffb6c3a6ee7bcd5592184db57c865d0a90748a6379636ca203a5ad42012718b9`;TTY99220只输入G handoff绝对路径,stdout只有ready/public hash与最终脱敏结构。source aliases明确指A bindings/node主包与provider,C/Harness peers保持当前正式registry,不伪称同号NPM已具新native接口。
179
+
180
+ 这一次不再直接new PapClient或传旧managed-callback helper:真实C创建批准→strict B独立用户确认/注册/Registry/PAP all3发布→同store按真实ref装入一次性PAP policy→实际Loader根marker、Fplugin、Fmanager、Ftools与真实ToolRuntime。F只收到C真实factory/config;测试用户control和个人Company登录actor留在controller外,插件没有Native/DeviceAccess/邮箱control。papHost仅提供明确fixture网络transport,不提供secrets,F走默认KeyringSecretStore与真实私有SecretService后端。
181
+
182
+ 实际路径:signed-out Session请求/Token0→用户Remote startSignIn→C目标绑定callback登记→G真实个人OTP/consent/code→真实TLS固定HTTPS callback→G唯一GET代理→Node只forward原query到B实际public callback→F用户collect经C真实原设备claim+本地PKCE换码→DPoP账户GET→实际Loader disable/enable F→DPoP key恢复→用户account/refresh→DPoP账户GET→account/sign-out/revoke→signed-out调用继续。callback forwarded/received各1;Token endpoint恰2次,grant_type只有authorization_code和refresh_token;revoke1。重启后记录 **userReselectedAfterRestart=true**,即复核状态后执行了一次显式用户重选,不能描述成全自动恢复无需用户动作;没有重新账户授权/新增code请求,原DPoP/账户恢复仍实际通过。
183
+
184
+ 实际唯一加载native为 `ffb6c3a6ee7bcd5592184db57c865d0a90748a6379636ca203a5ad42012718b9`,C production index `fd24642860074a964be7116ab7a045cdba16d0a474220a90f5b4c8e35c6a95fc` / target-policy `5dfa70b0f0b1dd3ac8c64a44c62b35fbdf13d7f857d43e7fddaed92aad91cb7b`。全部F src(含browser)与C src pre/post逐SHA相同,F源与执行43 commit blobs逐项绑定。G生产binary仍 `35f6265876ef98daa69e8780f055ed2e6f164468494f1241b711dd2e7be09444`,helper e564/strict bridge b89。主体仍本地AES-GCM文件;主key当前为已实现OS backend,sidecar只用于隔离模块验证,不新增运行时服务/文件fallback,不把这次计成宿主OS已配置。C Native root在fixture明确使用A任务local-file custody,非A OS keyring产品gate替代。
185
+
186
+ 消费者结构归档 `.artifacts/product-account-43/consumer-result.json` SHA `de0f2fd8c161df93adcce17c32a76cf07ff65b1e2dc8a24f302354e3e29337cd`,archiveProvenance明确:已完成PTY99220最后JSON stdout的结构化归档+postexit source重新hash/F43blob绑定,不是重新运行,不冒称runner直接原生落盘。对应G原生 `platform/.local/pap03/pap03_1b87dd6acaab/result.json` SHA `91bd206da87a009022650129f0e3ed286feea490712ad81de7ca219522574159`。
187
+
188
+ G独立核验真实公开metadata/JWKS各GET10,served字节SHA与实际B公开raw strings完全一致:`d67223640067a86017ee7e32afe4333adfb3792295f2d7d6266a857613b0ca20` / `796035da6c8f2a587ac8faa3b4046dda9251d8b4224af28ece484f82b9c8583a`;callback仅固定path1/error0,result/ledger无code/state/iss query或Token。G是handoff-only窗口owner checks0,不把历史16suite算本次重跑。
189
+
190
+ 消费者exit0后C/F临时state/SQL、Node relay、公开材料、SecretService/DBus/private tmpfs/container/shim全精确清理,HOME不变。G确认DB0/role0/process stopped,27432/29443无监听且ownedPG停止,guard已释放。B为实际production ASGI/fullmiddleware的逻辑HTTPS模块调用,Company为真实TLS/Rust/PG;没有GUI产品E2E、System Test、LLM runtime、共享部署、push或发布。Desktop正式profile/renderer最终验收另由Root owning。
191
+
192
+ ## 冻结 production43 后的 test-only 模块差额
193
+
194
+ 后继879eb4b与045ebf7仅新增测试,e65现有安装tar不重打。P19/P20/P21/P23/P24沿原fixture五组focused分别1/4/2/1/1通过,补same-grant双sid刷新、scope返回子集/empty/extra与unauthorized_client、第二次ended停止/validgrant保留、只选账号枚举全部RT、Company namespace旧身份/Token不迁移。P23第二resource行明确direct encrypted-storage fixture,不是实际AS多resource签发或Commerce隔离。G另补discovery/session差额5/5,B只读审过;执行命令、类型检查与G stdout provenance见 `.artifacts/pap-module-gap-final-summary.json`,不把不同轮次拼为新全套。
195
+
196
+ P18后继script `p18-native-wire-component.ts`(SHA `4d636239a1549cf108a3946d2790b0dc754bf485cca2fba78d22be68a9add55d`)在C clean46bf/AFFB上实际exit0。直接输出原生 `.artifacts/p18-native-wire/result.json` SHA `e5c910d002f5355f5f87e502dc70d63ae459b7153d471b997da6ceed2c5ab294`;69个相关production/script/helpers/Awrapper前后相同。Bearer无DPoP广告、create/sign/header各0,AS2post/RS2get;DPoP ASnonce challenge2、RSnonce1、code2post/refresh2post/RS3get,独立Nodecrypto核7proof/4assertion/3Session及jti/htm/htu/iat/ath/同origin nonce隔离。pass-through只计数不改真实C/A结果。回调明确published loopback,AS/RS为scripted HTTPS fixture,非独立第三方AS/GUI/System。B只读核源码/结果/69files无阻塞,全部listener/state/SQL/SS/container清理。
197
+
198
+ NoAS handler机械提取后继3961059只移到 `scripts/helpers/no-as-product-verifier.ts`(a74586…23817e),原product-native仅改调用(91f5aaa…a0048)。D只读确认默认company.test语义和原Nodecrypto验证未削弱;不重跑旧NoAS脚本,也不重标旧5113来源。新current P01/P28复用了此单一helper:C46bf/AFFB/D a8/F43同Host/provider/ref/mixedCIMD,真实FNoAS1/Token0→Context仍installed时F.stop且实际rawCtargets已dispose/assertActive拒→卸F三rows/关闭NoAS与SS→同一Host再MCP首次CC双工具→真8500ms SQL到期后CC2双工具,无authorize/callback/refresh。G实际1case pass,原生C `.local/verification/shared-product-current-host-20261106.json` SHA `00cc6b086d50ec09d9cccaac36d566ffaed86814befa60b2f982db368b1d7a66`,MySQL/Redis/Croot/TLS/PG/SS全清;D只读复审无阻塞,F不在此重复执行或提交C spec。首轮新case缺actualAgent被合法门禁拒,修test actor后成功,不算prodBug。
199
+
200
+ 以上新增仅test/script/docs,runtime仍43、安装文档制品仍e65;source/test后继与二者分开。没有改变存储、production、依赖或现有tar,未跑fullsuite/System/GUI/共享部署。
201
+
202
+ ## 2026-11-07 跨平台文件密钥后端
203
+
204
+ 按用户要求新增显式 `secretStore: local-file` / `secretsRoot` 配置及 `FileSecretStore`。状态仍加密;原生签名私钥不经过本文件后端。macOS/Linux 使用当前用户所有权与 0700/0600,Windows 使用当前 SID 的 DACL。跨进程首次创建通过已刷盘临时文件的原子 hard link 完成,不覆盖已有密钥;既有密文丢失密钥时沿用拒绝读取语义。插件及独立 Host provider 均可选择后端,默认配置和原 keyring 行为保留;后端切换不自动迁移已有数据。另调整 Windows 的目录 fsync 路径。
205
+
206
+ 实际执行 `npm run build`(TypeScript 编译及 browser client 构建)成功,`git diff --check` 通过。用户明确要求本轮不执行测试,由用户在平台验证;未运行单元、组件、系统或平台测试,因此不宣称 macOS/Windows 运行验收通过。未安装、打包、更新 Desktop 内置候选或部署服务;本记录不改变前面历史测试所对应的源码版本。
207
+
208
+ ## Release timing verification
209
+
210
+ The cross-client refresh and signout cases use explicit transaction/read barriers
211
+ to ensure the tested requests overlap; fixed 40 ms sleeps do not establish that
212
+ ordering on a durable filesystem. Cooldown cancellation cases freeze the injected
213
+ protocol clock and wait for an observed state, so cancellation must settle
214
+ without advancing the cooldown. The error-code, single-refresh, persisted-fence,
215
+ and no-extra-signature/network assertions remain in place. Whole signout duration
216
+ is not treated as cancellation latency because it also includes remote revocation.
217
+ These are test synchronization changes, not weakened production checks.
@@ -0,0 +1,19 @@
1
+ import type { PapAuthHint } from './errors.js';
2
+ import type { Company, HttpResponse } from './types.js';
3
+ interface Challenge {
4
+ scheme: 'Bearer' | 'DPoP';
5
+ error?: string;
6
+ scope?: string;
7
+ metadata?: string;
8
+ invalid: boolean;
9
+ }
10
+ export declare function parseAuthenticate(value: string | undefined): {
11
+ challenges: Challenge[];
12
+ relevant: boolean;
13
+ };
14
+ export declare function protocolFailure(response: HttpResponse, company?: Company, resource?: string, preferred?: 'Bearer' | 'DPoP'): {
15
+ code?: string;
16
+ hint?: PapAuthHint;
17
+ challenge: boolean;
18
+ };
19
+ export {};