@sema-agent/server 7.50.0 → 7.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/USAGE.md +83 -20
  4. package/dist/adoption/plan.d.ts +4 -4
  5. package/dist/adoption/plan.js +11 -0
  6. package/dist/approval-card.d.ts +26 -2
  7. package/dist/approval-card.js +9 -0
  8. package/dist/approval-hmac.d.ts +1 -1
  9. package/dist/approval-reconciler.d.ts +2 -2
  10. package/dist/approval-reconciler.js +1 -1
  11. package/dist/bench/l8/artifact.d.ts +1 -1
  12. package/dist/bench/s1/arms.d.ts +1 -1
  13. package/dist/bench/s1/live-deps.d.ts +1 -1
  14. package/dist/bench/s1/oracle.d.ts +1 -1
  15. package/dist/bench/s1/row.d.ts +1 -1
  16. package/dist/boot/budget-tracing.d.ts +1 -1
  17. package/dist/boot/budget-tracing.js +2 -5
  18. package/dist/boot/coordinators.js +3 -1
  19. package/dist/boot/deferred-sandbox-path-env.d.ts +1 -1
  20. package/dist/boot/device-lane.d.ts +79 -0
  21. package/dist/boot/device-lane.js +63 -0
  22. package/dist/boot/engine-lease.d.ts +1 -1
  23. package/dist/boot/execution-env.d.ts +48 -2
  24. package/dist/boot/execution-env.js +57 -5
  25. package/dist/boot/governance-seams.d.ts +2 -2
  26. package/dist/boot/leader.d.ts +1 -1
  27. package/dist/boot/memory-boundary.d.ts +2 -2
  28. package/dist/boot/memory-consolidation.d.ts +6 -6
  29. package/dist/boot/org-memory.d.ts +1 -1
  30. package/dist/boot/parked-revive-gate.d.ts +3 -3
  31. package/dist/boot/reapers.d.ts +2 -2
  32. package/dist/boot/reapers.js +17 -4
  33. package/dist/boot/resolve-spec.d.ts +15 -0
  34. package/dist/boot/resolve-spec.js +40 -15
  35. package/dist/boot/retention-lane.d.ts +2 -2
  36. package/dist/boot/runner-deps.d.ts +17 -7
  37. package/dist/boot/runner-deps.js +4 -2
  38. package/dist/boot/runtime-caps.d.ts +23 -0
  39. package/dist/boot/runtime-caps.js +24 -2
  40. package/dist/boot/session-faces.d.ts +6 -1
  41. package/dist/boot/session-faces.js +17 -3
  42. package/dist/boot/shutdown.d.ts +8 -0
  43. package/dist/boot/shutdown.js +3 -1
  44. package/dist/boot/stores.js +40 -1
  45. package/dist/boot/task-list-lane.d.ts +2 -2
  46. package/dist/brain.js +51 -31
  47. package/dist/budget.d.ts +2 -2
  48. package/dist/capabilities/center-plugins.d.ts +1 -1
  49. package/dist/capabilities/collab-workflows.d.ts +1 -1
  50. package/dist/capabilities/hands-lane.d.ts +3 -3
  51. package/dist/capabilities/scenarios.d.ts +3 -3
  52. package/dist/capabilities/skills.d.ts +1 -1
  53. package/dist/config-center/hot-keys-registry.js +5 -0
  54. package/dist/config-center/http-client.d.ts +2 -2
  55. package/dist/config-center/read-face.d.ts +1 -1
  56. package/dist/config-center/restart-signal.d.ts +1 -1
  57. package/dist/config-center/types.d.ts +10 -3
  58. package/dist/config-invariants.d.ts +2 -2
  59. package/dist/config-invariants.js +18 -0
  60. package/dist/config-types.d.ts +90 -18
  61. package/dist/config.js +91 -19
  62. package/dist/deployment-governance.d.ts +1 -1
  63. package/dist/device-enrollment.d.ts +125 -0
  64. package/dist/device-enrollment.js +156 -0
  65. package/dist/device-store.d.ts +385 -0
  66. package/dist/device-store.js +407 -0
  67. package/dist/device-ws-hub.d.ts +182 -0
  68. package/dist/device-ws-hub.js +1012 -0
  69. package/dist/device-ws-protocol.d.ts +429 -0
  70. package/dist/device-ws-protocol.js +464 -0
  71. package/dist/env-facts.d.ts +5 -2
  72. package/dist/env-facts.js +1 -0
  73. package/dist/execution-lane-caps.d.ts +152 -0
  74. package/dist/execution-lane-caps.js +166 -0
  75. package/dist/fleet/fleet-bus.d.ts +1 -1
  76. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  77. package/dist/fleet/fleet-terminal-window.d.ts +1 -1
  78. package/dist/http/active-run-conflict.d.ts +2 -2
  79. package/dist/http/principal-gate.d.ts +1 -1
  80. package/dist/http/route-ctx.d.ts +24 -4
  81. package/dist/http/routes/admin-memory-optout.d.ts +48 -0
  82. package/dist/http/routes/admin-memory-optout.js +75 -0
  83. package/dist/http/routes/agents-roster.d.ts +1 -1
  84. package/dist/http/routes/approvals-assistant.js +21 -21
  85. package/dist/http/routes/capabilities.js +27 -11
  86. package/dist/http/routes/diagnostics.d.ts +1 -1
  87. package/dist/http/routes/leader.d.ts +1 -1
  88. package/dist/http/routes/memory-bundle.d.ts +1 -1
  89. package/dist/http/routes/memory-bundle.js +3 -1
  90. package/dist/http/routes/memory-compliance.d.ts +4 -4
  91. package/dist/http/routes/memory-origin.d.ts +4 -4
  92. package/dist/http/routes/memory-origin.js +3 -1
  93. package/dist/http/routes/memory-policy.js +6 -2
  94. package/dist/http/routes/retention-ops.d.ts +1 -1
  95. package/dist/http/routes/rules.d.ts +5 -2
  96. package/dist/http/routes/rules.js +84 -5
  97. package/dist/http/routes/run-memory-capture.d.ts +34 -0
  98. package/dist/http/routes/run-memory-capture.js +97 -0
  99. package/dist/http/routes/runs.d.ts +1 -0
  100. package/dist/http/routes/runs.js +212 -6
  101. package/dist/http/routes/session-sync.d.ts +4 -6
  102. package/dist/http/routes/session-sync.js +60 -47
  103. package/dist/http/routes/sessions.js +61 -188
  104. package/dist/http/routes/shared-memory.d.ts +1 -1
  105. package/dist/http/routes/tasks.js +1 -1
  106. package/dist/http/routes/workflows.js +19 -0
  107. package/dist/http/server.d.ts +49 -13
  108. package/dist/http/server.js +109 -13
  109. package/dist/http/verify-rounds.d.ts +1 -1
  110. package/dist/http/wire-types.d.ts +41 -8
  111. package/dist/leader/endpoint.d.ts +1 -1
  112. package/dist/leader/leader.d.ts +1 -1
  113. package/dist/leader/repair-oracle.d.ts +2 -2
  114. package/dist/leader/repair-oracle.js +1 -1
  115. package/dist/leader/wire.js +4 -2
  116. package/dist/main.js +23 -9
  117. package/dist/memory-bundle-engine.d.ts +1 -1
  118. package/dist/memory-operator-faces.d.ts +5 -5
  119. package/dist/memory-origin-fence.d.ts +50 -0
  120. package/dist/memory-origin-fence.js +15 -0
  121. package/dist/memory-posture.d.ts +13 -1
  122. package/dist/memory-posture.js +1 -0
  123. package/dist/memory-scope.d.ts +6 -1
  124. package/dist/memory-scope.js +3 -2
  125. package/dist/model-select.d.ts +2 -2
  126. package/dist/observability/fail-open.d.ts +17 -5
  127. package/dist/observability/fail-open.js +17 -5
  128. package/dist/orchestration/hardened-vm-runner.d.ts +9 -2
  129. package/dist/orchestration/hardened-vm-runner.js +11 -1
  130. package/dist/orchestration/hardened-vm-worker-runner.js +2 -2
  131. package/dist/orchestration/workflow-completion-inbox.d.ts +2 -2
  132. package/dist/plugins/background-shell-support.d.ts +2 -2
  133. package/dist/plugins/blob-backend.d.ts +7 -2
  134. package/dist/plugins/blob-backend.js +22 -18
  135. package/dist/plugins/caching-session-store.d.ts +7 -3
  136. package/dist/plugins/checkpoint-store-sql.d.ts +2 -2
  137. package/dist/plugins/device-store-sql.d.ts +130 -0
  138. package/dist/plugins/device-store-sql.js +574 -0
  139. package/dist/plugins/file-history-store-sql.d.ts +170 -0
  140. package/dist/plugins/file-history-store-sql.js +827 -0
  141. package/dist/plugins/file-run-store.d.ts +44 -5
  142. package/dist/plugins/file-run-store.js +85 -13
  143. package/dist/plugins/fork-routing-session-store.d.ts +1 -1
  144. package/dist/plugins/fork-routing-session-store.js +2 -2
  145. package/dist/plugins/leader-run-store-sql.d.ts +1 -1
  146. package/dist/plugins/local-session-store.d.ts +9 -1
  147. package/dist/plugins/memory-embedder-fingerprint.d.ts +1 -1
  148. package/dist/plugins/memory-optout-grant-store-sql.d.ts +139 -0
  149. package/dist/plugins/memory-optout-grant-store-sql.js +157 -0
  150. package/dist/plugins/memory-origin-law.d.ts +2 -2
  151. package/dist/plugins/memory-run-store.d.ts +4 -3
  152. package/dist/plugins/memory-run-store.js +2 -1
  153. package/dist/plugins/permission-rule-store-file.d.ts +16 -6
  154. package/dist/plugins/permission-rule-store-file.js +77 -13
  155. package/dist/plugins/permission-rule-store-sql.d.ts +156 -8
  156. package/dist/plugins/permission-rule-store-sql.js +123 -21
  157. package/dist/plugins/pg-pool.js +59 -0
  158. package/dist/plugins/pg-safe-json.d.ts +1 -1
  159. package/dist/plugins/remote-env-device.d.ts +271 -0
  160. package/dist/plugins/remote-env-device.js +727 -0
  161. package/dist/plugins/remote-env-k8s.d.ts +1 -1
  162. package/dist/plugins/remote-scratchpad.js +1 -1
  163. package/dist/plugins/retention-lane-store-sql.d.ts +3 -3
  164. package/dist/plugins/retention-store-sql.d.ts +7 -7
  165. package/dist/plugins/retention-store-sql.js +6 -0
  166. package/dist/plugins/run-store-sql.d.ts +9 -3
  167. package/dist/plugins/run-store-sql.js +2 -2
  168. package/dist/plugins/send-user-file.d.ts +1 -1
  169. package/dist/plugins/session-placement.d.ts +1 -1
  170. package/dist/plugins/sql-errors.d.ts +1 -1
  171. package/dist/plugins/store-backend.d.ts +68 -29
  172. package/dist/plugins/store-backend.js +78 -15
  173. package/dist/plugins/store-contracts.d.ts +5 -3
  174. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  175. package/dist/plugins/tidb-pool.js +59 -0
  176. package/dist/plugins/web-search.d.ts +1 -1
  177. package/dist/prompts-domain-validate.js +1 -1
  178. package/dist/resource-suspend.d.ts +1 -1
  179. package/dist/resource-window.d.ts +3 -3
  180. package/dist/rules-consent.d.ts +231 -9
  181. package/dist/rules-consent.js +411 -13
  182. package/dist/run-local.js +1 -0
  183. package/dist/runs.d.ts +15 -1
  184. package/dist/runs.js +19 -0
  185. package/dist/runtime-caps-resolver.d.ts +36 -1
  186. package/dist/runtime-caps-resolver.js +25 -0
  187. package/dist/runtime-governance.d.ts +1 -1
  188. package/dist/security.d.ts +5 -5
  189. package/dist/security.js +1 -1
  190. package/dist/session-sync.d.ts +52 -37
  191. package/dist/session-sync.js +19 -16
  192. package/dist/shared-memory-scope-authorizer.d.ts +1 -1
  193. package/dist/sighup-idle.d.ts +1 -1
  194. package/dist/spec-fields.d.ts +22 -1
  195. package/dist/spec-fields.js +11 -0
  196. package/dist/store-live-probe.d.ts +2 -2
  197. package/dist/task-a2a.d.ts +1 -1
  198. package/dist/task-cwd.d.ts +25 -0
  199. package/dist/task-cwd.js +3 -0
  200. package/dist/task-mcp.d.ts +3 -3
  201. package/dist/task-settings.d.ts +3 -3
  202. package/dist/task-settings.js +3 -1
  203. package/dist/task-workflow.d.ts +1 -1
  204. package/dist/text-bidi.d.ts +2 -2
  205. package/dist/tool-approval.d.ts +191 -9
  206. package/dist/tool-approval.js +248 -29
  207. package/dist/trace/core-keyset-guard.d.ts +1 -1
  208. package/dist/trace/engine-notice-wire.d.ts +6 -4
  209. package/dist/trace/engine-notice-wire.js +2 -0
  210. package/dist/trace/ledger-events.d.ts +1 -1
  211. package/dist/trace/ledger-sink.d.ts +2 -2
  212. package/dist/trace/project.d.ts +3 -2
  213. package/dist/trace/project.js +1 -0
  214. package/dist/turn-activity.d.ts +1 -1
  215. package/dist/wall-clock-jump-guard.d.ts +3 -3
  216. package/package.json +2 -2
  217. package/dist/http/tar.d.ts +0 -17
  218. package/dist/http/tar.js +0 -53
  219. package/dist/http/workspace-content.d.ts +0 -11
  220. package/dist/http/workspace-content.js +0 -20
  221. package/dist/plugins/file-snapshot-store-sql.d.ts +0 -170
  222. package/dist/plugins/file-snapshot-store-sql.js +0 -213
@@ -0,0 +1,385 @@
1
+ /**
2
+ * device lane 的 HTTP 错误码闭集(v2 §4.8 逐字)。**唯一导出点** —— 端点车(A-3/车C)从这里取,
3
+ * 禁在路由里手抄字面量(§4.8 task-R1-12:「下表即闭集全集,禁四份手抄」)。
4
+ *
5
+ * 🔴 这里只是**码与状态的定义**;把它们登记进 `docs/ASSISTANT-WIRE-CONTRACT.md` 附录 A(以及
6
+ * `test/error-code-catalog-live.test.ts` 的目录双向 diff)是**端点车**的义务 —— 那道门扫的是
7
+ * `sendError`/`sendJson` 的发送点,本文件没有任何发送点,所以本车不动文档也不会让那道门变红/变假绿。
8
+ */
9
+ export declare const DEVICE_ERROR_CODES: {
10
+ /** 会话没有设备绑定(根会话未绑 / 子代继承不到根绑定)。 */
11
+ readonly NOT_BOUND: "device.not_bound";
12
+ /** 绑定的设备当前不在线(presence 判定 = 连接租约在 DB now 之后)。 */
13
+ readonly OFFLINE: "device.offline";
14
+ /** 身份失配:换绑/吊销后赎回、绑定设备与请求设备不一致。 */
15
+ readonly IDENTITY_MISMATCH: "device.identity_mismatch";
16
+ /** 设备已吊销(终态)。 */
17
+ readonly REVOKED: "device.revoked";
18
+ /** checkpoint 的 workspaceHandle.provider 与本 worker 的 lane 不符(§4.5 步 3)。 */
19
+ readonly PROVIDER_MISMATCH: "device.provider_mismatch";
20
+ /** 连接租约被别的副本/进程持有(§4.6 lease fencing)。 */
21
+ readonly ATTACHED_ELSEWHERE: "device.attached_elsewhere";
22
+ /** 并发首绑的输家且请求的是**另一台**设备(§4.3.2 绑定写协议)。 */
23
+ readonly CLAIM_CONFLICT: "device.claim_conflict";
24
+ /** 单设备在途指令数超 `maxInflightPerDevice`(§11-O3 默认 4)。 */
25
+ readonly BUSY: "device.busy";
26
+ /** enrollment 拒绝的**唯一**对外码 —— 过期 / 不存在 / principal 不匹配 / token 重用**同形**
27
+ * (反枚举:细分理由只进审计,不进 wire;否则 token 撞库能问出「这个 token 存在吗」)。 */
28
+ readonly ENROLLMENT_INVALID: "device.enrollment_invalid";
29
+ /** 反枚举 404:设备不存在 **与** 设备不是你的,逐字节同形。 */
30
+ readonly NOT_FOUND: "not_found.device";
31
+ };
32
+ /** {@link DEVICE_ERROR_CODES} 的值联合 —— 闭集(未知码 = 编译错误,#157 词表纪律)。 */
33
+ export type DeviceErrorCode = (typeof DEVICE_ERROR_CODES)[keyof typeof DEVICE_ERROR_CODES];
34
+ /**
35
+ * 限流拒绝复用**既有**的通用码(`docs/ASSISTANT-WIRE-CONTRACT.md` 已收录,429)。
36
+ *
37
+ * 🔴 刻意不铸 `device.rate_limited`:§4.8 的 device 闭集里没有限流成员,而限流面本仓已有属主
38
+ * (`observability/rate-limit.ts` 的 RateGate + `limit.rate_exceeded`)。为一个已有语义的面新铸一个
39
+ * 同义码 = 消费端要认两套。`device.busy`(429)留给**在途指令数**上限,不是这里。
40
+ */
41
+ export declare const DEVICE_RATE_LIMIT_CODE: "limit.rate_exceeded";
42
+ /** 拒绝码 → HTTP 状态。**穷举 map**(缺一个成员 = 编译错误),不是运行时 switch 的默认臂。 */
43
+ export declare const DEVICE_ERROR_STATUS: Readonly<Record<DeviceErrorCode | typeof DEVICE_RATE_LIMIT_CODE, number>>;
44
+ /**
45
+ * `device_audit.event` 的闭集(v2 §6 DDL 的 CHECK 清单 + §4.8「标审计行者」,两处逐字对齐)。
46
+ *
47
+ * ⚠️ §4.8 的**遥测**清单比这张表长(`device_connected`/`device_disconnected`/`device_heartbeat_lost`/
48
+ * `device_instruction_dispatched`/`device_outcome_unknown`)—— 那些是**计数器/日志**面,不落审计表。
49
+ * 只有下面这 8 个是「安全轴事件,必须可追溯查询」。加成员 = 同时改这里 + 两侧 DDL 的 CHECK。
50
+ */
51
+ export declare const DEVICE_AUDIT_EVENTS: readonly ["device_enrolled", "device_revoked", "device_token_rotated", "device_enroll_token_reuse", "device_frame_unexpected", "device_identity_mismatch", "device_superseded", "device_attached_elsewhere"];
52
+ export type DeviceAuditEvent = (typeof DEVICE_AUDIT_EVENTS)[number];
53
+ /** v1 平台闭集(AR-R1-8)。win32 = follow-on(§10 车A-4 的 flavor 注)。 */
54
+ export declare const DEVICE_PLATFORM_OS: readonly ["darwin", "linux"];
55
+ export type DevicePlatformOs = (typeof DEVICE_PLATFORM_OS)[number];
56
+ /** 设备生命周期闭集 —— `revoked` 是**终态**(§8-R4:无自动恢复,重注册 = 新 deviceId)。 */
57
+ export declare const DEVICE_STATUSES: readonly ["active", "revoked"];
58
+ export type DeviceStatus = (typeof DEVICE_STATUSES)[number];
59
+ /** O11 复合身份 —— device lane 本地结构对,**不是**全局 principal(见文件头注)。 */
60
+ export interface DeviceOwner {
61
+ readonly tenant: string;
62
+ readonly subject: string;
63
+ }
64
+ export interface DeviceRow {
65
+ deviceId: string;
66
+ owner: DeviceOwner;
67
+ displayName: string;
68
+ platformOs: DevicePlatformOs;
69
+ platformArch: string;
70
+ /** Ed25519 公钥 b64(AR-R1-1:凭据 = 密钥对,wire 上无长期 bearer)。 */
71
+ pubkey: string;
72
+ pubkeyRotatedAtMs: number | null;
73
+ /** 设备工作区根(hello 声明,enrollment/管理固定;park 期不静默改,task-R2-4)。 */
74
+ workspaceRoot: string;
75
+ workspaceRootRev: number;
76
+ status: DeviceStatus;
77
+ revokedAtMs: number | null;
78
+ revokedBy: string | null;
79
+ revokeReason: string | null;
80
+ /** 设备侧 executor 进程 epoch(§5.4 世代闸的设备侧输入)。 */
81
+ connEpoch: string | null;
82
+ replicaId: string | null;
83
+ /** 连接 lease 世代(task-R1-7 的 CAS fencing 计数器,单调递增)。 */
84
+ connGeneration: number;
85
+ leaseExpiresAtMs: number | null;
86
+ connectedAtMs: number | null;
87
+ lastSeenAtMs: number | null;
88
+ createdAtMs: number;
89
+ rev: number;
90
+ }
91
+ export interface DeviceSessionRow {
92
+ /** 键 = **根**会话(task-R1-3:后代继承不另绑)。 */
93
+ rootSessionId: string;
94
+ deviceId: string;
95
+ owner: DeviceOwner;
96
+ boundAtMs: number;
97
+ rev: number;
98
+ }
99
+ export interface DeviceAuditRow {
100
+ id: number;
101
+ atMs: number;
102
+ event: DeviceAuditEvent;
103
+ deviceId: string | null;
104
+ owner: DeviceOwner | null;
105
+ detail: unknown;
106
+ }
107
+ export interface DeviceEnrollTokenRow {
108
+ /** sha256(明文) 的小写 hex —— 明文一现,**永不落库**。 */
109
+ tokenHash: string;
110
+ /** 签发时绑定的复合身份;注册时强校验(§7-T5 ②)。 */
111
+ target: DeviceOwner;
112
+ createdBy: string;
113
+ createdAtMs: number;
114
+ expiresAtMs: number;
115
+ consumedAtMs: number | null;
116
+ consumedDeviceId: string | null;
117
+ /** AR-R1-2 的判别位:响应丢失重放 vs 真重用,全靠这一列。 */
118
+ consumedPubkey: string | null;
119
+ rev: number;
120
+ }
121
+ /** 身份键列的字节上界(全仓 190 家族:`sendfile_link.scope` / `agent_roster.name_key` / …)。 */
122
+ export declare const DEVICE_KEY_MAX_BYTES = 190;
123
+ /** `device_id` 列宽(`dev_` + 26 位 Crockford base32 ULID = 30 字节,64 是三倍余量)。 */
124
+ export declare const DEVICE_ID_MAX_BYTES = 64;
125
+ /** `root_session_id` 列宽(提交入口硬拒 >64 的 sessionId,128 留一倍余量)。 */
126
+ export declare const DEVICE_SESSION_ID_MAX_BYTES = 128;
127
+ /** `pubkey` / `token_hash` 列宽(Ed25519 b64 = 44,sha256 hex = 64)。 */
128
+ export declare const DEVICE_PUBKEY_MAX_BYTES = 128;
129
+ /** 内容列宽度(与两侧 DDL 逐字对齐;改列宽必须同时改这里,否则门与列脱钩)。 */
130
+ export declare const DEVICE_TEXT_LIMITS: {
131
+ readonly displayName: 255;
132
+ readonly platformArch: 32;
133
+ readonly workspaceRoot: 1024;
134
+ readonly actor: 190;
135
+ readonly revokeReason: 512;
136
+ readonly connEpoch: 64;
137
+ readonly replicaId: 128;
138
+ };
139
+ export declare function assertDeviceOwnerShape(owner: DeviceOwner): void;
140
+ export declare function assertDeviceIdShape(deviceId: string): void;
141
+ export declare function assertRootSessionIdShape(rootSessionId: string): void;
142
+ export declare function assertDevicePubkeyShape(pubkey: string): void;
143
+ /** 注册入参的整形门(**三形共用**:InMemory 与两方言从同一处过,门与列宽同源)。 */
144
+ export declare function assertNewDeviceShape(input: NewDeviceInput): void;
145
+ export declare function assertIssueTokenShape(input: IssueEnrollTokenInput): void;
146
+ export declare function assertRevokeShape(input: RevokeDeviceInput): void;
147
+ export declare function assertAcquireShape(input: AcquireConnectionInput): void;
148
+ /** token 摘要必须是**规范形**(小写 sha256 hex):大小写混形在 VARBINARY/COLLATE "C" 下是两个键,
149
+ * 于是同一个明文 token 能被消费两次 —— 这是 §7-T5 ③「一次性 CAS」的直接跳过面。 */
150
+ export declare function assertEnrollTokenHashShape(tokenHash: string): void;
151
+ /**
152
+ * 闭集列的**读侧**解码 —— 三个 `parse*` 是这些词表的唯一解码点(SQL 店读回的字符串必须经此)。
153
+ *
154
+ * 🔴 认不出的值 = **抛**,不是静默 cast(#157:安全轴的未知词是 fail-loud 而不是 fail-open)。
155
+ * 一行 `status='disabled'` 的设备如果被 `as DeviceStatus` 静默放行,准入链的 `status === "revoked"`
156
+ * 判据就对它返回「不是吊销的」⇒ 一台被管理面停用的设备照常领活。写侧不可能产出这些值(入参是
157
+ * TS 闭集),所以出现即「有人跳过本店直接写库」或「跨版本降级读新词」,两者都必须响亮。
158
+ */
159
+ export declare function parseDeviceStatus(v: string): DeviceStatus;
160
+ export declare function parseDevicePlatformOs(v: string): DevicePlatformOs;
161
+ export declare function parseDeviceAuditEvent(v: string): DeviceAuditEvent;
162
+ /** TTL / 租约时长必须是**整秒整数**:两方言的 INTERVAL 对小数的取整规则不同(MySQL 的
163
+ * `INTERVAL 0.5 SECOND` 与 PG 的 `0.5 * INTERVAL '1 second'` 不同义)⇒ 在门口收窄,方言分歧面消失。 */
164
+ export declare function assertWholeSeconds(what: string, seconds: number): void;
165
+ /** 明文 enrollment token → 落库摘要。明文只在签发响应里出现一次(§6 注册协议)。 */
166
+ export declare function hashEnrollToken(plaintext: string): string;
167
+ /** 签发一个 128-bit 熵的明文 token(b64url,无填充)。 */
168
+ export declare function mintEnrollToken(): string;
169
+ /**
170
+ * `dev_<ulid>` —— server 铸(§6)。ULID 而不是 UUIDv4:时间前缀让主键有序(TiDB 侧避免纯随机主键的
171
+ * 写热点分散/PG 侧 btree 局部性),且 26 位 Crockford base32 无大小写歧义(我们恒产大写,读侧字节比)。
172
+ */
173
+ export declare function mintDeviceId(nowMs?: number): string;
174
+ export interface NewDeviceInput {
175
+ deviceId: string;
176
+ owner: DeviceOwner;
177
+ displayName?: string;
178
+ platformOs: DevicePlatformOs;
179
+ platformArch?: string;
180
+ pubkey: string;
181
+ workspaceRoot: string;
182
+ }
183
+ export interface IssueEnrollTokenInput {
184
+ tokenHash: string;
185
+ target: DeviceOwner;
186
+ createdBy: string;
187
+ /** 有效期**时长**(秒,自 DB now 起算)。负值 = 立即过期(测试/管理面强制作废用),见文件头注的时间权威段。 */
188
+ ttlSeconds: number;
189
+ }
190
+ export interface ConsumeEnrollTokenInput {
191
+ tokenHash: string;
192
+ /** 请求方**验证过**的复合身份(不取自可自造头);与 token 的 target 逐字节比对。 */
193
+ requester: DeviceOwner;
194
+ device: NewDeviceInput;
195
+ }
196
+ /**
197
+ * enrollment 消费的判别式结果(§6 注册协议 + AR-R1-2)。
198
+ *
199
+ * 🔴 闭集且**理由分得比 wire 细**:wire 上这些全部收敛成一个 `device.enrollment_invalid`(反枚举),
200
+ * 细分只服务两件事 —— 审计行的 event 选择,与「幂等重放 vs 真重用」这条**安全判别**本身。
201
+ */
202
+ export type ConsumeEnrollTokenResult =
203
+ /** CAS 赢家:token 消费 + devices 行插入在**同一事务**里提交。 */
204
+ {
205
+ outcome: "enrolled";
206
+ device: DeviceRow;
207
+ }
208
+ /** 同 token + **同 pubkey** 重试(响应丢失重放):返回**同一个** deviceId。`device` 为 null =
209
+ * token 记着 deviceId 但 devices 行已不在(被删/被清)——调用方按 invalid 收尾,不猜。 */
210
+ | {
211
+ outcome: "replayed";
212
+ device: DeviceRow | null;
213
+ }
214
+ /** 同 token + **异 pubkey**:真重用 ⇒ 拒 + `device_enroll_token_reuse` 审计行(§7-T5 ④,告警级)。 */
215
+ | {
216
+ outcome: "token_reuse";
217
+ }
218
+ /** token 在,但它绑的复合身份不是请求方的(§7-T5 ②)。 */
219
+ | {
220
+ outcome: "principal_mismatch";
221
+ }
222
+ /** token 在、未消费、已过期(TTL,§7-T5 ①)。 */
223
+ | {
224
+ outcome: "expired";
225
+ }
226
+ /** 没有这个 token(或者从来没有过)。 */
227
+ | {
228
+ outcome: "unknown_token";
229
+ }
230
+ /** `(owner_tenant, pubkey)` 已被同租户内**另一台**设备占用(AR-R3-F21:唯一按租户,不全局)。
231
+ * token 消费**随事务回滚**——失败的注册不烧 token。 */
232
+ | {
233
+ outcome: "pubkey_taken";
234
+ };
235
+ export interface BindSessionInput {
236
+ rootSessionId: string;
237
+ deviceId: string;
238
+ /** 验证过的复合身份;与 devices 行的 owner 在**同一事务**内比对(§4.3.2 首绑)。 */
239
+ owner: DeviceOwner;
240
+ }
241
+ /** §4.3.2 首绑协议的判别式结果 —— 并发争抢**单赢家,无未定义态**。 */
242
+ export type BindSessionResult = {
243
+ outcome: "bound";
244
+ row: DeviceSessionRow;
245
+ }
246
+ /** 并发输家或重试,但绑的是**同一台**设备 ⇒ 幂等成功。 */
247
+ | {
248
+ outcome: "idempotent";
249
+ row: DeviceSessionRow;
250
+ }
251
+ /** 根会话已绑**另一台**设备(或另一个 owner)⇒ `device.claim_conflict`。 */
252
+ | {
253
+ outcome: "conflict";
254
+ row: DeviceSessionRow;
255
+ }
256
+ /** 设备不存在**或**不是请求方的 —— 反枚举同形(见文件头注)。 */
257
+ | {
258
+ outcome: "device_not_found";
259
+ } | {
260
+ outcome: "device_revoked";
261
+ };
262
+ export interface RevokeDeviceInput {
263
+ deviceId: string;
264
+ owner: DeviceOwner;
265
+ revokedBy: string;
266
+ reason?: string | null;
267
+ }
268
+ export type RevokeDeviceResult = {
269
+ outcome: "revoked";
270
+ row: DeviceRow;
271
+ } | {
272
+ outcome: "already_revoked";
273
+ row: DeviceRow;
274
+ } | {
275
+ outcome: "not_found";
276
+ };
277
+ export interface AcquireConnectionInput {
278
+ deviceId: string;
279
+ owner: DeviceOwner;
280
+ /** 设备侧 executor 进程 epoch(hello 帧携带)。 */
281
+ connEpoch: string;
282
+ replicaId: string;
283
+ /** 租约时长(秒,自 DB now 起算)。 */
284
+ leaseSeconds: number;
285
+ }
286
+ export type AcquireConnectionResult = {
287
+ outcome: "acquired";
288
+ generation: number;
289
+ }
290
+ /** 活租约在别处(§4.6 步 3:fail loud 不 fail wrong)⇒ `device.attached_elsewhere`。 */
291
+ | {
292
+ outcome: "attached_elsewhere";
293
+ generation: number;
294
+ } | {
295
+ outcome: "device_not_found";
296
+ } | {
297
+ outcome: "device_revoked";
298
+ };
299
+ export interface HeartbeatConnectionInput {
300
+ deviceId: string;
301
+ /** 世代谓词:影响 0 行 = 本连接已失权 ⇒ 调用方主动断开(§4.6 步 2)。 */
302
+ generation: number;
303
+ leaseSeconds: number;
304
+ }
305
+ export interface AppendAuditInput {
306
+ event: DeviceAuditEvent;
307
+ deviceId?: string | null;
308
+ owner?: DeviceOwner | null;
309
+ detail?: unknown;
310
+ }
311
+ export interface ListAuditFilter {
312
+ deviceId?: string;
313
+ event?: DeviceAuditEvent;
314
+ owner?: DeviceOwner;
315
+ limit?: number;
316
+ }
317
+ /** 准入读口的返回 —— presence 由**店**在 SQL 谓词里算(时间权威 = DB),不把租约时间交给调用方比。 */
318
+ export interface DeviceAdmissionView {
319
+ row: DeviceRow;
320
+ online: boolean;
321
+ }
322
+ export interface DeviceStore {
323
+ issueEnrollToken(input: IssueEnrollTokenInput): Promise<DeviceEnrollTokenRow>;
324
+ /** §6 注册协议:消费 CAS + INSERT devices **同一事务**;失败臂的判别见 {@link ConsumeEnrollTokenResult}。 */
325
+ consumeEnrollToken(input: ConsumeEnrollTokenInput): Promise<ConsumeEnrollTokenResult>;
326
+ /** 管理/测试读口(明文 token 永不落库,所以只能按摘要查)。 */
327
+ getEnrollToken(tokenHash: string): Promise<DeviceEnrollTokenRow | null>;
328
+ /** 🔴 **恒带 owner 谓词**:他人设备返回 null,与不存在同形(反枚举,见文件头注)。 */
329
+ readDeviceForAdmission(deviceId: string, owner: DeviceOwner): Promise<DeviceAdmissionView | null>;
330
+ /** 管理面/测试用的无 owner 谓词读口 —— **不得**接到任何 principal-scoped 的 wire 面上。 */
331
+ getDeviceUnscoped(deviceId: string): Promise<DeviceRow | null>;
332
+ listDevicesByOwner(owner: DeviceOwner): Promise<DeviceRow[]>;
333
+ revokeDevice(input: RevokeDeviceInput): Promise<RevokeDeviceResult>;
334
+ acquireConnection(input: AcquireConnectionInput): Promise<AcquireConnectionResult>;
335
+ /** 世代谓词命中 = true;0 行 = 已失权。 */
336
+ heartbeatConnection(input: HeartbeatConnectionInput): Promise<boolean>;
337
+ releaseConnection(deviceId: string, generation: number): Promise<boolean>;
338
+ bindSession(input: BindSessionInput): Promise<BindSessionResult>;
339
+ getSessionBinding(rootSessionId: string): Promise<DeviceSessionRow | null>;
340
+ /** purge coordinator 座(§6 注②:core 的会话删除是**逐 store 显式调用**,不是 DB 自动扫;
341
+ * 只建表不接 purge = 删会话后绑定残留 ⇒ sessionId 重用致旧设备粘连/claim conflict/隐私残留)。 */
342
+ deleteByRootSession(rootSessionId: string): Promise<number>;
343
+ appendAudit(input: AppendAuditInput): Promise<void>;
344
+ listAudit(filter?: ListAuditFilter): Promise<DeviceAuditRow[]>;
345
+ }
346
+ declare function sameOwner(a: DeviceOwner, b: DeviceOwner): boolean;
347
+ declare function cloneOwner(o: DeviceOwner): DeviceOwner;
348
+ /**
349
+ * 语义 oracle。**单线程 JS 的原子性**替代 SQL 事务:每个方法体内没有 `await`(除了返回值),所以
350
+ * 「读-判-写」在事件循环上不可分割 —— 与 SQL 侧的单事务 CAS 语义等价,这也是为什么并发格
351
+ * (两个并发消费同一 token)在这一形上必须给出与真库**同一个**赢家/输家分布。
352
+ */
353
+ export declare class InMemoryDeviceStore implements DeviceStore {
354
+ private readonly devices;
355
+ private readonly sessions;
356
+ private readonly tokens;
357
+ private readonly audit;
358
+ private auditSeq;
359
+ private readonly now;
360
+ constructor(opts?: {
361
+ now?: () => number;
362
+ });
363
+ issueEnrollToken(input: IssueEnrollTokenInput): Promise<DeviceEnrollTokenRow>;
364
+ consumeEnrollToken(input: ConsumeEnrollTokenInput): Promise<ConsumeEnrollTokenResult>;
365
+ getEnrollToken(tokenHash: string): Promise<DeviceEnrollTokenRow | null>;
366
+ readDeviceForAdmission(deviceId: string, owner: DeviceOwner): Promise<DeviceAdmissionView | null>;
367
+ getDeviceUnscoped(deviceId: string): Promise<DeviceRow | null>;
368
+ listDevicesByOwner(owner: DeviceOwner): Promise<DeviceRow[]>;
369
+ revokeDevice(input: RevokeDeviceInput): Promise<RevokeDeviceResult>;
370
+ acquireConnection(input: AcquireConnectionInput): Promise<AcquireConnectionResult>;
371
+ heartbeatConnection(input: HeartbeatConnectionInput): Promise<boolean>;
372
+ releaseConnection(deviceId: string, generation: number): Promise<boolean>;
373
+ bindSession(input: BindSessionInput): Promise<BindSessionResult>;
374
+ getSessionBinding(rootSessionId: string): Promise<DeviceSessionRow | null>;
375
+ deleteByRootSession(rootSessionId: string): Promise<number>;
376
+ appendAudit(input: AppendAuditInput): Promise<void>;
377
+ listAudit(filter?: ListAuditFilter): Promise<DeviceAuditRow[]>;
378
+ private isOnline;
379
+ private pushAudit;
380
+ /** 返回**拷贝**:调用方拿到的行改了也不能污染店内状态(SQL 侧天然如此,InMemory 必须显式做)。 */
381
+ private snapshotDevice;
382
+ private snapshotSession;
383
+ }
384
+ export { sameOwner as sameDeviceOwner, cloneOwner as cloneDeviceOwner };
385
+ //# sourceMappingURL=device-store.d.ts.map