@sema-agent/server 7.138.0 → 7.139.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 (215) hide show
  1. package/MIGRATION.md +276 -7
  2. package/README.md +7 -4
  3. package/README.zh-CN.md +6 -4
  4. package/USAGE.md +73 -29
  5. package/deploy/sema-up/README.md +1 -1
  6. package/deploy/sema-up/lib/lanes.json +3 -2
  7. package/dist/adoption/wire.d.ts +3 -3
  8. package/dist/approval-card.d.ts +20 -20
  9. package/dist/bench/s1/arms.d.ts +1 -1
  10. package/dist/bench/s1/arms.js +1 -3
  11. package/dist/bench/s1/run-firm.js +2 -2
  12. package/dist/boot/device-lane.d.ts +8 -3
  13. package/dist/boot/device-lane.js +7 -2
  14. package/dist/boot/execution-env.d.ts +4 -2
  15. package/dist/boot/execution-env.js +16 -24
  16. package/dist/boot/execution-lane.d.ts +1 -1
  17. package/dist/boot/governance-seams.d.ts +3 -2
  18. package/dist/boot/governance-seams.js +9 -11
  19. package/dist/boot/memory-consolidation.js +2 -2
  20. package/dist/boot/resolve-spec.d.ts +1 -1
  21. package/dist/boot/resolve-spec.js +8 -9
  22. package/dist/boot/retention-lane.d.ts +5 -5
  23. package/dist/boot/retention-lane.js +0 -6
  24. package/dist/boot/runner-deps.d.ts +3 -1
  25. package/dist/boot/runner-deps.js +2 -1
  26. package/dist/boot/session-faces.d.ts +0 -3
  27. package/dist/boot/session-faces.js +15 -8
  28. package/dist/boot/stage-02-web-admin-pull.js +2 -2
  29. package/dist/boot/stage-05-execution-env.js +2 -2
  30. package/dist/boot/stage-06-runners.js +0 -1
  31. package/dist/boot/stage-09-leader.js +1 -2
  32. package/dist/boot/stage-10-http-server.js +2 -2
  33. package/dist/boot/stores.js +4 -4
  34. package/dist/boot/web-admin.js +2 -2
  35. package/dist/capabilities/mcp-probe.js +1 -1
  36. package/dist/capabilities/scenarios.d.ts +1 -1
  37. package/dist/capability-facts.d.ts +15 -7
  38. package/dist/capability-facts.js +8 -3
  39. package/dist/config-catalog.js +7 -7
  40. package/dist/config-invariants.d.ts +23 -3
  41. package/dist/config-invariants.js +42 -0
  42. package/dist/config-provider.d.ts +19 -24
  43. package/dist/config-provider.js +27 -12
  44. package/dist/config-types.d.ts +10 -5
  45. package/dist/config.d.ts +33 -0
  46. package/dist/config.js +44 -15
  47. package/dist/delegated-session-owner.d.ts +2 -2
  48. package/dist/deployment-shape.d.ts +1 -1
  49. package/dist/device-enrollment.d.ts +41 -2
  50. package/dist/device-enrollment.js +27 -12
  51. package/dist/device-store.d.ts +58 -85
  52. package/dist/device-store.js +19 -49
  53. package/dist/device-ws-hub.js +2 -1
  54. package/dist/env-name-allowlist-knobs.d.ts +5 -4
  55. package/dist/exec-cut.d.ts +60 -0
  56. package/dist/exec-cut.js +36 -0
  57. package/dist/execution-lane-caps.d.ts +19 -0
  58. package/dist/execution-lane-caps.js +10 -0
  59. package/dist/execution-placement.d.ts +259 -0
  60. package/dist/execution-placement.js +199 -0
  61. package/dist/field-conflict.d.ts +3 -2
  62. package/dist/field-conflict.js +1 -0
  63. package/dist/hosted-posture.d.ts +2 -2
  64. package/dist/http/admission.js +8 -19
  65. package/dist/http/checkpoint-ctx.d.ts +21 -12
  66. package/dist/http/checkpoint-ctx.js +4 -2
  67. package/dist/http/claimed-run.d.ts +1 -1
  68. package/dist/http/durable-run-leg.js +9 -5
  69. package/dist/http/execution-context.d.ts +218 -0
  70. package/dist/http/execution-context.js +330 -0
  71. package/dist/http/resume-legs.js +50 -20
  72. package/dist/http/route-ctx.d.ts +14 -8
  73. package/dist/http/routes/background.d.ts +29 -1
  74. package/dist/http/routes/background.js +29 -2
  75. package/dist/http/routes/devices.d.ts +13 -19
  76. package/dist/http/routes/devices.js +21 -26
  77. package/dist/http/routes/session-sync.js +110 -15
  78. package/dist/http/routes/sessions.d.ts +6 -0
  79. package/dist/http/routes/sessions.js +115 -11
  80. package/dist/http/routes/side-query.d.ts +12 -4
  81. package/dist/http/routes/side-query.js +4 -5
  82. package/dist/http/routes/tasks.js +37 -31
  83. package/dist/http/server.d.ts +35 -19
  84. package/dist/http/server.js +11 -0
  85. package/dist/http/session-inherit-env.d.ts +3 -4
  86. package/dist/http/session-inherit-env.js +1 -1
  87. package/dist/http/wire-types.d.ts +8 -12
  88. package/dist/index.d.ts +1 -0
  89. package/dist/memory-sync-client.d.ts +53 -14
  90. package/dist/memory-sync-client.js +196 -116
  91. package/dist/memory-sync.d.ts +1 -1
  92. package/dist/memory-sync.js +3 -2
  93. package/dist/observability/cost-taxonomy.d.ts +2 -2
  94. package/dist/observability/fail-open.d.ts +12 -0
  95. package/dist/observability/fail-open.js +12 -0
  96. package/dist/observability/run-terminal.js +0 -1
  97. package/dist/orchestration/workflow-notify-journal.js +4 -4
  98. package/dist/org-memory-admission.d.ts +4 -3
  99. package/dist/org-memory-admission.js +6 -6
  100. package/dist/parked-decide.d.ts +34 -9
  101. package/dist/parked-decide.js +12 -19
  102. package/dist/parked-revive-surface.d.ts +12 -15
  103. package/dist/parked-revive-surface.js +3 -6
  104. package/dist/peer-seat.d.ts +13 -7
  105. package/dist/peer-seat.js +37 -3
  106. package/dist/plugins/approval-ask-store-file.d.ts +7 -0
  107. package/dist/plugins/approval-ask-store-file.js +11 -0
  108. package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
  109. package/dist/plugins/approval-ask-store-memory.js +12 -0
  110. package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
  111. package/dist/plugins/approval-ask-store-sql.js +30 -12
  112. package/dist/plugins/caching-session-store.d.ts +6 -2
  113. package/dist/plugins/caching-session-store.js +9 -3
  114. package/dist/plugins/checkpoint-store-sql.d.ts +6 -5
  115. package/dist/plugins/checkpoint-store-sql.js +5 -7
  116. package/dist/plugins/device-store-sql.d.ts +25 -51
  117. package/dist/plugins/device-store-sql.js +49 -103
  118. package/dist/plugins/execution-placement-sql.d.ts +151 -0
  119. package/dist/plugins/execution-placement-sql.js +223 -0
  120. package/dist/plugins/file-history-store-sql.d.ts +7 -6
  121. package/dist/plugins/file-history-store-sql.js +5 -5
  122. package/dist/plugins/file-run-store.d.ts +6 -1
  123. package/dist/plugins/file-run-store.js +4 -0
  124. package/dist/plugins/fork-routing-session-store.d.ts +6 -0
  125. package/dist/plugins/fork-routing-session-store.js +16 -0
  126. package/dist/plugins/local-session-store.d.ts +149 -50
  127. package/dist/plugins/local-session-store.js +382 -107
  128. package/dist/plugins/memory-key-guards.d.ts +4 -0
  129. package/dist/plugins/memory-key-guards.js +1 -0
  130. package/dist/plugins/memory-run-store.d.ts +1 -1
  131. package/dist/plugins/one-time-migrations.d.ts +111 -3
  132. package/dist/plugins/one-time-migrations.js +380 -10
  133. package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
  134. package/dist/plugins/permission-rule-store-sql.d.ts +13 -15
  135. package/dist/plugins/permission-rule-store-sql.js +13 -16
  136. package/dist/plugins/pg-pool.d.ts +7 -3
  137. package/dist/plugins/pg-session-storage.d.ts +31 -20
  138. package/dist/plugins/pg-session-storage.js +120 -52
  139. package/dist/plugins/remote-env-adb.d.ts +20 -4
  140. package/dist/plugins/remote-env-adb.js +70 -62
  141. package/dist/plugins/remote-env-device.d.ts +30 -12
  142. package/dist/plugins/remote-env-device.js +18 -17
  143. package/dist/plugins/remote-env-e2b.d.ts +18 -4
  144. package/dist/plugins/remote-env-e2b.js +41 -42
  145. package/dist/plugins/remote-env-file-error.d.ts +2 -0
  146. package/dist/plugins/remote-env-file-error.js +1 -1
  147. package/dist/plugins/remote-env-host.d.ts +21 -8
  148. package/dist/plugins/remote-env-host.js +66 -70
  149. package/dist/plugins/remote-env-k8s.d.ts +11 -16
  150. package/dist/plugins/remote-env-k8s.js +61 -54
  151. package/dist/plugins/remote-env-local-docker.d.ts +29 -6
  152. package/dist/plugins/remote-env-local-docker.js +46 -59
  153. package/dist/plugins/remote-env-ssh.d.ts +16 -4
  154. package/dist/plugins/remote-env-ssh.js +72 -56
  155. package/dist/plugins/remote-shell.d.ts +100 -3
  156. package/dist/plugins/remote-shell.js +166 -2
  157. package/dist/plugins/retention-store-sql.d.ts +9 -6
  158. package/dist/plugins/retention-store-sql.js +7 -1
  159. package/dist/plugins/run-store-sql.d.ts +13 -3
  160. package/dist/plugins/run-store-sql.js +5 -0
  161. package/dist/plugins/schema-consistency.d.ts +15 -5
  162. package/dist/plugins/schema-consistency.js +14 -8
  163. package/dist/plugins/schema-drift-sentence.d.ts +27 -0
  164. package/dist/plugins/schema-drift-sentence.js +38 -0
  165. package/dist/plugins/session-fork.d.ts +54 -0
  166. package/dist/plugins/session-fork.js +38 -1
  167. package/dist/plugins/session-row-sql.d.ts +22 -0
  168. package/dist/plugins/session-row-sql.js +81 -0
  169. package/dist/plugins/session-store.d.ts +1 -1
  170. package/dist/plugins/store-backend.d.ts +1 -1
  171. package/dist/plugins/store-backend.js +19 -7
  172. package/dist/plugins/store-contracts.d.ts +25 -5
  173. package/dist/plugins/tidb-pool.d.ts +12 -7
  174. package/dist/plugins/tidb-pool.js +9 -3
  175. package/dist/plugins/tidb-session-store.d.ts +57 -26
  176. package/dist/plugins/tidb-session-store.js +118 -50
  177. package/dist/plugins/tool-result-store-sql.d.ts +3 -2
  178. package/dist/plugins/tool-result-store-sql.js +18 -10
  179. package/dist/project-memory.d.ts +9 -15
  180. package/dist/project-memory.js +5 -4
  181. package/dist/request-key-closure.js +1 -1
  182. package/dist/request-value-closure.d.ts +6 -7
  183. package/dist/request-value-closure.js +1 -3
  184. package/dist/run-local.d.ts +6 -0
  185. package/dist/run-local.js +24 -20
  186. package/dist/runs.d.ts +2 -1
  187. package/dist/runs.js +3 -1
  188. package/dist/security.d.ts +38 -12
  189. package/dist/security.js +8 -2
  190. package/dist/server-secret-env.d.ts +9 -5
  191. package/dist/session-children-retire.d.ts +27 -9
  192. package/dist/session-children-retire.js +9 -5
  193. package/dist/session-incarnation.d.ts +19 -9
  194. package/dist/session-incarnation.js +4 -2
  195. package/dist/session-row.d.ts +114 -5
  196. package/dist/session-row.js +55 -5
  197. package/dist/session-titler.d.ts +2 -2
  198. package/dist/task-a2a.d.ts +1 -1
  199. package/dist/task-cwd.d.ts +6 -1
  200. package/dist/task-mcp.d.ts +3 -3
  201. package/dist/tool-approval.d.ts +6 -0
  202. package/dist/tool-approval.js +8 -1
  203. package/dist/trace/project.d.ts +1 -0
  204. package/dist/trace/project.js +1 -0
  205. package/dist/trace/self-minted-wire.d.ts +111 -2
  206. package/dist/trace/self-minted-wire.js +38 -1
  207. package/dist/url-refusal.d.ts +1 -1
  208. package/dist/web-admin-client/apply-effective.d.ts +17 -3
  209. package/dist/web-admin-client/apply-effective.js +20 -10
  210. package/dist/web-admin-client/skills-mcp.js +3 -2
  211. package/dist/web-admin-client/types.d.ts +6 -0
  212. package/package.json +3 -3
  213. package/wire-changes/server@7.139.0.json +348 -0
  214. package/dist/http/device-placement.d.ts +0 -175
  215. package/dist/http/device-placement.js +0 -145
@@ -1,10 +1,114 @@
1
+ import { type SessionLogMark, type SessionRowExpectation } from "@sema-agent/core";
1
2
  /** `title` 列的宽度(字符)= 用户标题的上界。两方言 DDL 内插它。 */
2
3
  export declare const SESSION_TITLE_MAX_CHARS = 120;
3
- /** 会话行的可写位(体闭集;两键至少一键)。会话店唯一写口 `patchSessionMeta` 的形参。`title: null` = 清回自动标题(列写 NULL)。 */
4
+ /** 会话行的可写位(体闭集;两键至少一键)。会话店唯一行格写口 `writeSessionRowCells` 的格参。`title: null` = 清回自动标题(列写 NULL)。 */
4
5
  export interface SessionRowPatch {
5
6
  readonly title?: string | null;
6
7
  readonly pinned?: boolean;
7
8
  }
9
+ /** 一行可写格的整组当前值(每格必在;没被写过的格 = 它的缺省值)。 */
10
+ export type SessionRowCells = {
11
+ readonly [K in keyof SessionRowPatch]-?: Exclude<SessionRowPatch[K], undefined>;
12
+ };
13
+ /**
14
+ * 可写格的闭集与每格缺省值 —— **一只记录**(头注「格的闭集与缺省值是一只记录」):PATCH 体闭集的键表与 {@link sessionRowTagOf} 的取格都读它;
15
+ * 映射型把它与 {@link SessionRowPatch} 双向绑住(漏一键 / 多一键 = 编译红)。
16
+ */
17
+ export declare const SESSION_ROW_CELL_DEFAULTS: SessionRowCells;
18
+ /** 行标签的形:SHA-256 的 base64url(无填充)= 43 个 `[A-Za-z0-9_-]` 字符。体读者对 `expectedRowTag` 判的就是它。 */
19
+ export declare const SESSION_ROW_TAG_SHAPE: RegExp;
20
+ /** 算一只行标签要的四样:会话 id、属主、这一位住客的化身(非空)、可写格的整组当前值。 */
21
+ export interface SessionRowTagInput {
22
+ readonly sessionId: string;
23
+ readonly owner: string | null;
24
+ readonly incarnation: string;
25
+ readonly cells: SessionRowCells;
26
+ }
27
+ /**
28
+ * 行标签 —— 唯一一只(头注「行标签」):纯函数、无进程密钥,多副本对同一行算出同一个串。格按 {@link SESSION_ROW_CELL_DEFAULTS} 的键取、
29
+ * 值等于缺省的不入、按键名升序成 `[[键, 值], …]`。化身只以这只单向摘要的形式出进程(`session-incarnation.ts` 头注)。
30
+ */
31
+ export declare function sessionRowTagOf(row: SessionRowTagInput): string;
32
+ /**
33
+ * 列表行上的 `rowTag` 键(present-iff 这一行可被条件写 = 店有行写口 ∧ 行上有化身):三只店的列表行映射都经它,化身那一格由调用方经
34
+ * `incarnationFromCell(…, "absent")` 解码好交进来(`undefined` = 行上没有令牌 ⇒ 键缺席,不铸)。
35
+ */
36
+ export declare function sessionRowTagKey(row: {
37
+ readonly sessionId: string;
38
+ readonly owner: string | null;
39
+ readonly incarnation: string | undefined;
40
+ readonly cells: SessionRowCells;
41
+ }): {
42
+ readonly rowTag?: string;
43
+ };
44
+ /** 客户端写(PATCH):行期望 + 可选的行标签(只有 PATCH 入口给)。 */
45
+ export interface ClientSessionRowWrite {
46
+ readonly writer: "client";
47
+ readonly row: SessionRowExpectation;
48
+ readonly rowTag?: string;
49
+ }
50
+ /** 行重放(2c 导入落定后的那一笔):只有行期望 —— 它是镜像行的名写者,不判镜像、不带标签。 */
51
+ export interface ReplaySessionRowWrite {
52
+ readonly writer: "replay";
53
+ readonly row: SessionRowExpectation;
54
+ }
55
+ /** 写原语的写法(写者身份闭集两员)。 */
56
+ export type SessionRowWrite = ClientSessionRowWrite | ReplaySessionRowWrite;
57
+ /**
58
+ * 写原语的结局(闭集四员):`written` / `changed` 带提交(回滚)之后另读的那一行(列表行投影,含新 `rowTag`);`mirror`(客户端写在只读镜像上)/
59
+ * `absent`(行期望不中 / 没有行 / 委派分区行 / 应答行已不是判过的那一位住客)一个字节没写。
60
+ */
61
+ export type SessionRowWriteOutcome<Row> = {
62
+ readonly kind: "written";
63
+ readonly row: Row;
64
+ } | {
65
+ readonly kind: "changed";
66
+ readonly row: Row;
67
+ } | {
68
+ readonly kind: "mirror";
69
+ } | {
70
+ readonly kind: "absent";
71
+ };
72
+ /** 行重放的结局:`changed` / `mirror` 对它不可达(判官对 `replay` 不判标签、不判镜像)。 */
73
+ export type ReplaySessionRowWriteOutcome<Row> = Extract<SessionRowWriteOutcome<Row>, {
74
+ readonly kind: "written" | "absent";
75
+ }>;
76
+ /** 写原语在锁下读到的那一行 —— 三店各自读成这一形,交同一只判官 {@link judgeSessionRowWrite}。 */
77
+ export interface LockedSessionRow {
78
+ readonly owner: string | null;
79
+ /** 化身那一格(`incarnationFromCell(…, "absent")` 解码:空 / 非串 ⇒ `undefined` = 住客未知,与 core 同读)。 */
80
+ readonly incarnation: string | undefined;
81
+ /** 委派分区行(SQL `placement_kind` 非空;local 没有)—— 不在列表面上,不写。 */
82
+ readonly placed: boolean;
83
+ /** 执行格是 `mirror`(写者在别处,本处只读)。 */
84
+ readonly mirror: boolean;
85
+ readonly cells: SessionRowCells;
86
+ }
87
+ /** 判官的四答(`write` = 可以写;其余三答 = 一个字节不写)。 */
88
+ export type SessionRowVerdict = "write" | "changed" | "mirror" | "absent";
89
+ /**
90
+ * 写原语的**唯一判官**(头注「写原语」):三店在各自的锁下读出那一行、交这一只,判序因此逐字同形 ——
91
+ * ① **行期望**:core 的 `sessionRowMatches(how.row, 锁住的行, logNow)`;不中、没有行(`undefined`)、委派分区行 ⇒ `absent`;
92
+ * ② **写者身份**:`client` ∧ 执行格为 `mirror` ⇒ `mirror`(镜像在本处只读;`replay` 是镜像的名写者,照写);
93
+ * ③ **标签**:`client` 带 `rowTag` ∧ 锁住的行算出的标签({@link sessionRowTagOf})≠ 它 ⇒ `changed`(行上没有化身 ⇒ 算不出标签 ⇒ 任何标签都不中);
94
+ * ④ `write`。
95
+ * 没有「已生效 ⇒ 写」的豁免:标签不中一律 `changed` —— 整体摘要分不出「住客换了」还是「格变了」,豁免会让恰好已有目标值的新住客拿到写。
96
+ * `logNow` 只在行期望带 `log` 时被调(调用方在同一把锁下先读好那只 mark)。
97
+ */
98
+ export declare function judgeSessionRowWrite(sessionId: string, how: SessionRowWrite, locked: LockedSessionRow | undefined, logNow: () => SessionLogMark): SessionRowVerdict;
99
+ /** 应答行:提交 / 回滚之后另读的那一行 + 读到它时行上的住客(属主 + 化身那一格)。 */
100
+ export interface SessionRowAnswer<Row> {
101
+ readonly row: Row;
102
+ readonly occupant: {
103
+ readonly owner: string | null;
104
+ readonly incarnation: string | undefined;
105
+ };
106
+ }
107
+ /**
108
+ * 判官答 `write` / `changed` 之后的结局 —— 三店同一只:应答行(提交 / 回滚之后另读)仍是判过的那一位住客(同一只 core 判官 `sessionRowMatches`,只比行期望的住客半,
109
+ * 不比日志 mark —— 那一维判的是写之前)⇒ `written` / `changed` 带它;读不到、或已换了住客 / 属主 ⇒ `absent`(不把另一位住客的行答给这位调用方)。
110
+ */
111
+ export declare function settleSessionRowWrite<Row>(how: SessionRowWrite, verdict: "write" | "changed", answer: SessionRowAnswer<Row> | undefined): SessionRowWriteOutcome<Row>;
8
112
  /** 一条已分类的拒:码 + 不回显输入的句子。 */
9
113
  export interface SessionRowProblem {
10
114
  readonly code: "request.body_shape" | "request.field_invalid";
@@ -27,13 +131,18 @@ export declare function readSessionPinned(v: unknown): {
27
131
  } | {
28
132
  readonly problem: SessionRowProblem;
29
133
  };
134
+ /** PATCH 体读出来的东西:要写的格 + 可选的前置条件(客户端读到的行标签)。 */
135
+ export interface SessionRowPatchRequest {
136
+ readonly patch: SessionRowPatch;
137
+ /** 在场 = 「这一行仍是我读到的那一份才写」(写原语在锁住的那一行上比 {@link sessionRowTagOf});缺席 = 无条件写。 */
138
+ readonly expectedRowTag?: string;
139
+ }
30
140
  /**
31
- * `PATCH /v1/sessions/:id` 体的**唯一**读者。形不对(非对象 / 空 / 表外键)⇒ `request.body_shape`;两键各走自己那一格的读者。
141
+ * `PATCH /v1/sessions/:id` 体的**唯一**读者。形不对(非对象 / 表外键 / 一格可写位都没有 —— 只带 `expectedRowTag` 也算)⇒ `request.body_shape`;
142
+ * 各格走自己那一格的读者;`expectedRowTag` 不是 {@link SESSION_ROW_TAG_SHAPE} ⇒ `request.field_invalid`。先形后值,值的判序:`title` → `pinned` → `expectedRowTag`。
32
143
  * 拒句不回显调用方的键名或值。
33
144
  */
34
- export declare function readSessionRowPatch(body: unknown): {
35
- readonly patch: SessionRowPatch;
36
- } | {
145
+ export declare function readSessionRowPatch(body: unknown): SessionRowPatchRequest | {
37
146
  readonly problem: SessionRowProblem;
38
147
  };
39
148
  //# sourceMappingURL=session-row.d.ts.map
@@ -1,7 +1,50 @@
1
- import { normalizePeerName } from "@sema-agent/core";
1
+ import { createHash } from "node:crypto";
2
+ import { normalizePeerName, sessionRowMatches } from "@sema-agent/core";
2
3
  export const SESSION_TITLE_MAX_CHARS = 120;
3
- const SESSION_ROW_PATCH_KEYS = { title: true, pinned: true };
4
- const BODY_SHAPE_MESSAGE = "the body must be a JSON object carrying at least one of `title` and `pinned`, and nothing else";
4
+ export const SESSION_ROW_CELL_DEFAULTS = { title: null, pinned: false };
5
+ const SESSION_ROW_TAG_DOMAIN = "sema.session-row-tag/1";
6
+ export const SESSION_ROW_TAG_SHAPE = /^[A-Za-z0-9_-]{43}$/;
7
+ export function sessionRowTagOf(row) {
8
+ const keys = Object.keys(SESSION_ROW_CELL_DEFAULTS).sort();
9
+ const cells = keys.filter((k) => row.cells[k] !== SESSION_ROW_CELL_DEFAULTS[k]).map((k) => [k, row.cells[k]]);
10
+ return createHash("sha256").update(JSON.stringify([SESSION_ROW_TAG_DOMAIN, row.sessionId, row.owner, row.incarnation, cells]), "utf8").digest("base64url");
11
+ }
12
+ export function sessionRowTagKey(row) {
13
+ return row.incarnation === undefined ? {} : { rowTag: sessionRowTagOf({ sessionId: row.sessionId, owner: row.owner, incarnation: row.incarnation, cells: row.cells }) };
14
+ }
15
+ export function judgeSessionRowWrite(sessionId, how, locked, logNow) {
16
+ if (locked === undefined || !sessionRowMatches(how.row, { owner: locked.owner, incarnation: locked.incarnation }, logNow) || locked.placed)
17
+ return "absent";
18
+ switch (how.writer) {
19
+ case "replay":
20
+ return "write";
21
+ case "client": {
22
+ if (locked.mirror)
23
+ return "mirror";
24
+ if (how.rowTag === undefined)
25
+ return "write";
26
+ const current = locked.incarnation === undefined ? undefined : sessionRowTagOf({ sessionId, owner: locked.owner, incarnation: locked.incarnation, cells: locked.cells });
27
+ return current === how.rowTag ? "write" : "changed";
28
+ }
29
+ default: {
30
+ const unknownWriter = how;
31
+ throw new Error(`judgeSessionRowWrite: no writer ${JSON.stringify(unknownWriter)}`);
32
+ }
33
+ }
34
+ }
35
+ export function settleSessionRowWrite(how, verdict, answer) {
36
+ const judged = how.row.row;
37
+ if (judged === null || answer === undefined)
38
+ return { kind: "absent" };
39
+ if (!sessionRowMatches({ row: judged }, answer.occupant, unreachableLogMark))
40
+ return { kind: "absent" };
41
+ return verdict === "write" ? { kind: "written", row: answer.row } : { kind: "changed", row: answer.row };
42
+ }
43
+ function unreachableLogMark() {
44
+ throw new Error("settleSessionRowWrite: the answer row's occupant check carries no log mark, yet the judge asked for one");
45
+ }
46
+ const BODY_SHAPE_MESSAGE = "the body must be a JSON object carrying at least one of `title` and `pinned` (and, optionally, `expectedRowTag`), and nothing else";
47
+ const ROW_TAG_INVALID_MESSAGE = "expectedRowTag must be the `rowTag` string a session list row carries (43 characters: letters, digits, `-` and `_`)";
5
48
  const EMPTY_TITLE_MESSAGE = "title must not be the empty string — send `null` to clear it back to the automatic title";
6
49
  const INVISIBLE_TITLE_MESSAGE = "title must contain at least one visible character";
7
50
  const C0_CONTROL = /[\u0000-\u001f]/u;
@@ -25,11 +68,13 @@ export function readSessionTitle(v) {
25
68
  export function readSessionPinned(v) {
26
69
  return typeof v === "boolean" ? { pinned: v } : { problem: { code: "request.field_invalid", message: "pinned must be a boolean" } };
27
70
  }
71
+ const EXPECTED_ROW_TAG_KEY = "expectedRowTag";
28
72
  export function readSessionRowPatch(body) {
29
73
  if (body === null || typeof body !== "object" || Array.isArray(body))
30
74
  return { problem: { code: "request.body_shape", message: BODY_SHAPE_MESSAGE } };
31
75
  const keys = Object.keys(body);
32
- if (keys.length === 0 || keys.some((k) => !Object.hasOwn(SESSION_ROW_PATCH_KEYS, k))) {
76
+ const isCell = (k) => Object.hasOwn(SESSION_ROW_CELL_DEFAULTS, k);
77
+ if (!keys.some(isCell) || keys.some((k) => !isCell(k) && k !== EXPECTED_ROW_TAG_KEY)) {
33
78
  return { problem: { code: "request.body_shape", message: BODY_SHAPE_MESSAGE } };
34
79
  }
35
80
  const b = body;
@@ -46,6 +91,11 @@ export function readSessionRowPatch(body) {
46
91
  return read;
47
92
  patch = { ...patch, pinned: read.pinned };
48
93
  }
49
- return { patch };
94
+ if (!(EXPECTED_ROW_TAG_KEY in b))
95
+ return { patch };
96
+ const tag = b.expectedRowTag;
97
+ if (typeof tag !== "string" || !SESSION_ROW_TAG_SHAPE.test(tag))
98
+ return { problem: { code: "request.field_invalid", message: ROW_TAG_INVALID_MESSAGE } };
99
+ return { patch, expectedRowTag: tag };
50
100
  }
51
101
  //# sourceMappingURL=session-row.js.map
@@ -5,8 +5,8 @@
5
5
  * submission's acceptance seat (`run-acceptance.ts`: the objective entered the conversation, or a result-only verify /
6
6
  * cascade leg came back having done work). A run the engine refuses before acceptance never reaches the titler (no
7
7
  * model call for a refused input). No need to wait for the run to finish, and the web Recents gets the title sooner. Fills a NULL title only (`setTitleIfNull`,
8
- * store-side `WHERE title IS NULL`) — the user writes the SAME column unconditionally (`PATCH /v1/sessions/:id` →
9
- * `patchSessionMeta`): a user-set title is never overwritten (the probe below reads "titled" and skips the model
8
+ * store-side `WHERE title IS NULL`) — the user writes the SAME column (`PATCH /v1/sessions/:id` → the session row's write
9
+ * primitive `writeSessionRowCells`, unconditional unless the request carries `expectedRowTag`): a user-set title is never overwritten (the probe below reads "titled" and skips the model
10
10
  * call), and a title the user cleared (`title: null` ⇒ NULL) is filled again at the next submit (law: `session-row.ts`).
11
11
  * "Has it a title?" is read from the column on every submit (one point read) — the process keeps NO "already titled"
12
12
  * memo, because such a memo would be a second answer to that question that a clear turns stale. Generation = one
@@ -57,7 +57,7 @@ export declare const A2A_PEER_DISPOSITION: {
57
57
  readonly toolAxes: "engine";
58
58
  };
59
59
  /** 请求体 `a2aPeers[i]` 的键闭集 = 处置表的键(书写序即判序)。 */
60
- export declare const A2A_PEER_ENTRY_KEYS: readonly ("name" | "toolAxes" | "url" | "principalHeader" | "cardUrl" | "allowSkills" | "headers")[];
60
+ export declare const A2A_PEER_ENTRY_KEYS: readonly ("name" | "headers" | "principalHeader" | "toolAxes" | "url" | "cardUrl" | "allowSkills")[];
61
61
  /**
62
62
  * **请求入口的一次读**(`boot/resolve-spec.ts` 在腿首铸一份,受理门与读器——续跑重放腿只有读器——都吃这一份):`body.a2aPeers` 若是数组,返回同形数组
63
63
  * (每个对象条目换成它的 {@link PeerSnapshot};非对象条目原样;长度保真 —— 界外的条数仍是受理门撞帽拒与读器丢弃留声的依据,只快照界内的条目);不是数组(缺席 / `null` / 别的形)原样返回。
@@ -87,8 +87,13 @@ export declare function parseAdditionalDirectories(raw: unknown): string[] | und
87
87
  * per-session choice always wins;
88
88
  * 2. the TRUSTED `ctx.parentCwd` (core threads the PARENT task's working root via `RunInternals` when this
89
89
  * task is a delegated child — never a TaskSpec field), UNLESS the child asked for `isolation:"worktree"`
90
- * (core contract: worktree wins — an isolated fan-out child must not share the parent's mutable dir);
90
+ * (an isolated fan-out child must not share the parent's mutable dir) — then `undefined`;
91
91
  * 3. undefined → the factory's ephemeral per-task dir (top-level task with no registered cwd).
92
+ * The `isolation:"worktree"` ⇒ `undefined` rule is this function's own and holds by itself (the child never inherits the
93
+ * parent's dir). It is NOT what answers a worktree ask on the host lane: `boot/execution-env.ts` never reaches here with one —
94
+ * the worktree wrapper (one layer out) mints the tree and does not call the base factory, and without the wrapper the base
95
+ * factory REFUSES (`isolation.unavailable`) instead of minting the empty ephemeral dir rule 3 would give. That refusal arm is
96
+ * revoked when engine 7.61.0 refuses by itself; this function's rule then goes on keeping the child off the parent's dir.
92
97
  * CC parity: a Task sub-agent inherits the main session's cwd. Trust: `parentCwd` comes from core's trusted
93
98
  * run-internals channel (same posture as `isolation`), so no tenancy gate is needed here — but the HOST lane
94
99
  * itself is single-user by deployment shape, and container lanes (k8s/e2b/local-docker) never consult this.
@@ -69,9 +69,9 @@ export declare const MAX_REQUEST_MCP_DROP_NAMES = 32;
69
69
  */
70
70
  export declare const MCP_SERVER_ENTRY_KEYS: readonly ["allowTools", "contentOrigin", "elicitation", "name", "sessionMetaKey", "source", "startupTimeoutMs", "toolAxes", "toolFaces", "transport"];
71
71
  /** `transport.kind:"stdio"` 的键闭集 = stdio 臂处置表的键(`env` 是件,其余进声明)。 */
72
- export declare const STDIO_MCP_TRANSPORT_KEYS: readonly ("kind" | "command" | "args" | "env")[];
72
+ export declare const STDIO_MCP_TRANSPORT_KEYS: readonly ("env" | "kind" | "args" | "command")[];
73
73
  /** `transport.kind:"http"` 的键闭集 = http 臂处置表的键(`headers` 是件,`assertionHeader` 承载不发送,其余进声明)。 */
74
- export declare const HTTP_MCP_TRANSPORT_KEYS: readonly ("kind" | "url" | "principalHeader" | "headers" | "assertionHeader")[];
74
+ export declare const HTTP_MCP_TRANSPORT_KEYS: readonly ("headers" | "kind" | "principalHeader" | "url" | "assertionHeader")[];
75
75
  /**
76
76
  * Does THIS deployment honor caller-supplied per-request MCP servers? TRUE for a SINGLE-USER deployment
77
77
  * (deployment-shape row `multiTenant` does not hold) — the requester is the super-admin of their own worker, so their `.mcp.json` is
@@ -188,7 +188,7 @@ export declare function assertRequestMcpEntries(bodyMcp: unknown): void;
188
188
  /**
189
189
  * `principalHeader` 的**名**有没有别的属主:判官是引擎包根的 `headerOwnershipCollision`(拨号时判同一条的那一只;这里只问身份头这一个名,件头名由引擎在发送时判)——
190
190
  * 名(任何大小写)是这一协议的传输自己写的头(MCP:`mcp-session-id` · `mcp-protocol-version` · `content-type` · `accept` · `last-event-id`;A2A 没有),或是引擎的断言头
191
- * (`connector-assertion`)⇒ 这一台拨号时必被拒,新提交在门上按名拒。原因句只点名**属主的拼写**(引擎 / 协议的词),不回显调用方写的串。
191
+ * (`connector-assertion`)⇒ 这一台拨号时必被拒,新提交在门上按名拒。原因句只点名**属主的拼写**(引擎固定表里的规范化小写头名),不回显调用方写的原串 / 大小写形(调用方写的恰是小写时,句里的名与所写相同)。
192
192
  * 新提交腿上按名 400(MCP 门表的 `transport`、A2A 判官表的 `principalHeader`)。续跑重放腿不 4xx:MCP 的读器不问它 —— 存量体里这一形照挂,由引擎在拨号时拒那一台、兄弟照挂;
193
193
  * A2A 的读器问同一张判官表 —— 这一条对端整条不进、`a2a_injection_dropped` 点名原因(引擎物化时同样拒那一台;结局同,原因说在本仓这一行)。
194
194
  */
@@ -1,3 +1,4 @@
1
+ import type { ExecutionLane } from "./execution-lane-caps.js";
1
2
  import { type ApprovalDecidedBy, type HostSettledBy, type RetiredDecisionKeyFacts } from "./host-decision.js";
2
3
  import type { IncomingMessage } from "node:http";
3
4
  import { type AskClass, type AskRequest, type AskOutcome, type PermissionResult, type CheckpointGate, type PendingAction, type PersistedRuleMandate, type ReadRootGrantCandidate, type RuleOffer, type AutoModeFallbackCause, type BoundGrantAbsence, type BoundSkillGrants, type ToolApprovalCard, type ReopenReason } from "@sema-agent/core";
@@ -872,6 +873,8 @@ interface ToolApprovalRunContextBase {
872
873
  taskId: string;
873
874
  sessionId?: string;
874
875
  owner: string | null;
876
+ /** 这条腿的执行车道 —— 装配点写所在边界执行上下文的 `ctx.lane`(`http/execution-context.ts`)。出处带车道:这只席造的问在铸行时记下它。 */
877
+ executionLane: ExecutionLane;
875
878
  abortSignal?: AbortSignal;
876
879
  /** [ref]([ref] §3.1 askId 派生的腿轴;车3 刀 3a 换轴:原 `leg?: number` → `legKey?: string`)。
877
880
  * = `sha256(resume checkpoint token)` 的 hex,**首腿缺席折空串**(空串是首腿的真值,不是「未知」)。
@@ -1770,6 +1773,7 @@ export declare class ToolApprovalCoordinator {
1770
1773
  owner: string | null;
1771
1774
  taskId: string;
1772
1775
  sessionId?: string;
1776
+ executionLane: ExecutionLane;
1773
1777
  }, why: LegUnattended) => ((req: AskRequest) => Promise<AskOutcome>);
1774
1778
  /**
1775
1779
  * 🔴 session grant 短路前的**持久出处复核**([ref] 的 codex R1-[high] 补丁;[ref] 换判据;[ref] / SN-C1 换读口)。
@@ -1968,6 +1972,8 @@ export declare class ToolApprovalCoordinator {
1968
1972
  /** [ref] 车3 刀 3b(§7.3):本腿的 walltime deadline —— 与 `legKey` 同源同理由,随**出处**走
1969
1973
  * (子代经继承链拿到的是宿主腿的闭包,窗必须按宿主腿的剩余 walltime 算)。 */
1970
1974
  legDeadlineMonotonic?: number;
1975
+ /** 宿主腿的执行车道(装配点写执行上下文的 `ctx.lane`);子代经继承链冻同一闭包 ⇒ 子代的问记宿主腿的车道。 */
1976
+ executionLane: ExecutionLane;
1971
1977
  }) => ((req: AskRequest, signal?: AbortSignal) => Promise<AskOutcome>);
1972
1978
  /** 广播版裁决路径——`ask()`(ALS,恒单元素数组)与 `boundAsk`([ref]四多活集合,可能多元素)共用。
1973
1979
  * 全体 `ctxs` 保证同一 (owner, sessionId)(streamKey 分组不变式;单元素数组平凡成立)。
@@ -1015,7 +1015,7 @@ export class ToolApprovalCoordinator {
1015
1015
  }
1016
1016
  boundUnattendedAsk = (identity, why) => {
1017
1017
  return async (req) => {
1018
- const origin = { owner: identity.owner, taskId: identity.taskId, ...(identity.sessionId !== undefined ? { sessionId: identity.sessionId } : {}), legKey: "" };
1018
+ const origin = { owner: identity.owner, taskId: identity.taskId, ...(identity.sessionId !== undefined ? { sessionId: identity.sessionId } : {}), legKey: "", executionLane: identity.executionLane };
1019
1019
  if (await this.standingGrantSettles(origin, req, this.governanceForcedOf(origin, req)))
1020
1020
  return true;
1021
1021
  return this.unattendedAskOutcome({ ...why, taskId: identity.taskId, owner: identity.owner, toolName: req.toolName });
@@ -1267,6 +1267,7 @@ export class ToolApprovalCoordinator {
1267
1267
  owner: ctx.owner,
1268
1268
  ...(ctx.sessionId !== undefined ? { sessionId: ctx.sessionId } : {}),
1269
1269
  legKey: ctx.legKey ?? "",
1270
+ executionLane: ctx.executionLane,
1270
1271
  ...(ctx.legDeadlineMonotonic !== undefined ? { legDeadlineMonotonic: ctx.legDeadlineMonotonic } : {}),
1271
1272
  }, [ctx], req, signal);
1272
1273
  };
@@ -1279,6 +1280,7 @@ export class ToolApprovalCoordinator {
1279
1280
  owner: identity.owner,
1280
1281
  ...(identity.sessionId !== undefined ? { sessionId: identity.sessionId } : {}),
1281
1282
  legKey: identity.legKey ?? "",
1283
+ executionLane: identity.executionLane,
1282
1284
  ...(identity.legDeadlineMonotonic !== undefined ? { legDeadlineMonotonic: identity.legDeadlineMonotonic } : {}),
1283
1285
  }, live, req, signal);
1284
1286
  };
@@ -1383,6 +1385,7 @@ export class ToolApprovalCoordinator {
1383
1385
  const card = this.askStore ? buildApprovalCard(frame, req, req.requiresRealApproval === true) : undefined;
1384
1386
  let cardForFrame = card;
1385
1387
  let persistedExpiresAtMs = expiresAtMs;
1388
+ let entryExecutionLane = origin.executionLane;
1386
1389
  let lateEnsuredRow;
1387
1390
  let lateTerminalRow;
1388
1391
  let abandonedAs;
@@ -1422,6 +1425,7 @@ export class ToolApprovalCoordinator {
1422
1425
  sourceTaskId,
1423
1426
  sessionId: origin.sessionId ?? origin.taskId,
1424
1427
  owner: origin.owner,
1428
+ executionLane: origin.executionLane,
1425
1429
  batchId,
1426
1430
  toolCallId: req.toolCallId,
1427
1431
  legKey,
@@ -1458,6 +1462,7 @@ export class ToolApprovalCoordinator {
1458
1462
  return existingOrCreated.inserted ? this.landUnattendedOutcome(unattended, existingOrCreated.row) : unattended;
1459
1463
  }
1460
1464
  persistedExpiresAtMs = existingOrCreated.row.expiresAtMs;
1465
+ entryExecutionLane = existingOrCreated.row.executionLane;
1461
1466
  cardForFrame = persistedEnvelope.card;
1462
1467
  if (cardForFrame.governanceForced === true)
1463
1468
  frame.governanceForced = true;
@@ -1936,6 +1941,7 @@ export class ToolApprovalCoordinator {
1936
1941
  ...(entryDeploymentListQuestion ? { deploymentListQuestion: true } : {}),
1937
1942
  registeredAtMs: Date.now(),
1938
1943
  expiresAtMs: persistedExpiresAtMs,
1944
+ executionLane: entryExecutionLane,
1939
1945
  ...(ruleLaneMaterial !== undefined ? { ruleLane: ruleLaneMaterial } : {}),
1940
1946
  ...(effectiveGovernanceForced ? { governanceForced: true } : {}),
1941
1947
  ...(req.requiresRealApproval === true ? { requiresRealApproval: true } : {}),
@@ -2899,6 +2905,7 @@ export class ToolApprovalCoordinator {
2899
2905
  forceParkNow: release,
2900
2906
  settleParkRoute: (cause) => leave({ outcome: SETTLE_OUTCOME.EXPIRED, cause, parked: this.unattendedRoutesToPark }),
2901
2907
  owner: row.owner,
2908
+ executionLane: row.executionLane,
2902
2909
  ...(row.sessionId !== row.taskId ? { sessionId: row.sessionId } : {}),
2903
2910
  ...(card.fromSubagent === true ? { originTaskId: row.sourceTaskId } : {}),
2904
2911
  toolName: card.toolName,
@@ -1016,6 +1016,7 @@ export declare function brainStatusEventData(ev: {
1016
1016
  providerConditionSource?: string;
1017
1017
  waitSegment?: string;
1018
1018
  sleptMs?: number;
1019
+ seat?: string;
1019
1020
  eventId?: string;
1020
1021
  parentToolCallId?: string;
1021
1022
  }): FrameData<{
@@ -822,6 +822,7 @@ export function brainStatusEventData(ev) {
822
822
  ...(num(ev.timeoutMs) ? { timeoutMs: ev.timeoutMs } : {}),
823
823
  ...(typeof ev.waitSegment === "string" && ev.waitSegment.length > 0 ? { waitSegment: ev.waitSegment } : {}),
824
824
  ...(num(ev.sleptMs) ? { sleptMs: ev.sleptMs } : {}),
825
+ ...(typeof ev.seat === "string" && ev.seat.length > 0 ? { seat: ev.seat } : {}),
825
826
  ...(num(ev.errorStatus) ? { errorStatus: ev.errorStatus } : {}),
826
827
  ...(typeof ev.errClass === "string" && ev.errClass.length > 0 ? { errClass: ev.errClass } : {}),
827
828
  ...(typeof ev.providerCondition === "string" && ev.providerCondition.length > 0 ? { providerCondition: ev.providerCondition } : {}),
@@ -649,6 +649,26 @@ export declare const SELF_MINTED_WIRE: {
649
649
  };
650
650
  };
651
651
  };
652
+ /** `GET /v1/sessions/:id/background` 的 `rows[]` 上本版新出现的键:`sessionId` —— 后台 agent 行的子会话 id(引擎绑定之后才在,别的行型恒缺席;只是 id,不授读权)。 */
653
+ readonly sessionBackgroundRowKey: {
654
+ readonly at: "GET /v1/sessions/:id/background rows[] 行键(<键> → 在场律)";
655
+ readonly members: {
656
+ sessionId: {
657
+ attr: string;
658
+ since: string;
659
+ };
660
+ };
661
+ };
662
+ /** 会话列表行(`GET /v1/sessions` 的 `sessions[]`;同一只投影 = `PATCH /v1/sessions/:id` 的 200 体与 409 `conflict.session_row_changed` 的 `currentRow`)上本版新出现的键:`rowTag` —— 行标签(条件写的前置条件值;读时派生、零存储)。 */
663
+ readonly sessionsListRowKey: {
664
+ readonly at: "GET /v1/sessions sessions[] 行键 = PATCH /v1/sessions/:id 200 体 = 409 conflict.session_row_changed currentRow(<键> → 在场律)";
665
+ readonly members: {
666
+ rowTag: {
667
+ attr: string;
668
+ since: string;
669
+ };
670
+ };
671
+ };
652
672
  /** `tool_end` 帧 `gate.disposition`(denied 臂)上的键(<臂>#<键> → 在场律;回放面 `GET /v1/runs/:id/events` 同读):`extension` —— hook 层拒且拒者的扩展注册名已知时 = 那张注册的名字(过出口座)。 */
653
673
  readonly toolEndGateDispositionKey: {
654
674
  readonly at: "tool_end gate.disposition 键(<臂>#<键> → 在场律)";
@@ -765,6 +785,10 @@ export declare const SELF_MINTED_WIRE: {
765
785
  attr: string;
766
786
  since: string;
767
787
  };
788
+ fork_target: {
789
+ attr: string;
790
+ since: string;
791
+ };
768
792
  scratchpad_root: {
769
793
  attr: string;
770
794
  since: string;
@@ -1242,6 +1266,30 @@ export declare const SELF_MINTED_WIRE: {
1242
1266
  readonly attr: 200;
1243
1267
  readonly since: "7.137.0";
1244
1268
  };
1269
+ readonly "POST /v1/tasks|/v1/tasks/stream|/v1/runs#rewindFiles(\u65B0\u63D0\u4EA4;\u4F53 request.body_shape + unknownKeys [rewindFiles])": {
1270
+ readonly attr: 400;
1271
+ readonly since: "7.139.0";
1272
+ };
1273
+ readonly "POST /v1/side-query#uncoded_error_with_preflight_prefix(\u6CA1\u6709\u5F15\u64CE\u7801\u3001\u82F1\u6587\u5F00\u5934\u4E0E\u524D\u7F00\u8868\u540C\u5F62\u7684\u9519\u8BEF;\u4F53 internal.error)": {
1274
+ readonly attr: 500;
1275
+ readonly since: "7.139.0";
1276
+ };
1277
+ readonly "PATCH /v1/sessions/:id#mirror_row(\u53EA\u8BFB\u955C\u50CF\u884C\u4E0A\u7684\u5199,\u5E26\u4E0D\u5E26 expectedRowTag;\u4F53 conflict.session_mirror + forkPath)": {
1278
+ readonly attr: 409;
1279
+ readonly since: "7.139.0";
1280
+ };
1281
+ readonly "PATCH /v1/sessions/:id#owner_changed_after_gate(\u95E8\u90A3\u4E00\u8BFB\u4E4B\u540E\u540C\u4E00\u4F1A\u8BDD\u7684\u5C5E\u4E3B\u88AB\u6539;\u4F53 not_found.session)": {
1282
+ readonly attr: 404;
1283
+ readonly since: "7.139.0";
1284
+ };
1285
+ readonly "PATCH /v1/sessions/:id#expectedRowTag_stale(\u884C\u5DF2\u4E0D\u5728\u90A3\u53EA\u6807\u7B7E\u4E0A;\u4F53 conflict.session_row_changed + currentRow)": {
1286
+ readonly attr: 409;
1287
+ readonly since: "7.139.0";
1288
+ };
1289
+ readonly "PATCH /v1/sessions/:id#expectedRowTag_current(\u884C\u4ECD\u5728\u90A3\u53EA\u6807\u7B7E\u4E0A;\u4F53 = \u5217\u8868\u884C)": {
1290
+ readonly attr: 200;
1291
+ readonly since: "7.139.0";
1292
+ };
1245
1293
  };
1246
1294
  };
1247
1295
  /**
@@ -1351,6 +1399,22 @@ export declare const SELF_MINTED_WIRE: {
1351
1399
  readonly attr: "unsupported (a body field of POST /v1/assistant/tasks/:id/plan_review — send it there, this door never reads it): checkpointId";
1352
1400
  readonly since: "7.137.0";
1353
1401
  };
1402
+ readonly "400 request.body_shape#PATCH /v1/sessions/:id": {
1403
+ readonly attr: "the body must be a JSON object carrying at least one of `title` and `pinned` (and, optionally, `expectedRowTag`), and nothing else";
1404
+ readonly since: "7.139.0";
1405
+ };
1406
+ readonly "400 request.field_invalid#PATCH /v1/sessions/:id.expectedRowTag": {
1407
+ readonly attr: "expectedRowTag must be the `rowTag` string a session list row carries (43 characters: letters, digits, `-` and `_`)";
1408
+ readonly since: "7.139.0";
1409
+ };
1410
+ readonly "409 conflict.session_mirror#PATCH /v1/sessions/:id": {
1411
+ readonly attr: "this session is a read-only mirror of a session whose writer is elsewhere — it cannot be renamed or pinned here; fork it (forkPath) to continue here; nothing was written";
1412
+ readonly since: "7.139.0";
1413
+ };
1414
+ readonly "409 conflict.session_row_changed#PATCH /v1/sessions/:id": {
1415
+ readonly attr: "the session row changed since the rowTag you sent was read — nothing was written; currentRow is the row as it stands now: decide again, then send its rowTag";
1416
+ readonly since: "7.139.0";
1417
+ };
1354
1418
  };
1355
1419
  };
1356
1420
  /**
@@ -1366,6 +1430,27 @@ export declare const SELF_MINTED_WIRE: {
1366
1430
  };
1367
1431
  };
1368
1432
  };
1433
+ /**
1434
+ * 会话行写口 `PATCH /v1/sessions/:id`:体受理键里本版新增的一键与它两只 409 拒体上的键(`<面>#<键>` → 读法 / 在场律)。受理闭集属主 = `session-row.ts` 的体读者 `readSessionRowPatch`;
1435
+ * `conflict.session_mirror#forkPath` 是执行面同码同键,本版新出现的面是 PATCH。
1436
+ */
1437
+ readonly sessionRowWriteKey: {
1438
+ readonly at: "PATCH /v1/sessions/:id 体受理键与 409 拒体键(<面>#<键> → 读法 / 在场律;只登本版新增的)";
1439
+ readonly members: {
1440
+ readonly "body#expectedRowTag": {
1441
+ readonly attr: "optional;43×[A-Za-z0-9_-] else 400 request.field_invalid;alone 400 request.body_shape;stale⇒409 conflict.session_row_changed";
1442
+ readonly since: "7.139.0";
1443
+ };
1444
+ readonly "409 conflict.session_row_changed#currentRow": {
1445
+ readonly attr: "always";
1446
+ readonly since: "7.139.0";
1447
+ };
1448
+ readonly "409 conflict.session_mirror#forkPath": {
1449
+ readonly attr: "always";
1450
+ readonly since: "7.139.0";
1451
+ };
1452
+ };
1453
+ };
1369
1454
  /**
1370
1455
  * `409 approval_stale` 拒体上的键,按出现面登记(`<端点>#<键>` → 在场律)。`currentPending` 的值形是每道门一形(`wire-types.ts` 的 `ApprovalStaleCurrentPending`:
1371
1456
  * 这道门的决断体回显的那几位);本表只登本版新出现的面(`/decide` 那一形早于本表,不在这里)。
@@ -1625,8 +1710,32 @@ export declare const SELF_MINTED_WIRE: {
1625
1710
  readonly since: "7.136.0";
1626
1711
  };
1627
1712
  readonly "GET /v1/config/catalog#rows[K8S_SANDBOX_ENV].semantics": {
1628
- readonly attr: "values-only-in-the-pod-own-secret;role-needs-secrets-create;denied-refuses-boot";
1629
- readonly since: "7.137.0";
1713
+ readonly attr: "values-only-in-the-pod-own-secret;role-needs-secrets-create;denied-refuses-boot;own-credential-name-refuses-boot";
1714
+ readonly since: "7.139.0";
1715
+ };
1716
+ readonly "GET /v1/config/catalog#rows[K8S_NAMESPACE].semantics": {
1717
+ readonly attr: "required-no-default;absent-or-blank-refuses-boot";
1718
+ readonly since: "7.139.0";
1719
+ };
1720
+ readonly "GET /v1/config/catalog#rows[E2B_SANDBOX_ENV].semantics": {
1721
+ readonly attr: "own-credential-name-refuses-boot";
1722
+ readonly since: "7.139.0";
1723
+ };
1724
+ readonly "GET /v1/config/catalog#rows[DOCKER_SANDBOX_ENV].semantics": {
1725
+ readonly attr: "own-credential-name-refuses-boot";
1726
+ readonly since: "7.139.0";
1727
+ };
1728
+ readonly "GET /v1/config/catalog#rows[CONFIG_PROVIDER].semantics": {
1729
+ readonly attr: "remote-without-center-url-refuses-boot";
1730
+ readonly since: "7.139.0";
1731
+ };
1732
+ readonly "GET /v1/config/catalog#rows[RETENTION_MODE].semantics": {
1733
+ readonly attr: "enforce-without-horizon-or-cadence-refuses-boot";
1734
+ readonly since: "7.139.0";
1735
+ };
1736
+ readonly "GET /v1/config/catalog#rows[RETENTION_SWEEP_INTERVAL_SEC].semantics": {
1737
+ readonly attr: "cadence-without-horizon-refuses-boot";
1738
+ readonly since: "7.139.0";
1630
1739
  };
1631
1740
  /**
1632
1741
  * MCP 远端失败句在面板与重拨回执上的出口读法:出口座的 `mcp-remote-text` 行(`trace/exit-seat.ts`)—— 与 trace / 通告同一个脱敏器(引擎记号 `[redacted]` = 已抹的值,原样;