@sema-agent/server 7.52.0 → 7.53.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 (328) hide show
  1. package/USAGE.md +22 -5
  2. package/dist/adoption/plan.d.ts +3 -3
  3. package/dist/adoption/quiesce.d.ts +1 -1
  4. package/dist/adoption/sql.d.ts +2 -2
  5. package/dist/adoption/wire.d.ts +1 -1
  6. package/dist/approval-ask-machine.d.ts +2 -2
  7. package/dist/approval-card.d.ts +18 -18
  8. package/dist/approval-deny-reasons.d.ts +1 -1
  9. package/dist/approval-hmac.d.ts +2 -2
  10. package/dist/approval-reconciler.d.ts +14 -14
  11. package/dist/approval.d.ts +2 -2
  12. package/dist/audit.d.ts +4 -4
  13. package/dist/auth-keys.d.ts +6 -6
  14. package/dist/bench/l8/artifact.d.ts +6 -1
  15. package/dist/bench/l8/artifact.js +2 -27
  16. package/dist/bench/l8/escape.d.ts +3 -3
  17. package/dist/bench/l8/index.d.ts +1 -1
  18. package/dist/bench/s1/arms.d.ts +3 -3
  19. package/dist/bench/s1/oracle.d.ts +2 -2
  20. package/dist/bench/s1/reviewer.d.ts +1 -1
  21. package/dist/bench/s1/row.d.ts +5 -5
  22. package/dist/bench/s1/runner-ctx.d.ts +3 -3
  23. package/dist/boot/config-center.d.ts +14 -7
  24. package/dist/boot/config-center.js +2 -0
  25. package/dist/boot/coordinators.d.ts +4 -4
  26. package/dist/boot/crash-last.d.ts +1 -1
  27. package/dist/boot/device-lane.d.ts +3 -3
  28. package/dist/boot/device-lane.js +2 -0
  29. package/dist/boot/engine-lease.d.ts +4 -4
  30. package/dist/boot/governance-seams.d.ts +5 -5
  31. package/dist/boot/leader.d.ts +5 -5
  32. package/dist/boot/limit-sync.d.ts +1 -1
  33. package/dist/boot/memory-boundary.d.ts +5 -5
  34. package/dist/boot/memory-consolidation.d.ts +8 -2
  35. package/dist/boot/memory-consolidation.js +1 -0
  36. package/dist/boot/org-memory.d.ts +5 -5
  37. package/dist/boot/parked-revive-gate.d.ts +6 -6
  38. package/dist/boot/permission-rules-audit.d.ts +2 -2
  39. package/dist/boot/reapers.d.ts +8 -8
  40. package/dist/boot/resolve-spec.d.ts +4 -4
  41. package/dist/boot/retention-lane.d.ts +1 -1
  42. package/dist/boot/runner-deps.d.ts +33 -27
  43. package/dist/boot/runner-deps.js +2 -1
  44. package/dist/boot/runtime-caps.d.ts +4 -4
  45. package/dist/boot/session-faces.d.ts +1 -1
  46. package/dist/boot/shutdown.d.ts +10 -10
  47. package/dist/boot/side-query-lane.d.ts +14 -14
  48. package/dist/boot/stores.js +5 -0
  49. package/dist/boot/task-list-lane.d.ts +3 -3
  50. package/dist/boot/webfetch-summarize-lane.d.ts +9 -9
  51. package/dist/boot/workflow-orchestration.d.ts +1 -1
  52. package/dist/bounded-session-map.d.ts +1 -1
  53. package/dist/brain.d.ts +3 -3
  54. package/dist/budget.d.ts +3 -3
  55. package/dist/canonical-json.d.ts +53 -0
  56. package/dist/canonical-json.js +48 -0
  57. package/dist/capabilities/center-prompts.d.ts +13 -13
  58. package/dist/capabilities/collab-workflows.d.ts +1 -1
  59. package/dist/capabilities/hands-lane.d.ts +4 -4
  60. package/dist/capabilities/memory-notice.d.ts +4 -4
  61. package/dist/capabilities/prompt.d.ts +2 -2
  62. package/dist/capabilities/sandbox-file-send.d.ts +2 -2
  63. package/dist/capabilities/scenarios.d.ts +16 -16
  64. package/dist/capabilities/skills.d.ts +1 -1
  65. package/dist/capabilities/team.d.ts +3 -3
  66. package/dist/capabilities/tool-defer.d.ts +6 -6
  67. package/dist/config-catalog.d.ts +139 -0
  68. package/dist/config-catalog.js +556 -0
  69. package/dist/config-center/apply-effective.d.ts +20 -7
  70. package/dist/config-center/apply-effective.js +45 -0
  71. package/dist/config-center/apply-ledger.d.ts +6 -6
  72. package/dist/config-center/facade.d.ts +3 -2
  73. package/dist/config-center/hot-keys-registry.d.ts +2 -2
  74. package/dist/config-center/http-client.d.ts +5 -5
  75. package/dist/config-center/mcp-revocation.d.ts +6 -4
  76. package/dist/config-center/mcp-revocation.js +2 -12
  77. package/dist/config-center/restart-signal.d.ts +11 -1
  78. package/dist/config-center/restart-signal.js +1 -1
  79. package/dist/config-center/skills-mcp.d.ts +2 -2
  80. package/dist/config-center/stage-limits.d.ts +3 -3
  81. package/dist/config-center/types.d.ts +23 -19
  82. package/dist/config-invariants.d.ts +1 -1
  83. package/dist/config-provider.d.ts +2 -2
  84. package/dist/config-types.d.ts +157 -134
  85. package/dist/config.d.ts +32 -24
  86. package/dist/config.js +48 -6
  87. package/dist/degenerate-instrument.d.ts +1 -1
  88. package/dist/deployment-governance.d.ts +13 -13
  89. package/dist/device-store.d.ts +2 -2
  90. package/dist/device-ws-hub.d.ts +6 -4
  91. package/dist/device-ws-hub.js +9 -3
  92. package/dist/device-ws-protocol.d.ts +3 -3
  93. package/dist/digest-form.d.ts +1 -1
  94. package/dist/elicitation.d.ts +1 -1
  95. package/dist/env-facts.d.ts +7 -7
  96. package/dist/execution-lane-caps.d.ts +5 -5
  97. package/dist/fleet/fleet-bus.d.ts +56 -53
  98. package/dist/fleet/fleet-reconciler.d.ts +2 -2
  99. package/dist/fleet/fleet-terminal-window.d.ts +1 -1
  100. package/dist/fleet/subagent-tail-bus.d.ts +3 -3
  101. package/dist/fleet-client.d.ts +3 -3
  102. package/dist/fleet-lease.d.ts +1 -1
  103. package/dist/hooks/branch-transcript.d.ts +2 -2
  104. package/dist/hooks/cc-agent-hook-prompt.d.ts +2 -2
  105. package/dist/hooks/cc-stop-prompt.d.ts +2 -2
  106. package/dist/hooks/hook-llm.d.ts +1 -1
  107. package/dist/hooks/hook-runner.d.ts +12 -5
  108. package/dist/http/active-run-conflict.d.ts +31 -33
  109. package/dist/http/active-run-conflict.js +4 -2
  110. package/dist/http/route-ctx.d.ts +23 -21
  111. package/dist/http/routes/a2a-serve.d.ts +2 -2
  112. package/dist/http/routes/admin-config-refresh.d.ts +1 -1
  113. package/dist/http/routes/admin-drain.d.ts +4 -4
  114. package/dist/http/routes/admin-memory-optout.d.ts +5 -5
  115. package/dist/http/routes/adoption.d.ts +1 -1
  116. package/dist/http/routes/agents-roster.d.ts +1 -1
  117. package/dist/http/routes/approvals-assistant.d.ts +6 -6
  118. package/dist/http/routes/approvals-assistant.js +4 -1
  119. package/dist/http/routes/capabilities.d.ts +1 -1
  120. package/dist/http/routes/capabilities.js +1 -0
  121. package/dist/http/routes/config-catalog.d.ts +28 -0
  122. package/dist/http/routes/config-catalog.js +42 -0
  123. package/dist/http/routes/diagnostics.d.ts +2 -2
  124. package/dist/http/routes/fleet.d.ts +1 -1
  125. package/dist/http/routes/images.d.ts +1 -1
  126. package/dist/http/routes/leader.d.ts +1 -1
  127. package/dist/http/routes/memory-bundle.d.ts +4 -4
  128. package/dist/http/routes/memory-bundle.js +2 -3
  129. package/dist/http/routes/memory-compliance.d.ts +7 -7
  130. package/dist/http/routes/memory-consolidation.d.ts +1 -1
  131. package/dist/http/routes/memory-origin.d.ts +9 -9
  132. package/dist/http/routes/memory-policy.d.ts +3 -3
  133. package/dist/http/routes/notify-wake.d.ts +1 -1
  134. package/dist/http/routes/observability.d.ts +1 -1
  135. package/dist/http/routes/retention-ops.d.ts +1 -1
  136. package/dist/http/routes/rules.d.ts +3 -3
  137. package/dist/http/routes/run-memory-capture.d.ts +1 -1
  138. package/dist/http/routes/runs.d.ts +3 -3
  139. package/dist/http/routes/runs.js +12 -17
  140. package/dist/http/routes/session-sync.d.ts +2 -2
  141. package/dist/http/routes/sessions-list.d.ts +1 -1
  142. package/dist/http/routes/sessions.d.ts +9 -1
  143. package/dist/http/routes/sessions.js +61 -1
  144. package/dist/http/routes/shared-memory.d.ts +1 -1
  145. package/dist/http/routes/side-query.d.ts +1 -1
  146. package/dist/http/routes/tasks.d.ts +1 -1
  147. package/dist/http/routes/trace-usage.d.ts +1 -1
  148. package/dist/http/routes/workflows.d.ts +1 -1
  149. package/dist/http/run-meta.d.ts +1 -1
  150. package/dist/http/send.d.ts +6 -6
  151. package/dist/http/server.d.ts +84 -67
  152. package/dist/http/server.js +25 -12
  153. package/dist/http/sse-lifecycle.d.ts +1 -1
  154. package/dist/http/sse-log.d.ts +6 -6
  155. package/dist/http/verify-rounds.d.ts +3 -3
  156. package/dist/http/wire-gate.d.ts +2 -2
  157. package/dist/http/wire-types.d.ts +38 -38
  158. package/dist/key-resolver.d.ts +1 -1
  159. package/dist/leader/diffout.d.ts +2 -2
  160. package/dist/leader/diffup.d.ts +1 -1
  161. package/dist/leader/endpoint.d.ts +1 -1
  162. package/dist/leader/fanout.d.ts +6 -6
  163. package/dist/leader/grader-env-factory.d.ts +1 -1
  164. package/dist/leader/leader.d.ts +12 -12
  165. package/dist/leader/merge.d.ts +3 -3
  166. package/dist/leader/planner.d.ts +5 -5
  167. package/dist/leader/repair-oracle.d.ts +1 -1
  168. package/dist/leader/wire.d.ts +9 -9
  169. package/dist/lsp/manager.d.ts +2 -2
  170. package/dist/lsp/types.d.ts +1 -1
  171. package/dist/lsp/ws-transport.d.ts +2 -2
  172. package/dist/main.js +13 -2
  173. package/dist/mcp-content-origin.d.ts +1 -1
  174. package/dist/memory-bundle-engine.d.ts +5 -3
  175. package/dist/memory-bundle-engine.js +2 -2
  176. package/dist/memory-operator-faces.d.ts +41 -11
  177. package/dist/memory-operator-faces.js +12 -0
  178. package/dist/memory-origin-fence.d.ts +20 -35
  179. package/dist/memory-origin-fence.js +41 -1
  180. package/dist/memory-posture.d.ts +6 -6
  181. package/dist/memory-scope.d.ts +7 -7
  182. package/dist/model-select.d.ts +5 -5
  183. package/dist/observability/cost-quota.d.ts +6 -6
  184. package/dist/observability/cost-taxonomy.d.ts +2 -2
  185. package/dist/observability/fail-open.d.ts +1 -5
  186. package/dist/observability/fail-open.js +0 -4
  187. package/dist/observability/metrics.d.ts +1 -1
  188. package/dist/observability/prompt-manifest.d.ts +8 -8
  189. package/dist/observability/rate-limit.d.ts +2 -2
  190. package/dist/observability/secret-env-scrub.d.ts +1 -1
  191. package/dist/observability/tool-trace.d.ts +1 -1
  192. package/dist/orchestration/hardened-vm-runner.d.ts +6 -6
  193. package/dist/orchestration/hardened-vm-worker-runner.d.ts +1 -1
  194. package/dist/orchestration/subagent-steer.d.ts +3 -3
  195. package/dist/orchestration/workflow-agent-steer.d.ts +1 -1
  196. package/dist/orchestration/workflow-completion-inbox.d.ts +6 -6
  197. package/dist/orchestration/workflow-notify-journal.d.ts +6 -6
  198. package/dist/parent-watch.d.ts +1 -1
  199. package/dist/parked-decide.d.ts +11 -11
  200. package/dist/plan-cache-probe.d.ts +1 -1
  201. package/dist/plugins/adoption-log-sql.d.ts +4 -4
  202. package/dist/plugins/approval-ask-store-memory.d.ts +1 -1
  203. package/dist/plugins/approval-ask-store-memory.js +12 -0
  204. package/dist/plugins/approval-ask-store-sql.d.ts +39 -17
  205. package/dist/plugins/approval-ask-store-sql.js +23 -6
  206. package/dist/plugins/approval-payload-fingerprint.d.ts +23 -0
  207. package/dist/plugins/approval-payload-fingerprint.js +23 -0
  208. package/dist/plugins/background-agent-store-sql.d.ts +8 -8
  209. package/dist/plugins/background-shell-support.d.ts +12 -12
  210. package/dist/plugins/blob-backend.d.ts +3 -3
  211. package/dist/plugins/breaker-state-sql.d.ts +3 -3
  212. package/dist/plugins/caching-session-store.d.ts +6 -6
  213. package/dist/plugins/checkpoint-store-sql.d.ts +162 -66
  214. package/dist/plugins/checkpoint-store-sql.js +76 -33
  215. package/dist/plugins/device-store-sql.d.ts +4 -3
  216. package/dist/plugins/e2b-orphan-reclaim.d.ts +3 -3
  217. package/dist/plugins/file-history-store-sql.d.ts +9 -8
  218. package/dist/plugins/file-run-store.d.ts +27 -27
  219. package/dist/plugins/fork-routing-session-store.d.ts +9 -9
  220. package/dist/plugins/image-bake-store-sql.d.ts +1 -1
  221. package/dist/plugins/image-index-sql.d.ts +2 -2
  222. package/dist/plugins/k8s-bg-scripts.d.ts +1 -1
  223. package/dist/plugins/k8s-exec-protocol.d.ts +1 -1
  224. package/dist/plugins/leader-run-store-sql.d.ts +1 -1
  225. package/dist/plugins/local-checkpoint-store.d.ts +26 -17
  226. package/dist/plugins/local-checkpoint-store.js +21 -11
  227. package/dist/plugins/local-session-store.d.ts +5 -5
  228. package/dist/plugins/mailbox-store-sql.d.ts +6 -6
  229. package/dist/plugins/memory-embedder-fingerprint.d.ts +2 -2
  230. package/dist/plugins/memory-engine-pg.d.ts +1 -1
  231. package/dist/plugins/memory-engine-tidb.d.ts +1 -1
  232. package/dist/plugins/memory-key-guards.d.ts +3 -3
  233. package/dist/plugins/memory-optout-grant-store-sql.d.ts +10 -10
  234. package/dist/plugins/memory-origin-law.d.ts +13 -13
  235. package/dist/plugins/memory-run-store.d.ts +12 -12
  236. package/dist/plugins/outcome-ledger-sql.d.ts +3 -3
  237. package/dist/plugins/permission-rule-store-file.d.ts +3 -3
  238. package/dist/plugins/permission-rule-store-sql.d.ts +38 -33
  239. package/dist/plugins/permission-rule-store-sql.js +7 -12
  240. package/dist/plugins/pg-cost-quota.d.ts +2 -2
  241. package/dist/plugins/pg-pool.js +5 -0
  242. package/dist/plugins/pg-query.d.ts +1 -1
  243. package/dist/plugins/pg-rate-limiter.d.ts +2 -2
  244. package/dist/plugins/pg-session-storage.d.ts +9 -9
  245. package/dist/plugins/remote-env-adb.d.ts +1 -1
  246. package/dist/plugins/remote-env-device.d.ts +2 -2
  247. package/dist/plugins/remote-env-e2b.d.ts +11 -11
  248. package/dist/plugins/remote-env-file-error.d.ts +2 -2
  249. package/dist/plugins/remote-env-host.d.ts +10 -10
  250. package/dist/plugins/remote-env-k8s.d.ts +7 -7
  251. package/dist/plugins/remote-env-local-docker.d.ts +1 -1
  252. package/dist/plugins/remote-env-ssh.d.ts +9 -9
  253. package/dist/plugins/remote-scratchpad.d.ts +1 -1
  254. package/dist/plugins/resume-anchor-store-sql.d.ts +1 -1
  255. package/dist/plugins/retention-lane-store-sql.d.ts +2 -2
  256. package/dist/plugins/retention-store-sql.d.ts +11 -11
  257. package/dist/plugins/roster-store-sql.d.ts +5 -5
  258. package/dist/plugins/run-store-sql.d.ts +12 -12
  259. package/dist/plugins/scheduler-support.d.ts +1 -1
  260. package/dist/plugins/send-user-file.d.ts +1 -1
  261. package/dist/plugins/session-capture-record-store-sql.d.ts +99 -0
  262. package/dist/plugins/session-capture-record-store-sql.js +110 -0
  263. package/dist/plugins/session-placement.d.ts +1 -1
  264. package/dist/plugins/session-policy-store-sql.d.ts +2 -2
  265. package/dist/plugins/session-store.d.ts +3 -3
  266. package/dist/plugins/shared-memory-store-sql.d.ts +5 -5
  267. package/dist/plugins/sql-driver.d.ts +7 -7
  268. package/dist/plugins/sql-errors.d.ts +2 -2
  269. package/dist/plugins/sql-escape.d.ts +1 -1
  270. package/dist/plugins/sql-row-helpers.d.ts +1 -1
  271. package/dist/plugins/store-backend.d.ts +32 -19
  272. package/dist/plugins/store-backend.js +4 -0
  273. package/dist/plugins/store-contracts.d.ts +9 -9
  274. package/dist/plugins/task-list-store-sql.d.ts +3 -3
  275. package/dist/plugins/tidb-cost-quota.d.ts +3 -3
  276. package/dist/plugins/tidb-pool.js +9 -0
  277. package/dist/plugins/tidb-rate-limiter.d.ts +2 -2
  278. package/dist/plugins/tidb-session-storage.d.ts +2 -2
  279. package/dist/plugins/tidb-session-store.d.ts +11 -11
  280. package/dist/plugins/tool-result-store-sql.d.ts +8 -8
  281. package/dist/plugins/usage-window-store-sql.d.ts +3 -3
  282. package/dist/plugins/web-search.d.ts +7 -7
  283. package/dist/plugins/workflow-journal-store-sql.d.ts +6 -6
  284. package/dist/plugins/workflow-run-store-sql.d.ts +1 -1
  285. package/dist/plugins/write-behind-counter.d.ts +6 -6
  286. package/dist/principal-jwt.d.ts +2 -2
  287. package/dist/project-memory.d.ts +1 -1
  288. package/dist/prompts-domain-validate.d.ts +8 -8
  289. package/dist/question.d.ts +3 -3
  290. package/dist/resource-suspend.d.ts +4 -4
  291. package/dist/resource-window.d.ts +3 -3
  292. package/dist/router/route-orchestration.d.ts +1 -1
  293. package/dist/rules-consent.d.ts +48 -40
  294. package/dist/run-local.d.ts +5 -5
  295. package/dist/run-local.js +28 -4
  296. package/dist/runs.d.ts +19 -19
  297. package/dist/runtime-caps-resolver.d.ts +6 -6
  298. package/dist/runtime-governance.d.ts +7 -7
  299. package/dist/security.d.ts +13 -13
  300. package/dist/session-leaf-bus.d.ts +1 -1
  301. package/dist/session-sync-content.d.ts +4 -4
  302. package/dist/session-sync-kernel.d.ts +2 -2
  303. package/dist/session-sync.d.ts +13 -13
  304. package/dist/session-titler.d.ts +1 -1
  305. package/dist/session-watch.d.ts +3 -3
  306. package/dist/shared-memory-scope-authorizer.d.ts +4 -4
  307. package/dist/sighup-idle.d.ts +1 -1
  308. package/dist/spec-fields.d.ts +20 -20
  309. package/dist/ssh-host-key.d.ts +5 -5
  310. package/dist/store-live-probe.d.ts +2 -2
  311. package/dist/task-cwd.d.ts +11 -11
  312. package/dist/task-mcp.d.ts +5 -5
  313. package/dist/task-settings.d.ts +35 -35
  314. package/dist/task-workflow.d.ts +3 -3
  315. package/dist/text-bidi.d.ts +1 -1
  316. package/dist/tool-approval.d.ts +171 -160
  317. package/dist/tool-approval.js +33 -28
  318. package/dist/trace/core-keyset-guard.d.ts +21 -7
  319. package/dist/trace/engine-notice-wire.d.ts +6 -6
  320. package/dist/trace/injection-tier.d.ts +2 -2
  321. package/dist/trace/ledger-events.d.ts +3 -3
  322. package/dist/trace/ledger-sink.d.ts +7 -7
  323. package/dist/trace/project.d.ts +35 -30
  324. package/dist/trace/project.js +9 -0
  325. package/dist/turn-activity.d.ts +4 -4
  326. package/dist/usage-analytics.d.ts +1 -1
  327. package/dist/wall-clock-jump-guard.d.ts +3 -3
  328. package/package.json +6 -6
@@ -1,5 +1,5 @@
1
1
  /**
2
- * [2252]/[2255]①/[2257] 追加件:409 `conflict.session_active_run` 的**真出路材料**装配(单源)。
2
+ * [ref]/[ref]①/[ref] 追加件:409 `conflict.session_active_run` 的**真出路材料**装配(单源)。
3
3
  *
4
4
  * 事故形:park(suspended/needs_review)占着 session claim,客户端每条新提交吃 409,而旧文案只教
5
5
  * cancel(毁灭当前 run)。对 parked 会话,「继续」的唯一合法动作是去**对的** resume 入口决议——但四条
@@ -15,7 +15,8 @@
15
15
  */
16
16
  import { type Autonomy } from "../runtime-governance.js";
17
17
  import { type RunRecord } from "../plugins/store-contracts.js";
18
- /** #220 归因的部署侧入参(两个治理旋钮;判据属主见 `governanceMandatesShellGateAlways`)。 */
18
+ import { type PendingRowBinding } from "../plugins/checkpoint-store-sql.js";
19
+ /** [ref] 归因的部署侧入参(两个治理旋钮;判据属主见 `governanceMandatesShellGateAlways`)。 */
19
20
  export interface GovernancePosture {
20
21
  autonomy?: Autonomy;
21
22
  manualModeShellGate?: "always" | "classify";
@@ -25,15 +26,15 @@ export declare const ACTIVE_RUN_CONFLICT_BASE_TEXT = "session already has an act
25
26
  /**
26
27
  * 409 体(与 SSE done 帧 result 共用)里的**待批门材料**。
27
28
  *
28
- * `kind`/`decidePath` = 出路(去哪决议);#220 追加的 `governanceForced` = **出身**(这道门是谁下的)——
29
- * [3513] T3「park 后待批通道事件」的读者此前只知道「有一道 X 型门」,不知道它是运维治理层强制的还是
29
+ * `kind`/`decidePath` = 出路(去哪决议);[ref] 追加的 `governanceForced` = **出身**(这道门是谁下的)——
30
+ * [ref] T3「park 后待批通道事件」的读者此前只知道「有一道 X 型门」,不知道它是运维治理层强制的还是
30
31
  * 别的来源,于是「我都开了 bypassPermissions 为什么还在问」这个 UX 缺口在 park 腿上原样复现
31
- * ([3031]#1/[3038] 在活卡腿上的实证)。
32
+ * ([ref]#1/[ref] 在活卡腿上的实证)。
32
33
  *
33
34
  * 🔴 **additive + 只在为真时在场**:与活卡帧 `ToolApprovalFrame.governanceForced` **同一条纪律**——
34
35
  * 缺席 ≠「这不是治理门」,而是「没有治理来源的证据」(判据够不着的形也落在缺席里,见装配处的注)。
35
36
  *
36
- * #285 追加的 `checkpointId` = **相关性**(这道门在别的面上叫什么名字),是出路/出身之外的第三个问题。
37
+ * [ref] 追加的 `checkpointId` = **相关性**(这道门在别的面上叫什么名字),是出路/出身之外的第三个问题。
37
38
  * 上文那条「askId 为什么不在这里」的记账(见 {@link governanceOriginOf} 顶注末段)说的是**同一个缺口的
38
39
  * 另一半**:park 门此前在 wire 上**没有任何稳定身份**——唯一单射的键是 `token`,而 token 是秘密能力、
39
40
  * 永不上 wire,于是消费端只能拿 `(sessionId, kind)` 这种非单射组合去猜「这次的门」和「上次的门」是不是
@@ -64,7 +65,7 @@ export interface PendingGateMaterial {
64
65
  decidePath: string;
65
66
  /** 见 {@link PendingGateMaterial} 顶注:`true` 才在场,恒不写 `false`。 */
66
67
  governanceForced?: true;
67
- /** #285(core 5.42.0):这道 park 门的**非秘密稳定身份**(`Checkpoint.checkpointId`)。逐字过境,
68
+ /** [ref](core 5.42.0):这道 park 门的**非秘密稳定身份**(`Checkpoint.checkpointId`)。逐字过境,
68
69
  * server 绝不自铸、绝不派生(信任边界校验见 `safeCheckpointIdOf`)。
69
70
  * 🔴 **缺席是三成因合流的一个形**(R3-[low] 验真后改真 —— 此前这里只写了第一条,那是失真):
70
71
  * ① **legacy 行**:该键诞生前 park 的(core 明写「absent ⇒ legacy row, read compatibly, no backfill」);
@@ -73,16 +74,13 @@ export interface PendingGateMaterial {
73
74
  * ③ **材料读取失败**:整只 `pendingGate` 都不在(那时本键连位置都没有)。
74
75
  * ⇒ 读作「不知道这道门叫什么」,**不是**「这道门没有身份」,更**不是**「这一定是条老行」。
75
76
  *
76
- * 🔴 **它命名的是「本次 409 实际读到的那一行」,不是「activeTaskId 这条 run 的门」**(codex 交叉复审
77
- * R1-[high] 验真后如实登记):同 session 可以并存两条 pending checkpoint(表上**没有** per-session
78
- * pending 唯一约束),而 `findPendingTokenBySession` 是**无序 `LIMIT 1`** —— 这个条件是本仓自己成文的
79
- * 已知事实(`src/http/server.ts` mintFreshRun 腿 409 那段的逐字论证:「两条 pending 并存时旧
80
- * task_done park 完全可能被选中」)。⇒ 本材料的**每一格**(kind / decidePath / governanceForced /
81
- * checkpointId)共享同一条归属不确定性;本键是**继承**它,不是引入它。
82
- * **对消费端的直接后果**:这一位**不是**跨调用的稳定去重键 —— 同一情形连续两次 409 可能报出不同的
83
- * id(选中了另一行),也可能 id 不变而 activeTaskId 已换。可安全用于:落日志/排障关联,以及「id 变了
84
- * ⇒ 我看到的门确实不是刚才那一道」这个**单向**判断。根治要一条能按 run 绑定选行的 store 读口
85
- * (SQL 面 = 双库门),已作为提货批未决项上报,不在本批。 */
77
+ * 🔴 **归属不确定性(codex 交叉复审 R1-[high] 曾如实登记)—— [ref]([ref])已收口**:同 session 可以
78
+ * 并存两条 pending checkpoint(表上**没有** per-session pending 唯一约束;并存形 = 终局后的 `task_done`
79
+ * park + 下一条 run 的门 park),而 `findPendingTokenBySession` 曾是**无序 `LIMIT 1`**,本材料的
80
+ * 每一格因此曾共享「读到的是哪一行」的不确定性。现形:本模块按 **run 绑定**选行(`LIVE_RUN_GATE_KINDS`
81
+ * —— activeTaskId 持有 claim 它的门绝非 task_done),且店读口自此有序(最新优先,token 兜平局;
82
+ * 谓词/序属主 `checkpoint-store-sql.ts` `pendingRowQuery`,LOCAL twin 同判)⇒ 同一情形连续两次 409
83
+ * 报的是同一行。残余如实记:这一位仍不是**跨 run** 的去重键 —— activeTaskId 换了,门自然也换。 */
86
84
  checkpointId?: string;
87
85
  }
88
86
  export interface ActiveRunConflictBody {
@@ -90,13 +88,13 @@ export interface ActiveRunConflictBody {
90
88
  errorCode: "conflict.session_active_run";
91
89
  activeTaskId: string | null;
92
90
  activeTaskStatus?: string;
93
- /** #245 S1([3777]):running 形专属的**活性证据**——本副本 ledger sink 最后一次 durable append 距今
91
+ /** [ref] S1([ref]):running 形专属的**活性证据**——本副本 ledger sink 最后一次 durable append 距今
94
92
  * 的毫秒数(「turn 真在推进」的判别材料;与行 updatedAt 的进程心跳语义刻意分离)。**同副本
95
93
  * best-effort**:缺席 = 无法证明(跨副本/重启后),不是「不活」——诚实缺席,绝不铸 0。消费端
96
- * (cli running 臂,[3779] C3)凭它区分「真忙的后台 run」与「久无进展的疑似僵局」,替代猜测文案。 */
94
+ * (cli running 臂,[ref] C3)凭它区分「真忙的后台 run」与「久无进展的疑似僵局」,替代猜测文案。 */
97
95
  msSinceLastActivity?: number;
98
96
  /**
99
- * #316(c)([4664]② 成文的洞 (c) 的修):**两面口径的对齐位**。
97
+ * [ref](c)([ref]② 成文的洞 (c) 的修):**两面口径的对齐位**。
100
98
  *
101
99
  * 病:poll 面(`GET /v1/runs/:id`)对「`running` 且 `now - updatedAt > runStaleSec`」的行**折叠**成
102
100
  * `status:"failed"`(+「run stalled (instance lost?)」),而本体把 run 行 `status` **原样**报 `running`。
@@ -110,10 +108,10 @@ export interface ActiveRunConflictBody {
110
108
  * `msSinceLastActivity` **并存**,壳凭它把两面对上(「poll 那边会说 failed = 这条大概率是死行」)。
111
109
  *
112
110
  * 🔴 **只在为真时在场**(与 `PendingGateMaterial.governanceForced` 同一条纪律):缺席 = 「没有陈旧的
113
- * 证据」,**不是**「证明它活着」——判据只有 `updated_at` 一维,慢而活的 run 有误杀窗([4664]② 洞 (b)
111
+ * 证据」,**不是**「证明它活着」——判据只有 `updated_at` 一维,慢而活的 run 有误杀窗([ref]② 洞 (b)
114
112
  * 原样有效)。⇒ 这一位是**分诊材料**,不是终态断言。
115
113
  *
116
- * 🔴 **只对 `running` 铸**:park 两态(suspended/needs_review)根本不在 `reapStale` 射程内([4664]②
114
+ * 🔴 **只对 `running` 铸**:park 两态(suspended/needs_review)根本不在 `reapStale` 射程内([ref]②
117
115
  * 洞 (a)),给它们标 stale 就是假材料。
118
116
  */
119
117
  stale?: true;
@@ -137,20 +135,20 @@ export declare function governanceOriginOf(gate: {
137
135
  */
138
136
  export interface ActiveRunConflictDoneResult {
139
137
  status: "failed";
140
- /** [2373]C-1:与 409 体同一机器码——流腿客户端凭它认拒绝,禁按 byte-frozen 文案匹配。 */
138
+ /** [ref]C-1:与 409 体同一机器码——流腿客户端凭它认拒绝,禁按 byte-frozen 文案匹配。 */
141
139
  errorCode: "conflict.session_active_run";
142
140
  errorMessage: string;
143
141
  activeTaskId: string | null;
144
142
  activeTaskStatus?: string;
145
- /** #245 S1:与 409 body 同键同语义(见 {@link ActiveRunConflictBody.msSinceLastActivity})。 */
143
+ /** [ref] S1:与 409 body 同键同语义(见 {@link ActiveRunConflictBody.msSinceLastActivity})。 */
146
144
  msSinceLastActivity?: number;
147
145
  /**
148
- * #316(c):与 409 body 同键同语义(见 {@link ActiveRunConflictBody.stale})。
146
+ * [ref](c):与 409 body 同键同语义(见 {@link ActiveRunConflictBody.stale})。
149
147
  *
150
148
  * 🔴 **跨仓欠账,如实登记**(codex 交叉复审 R1-[medium] 验真后的真形):sema-sdk 的
151
149
  * `spec/openapi.yaml` 里 `ActiveRunConflictDoneResult` 是 `additionalProperties: false` 的**封闭**
152
150
  * schema,今天只声明 `status/errorCode/errorMessage/activeTaskId/activeTaskStatus/pendingGate` 六键。
153
- * ⚠️ 亲验后的关键修正:这**不是本键引入的新问题** —— `msSinceLastActivity`(#245 S1)早就在这条
151
+ * ⚠️ 亲验后的关键修正:这**不是本键引入的新问题** —— `msSinceLastActivity`([ref] S1)早就在这条
154
152
  * done 帧上,同样没进那张封闭表,即**同族违例已存在**且没有任何门看得见它(producer-contract 只校
155
153
  * 409 体那条 op,不校这条 SSE 帧)。本批**刻意不**为了绕开它而让 done 帧与 409 体分家(「同材料禁
156
154
  * 分家」是本文件自己的纪律,分家换来的是两面口径再次相左 —— 正是本件在修的病)。
@@ -165,7 +163,7 @@ interface ConflictProbeDeps<TToken> {
165
163
  /** 结构形入参,但 `status` 取 run 行的**闭词表**(合并码重扫):判 park 要走词表属主
166
164
  * `isParkedRunStatus`,而它的入参是穷举联合 —— 这一格写成开放 `string` 就只能在调用点裸 cast,
167
165
  * 绕开那道编译期执法(core 加一个 park 类成员时本文件不会红)。 */
168
- /** `updatedAt`(#316(c)):stale 折叠的唯一判据维([4664]② 洞 (b):慢而活的 run 有误杀窗)。可选 —— 缺席
166
+ /** `updatedAt`([ref](c)):stale 折叠的唯一判据维([ref]② 洞 (b):慢而活的 run 有误杀窗)。可选 —— 缺席
169
167
  * 或不可解析 ⇒ `stale` 键诚实缺席(与本模块「材料是 best-effort 增强」同方向)。 */
170
168
  runStore?: {
171
169
  getRun?: (id: string) => Promise<{
@@ -174,11 +172,11 @@ interface ConflictProbeDeps<TToken> {
174
172
  } | null | undefined>;
175
173
  } | undefined;
176
174
  checkpointStore?: {
177
- peekPendingScope?: (sessionId: string) => Promise<string | null | undefined>;
178
- findPendingTokenBySession?: (sessionId: string, scope?: string) => Promise<TToken | null | undefined>;
175
+ peekPendingScope?: (sessionId: string, binding?: PendingRowBinding) => Promise<string | null | undefined>;
176
+ findPendingTokenBySession?: (sessionId: string, scope?: string, binding?: PendingRowBinding) => Promise<TToken | null | undefined>;
179
177
  /** 结构形(不 import core 的 `Checkpoint`):只声明本模块**真读**的几格。`riskDescriptor` 是
180
178
  * core 在 mint 时挂到升级门上的判读元数据(display/triage only),`shellGateDoctrine` 是 2026-08-05
181
- * 裁定加的取证格 —— 见下方 `governanceOriginOf` 的推导论证。`checkpointId`(#285,core 5.42.0)
179
+ * 裁定加的取证格 —— 见下方 `governanceOriginOf` 的推导论证。`checkpointId`([ref],core 5.42.0)
182
180
  * 是行的非秘密稳定身份,可选 —— legacy 行没有它(见 `PendingGateMaterial.checkpointId`)。 */
183
181
  get?: (token: TToken) => Promise<{
184
182
  checkpointId?: string;
@@ -190,13 +188,13 @@ interface ConflictProbeDeps<TToken> {
190
188
  };
191
189
  } | null | undefined>;
192
190
  } | undefined;
193
- /** #220:出身归因的部署侧一半(缺席 ⇒ 归不出治理出身 ⇒ 键缺席 —— 与 best-effort 同方向)。 */
191
+ /** [ref]:出身归因的部署侧一半(缺席 ⇒ 归不出治理出身 ⇒ 键缺席 —— 与 best-effort 同方向)。 */
194
192
  governance?: GovernancePosture | undefined;
195
- /** #316(c):stale 折叠的阈值(秒),生产装配 = `config.runStaleSec` —— 与 poll 面
193
+ /** [ref](c):stale 折叠的阈值(秒),生产装配 = `config.runStaleSec` —— 与 poll 面
196
194
  * (`routes/runs.ts` 的 `deps.config.runStaleSec * 1000`)**同一个旋钮**,两面口径因此同源。
197
195
  * 缺席/非正数 ⇒ 不折叠(键缺席),等价于「本部署没有配这条判据」。 */
198
196
  runStaleSec?: number | undefined;
199
- /** #245 S1:turn 活性读口(生产装配 = `readTurnActivityMs`,turn-activity.ts)。返回最后活性时刻
197
+ /** [ref] S1:turn 活性读口(生产装配 = `readTurnActivityMs`,turn-activity.ts)。返回最后活性时刻
200
198
  * (epoch ms)或 undefined。可选:未装配/读不到 ⇒ `msSinceLastActivity` 键缺席,best-effort 同方向。 */
201
199
  turnActivity?: ((taskId: string) => number | undefined) | undefined;
202
200
  }
@@ -1,5 +1,6 @@
1
1
  import { governanceMandatesShellGateAlways } from "../runtime-governance.js";
2
2
  import { isParkedRunStatus } from "../plugins/store-contracts.js";
3
+ import { LIVE_RUN_GATE_KINDS } from "../plugins/checkpoint-store-sql.js";
3
4
  import { recordFailOpen } from "../observability/fail-open.js";
4
5
  export const ACTIVE_RUN_CONFLICT_BASE_TEXT = "session already has an active run — POST /v1/runs/{activeTaskId}/cancel stops it (same-instance interactive runs abort immediately)";
5
6
  export function resumeEntryForGate(kind, ids) {
@@ -72,8 +73,9 @@ export async function buildActiveRunConflict(deps, sessionId, activeTaskId) {
72
73
  const cs = deps.checkpointStore;
73
74
  let pendingGate;
74
75
  if (cs?.findPendingTokenBySession) {
75
- const scope = (await cs.peekPendingScope?.(sessionId)) ?? undefined;
76
- const token = scope === null ? null : await cs.findPendingTokenBySession(sessionId, scope);
76
+ const runBinding = { gateKinds: LIVE_RUN_GATE_KINDS };
77
+ const scope = (await cs.peekPendingScope?.(sessionId, runBinding)) ?? undefined;
78
+ const token = scope === null ? null : await cs.findPendingTokenBySession(sessionId, scope, runBinding);
77
79
  const row = token ? await cs.get?.(token) : undefined;
78
80
  const gate = row?.gate;
79
81
  const kind = gate?.kind;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * design/158 A9 — 路由域装配缝(`handle()` 按路由域拆多文件 + 装配器)。
2
+ * [ref] A9 — 路由域装配缝(`handle()` 按路由域拆多文件 + 装配器)。
3
3
  *
4
4
  * `createHttpServer` 建**一次** `RouteCtxBase`(deps/registry/helpers/local 四格),`handle()` 每请求把它
5
5
  * 加上一格 `req`(每请求局部量)交给按序尝试的域表。域模块只从这里取自己那份窄切片,**在函数首行解构**
@@ -47,11 +47,13 @@ export interface RouteHelpers {
47
47
  rateLimited(req: IncomingMessage, res: ServerResponse): boolean;
48
48
  quotaExceeded(req: IncomingMessage, res: ServerResponse): boolean;
49
49
  leaseDenied(req: IncomingMessage, res: ServerResponse): Promise<boolean>;
50
- /** design/166-T1:治理窗 pre-admission(异步 202 车道的唯一 429 出路;key 公式与 core 单源)。 */
50
+ /** [ref]-T1:治理窗 pre-admission(异步 202 车道的唯一 429 出路;key 公式与 core 单源)。 */
51
51
  usageWindowDenied(req: IncomingMessage, res: ServerResponse): Promise<boolean>;
52
52
  safeDecode(seg: string): string | null;
53
53
  isFleetWide(req: IncomingMessage): boolean;
54
- runOwnerOk(req: IncomingMessage, res: ServerResponse, owner: string | null): boolean;
54
+ /** 属主门。`notFoundForm` not-yours 臂的 404 拼法:缺省 `"run"`(not_found.run 长文,[ref]);session
55
+ * 资源面传 `"session"`(not_found.session + "session not found")与其 unknown 臂同码同串(G52 [ref])。 */
56
+ runOwnerOk(req: IncomingMessage, res: ServerResponse, owner: string | null, notFoundForm?: "run" | "session"): boolean;
55
57
  sessionOwnerScope(req: IncomingMessage): {
56
58
  fleetWide: boolean;
57
59
  gateOwner: string | null;
@@ -82,7 +84,7 @@ export interface RouteRequestState {
82
84
  * 命名后好处不只是过 B4 门:两个消费域现在都能对同一个符号做 `import type` 标注,而不是各自重推断结构。 */
83
85
  export interface PreparedTaskSubmission {
84
86
  spec: TaskSpec;
85
- /** #196:本次提交的执行 Runner —— 场景 hands=none 时是无手孪生(不挂 executionEnvFactory)。
87
+ /** [ref]:本次提交的执行 Runner —— 场景 hands=none 时是无手孪生(不挂 executionEnvFactory)。
86
88
  * 两个消费域一律用它,不再直接摸 `deps.runner`(那正是「场景表态了、执行点没听」的缝)。 */
87
89
  runner: Runner;
88
90
  auth?: RequestAuth;
@@ -94,7 +96,7 @@ export interface PreparedTaskSubmission {
94
96
  /** B4①(命名化):`driveResumeIntoRunLog` 的入参形(resume 家族共用)——原为 9 成员内联匿名对象。 */
95
97
  export interface DriveResumeArgs {
96
98
  token: CheckpointToken;
97
- /** #196:续跑腿的执行 Runner。resume 会用同一条 resolveSpec 重解析场景,故与首跑选同一只 —— 否则
99
+ /** [ref]:续跑腿的执行 Runner。resume 会用同一条 resolveSpec 重解析场景,故与首跑选同一只 —— 否则
98
100
  * 一次续跑就把手带 band 重新 mount 回来(收窄只在首跑成立 = 没成立)。 */
99
101
  runner: Runner;
100
102
  sessionId: string;
@@ -109,7 +111,7 @@ export interface DriveResumeArgs {
109
111
  * ask sees them — the decide leg's exemption grant). Contract: must not throw (callers swallow internally);
110
112
  * awaited so the ordering guarantee is real, and a store write here is ms-scale vs the model leg. */
111
113
  onResumeCommitted?: () => Promise<void>;
112
- /** [3829]/[3830]:调用方声明「本腿的 park 是终局后纯 park,session claim 已随终局 finalize 删除」——
114
+ /** [ref]/[ref]:调用方声明「本腿的 park 是终局后纯 park,session claim 已随终局 finalize 删除」——
113
115
  * getActiveTaskId 缺席时**铸新 canonical taskId + createRun 全生命周期行**(wake 续跑=同 session 新一轮
114
116
  * turn),而不是无行裸跑(不可取消/无计费归因/无 durable append/fleet 不可见,且 core `spec.taskId ??
115
117
  * sessionId` fallback 会把 lastRunId 铸成 sessionId)。`source` 进 run 行元数据(runMeta 同列)。
@@ -118,7 +120,7 @@ export interface DriveResumeArgs {
118
120
  mintFreshRun?: {
119
121
  source: string;
120
122
  };
121
- /** #316([4660] Inkglow 案 → [4664]① 定谳):**200 受理语义**——调用方声明「我的消费方按 poll/SSE 跟
123
+ /** [ref]([ref] Inkglow 案 → [ref]① 定谳):**200 受理语义**——调用方声明「我的消费方按 poll/SSE 跟
122
124
  * 终态,别让 HTTP 等模型往返」。在场为 `true` 时本腿在**受理点**(`resumeStream` 解析之后)立刻把
123
125
  * `200 {taskId, status:"resuming", bindingEnforced:true}` 交回调用方,模型腿(流迭代 + 行驱动)继续
124
126
  * 在同一条 promise 链上跑完 —— 不是新写口,逐字还是那条 `createSerialLedgerAppend` 单写串行链。
@@ -133,7 +135,7 @@ export interface DriveResumeArgs {
133
135
  * await,没有「CAS 已过、模型还没跑」这个缝可停 —— 在那条臂上提前受理就等于把绑定判别也异步化了
134
136
  * (那是决策证明的一部分,不能丢)。故它维持同步长调用形,如实登记在 CHANGELOG/契约文档。
135
137
  *
136
- * **今天传 `true` 的调用方**([3833] 件 S-1 之后 = 全部有人在等响应的 HTTP 腿):legacy 任务级
138
+ * **今天传 `true` 的调用方**([ref] 件 S-1 之后 = 全部有人在等响应的 HTTP 腿):legacy 任务级
137
139
  * `/v1/approvals/:sessionId/decide`、`/v1/assistant/tasks/:id/resume`、`…/plan_review`、
138
140
  * `/v1/sessions/:id/wake`、以及 live 回决腿的 parked 赎回席(`redeemParkedAsk`)。
139
141
  * **唯一不设此位的**是内部 D-D SLA deny-sweep:它没有在等响应的人,提前受理对它零收益,而且那条
@@ -158,7 +160,7 @@ export interface RouteLegs {
158
160
  * `sendError` 连 `extra` 一起回显。DESIGN-269 车2 的 A2A 腿必须传它 —— 那些 `extra`(尤其
159
161
  * `scenario_unknown` 的**全部场景名**)对壳是指路材料,对一个外部 peer 是内部词表外泄。 */
160
162
  prepareSpec(req: IncomingMessage, res: ServerResponse, body?: TaskRequestBody, onTypedFailure?: (err: import("../security.js").HttpError) => void,
161
- /** S-46 件C:**腿身份**(不是能力表态)。`liveStream: true` 只由 `POST /v1/tasks/stream` 的装配点按
163
+ /** [ref] 件C:**腿身份**(不是能力表态)。`liveStream: true` 只由 `POST /v1/tasks/stream` 的装配点按
162
164
  * URL 传 —— 那是全树唯一挂 HITL 活流投递面的腿,逐腿 `interactionPosture` 判据的第一条合取项。
163
165
  * 缺席 ⇒ 无人腿(bg / A2A / resume),行为字节不变。 */
164
166
  legFacts?: {
@@ -171,7 +173,7 @@ export interface RouteLegs {
171
173
  * `/decide` = 人;内部 D-D SLA deny-sweep = 窗到期),而函数内部分辨不出谁在叫它 —— 必填参数把
172
174
  * 「漏报出处」变成编译错,不是一条下游把「没人答」渲染成「有人拒」的静默假出处。 */
173
175
  resumeCheckpoint(sessionId: string, decision: "approve" | "deny", reason: string | undefined, settledBy: ApprovalSettledBy, req?: IncomingMessage, answer?: QuestionAnswer, binding?: DecideBinding,
174
- /** S-02 codex R4(验真后修):remember 豁免的 grant 挂点。**工具名不再由路由自己读**(那是与本函数
176
+ /** [ref] codex R4(验真后修):remember 豁免的 grant 挂点。**工具名不再由路由自己读**(那是与本函数
175
177
  * 载入行分歧的第三次 scope-less 读,三读分歧下会给他人工具落豁免=提权)——由本函数把**已属主校验的
176
178
  * 载入 cp** 的工具名(`validatedToolName`,非 tool_approval / AskUserQuestion / legacy null ⇒ `null`
177
179
  * = 无可记)一并回传,路由只对这个逐字落店。`overrideSessionId` = parked 腿的 root/host 会话 grant 锚。 */
@@ -179,10 +181,10 @@ export interface RouteLegs {
179
181
  overrideSessionId?: string;
180
182
  validatedToolName: string | null;
181
183
  }) => Promise<void>,
182
- /** #316:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/decide` 腿传 `true`;
184
+ /** [ref]:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/decide` 腿传 `true`;
183
185
  * 内部 D-D SLA deny-sweep 不传 —— 它没有在等响应的人,提前受理对它零收益而少一条同步失败面。 */
184
186
  acceptEarly?: boolean,
185
- /** S-02:调用方已验身份的裁定 —— stale 臂铸 `currentPending` 指路键前在被读回的行上重跑 decide 门
187
+ /** [ref]:调用方已验身份的裁定 —— stale 臂铸 `currentPending` 指路键前在被读回的行上重跑 decide 门
186
188
  * 同一属主判(缺席 ⇒ 恒不造键;判据属主=server.ts 铸键点注)。 */
187
189
  decider?: {
188
190
  principal?: string;
@@ -198,14 +200,14 @@ export interface RouteLegs {
198
200
  }>;
199
201
  /** assistant 抢占腿的复位(gate-kind 守卫 + 驱动)。 */
200
202
  resumePreempted(sessionId: string, req: IncomingMessage | undefined,
201
- /** [3833] 件 S-1:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/resume` 腿传 `true`。 */
203
+ /** [ref] 件 S-1:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/resume` 腿传 `true`。 */
202
204
  acceptEarly?: boolean): Promise<{
203
205
  status: number;
204
206
  body: object;
205
207
  }>;
206
208
  /** notify-wake 域:唤醒一条 parked checkpoint。 */
207
209
  resumeWake(sessionId: string, message: string | undefined, caller: string | undefined, req: IncomingMessage | undefined,
208
- /** [3833] 件 S-1:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/wake` 腿传 `true`
210
+ /** [ref] 件 S-1:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/wake` 腿传 `true`
209
211
  * —— 本腿走 `mintFreshRun`,受理体里的 `taskId` 因此是**新铸的**那个(壳的 poll 锚)。 */
210
212
  acceptEarly?: boolean): Promise<{
211
213
  status: number;
@@ -213,19 +215,19 @@ export interface RouteLegs {
213
215
  }>;
214
216
  /** assistant plan_review 三态腿。 */
215
217
  resumePlanReview(sessionId: string, decision: "approve" | "edit" | "reject", editedPlan: string | undefined, reason: string | undefined, req: IncomingMessage | undefined,
216
- /** [4277]/[4288] 件5:`decide_404` 判别日志的附加位(只进日志,不上 wire;身份只记有无不记值)。 */
218
+ /** [ref]/[ref] 件5:`decide_404` 判别日志的附加位(只进日志,不上 wire;身份只记有无不记值)。 */
217
219
  log?: {
218
220
  taskId?: string;
219
221
  principalPresent?: boolean;
220
222
  },
221
- /** [3833] 件 S-1:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/plan_review` 腿传 `true`。 */
223
+ /** [ref] 件 S-1:透传给 {@link DriveResumeArgs.acceptEarly}(200 受理语义)。HTTP `/plan_review` 腿传 `true`。 */
222
224
  acceptEarly?: boolean): Promise<{
223
225
  status: number;
224
226
  body: object;
225
227
  }>;
226
228
  }
227
229
  /**
228
- * [3833] 件 S-2 —— resume 族**受理点的断连留痕**(裁定:维持 detach,补观察面)。
230
+ * [ref] 件 S-2 —— resume 族**受理点的断连留痕**(裁定:维持 detach,补观察面)。
229
231
  *
230
232
  * ## 裁定(fable,与 S-1 同批;这里是它的唯一属主)
231
233
  *
@@ -258,7 +260,7 @@ export declare function noteResumeClientGone(res: ServerResponse, out: {
258
260
  info?: (msg: string, fields?: Record<string, unknown>) => void;
259
261
  } | undefined): void;
260
262
  /**
261
- * #359②(A-075.6)—— resume 族四腿(`/decide` / `/assistant/tasks/:id/resume` / `/plan_review` /
263
+ * [ref]②([ref])—— resume 族四腿(`/decide` / `/assistant/tasks/:id/resume` / `/plan_review` /
262
264
  * `/wake`)的**唯一**回执发送口。
263
265
  *
264
266
  * 为什么是一个函数而不是「在四处各加一行 `res.setHeader`」:这四条腿此前已经各自记得调
@@ -297,14 +299,14 @@ export interface RouteMiss {
297
299
  fell: boolean;
298
300
  }
299
301
  /**
300
- * #262(A-041 存在性 oracle 封口)——`not_found.run` 的**唯一**文案源,unknown 与 not-yours 两臂共用。
302
+ * [ref]([ref] 存在性 oracle 封口)——`not_found.run` 的**唯一**文案源,unknown 与 not-yours 两臂共用。
301
303
  * 修前:unknown 臂发这条长指路文案、not-yours 臂发短文「run not found」,同 code 下按**文案长度**即可
302
304
  * 枚举他人 run id 的存在性(822 行「no existence oracle」注释的意图被长短差打穿)。not-yours 臂只可能
303
305
  * 拿到非 a\* id(store 查到行才有 owner 比对;a\* 与 wa\* 形 id 永不在 run store)⇒ 非 a\* 长文串足以让
304
- * 两臂逐字节同形,指路价值不丢。钉=audit-fixes-http「#262」格(两臂全文比对);文案变更走
306
+ * 两臂逐字节同形,指路价值不丢。钉=audit-fixes-http「[ref]」格(两臂全文比对);文案变更走
305
307
  * api-error-text-freeze 基线流程。
306
308
  */
307
309
  export declare const RUN_NOT_FOUND_MESSAGE = "run not found \u2014 the id belongs to no run in this deployment's run store (a run from another server process, or an in-memory store that did not survive a restart, is not visible here)";
308
- /** [1434] 前缀=域判别子既成契约:a\* 与 wa\* 形 id 给 TaskOutput/journal 指路;其余给 {@link RUN_NOT_FOUND_MESSAGE}。 */
310
+ /** [ref] 前缀=域判别子既成契约:a\* 与 wa\* 形 id 给 TaskOutput/journal 指路;其余给 {@link RUN_NOT_FOUND_MESSAGE}。 */
309
311
  export declare function runNotFoundMessage(id: string): string;
310
312
  //# sourceMappingURL=route-ctx.d.ts.map
@@ -36,12 +36,12 @@ export declare function buildAgentCard(serve: A2aServeConfig): A2aAgentCard;
36
36
  */
37
37
  export declare function handleA2aServe(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
38
38
  /**
39
- * 🔴 **反枚举不变式(A-041)在本模块的执行点**:`tasks/get` 的「这条 task 不存在」与「这条 task 不是
39
+ * 🔴 **反枚举不变式([ref])在本模块的执行点**:`tasks/get` 的「这条 task 不存在」与「这条 task 不是
40
40
  * 你的」必须**逐字节**同形 —— 同一个 code、同一条 message、同一个(缺席的)data。两臂共用**这一个**
41
41
  * 常量就是那条不变式的机制支撑:任何一臂想说得更具体,都得先改这里,而改这里会被
42
42
  * `a2a-serve-rpc.test.ts` 的逐字节比对当场钉住。
43
43
  *
44
- * (同族先例:`route-ctx.ts` 的 `RUN_NOT_FOUND_MESSAGE` —— #262 抓到的正是两臂**文案长度**不同就足以
44
+ * (同族先例:`route-ctx.ts` 的 `RUN_NOT_FOUND_MESSAGE` —— [ref] 抓到的正是两臂**文案长度**不同就足以
45
45
  * 枚举他人 run id 的存在性。JSON-RPC 侧一模一样,只是载体从 HTTP body 换成了 error 对象。)
46
46
  */
47
47
  export declare const A2A_TASK_NOT_FOUND_MESSAGE = "task not found";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * #322 批1 追加件(clay 当场裁定,design/322 批1 行):`POST /v1/admin/config/refresh` —— operator 改完
2
+ * [ref] 批1 追加件(clay 当场裁定,[ref] 批1 行):`POST /v1/admin/config/refresh` —— operator 改完
3
3
  * 配置**不等 60s tick**,手动触发一次立即拉取。
4
4
  *
5
5
  * 族属 = `POST /v1/admin/drain` 逐字同族(operator lane:同一条 `explicitOperatorOk` 门、billable=false、
@@ -1,5 +1,5 @@
1
1
  /**
2
- * #291(C17,[4470]/[4472] 认领,黑板 [4472] 原文即本口的契约):`POST /v1/admin/drain {reason}` ——
2
+ * [ref](C17,[ref]/[ref] 认领,黑板 [ref] 原文即本口的契约):`POST /v1/admin/drain {reason}` ——
3
3
  * 编排壳在发停机信号(SIGTERM)**之前**先调本口显式声明停机因由;server 记入 `drainState.reason`,
4
4
  * draining 期间由 `/health`(`drainReason`)与 503 draining 体(`reason`)透出。未声明 = 两面键缺席
5
5
  * (additive,不编数)——升级/缩容/驱逐在消费端因此可判别,而不是一律读成「实例没了」。
@@ -11,9 +11,9 @@
11
11
  * operator 门(空表恒拒,fail-closed)已是正确强度。
12
12
  *
13
13
  * reason 校验:非空 trim 后 string ≤ {@link MAX_DRAIN_REASON_CHARS} —— 它会进 /health 与 503 体
14
- * (消费面是监控/壳),超长或怪型响亮拒([3425] 坏值立律),拒绝不留痕(不写半个值)。
14
+ * (消费面是监控/壳),超长或怪型响亮拒([ref] 坏值立律),拒绝不留痕(不写半个值)。
15
15
  *
16
- * 🔴 **写侧特权、读侧公开 —— 这条不对称是刻意的,但必须被写的人知道**(A-054.11,2026-08-19 合并重扫
16
+ * 🔴 **写侧特权、读侧公开 —— 这条不对称是刻意的,但必须被写的人知道**([ref],2026-08-19 合并重扫
17
17
  * partial,存活断言):本口是 operator-only + fail-closed(空 `OPERATOR_PRINCIPALS` 恒拒),而透出面里
18
18
  * `/health` 在 `server.ts` 的鉴权门**之前**、无鉴权、缺省全网卡监听,USAGE 三处白纸黑字把它定为「无需
19
19
  * 鉴权」—— 任何能连到这个端口的人都读得到这段**运维手打的自由文本**。
@@ -22,7 +22,7 @@
22
22
  * operator 自选,且窗口只在 draining 期;③ 同一免鉴权体上早已有 `dataRoot` 绝对路径 / `pid` / `port` /
23
23
  * `instanceId` / `configHash` / `storeProbe`,单独收紧本键不改变那面的暴露量级。
24
24
  * (那条另立的兄弟件 —— `storeProbe.error` 把**原始异常 message 未截断**塞出去、DSN 片段可随之外泄 ——
25
- * 已在 #305 修掉:免鉴权面上它改成闭集词,原文只走日志轴。两件的判据不同故不合并:本键的值由 operator
25
+ * 已在 [ref] 修掉:免鉴权面上它改成闭集词,原文只走日志轴。两件的判据不同故不合并:本键的值由 operator
26
26
  * 自选且窗口只在 draining 期,`storeProbe.error` 的值则来自不受控的驱动异常。)
27
27
  * ⇒ 真正的缺口是**告诫缺席**:此前路由头注、400 文案、CHANGELOG、wire 契约四处都只说「透出」,没有一处
28
28
  * 说「其中一面免鉴权」,操作员要拼出「我写的字是公开的」得自己合并两处文档去推理。本批把它写进**写口
@@ -1,19 +1,19 @@
1
1
  /**
2
- * design/383 §3.1 / S-50 §1.3(S-49 S-2)—— per-principal **memory-capture opt-out 授权表**的 operator 四口:
2
+ * [ref] §3.1 / [ref] §1.3([ref] S-2)—— per-principal **memory-capture opt-out 授权表**的 operator 四口:
3
3
  *
4
4
  * · `GET /v1/admin/memory-optout` → `{ deploymentDefault: Row|null, overrides: Row[] }`
5
5
  * · `PUT /v1/admin/memory-optout` body `{allow, note?}` → 部署缺省行 upsert(哨兵 `principal=''`)
6
6
  * · `PUT /v1/admin/memory-optout/:principal` body `{allow, note?}` → per-principal 覆盖行 upsert
7
7
  * · `DELETE /v1/admin/memory-optout/:principal` → 撤覆盖(回落部署缺省);`{ deleted: boolean }` 诚实答
8
8
  *
9
- * Row = `{ principal, allow, updatedAtMs, updatedBy, note? }`(审计行内,S-50 §1.3;`updatedBy` = 调用方 operator
9
+ * Row = `{ principal, allow, updatedAtMs, updatedBy, note? }`(审计行内,[ref] §1.3;`updatedBy` = 调用方 operator
10
10
  * principal,server 铸,body 不收)。
11
11
  *
12
12
  * ── 稿偏离两条(如实记)────────────────────────────────────────────────────────────────────────────
13
- * ① S-50 §1.1/§1.3 写的是 `orgDefault` + `(org_id, principal)`。亲读本仓(2026-08-30 侦察):server **没有 org 身份维**
13
+ * ① [ref] §1.1/§1.3 写的是 `orgDefault` + `(org_id, principal)`。亲读本仓(2026-08-30 侦察):server **没有 org 身份维**
14
14
  * (租户维 = 单 principal;`org` 只是记忆 scope 目录里的词),给表/wire 铸一根没人能填的 `org_id` 是编数据。一台
15
15
  * worker = 一个租户面 ⇒ 「org 级缺省」落成**部署级缺省**,wire 键名随实体改叫 `deploymentDefault`。折叠律不变。
16
- * ② S-50 §1.3 把部署缺省写成 `PUT …/memory-optout/default`。codex R1-[medium] 验真:`default` 是一个**合法 principal
16
+ * ② [ref] §1.3 把部署缺省写成 `PUT …/memory-optout/default`。codex R1-[medium] 验真:`default` 是一个**合法 principal
17
17
  * 拼写**,字面路径 `/default` 与 `%64efault`(解码后同为 `default`)在第一版里分派到**两个不同的行**(哨兵行 vs
18
18
  * 一条名叫 default 的覆盖行)—— 命名空间碰撞,而且 DELETE 侧还不对称。修法不是「解码后再保留一个词」(那只是把
19
19
  * 碰撞改成一条不可寻址的 principal),而是**让缺省行住在集合根**:`PUT /v1/admin/memory-optout`(集合本身的
@@ -35,7 +35,7 @@
35
35
  * 本仓 501 `capability.*` 族的定义(`capability.memory_engine_required` / `capability.outcome_ledger_required`
36
36
  * 同族)。能力位 `memoryOptOutGrant`(`GET /v1/capabilities`)读同一个事实 + operator 名单非空。
37
37
  *
38
- * ── 撤销窗(S-50 §1.4)──────────────────────────────────────────────────────────────────────────
38
+ * ── 撤销窗([ref] §1.4)──────────────────────────────────────────────────────────────────────────
39
39
  * 写后**零缓存**:resolver 腿(`RuntimeCaps.allowMemoryOptOut`)每次 prepare 直读同一张表 ⇒ 下一次带声明的
40
40
  * prepare 即读到新 verdict(撤权后新声明具名拒;已声明会话 record wins,core 判,server 零码)。
41
41
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * design/183 §4.3 —— **收编面**(operator lane):`POST /v1/adoption` 发起、`GET /v1/adoption/:id` 读状态。
2
+ * [ref] §4.3 —— **收编面**(operator lane):`POST /v1/adoption` 发起、`GET /v1/adoption/:id` 读状态。
3
3
  *
4
4
  * 形态:一次性的**部署级动作**,不是常驻业务面 —— 所以它 billable=false(零模型工作)、operator-only、
5
5
  * 且在没有 SQL 后端的部署上诚实 501(收编重绑的是多租身份轴,local 后端根本没有那个轴)。
@@ -1,5 +1,5 @@
1
1
  /**
2
- * #A1([4147] 窗三件批 件3;C-R13 链的 server 前置)—— 后台 agent **名册读面**
2
+ * #A1([ref] 窗三件批 件3;[ref] 链的 server 前置)—— 后台 agent **名册读面**
3
3
  * `GET /v1/agents/roster`。
4
4
  *
5
5
  * ## 读的是哪个店(两个「名册」概念的定界)
@@ -1,10 +1,10 @@
1
1
  /**
2
- * design/158 A9 域模块 —— 人在环审批面(durable F4 + legacy)与 assistant-scheduler 三动词。
2
+ * [ref] A9 域模块 —— 人在环审批面(durable F4 + legacy)与 assistant-scheduler 三动词。
3
3
  *
4
4
  * 路由(前缀 `/v1/approvals` 与 `/v1/assistant`):
5
5
  * · durable 腿(接了 checkpointStore 时优先):list / stream(SSE 原生推送)/ decide|answer / preempt /
6
6
  * resume / plan_review;
7
- * · legacy 腿(approvalStore 轮询车道)已于 5.0.0 整体退役([2354]/[2356] A-5)——无 checkpointStore 时
7
+ * · legacy 腿(approvalStore 轮询车道)已于 5.0.0 整体退役([ref]/[ref] A-5)——无 checkpointStore 时
8
8
  * `/v1/approvals` 落 404(诚实缺席),不再有 trusted-header 决裁面。
9
9
  *
10
10
  * 所有会**烧模型**的续跑都经 `ctx.legs.*`(resumeCheckpoint / resumePreempted / resumePlanReview)走 resume
@@ -25,20 +25,20 @@ export declare const ASSISTANT_PLAN_REVIEW_RE: RegExp;
25
25
  export declare function isQuestionAnswer(v: unknown): v is QuestionAnswer;
26
26
  export declare function handleApprovalsAssistant(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
27
27
  /**
28
- * GET /v1/approvals/stream (design/80 native push): SSE — pushes pending-approval deltas so the portal
28
+ * GET /v1/approvals/stream ([ref] native push): SSE — pushes pending-approval deltas so the portal
29
29
  * SUBSCRIBES ONCE instead of polling GET /v1/approvals every ~10s (better UX: near-real-time + no client poll
30
30
  * loop). Polls listPending(scope) and diffs against the prior snapshot: `pending` for a new suspend, `resolved`
31
31
  * for a decided/expired/gone one. Cross-replica BY CONSTRUCTION — the poll reads the SHARED checkpoint table,
32
32
  * so a suspend on ANY replica is seen by an operator streaming on a DIFFERENT replica. A transient DB blip
33
33
  * heartbeats + retries (never kills the stream); a 15-min cap + req-close end it (parity with streamTaskTrace).
34
- * Poll-granularity caveat (**narrowed** by [3684]②): the delta now re-emits a `pending` frame whenever a key's
34
+ * Poll-granularity caveat (**narrowed** by [ref]②): the delta now re-emits a `pending` frame whenever a key's
35
35
  * WIRE PROJECTION changes (upsert), not only when the key enters — so a same-key re-suspend within one interval
36
36
  * IS visible as long as anything on the row differs. What still shows no delta is the strictly degenerate case:
37
37
  * a resolve + re-suspend on the same (session,toolCallId) whose projection is BYTE-IDENTICAL — indistinguishable
38
38
  * by construction, and harmless (the card the operator sees is the card that is pending). Pins: the two halves of
39
39
  * `test/wire-pairing-approvals-stream.test.ts` S3b (changed ⇒ re-emit with the NEW payload; unchanged ⇒ silence).
40
40
  *
41
- * A-002.19(2026-08-09 亲验定性=设计接受,非欠账):每连接自跑 pollMs 轮询打共享 checkpoint 表,
41
+ * [ref](2026-08-09 亲验定性=设计接受,非欠账):每连接自跑 pollMs 轮询打共享 checkpoint 表,
42
42
  * 之所以不建 fan-out/单轮询器基建——①消费方=portal 运营面,并发连接数量级为个位(不是用户面);
43
43
  * ②listPending 走 (scope,status) 索引,单查成本与一次 /v1/approvals 轮询同阶,而本路正是替代客户端
44
44
  * ~10s 轮询的(净负载持平或更低);③DB blip 已 fail-soft(心跳+下拍重试),15-min cap 兜顶。连接
@@ -46,7 +46,7 @@ export declare function handleApprovalsAssistant(req: IncomingMessage, res: Serv
46
46
  * 演化,不是现在的缺陷。
47
47
  */
48
48
  export declare function streamApprovals(req: IncomingMessage, res: ServerResponse, cs: Pick<CheckpointStoreFull, "listPending">, scope: string | undefined,
49
- /** [3684]②:出身归因的部署侧一半(缺席 ⇒ 归不出治理出身 ⇒ 键缺席,与 best-effort 同方向)。**位置在
49
+ /** [ref]②:出身归因的部署侧一半(缺席 ⇒ 归不出治理出身 ⇒ 键缺席,与 best-effort 同方向)。**位置在
50
50
  * `pollMs` 之前**是刻意的:`pollMs` 只有测试传,而本参数是每个生产调用点都必须给的那一个。 */
51
51
  governance?: GovernancePosture, pollMs?: number): Promise<void>;
52
52
  //# sourceMappingURL=approvals-assistant.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { DECIDED_REPLAY_SCAN_CAP, approvalPayloadFingerprint } from "../../plugins/checkpoint-store-sql.js";
2
+ import { APPROVAL_GATE_KINDS } from "../../tool-approval.js";
2
3
  import { isParkedRunStatus } from "../../plugins/store-contracts.js";
3
4
  import { principalFrom, decodeCheckpointScope, PRINCIPAL_TOKEN_HEADER, APPROVAL_MAC_HEADER, APPROVAL_MAC_KID_HEADER } from "../../security.js";
4
5
  import { verifyDirectDoorProof } from "../../principal-jwt.js";
@@ -457,7 +458,9 @@ async function handleApprovalsAssistantBody(req, res, url, ctx, miss) {
457
458
  const operators = deps.config.operatorPrincipals;
458
459
  const explicitOperator = explicitOperatorOk(deciderPrincipal, operators);
459
460
  if (!explicitOperator) {
460
- const cpScope = await cs.peekPendingScope(sessionId);
461
+ const cpScope = await cs
462
+ .peekPendingScope(sessionId, { gateKinds: APPROVAL_GATE_KINDS })
463
+ .then((s) => (s === undefined ? cs.peekPendingScope(sessionId) : s));
461
464
  const decodedCpScope = cpScope != null ? decodeCheckpointScope(cpScope) : undefined;
462
465
  const ownsIt = cpScope == null || decodedCpScope === undefined || decodedCpScope === deciderPrincipal;
463
466
  if (!ownsIt) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * design/158 A9 域模块 —— 能力/场景/模型目录只读面。
2
+ * [ref] A9 域模块 —— 能力/场景/模型目录只读面。
3
3
  *
4
4
  * 路由:`GET /v1/capabilities/scenarios/:name`、`GET /v1/capabilities`、`GET /v1/models`。
5
5
  * 三条都在全局 service-credential 门**之后**(config 面非密只读),装配表里的位置必须保住这一点。
@@ -156,6 +156,7 @@ async function handleCapabilitiesBody(req, res, url, ctx, miss) {
156
156
  return allow.filter((n) => Object.hasOwn(live, n));
157
157
  })(),
158
158
  manualCompact: Boolean(deps.runStore),
159
+ configCatalog: deps.config.configCatalogEnabled === true && deps.config.operatorPrincipals.length > 0,
159
160
  });
160
161
  return;
161
162
  }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * DESIGN-278 §5 S2([ref])—— `GET /v1/config/catalog`:配置目录自描述端点(operator lane)。
3
+ *
4
+ * TOB 运维在 web 上要一个**不撒谎**的配置目录:哪个键、什么腿(env/center)、改了何时生效
5
+ * (hot/restart-片名/deploy/inert)、本机实际值 —— 今天这些事实散在 config.ts 数千行与三份文档里,
6
+ * 人肉汇编必然漂移。目录本体(逐键登记 + 实算)在 `src/config-catalog.ts`(D1 双向对账门钉住完备性),
7
+ * 本文件只做门与投影。
8
+ *
9
+ * 门序 = `POST /v1/admin/config/refresh` 逐字同族(operator lane):身份 → 授权 → 应答;billable=false,
10
+ * 刻意不吃 drain / roster-pending 两道 503(排障读面在停机窗里恰恰要打得通)。
11
+ *
12
+ * 🔴 鉴权 = `explicitOperatorOk`(空名单=谁都不是)——设计稿 §0.5 点名**禁** `isOperator` 那个
13
+ * 「空名单=人人都是」的 fail-open 谓词:本面是部署事实外泄口(env 在场性/后端形态/限额值),
14
+ * 单用户形也不放宽。
15
+ *
16
+ * 🔴 旋钮 `CONFIG_CATALOG_ENABLED=false` ⇒ **本域不认领**(装配器尾部 404 `not_found.route`)——
17
+ * 与 memory-consolidation 阀门同判:旋钮没开是一句运维表态(合规部署不想让部署事实上 wire),
18
+ * 不是部署能力缺失,404 的动作是「去把旋钮打开」,501 会指去一条修不好的路。能力位 `configCatalog`
19
+ * 与本判据同源(capabilities.ts,两项合取)。
20
+ *
21
+ * 🔴 secret 纪律:值的裁剪在 catalog 构建层(secret=在场位、opaque=在场位+长度、url=剥 userinfo),
22
+ * 本文件不再碰值 —— 一处裁剪,机器钉 = test/config-catalog.test.ts 的响应体 canary 扫描格。
23
+ */
24
+ import type { IncomingMessage, ServerResponse } from "node:http";
25
+ import type { RouteCtx } from "../route-ctx.js";
26
+ export declare const CONFIG_CATALOG_PATH = "/v1/config/catalog";
27
+ export declare function handleConfigCatalog(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
28
+ //# sourceMappingURL=config-catalog.d.ts.map
@@ -0,0 +1,42 @@
1
+ import { DOMAINS } from "@sema-agent/settings-schema";
2
+ import { sendJson, sendError } from "../send.js";
3
+ import { gatedPrincipal, explicitOperatorOk } from "../principal-gate.js";
4
+ import { configKnobTable } from "../../config.js";
5
+ import { buildConfigCatalog } from "../../config-catalog.js";
6
+ export const CONFIG_CATALOG_PATH = "/v1/config/catalog";
7
+ const OPERATOR_ONLY_MESSAGE = "the config catalog is operator-only: the caller principal is not in OPERATOR_PRINCIPALS (an empty list means NO one is an operator — configure it to enable this endpoint)";
8
+ export async function handleConfigCatalog(req, res, url, ctx) {
9
+ const miss = { fell: false };
10
+ handleConfigCatalogBody(req, res, url, ctx, miss);
11
+ return !miss.fell;
12
+ }
13
+ function handleConfigCatalogBody(req, res, url, ctx, miss) {
14
+ const { deps } = ctx;
15
+ const path = url.split("?")[0] ?? url;
16
+ if (req.method !== "GET" || path !== CONFIG_CATALOG_PATH) {
17
+ miss.fell = true;
18
+ return;
19
+ }
20
+ if (deps.config.configCatalogEnabled !== true) {
21
+ miss.fell = true;
22
+ return;
23
+ }
24
+ const principal = gatedPrincipal(req, deps.config);
25
+ if (deps.config.requirePrincipal && !principal) {
26
+ sendError(res, 401, "auth.principal_required", `missing principal header '${deps.config.principalHeader}'`);
27
+ return;
28
+ }
29
+ if (!explicitOperatorOk(principal, deps.config.operatorPrincipals)) {
30
+ sendError(res, 403, "auth.operator_only", OPERATOR_ONLY_MESSAGE);
31
+ return;
32
+ }
33
+ res.setHeader("Cache-Control", "no-store");
34
+ sendJson(res, 200, buildConfigCatalog({
35
+ config: deps.config,
36
+ env: process.env,
37
+ knobs: configKnobTable(),
38
+ centerDomains: DOMAINS,
39
+ centerManagedKeys: deps.configCenterManagedKeys?.(),
40
+ }));
41
+ }
42
+ //# sourceMappingURL=config-catalog.js.map