@sema-agent/server 7.140.0 → 7.142.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 (296) hide show
  1. package/MIGRATION.md +505 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +142 -25
  5. package/dist/approval-ask-audit-store.d.ts +54 -38
  6. package/dist/approval-ask-audit-store.js +58 -39
  7. package/dist/approval-batch-census.d.ts +27 -0
  8. package/dist/approval-batch-census.js +27 -0
  9. package/dist/approval-card.d.ts +39 -24
  10. package/dist/approval-card.js +6 -3
  11. package/dist/approval-crash-convergence.d.ts +17 -7
  12. package/dist/approval-crash-convergence.js +94 -22
  13. package/dist/approval-deny-reasons.d.ts +34 -30
  14. package/dist/approval-deny-reasons.js +21 -6
  15. package/dist/approval-policy-settlement.d.ts +1 -1
  16. package/dist/approval-reconciler.d.ts +33 -1
  17. package/dist/approval-reconciler.js +43 -40
  18. package/dist/approval.d.ts +15 -0
  19. package/dist/approval.js +10 -0
  20. package/dist/audit.d.ts +4 -2
  21. package/dist/audit.js +2 -2
  22. package/dist/auth-bridge.d.ts +9 -6
  23. package/dist/auth-bridge.js +9 -3
  24. package/dist/boot/adoption.js +2 -1
  25. package/dist/boot/budget-tracing.d.ts +16 -0
  26. package/dist/boot/budget-tracing.js +10 -6
  27. package/dist/boot/device-lane.d.ts +11 -0
  28. package/dist/boot/device-lane.js +16 -0
  29. package/dist/boot/engine-lease.d.ts +24 -3
  30. package/dist/boot/engine-lease.js +9 -2
  31. package/dist/boot/execution-env.d.ts +24 -4
  32. package/dist/boot/execution-env.js +34 -27
  33. package/dist/boot/execution-lane.js +2 -1
  34. package/dist/boot/exit-boundary.js +5 -4
  35. package/dist/boot/memory-boundary.d.ts +2 -2
  36. package/dist/boot/memory-consolidation.d.ts +1 -1
  37. package/dist/boot/memory-consolidation.js +3 -2
  38. package/dist/boot/parked-revive-gate.js +2 -1
  39. package/dist/boot/permission-rules-audit.d.ts +0 -28
  40. package/dist/boot/permission-rules-audit.js +2 -1
  41. package/dist/boot/read-deny-anchor-audit.js +2 -1
  42. package/dist/boot/reapers.d.ts +2 -2
  43. package/dist/boot/reapers.js +4 -3
  44. package/dist/boot/resolve-spec.js +18 -6
  45. package/dist/boot/retention-lane.js +5 -3
  46. package/dist/boot/runner-deps.js +16 -13
  47. package/dist/boot/runtime-caps.js +3 -2
  48. package/dist/boot/session-faces.d.ts +1 -1
  49. package/dist/boot/session-faces.js +8 -6
  50. package/dist/boot/shutdown.js +8 -2
  51. package/dist/boot/stage-04-stores.js +3 -2
  52. package/dist/boot/stage-05-execution-env.d.ts +1 -1
  53. package/dist/boot/stage-05-execution-env.js +11 -7
  54. package/dist/boot/stage-06-runners.d.ts +1 -3
  55. package/dist/boot/stage-06-runners.js +3 -2
  56. package/dist/boot/stage-07-capability-layer.d.ts +1 -2
  57. package/dist/boot/stage-07-capability-layer.js +10 -11
  58. package/dist/boot/stage-08-reapers.d.ts +1 -2
  59. package/dist/boot/stage-08-reapers.js +3 -2
  60. package/dist/boot/stage-09-leader.d.ts +1 -2
  61. package/dist/boot/stage-10-http-server.d.ts +1 -2
  62. package/dist/boot/stage-10-http-server.js +6 -4
  63. package/dist/boot/stores.js +13 -6
  64. package/dist/boot/web-admin.js +18 -17
  65. package/dist/boot/webfetch-summarize-lane.js +2 -1
  66. package/dist/boot/workflow-orchestration.js +3 -2
  67. package/dist/capabilities/builtin-tools.d.ts +2 -1
  68. package/dist/capabilities/builtin-tools.js +2 -4
  69. package/dist/capabilities/composite-members.d.ts +2 -1
  70. package/dist/capabilities/composite-members.js +2 -1
  71. package/dist/capabilities/scenarios.d.ts +1 -1
  72. package/dist/capability-facts.d.ts +33 -0
  73. package/dist/capability-facts.js +32 -0
  74. package/dist/card-void.d.ts +38 -0
  75. package/dist/card-void.js +23 -0
  76. package/dist/config-catalog.js +12 -8
  77. package/dist/config-provider.d.ts +13 -13
  78. package/dist/config-provider.js +19 -33
  79. package/dist/config-types.d.ts +39 -10
  80. package/dist/config.d.ts +6 -0
  81. package/dist/config.js +72 -49
  82. package/dist/delegated-session-owner.d.ts +21 -19
  83. package/dist/delegated-session-owner.js +1 -1
  84. package/dist/device-store.d.ts +7 -0
  85. package/dist/device-store.js +3 -0
  86. package/dist/execution-config-root.d.ts +22 -0
  87. package/dist/execution-config-root.js +35 -0
  88. package/dist/execution-lane-caps.d.ts +50 -2
  89. package/dist/execution-lane-caps.js +90 -13
  90. package/dist/execution-placement.d.ts +3 -0
  91. package/dist/execution-placement.js +7 -0
  92. package/dist/fleet/drain-entry.d.ts +3 -0
  93. package/dist/fleet/fleet-bus.d.ts +6 -3
  94. package/dist/hooks/hook-runner.d.ts +6 -0
  95. package/dist/hooks/hook-runner.js +30 -1
  96. package/dist/hosted-posture.d.ts +8 -0
  97. package/dist/hosted-posture.js +4 -0
  98. package/dist/http/admission.js +3 -3
  99. package/dist/http/caller-trust.d.ts +3 -2
  100. package/dist/http/caller-trust.js +2 -1
  101. package/dist/http/dispatch.js +8 -2
  102. package/dist/http/execution-context.d.ts +2 -2
  103. package/dist/http/idempotency.d.ts +1 -1
  104. package/dist/http/live-frame.d.ts +24 -0
  105. package/dist/http/live-frame.js +16 -0
  106. package/dist/http/principal-gate.d.ts +3 -1
  107. package/dist/http/principal-gate.js +17 -8
  108. package/dist/http/resume-legs.js +42 -29
  109. package/dist/http/route-table.js +4 -0
  110. package/dist/http/routes/approvals-assistant.js +1 -0
  111. package/dist/http/routes/attachments.js +18 -0
  112. package/dist/http/routes/capabilities.js +10 -6
  113. package/dist/http/routes/diagnostics.d.ts +0 -19
  114. package/dist/http/routes/diagnostics.js +16 -2
  115. package/dist/http/routes/memory-bundle.d.ts +2 -2
  116. package/dist/http/routes/memory-bundle.js +1 -1
  117. package/dist/http/routes/memory-compliance.js +1 -1
  118. package/dist/http/routes/memory-policy.js +27 -7
  119. package/dist/http/routes/run-permission-mode.d.ts +75 -0
  120. package/dist/http/routes/run-permission-mode.js +170 -0
  121. package/dist/http/routes/runs.js +3 -3
  122. package/dist/http/routes/session-memory-sync.d.ts +63 -0
  123. package/dist/http/routes/session-memory-sync.js +157 -0
  124. package/dist/http/routes/session-sync.d.ts +3 -6
  125. package/dist/http/routes/session-sync.js +7 -2
  126. package/dist/http/routes/sessions-list.d.ts +2 -1
  127. package/dist/http/routes/sessions.js +5 -4
  128. package/dist/http/routes/tasks.js +70 -71
  129. package/dist/http/run-read-face.d.ts +7 -0
  130. package/dist/http/run-read-face.js +10 -4
  131. package/dist/http/send.d.ts +6 -1
  132. package/dist/http/send.js +10 -3
  133. package/dist/http/server.d.ts +20 -7
  134. package/dist/http/server.js +2 -4
  135. package/dist/http/sse-log.d.ts +3 -8
  136. package/dist/http/stored-body-replay.d.ts +3 -3
  137. package/dist/http/stored-body-replay.js +3 -1
  138. package/dist/http/submit-replay.d.ts +4 -3
  139. package/dist/http/submit-replay.js +2 -2
  140. package/dist/http/sync-submit-body.d.ts +21 -4
  141. package/dist/http/sync-submit-body.js +13 -0
  142. package/dist/identity-source.d.ts +21 -2
  143. package/dist/identity-source.js +6 -0
  144. package/dist/instruction-source-notice.d.ts +7 -0
  145. package/dist/instruction-source-notice.js +6 -6
  146. package/dist/mcp-assertion-header.d.ts +4 -0
  147. package/dist/mcp-assertion-header.js +5 -0
  148. package/dist/memory-incident-sink.d.ts +19 -6
  149. package/dist/memory-incident-sink.js +8 -4
  150. package/dist/memory-posture.d.ts +1 -1
  151. package/dist/memory-scope.d.ts +4 -4
  152. package/dist/memory-scope.js +1 -1
  153. package/dist/memory-sync-client.d.ts +35 -23
  154. package/dist/memory-sync-client.js +122 -52
  155. package/dist/memory-sync-identity.d.ts +24 -0
  156. package/dist/memory-sync-identity.js +57 -0
  157. package/dist/memory-sync.d.ts +7 -1
  158. package/dist/memory-sync.js +6 -3
  159. package/dist/observability/fail-open.d.ts +57 -12
  160. package/dist/observability/fail-open.js +50 -9
  161. package/dist/observability/metrics.js +0 -1
  162. package/dist/observability/run-terminal.d.ts +93 -31
  163. package/dist/observability/run-terminal.js +175 -171
  164. package/dist/observability/secret-env-scrub.d.ts +20 -1
  165. package/dist/observability/secret-env-scrub.js +14 -0
  166. package/dist/orchestration/workflow-completion-inbox.d.ts +5 -2
  167. package/dist/orchestration/workflow-completion-inbox.js +13 -5
  168. package/dist/orchestration/workflow-notify-journal.d.ts +5 -3
  169. package/dist/orchestration/workflow-notify-journal.js +2 -1
  170. package/dist/permission-mode-admission.d.ts +68 -0
  171. package/dist/permission-mode-admission.js +23 -0
  172. package/dist/permission-rule-list.d.ts +55 -6
  173. package/dist/permission-rule-list.js +52 -5
  174. package/dist/plugins/approval-ask-store-file.d.ts +14 -4
  175. package/dist/plugins/approval-ask-store-file.js +48 -7
  176. package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
  177. package/dist/plugins/approval-ask-store-memory.js +9 -8
  178. package/dist/plugins/approval-ask-store-sql.d.ts +42 -10
  179. package/dist/plugins/approval-ask-store-sql.js +49 -19
  180. package/dist/plugins/caching-session-store.d.ts +6 -0
  181. package/dist/plugins/caching-session-store.js +3 -0
  182. package/dist/plugins/checkpoint-store-sql.d.ts +65 -17
  183. package/dist/plugins/checkpoint-store-sql.js +74 -3
  184. package/dist/plugins/device-store-sql.d.ts +5 -2
  185. package/dist/plugins/device-store-sql.js +4 -1
  186. package/dist/plugins/execution-placement-sql.d.ts +11 -1
  187. package/dist/plugins/execution-placement-sql.js +12 -1
  188. package/dist/plugins/file-run-store.d.ts +7 -2
  189. package/dist/plugins/file-run-store.js +12 -2
  190. package/dist/plugins/fork-routing-session-store.d.ts +10 -32
  191. package/dist/plugins/fork-routing-session-store.js +2 -61
  192. package/dist/plugins/k8s-exec-protocol.d.ts +4 -1
  193. package/dist/plugins/k8s-exec-protocol.js +6 -1
  194. package/dist/plugins/local-checkpoint-store.d.ts +10 -1
  195. package/dist/plugins/local-checkpoint-store.js +22 -0
  196. package/dist/plugins/local-session-store.d.ts +260 -39
  197. package/dist/plugins/local-session-store.js +582 -57
  198. package/dist/plugins/local-session-window.d.ts +17 -3
  199. package/dist/plugins/local-session-window.js +7 -13
  200. package/dist/plugins/local-task-attachment-store.d.ts +12 -2
  201. package/dist/plugins/local-task-attachment-store.js +67 -43
  202. package/dist/plugins/memory-key-guards.d.ts +3 -3
  203. package/dist/plugins/memory-run-store.d.ts +7 -2
  204. package/dist/plugins/memory-run-store.js +12 -2
  205. package/dist/plugins/one-time-migrations.d.ts +68 -2
  206. package/dist/plugins/one-time-migrations.js +120 -4
  207. package/dist/plugins/pg-pool.js +3 -2
  208. package/dist/plugins/pg-session-storage.d.ts +2 -0
  209. package/dist/plugins/pg-session-storage.js +3 -2
  210. package/dist/plugins/remote-env-e2b.d.ts +47 -7
  211. package/dist/plugins/remote-env-e2b.js +242 -46
  212. package/dist/plugins/remote-env-k8s.d.ts +51 -6
  213. package/dist/plugins/remote-env-k8s.js +234 -44
  214. package/dist/plugins/remote-env-local-docker.d.ts +40 -14
  215. package/dist/plugins/remote-env-local-docker.js +127 -33
  216. package/dist/plugins/run-store-sql.d.ts +11 -3
  217. package/dist/plugins/run-store-sql.js +13 -4
  218. package/dist/plugins/sandbox-read-floor.d.ts +273 -0
  219. package/dist/plugins/sandbox-read-floor.js +608 -0
  220. package/dist/plugins/session-ownership.d.ts +2 -1
  221. package/dist/plugins/session-placement.d.ts +17 -4
  222. package/dist/plugins/session-placement.js +2 -1
  223. package/dist/plugins/session-store.d.ts +18 -20
  224. package/dist/plugins/session-store.js +4 -12
  225. package/dist/plugins/store-backend.d.ts +41 -7
  226. package/dist/plugins/store-backend.js +22 -4
  227. package/dist/plugins/store-contracts.d.ts +35 -3
  228. package/dist/plugins/store-contracts.js +3 -0
  229. package/dist/plugins/task-attachment-store.d.ts +112 -14
  230. package/dist/plugins/task-attachment-store.js +221 -28
  231. package/dist/plugins/tidb-pool.js +2 -1
  232. package/dist/plugins/tidb-session-store.d.ts +4 -1
  233. package/dist/plugins/tidb-session-store.js +3 -2
  234. package/dist/plugins/workspace-fill.d.ts +60 -0
  235. package/dist/plugins/workspace-fill.js +106 -0
  236. package/dist/project-bundle.d.ts +38 -0
  237. package/dist/project-bundle.js +609 -0
  238. package/dist/run-cancel-context.d.ts +34 -0
  239. package/dist/run-cancel-context.js +7 -0
  240. package/dist/run-local.js +2 -8
  241. package/dist/runs.d.ts +39 -12
  242. package/dist/runs.js +69 -55
  243. package/dist/sandbox-egress-policy.d.ts +4 -1
  244. package/dist/sandbox-egress-policy.js +3 -1
  245. package/dist/sandbox-git-plane.d.ts +31 -12
  246. package/dist/sandbox-git-plane.js +24 -4
  247. package/dist/security.d.ts +11 -2
  248. package/dist/security.js +8 -0
  249. package/dist/server-secret-env.d.ts +2 -1
  250. package/dist/server-secret-env.js +2 -4
  251. package/dist/session-error-wire.d.ts +46 -4
  252. package/dist/session-error-wire.js +23 -0
  253. package/dist/session-incarnation.d.ts +9 -3
  254. package/dist/session-sync-kernel.d.ts +42 -1
  255. package/dist/session-sync-kernel.js +17 -0
  256. package/dist/session-sync.js +16 -4
  257. package/dist/sql-engine-coordinates.d.ts +49 -0
  258. package/dist/sql-engine-coordinates.js +27 -0
  259. package/dist/standing-answer-grant.d.ts +31 -2
  260. package/dist/standing-answer-grant.js +14 -2
  261. package/dist/store-posture.d.ts +1 -1
  262. package/dist/task-a2a.d.ts +1 -1
  263. package/dist/task-mcp.d.ts +1 -1
  264. package/dist/task-settings.d.ts +62 -27
  265. package/dist/task-settings.js +105 -29
  266. package/dist/terminal.d.ts +97 -20
  267. package/dist/terminal.js +107 -18
  268. package/dist/tool-approval.d.ts +4 -3
  269. package/dist/tool-approval.js +12 -14
  270. package/dist/trace/core-keyset-guard.d.ts +196 -2
  271. package/dist/trace/engine-notice-wire.d.ts +8 -2
  272. package/dist/trace/engine-notice-wire.js +4 -2
  273. package/dist/trace/exit-seat.d.ts +9 -1
  274. package/dist/trace/exit-seat.js +1 -0
  275. package/dist/trace/ledger-sink.d.ts +8 -4
  276. package/dist/trace/ledger-sink.js +2 -2
  277. package/dist/trace/model-segment.d.ts +2 -2
  278. package/dist/trace/project.d.ts +18 -1
  279. package/dist/trace/project.js +16 -0
  280. package/dist/trace/redact.js +323 -90
  281. package/dist/trace/self-minted-wire.d.ts +419 -4
  282. package/dist/trace/self-minted-wire.js +145 -0
  283. package/dist/trace/wire-projection-faces.d.ts +1 -1
  284. package/dist/trace/wire-projection-faces.js +1 -1
  285. package/dist/verifier-pause-card.d.ts +8 -0
  286. package/dist/verifier-pause-card.js +19 -0
  287. package/dist/web-admin-client/apply-effective.d.ts +5 -7
  288. package/dist/web-admin-client/apply-effective.js +22 -2
  289. package/dist/web-admin-client/candidate-gate.d.ts +1 -1
  290. package/dist/web-admin-client/effective-keys.js +2 -0
  291. package/dist/web-admin-client/read-warnings.d.ts +2 -2
  292. package/dist/web-admin-client/types.d.ts +4 -0
  293. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -2
  294. package/package.json +2 -2
  295. package/wire-changes/server@7.141.0.json +367 -0
  296. package/wire-changes/server@7.142.0.json +639 -0
@@ -1,23 +1,81 @@
1
- import { FileSessionRepo, type AcquiredSession, type SessionHead, type SessionStore, type SessionRepo, type SessionTreeEntry } from "@sema-agent/core";
2
- import type { SessionRunClaimSource, SessionRunRollupSource, SessionSummary } from "./store-contracts.js";
1
+ import { FileSessionRepo, type AcquiredSession, type PlacedSessionRow, type SessionHead, type SessionPlacementRecord, type SessionStore, type SessionRepo, type SessionMetadata, type SessionTreeEntry, type StoreDurability } from "@sema-agent/core";
2
+ import { type OwnerlessClaim } from "../delegated-session-owner.js";
3
+ import { type PlacementAcquireOpts } from "./session-placement.js";
4
+ import { z } from "zod";
5
+ import { StoreBootRefusalError, type SessionRunClaimSource, type SessionRunRollupSource, type SessionSummary } from "./store-contracts.js";
3
6
  import { type ClientSessionRowWrite, type ReplaySessionRowWrite, type ReplaySessionRowWriteOutcome, type SessionRowPatch, type SessionRowWriteOutcome } from "../session-row.js";
7
+ import { type LocalArchiveKeptStamped, type LocalArchiveUnreadable } from "./one-time-migrations.js";
4
8
  import { type Logger } from "../observability/logger.js";
5
9
  import { type SessionFace } from "../session-incarnation.js";
10
+ import { type ExecutionLane } from "../execution-lane-caps.js";
6
11
  import { type ExecutionPlacementSeat, type LocalPlacementBackfillSeat } from "../execution-placement.js";
7
12
  import { type ForkTarget, type ForkToOutcome } from "./session-fork.js";
8
13
  import { type InstructionSourceBaseline } from "../instruction-source-notice.js";
9
14
  import type { SessionWorkspace } from "../session-workspace.js";
10
15
  import { type StagedCommitOptions, type StagingHandle, type SyncRelation } from "../session-sync-kernel.js";
11
16
  /**
12
- * local 车道会话存档的**唯一 repo 出口**:本仓里每一只读 `<root>/sessions/*.jsonl` 的 `FileSessionRepo` 都从这里取(`LocalSessionStore` 的底座与会话视图口
13
- * 窗口 `local-session-window.ts#LocalSessionWindow.wake` 的读旁路),所以坏记录的披露座只有这一份接线 —— 修前视图口自建一只不带座的 repo,同一份坏档在这里读到有计数 / 探针,
14
- * 在视图口读到一个字都没有。座 = F 类 `server.session-repo.corrupt-record-skipped`(会话存档里读不出的记录丢的是可用性:历史少一截 / 列表少一行,不开任何门;
15
- * 计数单位 = 一条被跳过的记录,逐命中探针行,warn 每进程一次),外加会话打开作用域的计数腿(`noteReplayInSessionOpenScope`:只在 `openSessionForItself`
16
- * 的作用域里才记,作用域外 —— 列表 / 导出 / 视图口 —— 是空操作,那些读只进运维面)。
17
+ * 对象形一格的形(本店是它唯一的写者,形属主就在这里):不收别的键 —— 一只不认得某一位的读者(回滚到的上一版)对带着那一位的格整只严格拒,
18
+ * 而不是把它读丢(边档是严格读,见 `SidecarMap.strict`)。
19
+ */
20
+ export declare const SESSION_META_CELL_OBJECT: z.ZodObject<{
21
+ incarnation: z.ZodString;
22
+ owner: z.ZodOptional<z.ZodNullable<z.ZodString>>;
23
+ execution: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
24
+ role: z.ZodLiteral<"writer">;
25
+ lane: z.ZodCustom<ExecutionLane, ExecutionLane>;
26
+ }, z.core.$strict>, z.ZodObject<{
27
+ role: z.ZodLiteral<"mirror">;
28
+ }, z.core.$strict>], "role">>;
29
+ forkKey: z.ZodOptional<z.ZodString>;
30
+ createdAt: z.ZodOptional<z.ZodString>;
31
+ forkedFrom: z.ZodOptional<z.ZodString>;
32
+ }, z.core.$strict>;
33
+ /**
34
+ * local 车道会话存档的**唯一 repo 出口**:本仓里每一只读 `<root>/sessions/*.jsonl` 的 `FileSessionRepo` 都从这里取(`LocalSessionStore` 的底座;会话视图窗不再自开 repo,
35
+ * 它的元数据与日志都由店交出 —— `local-session-window.ts`),所以坏记录的披露座只有这一份接线。座 = F 类 `server.session-repo.corrupt-record-skipped`(会话存档里读不出的记录丢的是可用性:
36
+ * 历史少一截 / 列表少一行,不开任何门;计数单位 = 一条被跳过的记录,逐命中探针行,warn 每进程一次),外加两条作用域腿:会话打开作用域(`noteReplayInSessionOpenScope`:
37
+ * 只在 `openSessionForItself` 的作用域里才记)与一次性迁移 M33 的整档读作用域({@link noteReplayInArchiveRewriteRead});作用域外 —— 列表 / 导出 / 视图 —— 两条腿都是空操作,那些读只进运维面。
17
38
  */
18
39
  export declare function createLocalSessionRepo(root: string): FileSessionRepo;
40
+ /** 快照目录名(数据根下;本店自有的目录与格式)。常设拒启臂 {@link assertNoArchiveSnapshots} 读它,所以它活得比 M33 的码久。 */
41
+ export declare const LOCAL_ARCHIVE_SNAPSHOT_DIR = "session-archive-m33";
42
+ /**
43
+ * 数据根下的快照目录非空 ⇒ 拒启(起服对账一族的 local 腿;机读码 `config.local_archive_snapshot_present`)。快照是一次性迁移 M33 改写一只存档之前留下的那只会话的
44
+ * 对话副本:它在,就说明那一次改写被打断了 —— 存档可能已经删掉、内容只在快照里;而会话删除碰不到它(删除权残留)。M33 窗内起服先消化每一只(恢复先行),
45
+ * 消化不了的点名拒启;M33 删码之后只剩这一臂。属 {@link StoreBootRefusalError} 族:起服降级臂不吞它。
46
+ */
47
+ export declare class LocalArchiveSnapshotsPresentError extends StoreBootRefusalError {
48
+ readonly dir: string;
49
+ readonly names: readonly string[];
50
+ readonly code = "config.local_archive_snapshot_present";
51
+ constructor(dir: string, names: readonly string[], detail?: string);
52
+ }
53
+ /**
54
+ * **常设拒启臂**(无窗;M33 删码后仍在):快照目录非空 ⇒ {@link LocalArchiveSnapshotsPresentError}。只读一个目录在不在、有没有东西;
55
+ * 目录在而读不了(权限 / I/O)⇒ 同一只拒(判不出里面有没有快照 —— fail-closed,不让起服降级臂把它读成「这台机器存不了盘」)。
56
+ */
57
+ export declare function assertNoArchiveSnapshots(dir: string): void;
58
+ export interface LocalArchiveMigrationReading {
59
+ /** 补了行事实(建档时刻 / 谱系)的格数(含为盘上有存档而没有格的会话新建的格)。 */
60
+ readonly rowFactsBackfilled: number;
61
+ /** 由带戳改写成匿名的存档数。 */
62
+ readonly anonymized: number;
63
+ /** 留着带戳的存档(点名 + 原因)。 */
64
+ readonly keptStamped: readonly LocalArchiveKeptStamped[];
65
+ /** 边档里有格、存档头读不出的会话(点名)。 */
66
+ readonly unreadable: readonly LocalArchiveUnreadable[];
67
+ /** 本进程起服以来消化掉的快照记录数(恢复先行)。 */
68
+ readonly snapshotsRecovered: number;
69
+ }
19
70
  /** 本店包的 repo:core `SessionRepo` 且答头读(`headOf` —— 叶子出自它;core 7.55.0 起 `FileSessionRepo` / `InMemorySessionRepo` 都答)。 */
20
71
  export type HeadReadingSessionRepo = SessionRepo & Required<Pick<SessionRepo, "headOf">>;
72
+ /** repo 记 placement 的两只读口(core `FileSessionRepo` 有;`InMemorySessionRepo` 不记 placement,两只都没有)。同在或同缺。 */
73
+ type PlacementRecordingRepo = Pick<FileSessionRepo, "placementOf" | "listPlaced">;
74
+ /** 本店的部署声明(装配方给,core `TtlSessionStore` 同名两格):会话耐久(未 placed 的会话)与委派分区的声明。 */
75
+ export interface LocalSessionStoreDeclaration {
76
+ readonly durability?: StoreDurability;
77
+ readonly placements?: NonNullable<SessionStore["placements"]>;
78
+ }
21
79
  export declare class LocalSessionStore implements SessionStore {
22
80
  private readonly repo;
23
81
  private readonly runs;
@@ -26,8 +84,39 @@ export declare class LocalSessionStore implements SessionStore {
26
84
  * **正确行为**不是缺口(要留存治理先上 DB 后端;设计稿 §1「不做清单」逐字)。缺席也会被读成 none,
27
85
  * 显式写出来是文档义务:沉默表达不出「我核对过我的介质就是删不了」。 */
28
86
  readonly retention: import("@sema-agent/core").RetentionDeclaration;
87
+ /**
88
+ * core `SessionStore.durability` —— 未 placed 的会话活不活过重启。**装配方声明**(`LocalBackend` 用文件 repo 构造时给 `"durable"`):店读不出 repo 是否持久,
89
+ * 由接 repo 的一方说(core 声明律)。缺席 ⇒ core 读作 `process-local`。声明 `durable` 而没有数据根(边档不落盘 ⇒ 属主与化身重启即失)⇒ 构造即拒。
90
+ */
91
+ readonly durability?: StoreDurability;
92
+ /**
93
+ * core `SessionStore.placements` —— 本店懂委派分区、分区里的会话是这个耐久度(六条义务,文件头注)。装配方声明(值与 core `FileStorageBackend` 同);
94
+ * repo 记不了 placement(没有 `placementOf` / `listPlaced`)或没有数据根 ⇒ 构造即拒(那句声明是谎)。缺席 = 不懂分区:带 placement 的 acquire 合法地当普通会话建。
95
+ */
96
+ readonly placements?: NonNullable<SessionStore["placements"]>;
97
+ /** 一只会话存档行头上的 placement 元组(`undefined` = 普通会话或无此存档;读不出 ⇒ 拒)。repo 记 placement 时在,透传 repo 的同名读口。 */
98
+ readonly placementOf?: (sessionId: string) => Promise<SessionPlacementRecord | undefined>;
99
+ /** 委派分区的自有枚举(联合收割的分区腿输入;透传 repo 的同名读口,年龄 = 存档的修改时刻)。repo 记 placement 时在。 */
100
+ readonly listPlaced?: (kind: "subagent", opts?: {
101
+ olderThanMs?: number;
102
+ scope?: string;
103
+ }) => Promise<PlacedSessionRow[]>;
104
+ /**
105
+ * 委派继承律的认领口(`delegated-session-owner.ts`;停驻挂点对宿主无主子代行的认领):这只会话的那一位住客(判断时读到的化身)仍无主、且是 placed 行 ⇒ 写 `owner`,
106
+ * 返回是否写成。与 `placementOf` 同在或同缺(`delegatedOwnerHostOf`)。随一次性迁移 M23 的窗同删(登记表 M23 行)。
107
+ */
108
+ readonly claimOwnerless?: OwnerlessClaim;
109
+ /** placement 的唯一读法(repo 的 `placementOf`;repo 不记 placement ⇒ 恒答缺席 —— 那种 repo 里没有 placed 行)。 */
110
+ private readonly recordedPlacementOf;
29
111
  /** In-flight acquisitions keyed by id, so concurrent acquire(sameId) in one process share one (mirrors TiDBSessionStore). */
30
112
  private readonly pending;
113
+ /**
114
+ * 本进程里删行已经开始的会话 id(删除与 placed 行的 release 都在 {@link dropRowHeld} 第一步登记)。锁外读者的补铸({@link cellOfPresent}:格缺而存档在 ⇒ 当作
115
+ * 7.104.0 之前写下的会话补一格)对登记过的 id 不铸 —— 删行的那一笔与存档的删除不是同一笔(placed 行存档最后删,存档行头是重试判别位),两笔之间盘上正是
116
+ * 「格缺而存档在」那一形;锁外的读若照旧补铸,存档随后删掉就留下一只没有存档的格(读作一只无主会话,再 release 也清不掉)。删行一开始,这一行对读者就不在了;
117
+ * 中途失败、存档还在 ⇒ 读者读作不在,重发收完。进程内只增(一只删掉的会话一个 id);补铸只对格缺的存档起作用,所以同 id 再建(登记 / 导入 / 建会话都自己铸格)不受影响。
118
+ */
119
+ private readonly rowsDropped;
31
120
  /** Last-activity marker (touch) for ordering — the keyset sort key for {@link listSessions}. PERSISTED to a JSON
32
121
  * sidecar under {@link dataDir} (when given) so the /resume picker's newest-first order SURVIVES a service restart:
33
122
  * without persistence the map starts EMPTY on boot and every session degrades to `createdAt` ordering (the picker
@@ -81,7 +170,7 @@ export declare class LocalSessionStore implements SessionStore {
81
170
  * 盘上有会话而边档里没有它那一格 ⇒ 第一次读补铸一格只有化身的(属主没有事实可写)并落盘。严格读(读不出 ⇒ 整只拒,见 `SidecarMap.strict`)。
82
171
  */
83
172
  private readonly meta;
84
- /** 认领行(`session_owner_claimed`)的出口 —— 一次性迁移 M10 的认领臂专用(窗口见 `plugins/one-time-migrations.ts` 登记表)。 */
173
+ /** 认领行(`session_owner_claimed`,一次性迁移 M10 的认领臂,窗口见 `plugins/one-time-migrations.ts` 登记表)与委派孤行 warn(`delegated_session_owner_orphaned`)的出口。 */
85
174
  private readonly log;
86
175
  /**
87
176
  * 按会话的写锁(表见 {@link SESSION_WRITE_LOCKS_BY_ROOT})—— 会话行两位的**每一笔**写(用户的行格写原语:判 → 边档草稿 → 落盘 → 发布;自动标题器的
@@ -105,17 +194,22 @@ export declare class LocalSessionStore implements SessionStore {
105
194
  * `place` 就是席的 `place`。
106
195
  */
107
196
  readonly executionPlacementBackfill: LocalPlacementBackfillSeat;
197
+ /** 数据根(`resolve()` 之后;内存部署 = `undefined`)—— 一次性迁移 M33 的快照目录住在它下面(窗口见 `plugins/one-time-migrations.ts` 登记表)。 */
198
+ private readonly dataRoot;
199
+ /** 一次性迁移 M33:本进程起服以来消化掉的快照记录数(恢复先行那一步累加,迁移读数交出时清零)。 */
200
+ private archiveSnapshotsSettled;
108
201
  /** @param repo the core SessionRepo this store projects into the §0.5 SessionStore shape.
109
202
  * @param runs the run store whose per-session projection is the ONLY source of a row's `runCount` / `lastStatus` / `lastRunId` /
110
203
  * `lastTaskRunId` (LocalBackend passes its `FileRunStore`). Required — a run-less local session store does not exist.
111
204
  * @param dataDir the SAME data dir the file-backed repo persists under (LocalBackend passes `fileBackend.root`).
112
205
  * When given, lastActivity is persisted to `<dataDir>/session-last-activity.json` so it survives a
113
206
  * restart (the file-backed deployment); omit it for the in-memory deployment (nothing survives).
114
- * @param opts.log the `session_owner_claimed` line's sink (LocalBackend passes a logger at the deployment's LOG_LEVEL;
115
- * absent ⇒ an info-level JSON-line logger — a claim is never silent). */
116
- constructor(repo: HeadReadingSessionRepo, runs: SessionRunRollupSource & SessionRunClaimSource, dataDir?: string, opts?: {
117
- log?: Pick<Logger, "info">;
118
- });
207
+ * @param opts.log the `session_owner_claimed` / `delegated_session_owner_orphaned` lines' sink (LocalBackend passes a logger at the deployment's
208
+ * LOG_LEVEL; absent ⇒ an info-level JSON-line logger — a claim or an orphaned delegated row is never silent).
209
+ * @param opts.durability / opts.placements the deployment's declaration ({@link LocalSessionStoreDeclaration}; see the two fields). */
210
+ constructor(repo: HeadReadingSessionRepo & Partial<PlacementRecordingRepo>, runs: SessionRunRollupSource & SessionRunClaimSource, dataDir?: string, opts?: {
211
+ log?: Pick<Logger, "info" | "warn">;
212
+ } & LocalSessionStoreDeclaration);
119
213
  /**
120
214
  * 这一格此刻是不是 `forking`(fork 创建的格 {@link isForkCreatedCell} ∧ 存档不在)。存档在不在只问 repo 的唯一探针 {@link probeArchive} 的「不在」—— **只问有没有**:存档在而用不了(会话头读不出 / 截断)
121
215
  * 是「在」,内容读不读得出归真正读内容的那一读(门之后、体之前读一次叶子,读不出 ⇒ `corrupt_session`)。所以带键的会话与不带键的会话在执行席上同形,坏档照样能被换装修好
@@ -170,6 +264,20 @@ export declare class LocalSessionStore implements SessionStore {
170
264
  * {@link metaRead} / {@link forkingRead} 收下它、点名跳过,不上抛。只问有没有的 {@link forkingRead} 把 `corrupt_session` / `invalid_session` 读作「在」(存档找到了),`storage` 不替它答。
171
265
  */
172
266
  private probeArchive;
267
+ /**
268
+ * 委派分区的**唯一一读**(存档行头上的元组,repo 的 `placementOf`;文件头注):placed · 普通 · 读不出。repo 只吞「不在」,别的故障原样抛 ⇒ 这里收成
269
+ * {@link UnusableArchive}(词同 {@link archiveFaultWord}),由读者决定上抛还是按普通行答。
270
+ */
271
+ private placementProbe;
272
+ /**
273
+ * 改写面与执行席的读法({@link placementProbe} 的一形):placed ⇒ 那份元组;普通 ⇒ `undefined`;行头读不出(`corrupt_session` / `invalid_session`)⇒ `undefined` —— 没有可读的
274
+ * placement 记录,这一行按普通行答,内容读不读得出归真正读内容的那一读(坏档照样换得掉,与 forking 探针同一条规矩);说不出(`storage`)⇒ 抛那只故障。
275
+ */
276
+ private placedRecordOf;
277
+ /** {@link placedRecordOf} 的是非形。 */
278
+ private isPlacedRow;
279
+ /** 删除与认领的读法({@link placementProbe} 的另一形):读不出的任何一形 ⇒ 抛那只故障(说不准是不是 placed 行,就不删、不写)。 */
280
+ private placedRecordOrThrow;
173
281
  /** 盘上有没有一份**读得出**的这只会话的存档(补铸 / 登记 / 导入的落点判 / fork 目标这些要对存档动手的读者用):用不了的存档照旧上抛它的故障。 */
174
282
  private existsInRepo;
175
283
  /**
@@ -203,10 +311,20 @@ export declare class LocalSessionStore implements SessionStore {
203
311
  */
204
312
  headOf(sessionId: string): Promise<SessionHead | undefined>;
205
313
  /**
206
- * 三条 acquire 腿(无 id 建 / 按 id 打开 / 按 id 首建)交出会话的唯一一处:住客 = 这只会话那一格({@link cellOfPresent} —— 刚建或刚在写锁里
207
- * 打开,就是在盘上的证明,不再回 repo 探一次),经活住客的唯一投影(`sessionFaceFromRow`)解码,挂到交出的会话上({@link occupiedBy})。
314
+ * 引擎仓存档的头(core `SessionRepo.headOf`:日志首记录与尾,不重放)—— 本店读存档头的**唯一**一处。存档头在本店只有两种读法:叶子(读内容的人要的那一格)
315
+ * 与行代号(换装 / 一次性迁移的 `expect.row`、迁移判「有没有、读不读得出」);属主 / 建档时刻 / 谱系从不从这里读(规则一,行事实只住边档)。
316
+ */
317
+ private archiveHeadOf;
318
+ /**
319
+ * 三条 acquire 腿(无 id 建 / 按 id 打开 / 按 id 首建)交出会话的唯一一处:行事实 = 这只会话那一格({@link cellOfPresent} —— 刚建或刚在写锁里
320
+ * 打开,就是在盘上的证明,不再回 repo 探一次),经唯一投影 {@link rowMetadataOf}(活住客解码、建档时刻、谱系)挂到交出的会话上({@link occupiedBy})。
208
321
  */
209
322
  private handOut;
323
+ /**
324
+ * 按 id 读一只会话的元数据(会话视图窗的元数据口,`local-session-window.ts`):行事实经与交出的会话**同一只**投影 {@link rowMetadataOf} 取自那一格(读口 {@link metaOf}:
325
+ * 格缺而存档在 ⇒ 补铸;存档读不出 ⇒ 抛那只故障)。`undefined` = 无此会话。窗只读日志内容,不自开 repo、不读存档头。
326
+ */
327
+ sessionMetadataOf(sessionId: string): Promise<SessionMetadata | undefined>;
210
328
  /** Cheap pre-LLM probe (local twin). The map write needs no session_meta row, so there is
211
329
  * no "none" (register-lag) dimension here — two states only. */
212
330
  probeTitle(sessionId: string): Promise<"none" | "untitled" | "titled">;
@@ -231,8 +349,9 @@ export declare class LocalSessionStore implements SessionStore {
231
349
  writeSessionRowCells(sessionId: string, cells: SessionRowPatch, how: ReplaySessionRowWrite): Promise<ReplaySessionRowWriteOutcome<SessionSummary>>;
232
350
  /**
233
351
  * 写原语锁住的那一行(调用方持这只会话的写锁并已 {@link loadRowSidecars}):会话元数据那一格(属主 `owner ?? null` —— 与头读、列表行同读;化身经
234
- * `incarnationFromCell` 的 `absent` 读法;执行位 `mirror`)+ 列表面上有它(会话仓里有;`forking` 中间态的存档不在 ⇒ 不在列表上)+ 两只边档的格。
235
- * 没有那一格或不在列表面上 ⇒ `undefined`(没有行)。local 没有委派分区行。
352
+ * `incarnationFromCell` 的 `absent` 读法;执行位 `mirror`)+ 行集里有它({@link rowHeaderOf};`forking` 中间态的存档不在 ⇒ 不在列表上)+ 两只边档的格。
353
+ * 没有那一格或不在列表面上 ⇒ `undefined`(没有行)。委派分区行(placed)不上列表面(repo 的 `list()` 按存档行头排除,义务 2;行头读不出的行没有可读的 placement 记录、
354
+ * 按普通行读 —— 文件头注那一条)⇒ `placed: false` 是列表面那一判的投影,不是另一读。存档读不出的行照样是一行(行格住在边档,写得了;HTTP 改名口的坏档判据排在本原语之前)。
236
355
  */
237
356
  private lockedRowOf;
238
357
  /** 两只边档上这只会话的可写格(已发布的值;缺键 = 缺省)。调用方先 {@link loadRowSidecars}。 */
@@ -242,10 +361,35 @@ export declare class LocalSessionStore implements SessionStore {
242
361
  /** 应答行(锁内另读):列表行同一只合成 + 读到它时那一格上的住客。不在列表面上 / 没有那一格 ⇒ `undefined`。 */
243
362
  private listRowOf;
244
363
  /** ONE session's list row — {@link listSessions}' projection ({@link summaryOf}, the same synthesis) for one id;
245
- * `undefined` = not a row of the list face (not in the session repo). */
364
+ * `undefined` = not a row of the list face ({@link rowHeaders}). */
246
365
  sessionSummaryOf(sessionId: string): Promise<SessionSummary | undefined>;
247
- /** 会话仓里这只会话的列表元数据(列表面上的行 = `repo.list()` 里的一项)。 */
248
- private listedMeta;
366
+ /**
367
+ * 本店的**行集** —— 唯一的会话枚举(列表 {@link listSessions}、一次性迁移 M33 的步 1 读它;按 id 读的 {@link rowHeaderOf} 是同一只判据的一只 id 形):
368
+ * · 引擎仓的列表(core `repo.list()`:存档**行头**读得出、非 placed)—— 行头读得出的行;
369
+ * · ∪ 会话元数据边档里有格、不在引擎仓列表里的 id,经 {@link headerUnreadableRowOf}:存档头读了抛、且不是 placed 行 ⇒ 行头读不出的行(带那只故障);
370
+ * 不抛(存档不在:fork 中间态 / 删除中;或读间新建)/ placed 行(行头读得出,repo 的 `listPlaced` 认得它,尾部再坏也不上列表面)⇒ 不是行集里的行。
371
+ * 边档里没有格、存档头又读不出的会话(7.104.0 之前写下、此后从没被读过)没有一格可读的行事实 —— 属主读不出 ⇒ 不进行集(fail-closed,与归属门同读:
372
+ * {@link metaOf} 判不了它在不在 ⇒ 整只拒);运维面由 core 列表的披露座与起服 warn 点名它。
373
+ * 「行头读不读得出」(行集,M33 回填行事实问的就是它)与「叶子读不读得出」(列表行的 `unreadable`,{@link listedRowOf})是两件事、各一只读法。
374
+ */
375
+ private rowHeaders;
376
+ /**
377
+ * 行集里的这一行({@link rowHeaders} 的按 id 一形:同一只判据,只判这一只 id 的行 —— 别的会话读不出不改它的答)。`undefined` = 不是行集里的行。
378
+ * ⚠️ 如实:取它的行头仍经引擎仓列表(`repo.list()` 读一遍各会话的头),所以别的会话的头坏了,这一次读照旧为它报一次读坏披露;按 id 直读不在本形里。
379
+ */
380
+ private rowHeaderOf;
381
+ /** 不在引擎仓列表里、边档有格的一只 id:存档头读了抛、且不是 placed 行 ⇒ 行头读不出的那一行;否则 `undefined`(见 {@link rowHeaders})。 */
382
+ private headerUnreadableRowOf;
383
+ /**
384
+ * 委派分区行的 id 集的读者(repo 记 placement ⇒ 它的 `listPlaced`,行头那一读;不记 ⇒ 空集 —— 那种 repo 里没有 placed 行)。惰性、一次读:只在有一只 id 的存档头读抛、
385
+ * 要分「行头读不出」与「行头读得出的 placed 行尾部坏了」时才读。
386
+ */
387
+ private createPlacedIdsReader;
388
+ /**
389
+ * 列表面上的一行的内容那一半 = 头读的**叶子**那一读({@link archiveHeadOf},与 {@link headOf} 的叶子同一读):行头读不出 ⇒ 读不出(那只故障);行头读得出 ⇒ 再读叶子,
390
+ * 抛 ⇒ 读不出(尾部 I/O 故障之类:行头好、头读照样抛);否则读得出。所以行上的 `unreadable` 与头读、读口对同一只会话的答复同读。
391
+ */
392
+ private listedRowOf;
249
393
  /** [ref] —— 换源通告的基线读(local 孪生;三态读法与 SQL 两孪生的 `session_meta.instruction_source` 同一只编解码)。 */
250
394
  readInstructionSource(sessionId: string): Promise<InstructionSourceBaseline>;
251
395
  /**
@@ -299,9 +443,9 @@ export declare class LocalSessionStore implements SessionStore {
299
443
  /** `which` 点名是哪一只边档([ref] 起有三只 —— 此前这句恒写 lastActivity,title 边档的失败也被报成「recency 降级」)。
300
444
  * 节流仍是本实例一只。 */
301
445
  private warnSidecar;
302
- acquire(sessionId?: string, opts?: {
303
- requireExisting?: boolean;
304
- }): Promise<AcquiredSession>;
446
+ acquire(sessionId?: string, opts?: PlacementAcquireOpts): Promise<AcquiredSession>;
447
+ /** 这次 acquire 要落的 placement:只有声明了分区的店才收(未声明 ⇒ `undefined`,会话就是普通会话 —— core `SessionStore.placements` 缺席的读法)。 */
448
+ private declaredPlacement;
305
449
  private load;
306
450
  /** 为这只会话打开它自己的存档,锁内一形(调用方持这只会话的写锁,见 {@link load})。[ref]:这是「为这只会话打开它自己的存档」的那一次
307
451
  * (引擎 prepare 的 acquire)⇒ 包在打开作用域里:这次回放跳过了记录 ⇒ 打开成功后铸一帧 `session.records_skipped` 投给这只会话(唯一铸点
@@ -309,6 +453,15 @@ export declare class LocalSessionStore implements SessionStore {
309
453
  * 写下的会话)时,这次打开就是补铸的证明({@link handOut})。GUARD(open 腿):打开一只已存在的会话**不写属主** —— 记下的属主(含「登记为
310
454
  * 无主」)一个字节不动,没被记下的也不在这里替它记成无主:打开不是一个属主事实(7.119.0 前这一腿把「不知道」记成进程内存里的 null,重启即失)。 */
311
455
  private openForItselfHeld;
456
+ /**
457
+ * 带 placement 的按 id 首建(锁内一形,调用方持这只会话的写锁、已判过存档不在且不是 fork 创建的格)。写序 = **判别位先落**:先建存档(引擎文件 repo 把元组写进行头、
458
+ * 首写不可变),再写会话元数据那一格(化身新铸;属主按委派继承律 —— 根会话的属主,根行不在取父,都不在 ⇒ 孤行哨兵 + 一行 warn;读法与次序只住在
459
+ * `delegated-session-owner.ts` 的 `createPlacedSessionRow`,三只店同调)。崩在两笔之间 = 存档在而格缺 = 一只 placed 行、属主从没被记下(读作无主;
460
+ * 这形只在 fleet 调用方可读,停驻挂点的认领口 {@link claimOwnerless} 按委派律补上)。
461
+ * 格已在而存档不在(登记先落了格、存档还没建 —— 一只普通会话的行)⇒ `placement_refused`(SQL 孪生:登记过的行在,带 placement 的建读回缺席元组,同一判)。
462
+ * 建后读回准入(镜像方向):别的进程(同一数据根上的 run-local 腿)在这一刻抢先建了同 id 的存档 ⇒ repo 返回的是那一只 ⇒ 元组缺席 / 异组 ⇒ 响亮拒。
463
+ */
464
+ private createPlacedHeld;
312
465
  /**
313
466
  * Idempotently record a session's owner — never overwrites a RECORDED owner (incl. a recorded `null`, "registered ownerless";
314
467
  * mirrors TiDBSessionStore.register's first-write rule). TiDB parity: register INSERTs a session_meta row so the session EXISTS
@@ -323,8 +476,19 @@ export declare class LocalSessionStore implements SessionStore {
323
476
  */
324
477
  register(sessionId: string, owner: string | null): Promise<void>;
325
478
  touch(sessionId: string): Promise<void>;
326
- /** Durable history is retained by the repo; just drop the in-flight cache entry (mirrors TiDBSessionStore.release). */
479
+ /**
480
+ * 普通会话:durable 史留在 repo,只丢 in-flight 那一格(义务 3,与 SQL 孪生同)。
481
+ * 🔴 义务 4 —— **placed 会话:release 是真删除**(联合收割先删 agent 行、赢了才调这里终结转录)。判据 = 存档行头上的元组(冷启动后照样成立);
482
+ * 读不出 ⇒ 上抛、一个字节不删(说不准是不是 placed 行;吞掉 = 收割腿数一条「已终结」而字节还在)。删序 = **判别位最后删**:四只行边档与新近 → 元数据格 → 存档最后
483
+ * —— 崩在中途,存档(连同它的元组)还在,重发的 release 与分区收割腿都还认得它、收得完;反过来先删存档,剩下的边档就没人认领了。
484
+ * 整段在这只会话的写锁里(与删除 / 换装 / 登记同一把)。
485
+ */
327
486
  release(sessionId: string): Promise<void>;
487
+ /**
488
+ * 委派继承律的认领口(锁内 CAS):placed 行、那一格的化身 = `incarnation`、属主无主(记下的 `null` 或从没被记下)⇒ 写 `owner`、返回 true;任何一条不符 ⇒ false、零写
489
+ * (SQL 孪生的 `CLAIM_OWNERLESS_PLACED_SQL` 同四个条件)。placement 读不出 ⇒ 上抛(不写)。
490
+ */
491
+ private claimOwnerlessPlaced;
328
492
  /**
329
493
  * P0.5 variant-2 (E16, clay 2026-06-26) — enumerate the caller's sessions (CC /resume picker) from the SESSION
330
494
  * abstraction (`repo.list()`), keyset-paginated newest-first by last activity. Session IDENTITY comes from the
@@ -333,7 +497,7 @@ export declare class LocalSessionStore implements SessionStore {
333
497
  * - `owner` — the session's persisted session-meta cell (null when ownerless / never recorded). A
334
498
  * single-user local deployment runs REQUIRE_PRINCIPAL=off; the route already owner-gates
335
499
  * at the HTTP layer.
336
- * - `firstActivityAt` — the session's `createdAt` (repo metadata).
500
+ * - `firstActivityAt` — the row's `createdAt` (the session-meta cell — the SQL twins' `session_meta.created_at`; the archive header's copy is not read).
337
501
  * - `lastActivityAt` — the touch marker (falls back to `createdAt`); the keyset sort key.
338
502
  * - `objectivePreview`— the last USER-text entry, synthesized from the session tree (no run ledger).
339
503
  * - `runCount`/`lastStatus`/`lastRunId`/`lastTaskRunId` — [ref]:read from the run store handed in (`runs`; the TiDB
@@ -342,6 +506,10 @@ export declare class LocalSessionStore implements SessionStore {
342
506
  * `lastTaskRunId` = that run's `result.runId`). One call per list (not per row); a session with no
343
507
  * run row ⇒ `0 / "" / null` (TiDB's null→"" mapping); a run-store read failure throws (never `0 / ""`).
344
508
  *
509
+ * - `unreadable` — present-iff the row's head leaf cannot be read ({@link listedRowOf}: the archive header, or the tail the head read
510
+ * scans): the row's facts above still come from its session-meta cell; `objectivePreview` is null; the marker's
511
+ * `errorCode` is what the session's own reads answer.
512
+ *
345
513
  * Keyset matches the contract: STRICTLY older than the cursor, ties broken by id DESC; `limit` is honored after
346
514
  * the in-memory sort. Cheap (a local single-user store holds few sessions). Errors reading one session's entries
347
515
  * degrade that row's preview to null rather than failing the whole list.
@@ -390,8 +558,9 @@ export declare class LocalSessionStore implements SessionStore {
390
558
  * **fork 续写的店契约**(local 一形;规则与结果闭集在 `session-fork.ts`,SQL 孪生同义):
391
559
  * · **两把写锁**:按 id 字典序依次取源与目标的写锁(锁不可重入;同 id 只取一把)—— 同 id 的每个写者(删除 / 登记 / 导入 / 按 id 首建 / 别的 fork)都在目标那把锁里,
392
560
  * core `repo.fork` 的改名覆盖写只在锁内被调;
393
- * · **源先判**:源存档不在 ⇒ `null`(源被删之后的同键重试答「源不在」);属主读在拷贝之前(源锁持到拷贝落定)—— 唯一读法 `forkOwnerOf`;
394
- * · **唯一创建点 = 格先、存档后**:锁内「目标格不在 ∧ 目标存档不在」才写目标格(带 fork 键;新住客,执行位 absent),再交 core `repo.fork` 写存档。
561
+ * · **源先判**:源存档不在 ⇒ `null`(源被删之后的同键重试答「源不在」);源存档带属主戳 ⇒ {@link StampedSessionArchiveError}(零写);属主读在拷贝之前(源锁持到拷贝落定)—— 唯一读法 `forkOwnerOf`;
562
+ * · **唯一创建点 = 格先、存档后**:锁内「目标格不在 ∧ 目标存档不在」才写目标格(带 fork 键;新住客,执行位 absent;建档时刻与谱系 `forkedFrom` = 源 id 同一笔写),再交 core `repo.fork` 写存档
563
+ * (不交属主 —— 引擎仓匿名;子存档的属主格抄自源存档,源匿名 ⇒ 子匿名)。
395
564
  * 崩在两步之间 = fork 创建的格而存档不在 = `forking`:普通取用一律 {@link SessionForkInProgressError};同键重试在两把锁内补拷存档、答 `replayed`。
396
565
  * 拷贝抛错(不是崩溃)⇒ 撤掉刚写的目标格再上抛(撤不掉 ⇒ 留下的就是 `forking`,与崩在中间同形);
397
566
  * · **撞已在** ⇒ 按目标格的属主与 fork 键分类({@link classifyForkTarget})。
@@ -422,20 +591,21 @@ export declare class LocalSessionStore implements SessionStore {
422
591
  /**
423
592
  * 2c session-sync — IMPORT a verbatim entry log into a **new** session `sessionId`(`owner` = 鉴权过的导入者)。按接口句(`importEntries` 只建新会话;改写既有会话走
424
593
  * {@link replaceEntries} / 暂存提交),SQL 孪生同判(占行不成 ⇒ 拒):id 上已有行(或格缺而存档在)⇒ `conflict`,一个字节不写;新行的属主 = 导入者、铸一只化身、
425
- * 执行位 mirror。属主在本店的属主格上判(会话元数据那一格是本店唯一的属主真源;本店建的存档在引擎仓里不带属主戳 —— `register` 只 `repo.create({ id })` ——
426
- * 引擎仓的属主比较替这一格答不了)。整段在这只会话的写锁里,写序见 {@link importHeld}。
594
+ * 执行位 mirror、建档时刻 = 此刻。属主在本店的属主格上判(会话元数据那一格是本店唯一的属主真源;本店交给引擎仓的写一律匿名 —— 规则一 —— 引擎仓的属主比较替这一格答不了)。
595
+ * 整段在这只会话的写锁里,写序见 {@link importHeld}。
427
596
  */
428
597
  importEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
429
598
  /**
430
599
  * 2c session-sync (§7/§8) — IDEMPOTENT REPLACE,按接口句(`SessionStorage.replaceEntries`:先清这只会话既有的对话日志,再导入 `entries`)。
431
600
  * 与 {@link importEntries} 同一个入口、同一只写序,只差落点(行不在,或行上的属主就是导入者)与内容那一半(先清内容存档再导入,见 {@link importHeld} ③)——
432
- * 所以一只会话头读不出的存档也换得掉;存档是重建的那一只,建档时刻 = 换装时刻(SQL 孪生 replace 重插行、`created_at` 重记,同义)。行的四只边档原样。
601
+ * 所以一只会话头读不出的存档也换得掉;存档是重建的那一只(匿名),行原样:属主重戳为导入者,化身、建档时刻、谱系与四只边档照带(行事实不住在存档上 ——
602
+ * 重建存档不移动它们)。
433
603
  */
434
604
  replaceEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
435
605
  /**
436
606
  * 换装三条写腿(公开 {@link importEntries} / {@link replaceEntries} 与暂存提交 {@link commitStagedImport})的**同一个入口**:调用方给的属主先过
437
607
  * {@link importerOwnerOf}(主体名或 `null`;否则 `TypeError`,什么都没读、一个字节没写),再进这只会话的写锁 —— 锁里的写体只见判过的那一个值,
438
- * 写进行的属主就是它。引擎导入口的属主判管不到这一格:换装交给引擎的是存档自己的戳(见 {@link importHeld} ③),不是调用方的属主。
608
+ * 写进行的属主就是它。引擎导入口的属主判管不到这一格:换装交给引擎的属主恒缺席(匿名,见 {@link importHeld} ③),不是调用方的属主。
439
609
  */
440
610
  private withImportLock;
441
611
  /**
@@ -443,12 +613,12 @@ export declare class LocalSessionStore implements SessionStore {
443
613
  * ① 只读、零写:引擎闸 `validateEntriesForImport`(坏包 ⇒ `invalid_session`)· 本处写者 ⇒ {@link SessionWriterPresentError} · `forking` ⇒
444
614
  * {@link SessionForkInProgressError} · 不是这个写口的门判过的行 ⇒ {@link importRowRefused}(判据 {@link importMayLand},按写口带来的 {@link ImportLanding};
445
615
  * 这条路径上唯一一次判属主);
446
- * ② 行先:{@link landImportCell}(属主重戳为导入者、化身与 fork 键沿用或新铸、执行位 mirror);
447
- * ③ 内容,按写口的动词(唯一读法在下面这一只 switch;这里不读那一格、不判属主,只换**内容**):
448
- * · `create` / `judged`(导入):原地换锁里读到的那一份存档的日志(没有存档 ⇒ 导入新建一只),存档的元数据整只留着(其中的建档时刻是列表行的
449
- * firstActivityAt,与 SQL 孪生留在行上的 `created_at` 同义)。存档上的属主戳不是本店的事实(本店建的存档一律不带戳,存量存档可能带着此前导入者的戳),
450
- * 只是引擎仓原地换的条件:按那一份存档自己的戳导入,并以它为 `expect`(戳 + 存档的令牌)—— 读与写之间它换了一代 ⇒ 引擎仓拒 `conflict`。
451
- * 读存档、校验、存档判与写在引擎仓里是一步,抛在哪一处内容都一个字节没动 ⇒ 撤回 ②({@link withdrawImportCell}:行原样,SQL 孪生的事务回滚同义)再原样上抛;
616
+ * ② 行先:{@link landImportCell}(属主重戳为导入者、化身与 fork 键沿用或新铸、执行位 mirror;建档时刻与谱系照带,新行写此刻);
617
+ * ③ 内容,按写口的动词(唯一读法在下面这一只 switch;这里不读那一格、不判属主,只换**内容**;交给引擎仓的属主恒缺席 —— 规则一):
618
+ * · `create` / `judged`(导入):原地换锁里读到的那一份存档的日志(没有存档 ⇒ 导入新建一只,匿名),以锁里读到的存档头为 `expect.row`(**行代号**:
619
+ * 读与写之间存档换了一代 ⇒ 引擎仓拒 `conflict`;它判不出同一代里的追加)。匿名导入只换匿名存档的日志 —— 仍带属主戳的存档(更早的版本写下、一次性迁移 M33
620
+ * 改写不了的,或跳版升上来的)本店先以具名拒 `StampedSessionArchiveError` 答(与 fork 同一只;引擎导入律同样会拒,本店不重写、不绕,只让拒带对的出路)。
621
+ * 读存档、校验、存档判与写在引擎仓里是一步,抛在哪一处内容都一个字节没动 ⇒ 撤回 ②({@link withdrawImportCell}:行原样 —— 净零写,SQL 孪生的事务回滚同义)再原样上抛;
452
622
  * · `replace`(接口句「先清既有对话日志,再导入」):先清掉内容存档(不带 `expect` —— 带了就得先读它的头,读不出的存档就清不掉),再导入一只新存档。
453
623
  * 清不可撤:清过之后导入再抛(I/O 故障),内容就没了,行留 ② 落下的 mirror(只读方向,下次推送补齐)—— 已发版本的 replace 同形(删后导入)。
454
624
  * 带 fork 键的行(fork 建出的目标)留下的是「mirror、键仍在、存档不在」:不读作 `forking`({@link isForkCreatedCell}:fork 创建点写下的格执行位恒缺,② 落下 mirror 之后它就不再是那一形),
@@ -457,6 +627,11 @@ export declare class LocalSessionStore implements SessionStore {
457
627
  * 崩在 ②③ 之间 = 格已是 mirror、内容旧或空 = 只读方向,下次推送补齐(SQL 孪生在一个事务里写行与内容,没有这个中间态)。
458
628
  */
459
629
  private importHeld;
630
+ /**
631
+ * 改写面的分区判(调用方持这只会话的写锁):placed 行 ⇒ `placement_refused`(import 面 409 `conflict.session_placed`,`session-error-wire.ts`),一个字节不写。
632
+ * 读法 = {@link isPlacedRow}(行头读不出 ⇒ 按普通行答,坏档照样换得掉;说不出 ⇒ 抛)。
633
+ */
634
+ private assertNotPlacedHeld;
460
635
  /**
461
636
  * ① 的属主 / 住客条件:这一行此刻是不是这个写口的门判过的行({@link ImportLanding};一次读、零写 —— 格缺时「行在不在」只问存档的唯一探针
462
637
  * {@link existsInRepo},不补铸那一格)。属主比的是头读的读法 `owner ?? null`(从没被记下 = 无主;格缺而存档在 = 从没被记下),比较器是删除门的那一只
@@ -467,8 +642,8 @@ export declare class LocalSessionStore implements SessionStore {
467
642
  /**
468
643
  * ② 推送落下的那一格 —— 三个导入写口与暂存提交「内容相同、日志不动」那一支都经这**一处**(调用方持写锁、① 已判过):属主重戳为导入者;
469
644
  * 化身与 fork 键经 {@link carriedRowCells}(三只店同一句)读那一格自己 —— 行在 ⇒ 沿用(同一行 = 同一位住客,属主重戳与否不改这一判),刚建 ⇒ 新铸、不带键;
470
- * 执行位 = mirror(导入落下的是「写者在别处」;SQL 孪生的提交点同一句写)。只写这一格:四只行边档与新近不在这里。
471
- * 交回写之前的那一格(`undefined` = 原本没有),③ 撤回用。
645
+ * 执行位 = mirror(导入落下的是「写者在别处」;SQL 孪生的提交点同一句写)。**在 `before` 上改这三位**,别的位(建档时刻、谱系)照带;刚建的行建档时刻 = 此刻。
646
+ * 只写这一格:四只行边档与新近不在这里。交回写之前的那一格(`undefined` = 原本没有),③ 撤回用。
472
647
  */
473
648
  private landImportCell;
474
649
  /**
@@ -516,9 +691,55 @@ export declare class LocalSessionStore implements SessionStore {
516
691
  * [ref]:化身随那一格消失(同 id 重登记铸新的 —— 那就是下一位住客)。
517
692
  */
518
693
  private deleteSessionHeld;
694
+ /**
695
+ * 删一只会话的**行**(调用方持这只会话的写锁)—— 删除与 placed 的 release 两处共用这一只,存档的删除由两位各自排在前或后:
696
+ * ⓪ 登记「删行已开始」(锁外读者从此不补铸,见 {@link rowsDropped});① 四只行边档(标题 / 置顶 / 指令来源 / 工作区),落不了盘 ⇒ 抛(留下的那一格会在重启后
697
+ * 挂到同 id 的下一位身上);② 新近标记:先把盘上那一份读进来再删(冷起服后的第一笔就是删 ⇒ 删的若是空表,随后那次落盘会把盘上那一笔并回去),防抖落盘;
698
+ * ③ 属主 + 化身那一格**最后**删,落不了盘 ⇒ 抛(留下的格会让删掉的会话重启后「还在」;边档任一只先抛时那一格还在 ⇒ 重发照样走得进来、收敛)。
699
+ */
700
+ private dropRowHeld;
701
+ /**
702
+ * 引擎文件仓的存档目录(`<数据根>/sessions`,`FileSessionRepo` 的布局)fsync 一次,失败即抛 —— M33 在删快照之前确知新写的存档目录项在盘上
703
+ * (引擎的导入只尽力 fsync 目录,吞掉失败)。只有 M33 用;目录不在 ⇒ 抛(布局变了就响亮,不静默跳过屏障)。
704
+ */
705
+ private syncArchiveDirectory;
706
+ /** 快照目录(数据根下;内存部署 ⇒ `undefined`:没有持久存档,迁移零动作)。 */
707
+ private archiveSnapshotDir;
708
+ /**
709
+ * **步 0 · 恢复先行**(起服、先于一切请求与本条其余步骤;`LocalBackend.ensureSchema` 调,`migrateLocalArchives` 开头再调一次 —— 幂等):快照目录里的每一份记录 ——
710
+ * · 存档不在(崩在删之后、导入之前)⇒ 用记录匿名导入补回、行上缺的事实从记录补、删记录;
711
+ * · 存档在且匿名(崩在导入之后、删记录之前)⇒ 补行上缺的事实、删记录;
712
+ * · 存档在、带戳、行代号 = 记录里那一代(崩在删之前)⇒ 删记录(这只存档在步 3 重做);
713
+ * · 别的组合 / 记录读不出 / 补回抛 ⇒ 拒启({@link LocalArchiveSnapshotsPresentError},点名会话、路径与原因)。
714
+ * `atomicWriteFile` 留下的 `.tmp`(改名没发生 = 记录从没写成 ⇒ 那一次什么都还没删)直接删。消化完,常设臂 {@link assertNoArchiveSnapshots}:目录必空 ⇒ 服务开始之前快照与服务从不并存。
715
+ * 交回这一次消化掉的记录数。
716
+ */
717
+ settleArchiveSnapshots(): Promise<number>;
718
+ /** 消化一份快照记录(步 0 的一条;拒 ⇒ {@link LocalArchiveSnapshotsPresentError},记录原样留着)。 */
719
+ private settleArchiveSnapshot;
720
+ /** 把行事实补进那一格(格缺 ⇒ 铸一格;已有的位一个不动)并落盘。 */
721
+ private fillRowFacts;
722
+ /**
723
+ * 一次性迁移 M33 的 local 腿(`LocalBackend.runOneTimeMigrations` 调;起服、先于任何请求;窗内每次起服都跑,第二次起零命中):
724
+ * 0. 恢复先行({@link settleArchiveSnapshots},幂等);
725
+ * 1. **枚举**(行集 `rowHeaders`):id 全集 = 引擎仓的列表(读得出头的存档)∪ 边档全部键;只在边档里的、头读抛且不是 placed 行(行头读得出)的 ⇒ 计 unreadable(步 3 整档读抛的同计)。两边都不在的读不出存档(列表跳过它、边档里没它的格)
726
+ * 对本店与引擎同样不可见,不计;
727
+ * 2. **行回填**:列表里每一只存档 —— 格缺 ⇒ 建一格(化身新铸、属主「从没被记下」,与补铸同义);格缺建档时刻 ⇒ 写存档头的;格缺谱系而存档头有 ⇒ 写它。只写行(边档的一次提交),
728
+ * 然后一道**落盘屏障**(边档文件与目录各 fsync)—— 在这之前不碰任何存档;
729
+ * 3. **存档归一**(每只头上带属主戳的存档,在它的会话写锁里):a 整档一次读(读时跳过了记录 ⇒ 留着,计 kept `records_skipped`:重写会抹掉盘上那几行读不出的字节)→
730
+ * b 先验(引擎导入闸,带 `preserveActorAssertions`:同部署迁移,发言者归属不剥)—— 抛 ⇒ kept `invalid`;验后的日志与原日志不逐条相等(引擎导入会改写内容)⇒ kept `normalizes`;
731
+ * 两种都原样不动 —— 迁移**从不改内容** → c 快照记录经 core `atomicWriteFile`(tmp → fsync → rename → fsync 目录)→ d 以这一代为条件删存档 → e 匿名导入(缺行 ⇒ 新存档,
732
+ * 引擎自己 fsync)→ f 删记录。
733
+ * 屏障(本店自做、失败即抛;core 的 `atomicWriteFile` 与引擎导入只尽力 fsync 目录):c 之后快照目录、e 之后存档目录、f 之后快照目录各 fsync 一次。
734
+ * 保证分档:进程崩在任一步 ⇒ 不丢(下一次起服步 0 消化);掉电 ⇒ 在兑现 fsync 的文件系统上不丢。d / e / 屏障抛 ⇒ 原样上抛(起服拒;下一次起服步 0 消化)。
735
+ */
736
+ migrateLocalArchives(): Promise<LocalArchiveMigrationReading>;
737
+ /** 步 3 的一只(调用方持这只会话的写锁)。 */
738
+ private anonymizeArchiveHeld;
519
739
  get size(): number;
520
740
  /** Graceful shutdown: AWAIT the final sidecar write (bug C) so a restart doesn't lose the last debounced-but-unwritten
521
741
  * touch. Cancels any queued debounce, then awaits a flush (which chains after any in-flight write and merges disk). */
522
742
  dispose(): Promise<void>;
523
743
  }
744
+ export {};
524
745
  //# sourceMappingURL=local-session-store.d.ts.map