@sema-agent/server 7.43.0 → 7.44.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 (345) hide show
  1. package/USAGE.md +18 -0
  2. package/dist/adoption/plan.js +31 -192
  3. package/dist/adoption/quiesce.js +3 -86
  4. package/dist/adoption/runner.js +3 -140
  5. package/dist/adoption/sql.js +0 -74
  6. package/dist/adoption/wire.js +0 -80
  7. package/dist/approval-ask-machine.js +0 -75
  8. package/dist/approval-card.js +0 -323
  9. package/dist/approval-deny-reasons.js +0 -42
  10. package/dist/approval-hmac.js +0 -35
  11. package/dist/approval-reconciler.js +8 -166
  12. package/dist/approval.js +4 -67
  13. package/dist/audit.js +1 -44
  14. package/dist/auth-bridge.js +4 -47
  15. package/dist/auth-keys.js +0 -23
  16. package/dist/bake-runner/main.js +4 -65
  17. package/dist/bake-runner/protocol.js +3 -58
  18. package/dist/bake-runner/runner.js +5 -91
  19. package/dist/bench/l8/artifact.js +2 -61
  20. package/dist/bench/l8/escape.js +0 -25
  21. package/dist/bench/l8/index.js +0 -14
  22. package/dist/bench/l8/probes.js +0 -60
  23. package/dist/bench/l8/run-probes.js +2 -45
  24. package/dist/bench/s1/arms.js +14 -189
  25. package/dist/bench/s1/live-deps.js +11 -253
  26. package/dist/bench/s1/oracle.js +1 -36
  27. package/dist/bench/s1/repair-oracle-adapter.js +0 -30
  28. package/dist/bench/s1/reviewer.js +0 -34
  29. package/dist/bench/s1/row.js +0 -62
  30. package/dist/bench/s1/run-firm.js +4 -70
  31. package/dist/bench/s1/runner-ctx.js +0 -40
  32. package/dist/bench/s1/tasks.js +0 -115
  33. package/dist/boot/adoption.js +0 -20
  34. package/dist/boot/budget-tracing.js +3 -55
  35. package/dist/boot/config-center.js +43 -551
  36. package/dist/boot/coordinators.js +1 -69
  37. package/dist/boot/crash-last.js +0 -18
  38. package/dist/boot/deferred-sandbox-path-env.js +3 -119
  39. package/dist/boot/execution-env.js +5 -171
  40. package/dist/boot/governance-seams.js +0 -92
  41. package/dist/boot/leader.js +0 -69
  42. package/dist/boot/limit-sync.js +0 -2
  43. package/dist/boot/memory-boundary.js +3 -91
  44. package/dist/boot/org-memory.js +1 -25
  45. package/dist/boot/parked-revive-gate.js +0 -150
  46. package/dist/boot/permission-rules-audit.js +1 -56
  47. package/dist/boot/reapers.js +15 -273
  48. package/dist/boot/resolve-spec.js +9 -768
  49. package/dist/boot/retention-lane.js +4 -87
  50. package/dist/boot/runner-deps.js +3 -297
  51. package/dist/boot/runtime-caps.js +0 -40
  52. package/dist/boot/session-faces.js +2 -133
  53. package/dist/boot/shutdown.js +9 -83
  54. package/dist/boot/side-query-lane.js +2 -137
  55. package/dist/boot/stores.js +15 -215
  56. package/dist/boot/task-list-lane.js +0 -18
  57. package/dist/boot/webfetch-summarize-lane.js +0 -47
  58. package/dist/boot/workflow-orchestration.js +3 -99
  59. package/dist/boot-reclaim.js +0 -20
  60. package/dist/bounded-session-map.js +0 -19
  61. package/dist/brain.js +2 -139
  62. package/dist/budget.js +9 -244
  63. package/dist/capabilities/builtin-tools.js +0 -3
  64. package/dist/capabilities/center-plugins.js +6 -51
  65. package/dist/capabilities/center-prompts.js +6 -71
  66. package/dist/capabilities/code-review-council.js +7 -40
  67. package/dist/capabilities/collab-workflows.js +1 -44
  68. package/dist/capabilities/hands-lane.js +0 -65
  69. package/dist/capabilities/memory-notice.js +0 -70
  70. package/dist/capabilities/prompt.js +0 -14
  71. package/dist/capabilities/prompts/code-review.js +0 -14
  72. package/dist/capabilities/prompts/identity.js +0 -6
  73. package/dist/capabilities/prompts/team.js +0 -4
  74. package/dist/capabilities/repo-tools.js +0 -34
  75. package/dist/capabilities/sandbox-file-send.js +3 -92
  76. package/dist/capabilities/scenarios.d.ts +0 -1
  77. package/dist/capabilities/scenarios.js +18 -279
  78. package/dist/capabilities/select-environment-tool.js +0 -32
  79. package/dist/capabilities/send-user-file-tool.js +2 -66
  80. package/dist/capabilities/skills.d.ts +1 -2
  81. package/dist/capabilities/skills.js +3 -21
  82. package/dist/capabilities/team.d.ts +3 -11
  83. package/dist/capabilities/team.js +3 -51
  84. package/dist/capabilities/tool-defer.js +0 -3
  85. package/dist/config-center/apply-effective.js +15 -330
  86. package/dist/config-center/apply-ledger.js +5 -38
  87. package/dist/config-center/facade.js +0 -41
  88. package/dist/config-center/hot-keys-registry.js +0 -20
  89. package/dist/config-center/http-client.js +2 -125
  90. package/dist/config-center/mcp-revocation.js +2 -34
  91. package/dist/config-center/read-face.js +0 -59
  92. package/dist/config-center/restart-signal.js +1 -85
  93. package/dist/config-center/skills-mcp.d.ts +1 -1
  94. package/dist/config-center/skills-mcp.js +9 -76
  95. package/dist/config-center/stage-limits.js +8 -35
  96. package/dist/config-invariants.js +0 -16
  97. package/dist/config-lkg.js +0 -42
  98. package/dist/config-provider.js +3 -186
  99. package/dist/config-types.js +0 -5
  100. package/dist/config.js +107 -1145
  101. package/dist/degenerate-instrument.js +3 -67
  102. package/dist/deployment-governance.js +0 -124
  103. package/dist/digest-form.js +0 -12
  104. package/dist/elicitation.js +3 -86
  105. package/dist/env-facts.js +7 -75
  106. package/dist/fleet/fleet-bus.js +34 -507
  107. package/dist/fleet/fleet-reconciler.js +9 -149
  108. package/dist/fleet/fleet-terminal-window.js +10 -178
  109. package/dist/fleet/subagent-tail-bus.js +3 -72
  110. package/dist/fleet-client.js +10 -70
  111. package/dist/fleet-lease.js +5 -79
  112. package/dist/git-api-kind.js +0 -3
  113. package/dist/governance-ask-marks.js +2 -78
  114. package/dist/hooks/branch-transcript.js +0 -74
  115. package/dist/hooks/cc-agent-hook-prompt.js +0 -29
  116. package/dist/hooks/cc-stop-prompt.js +1 -46
  117. package/dist/hooks/hook-llm.js +1 -53
  118. package/dist/hooks/hook-runner.js +20 -414
  119. package/dist/http/active-run-conflict.js +4 -129
  120. package/dist/http/cursor-fingerprint.d.ts +5 -0
  121. package/dist/http/cursor-fingerprint.js +5 -0
  122. package/dist/http/idempotency.js +0 -37
  123. package/dist/http/principal-gate.js +3 -40
  124. package/dist/http/route-ctx.js +0 -9
  125. package/dist/http/routes/a2a-serve.js +7 -319
  126. package/dist/http/routes/admin-config-refresh.js +0 -4
  127. package/dist/http/routes/admin-drain.js +0 -10
  128. package/dist/http/routes/adoption.js +1 -29
  129. package/dist/http/routes/agents-roster.js +1 -47
  130. package/dist/http/routes/approvals-assistant.js +32 -395
  131. package/dist/http/routes/attachments.js +4 -22
  132. package/dist/http/routes/capabilities.js +3 -420
  133. package/dist/http/routes/diagnostics.js +1 -81
  134. package/dist/http/routes/fleet.js +9 -185
  135. package/dist/http/routes/images.js +14 -239
  136. package/dist/http/routes/leader.js +0 -13
  137. package/dist/http/routes/memory-bundle.js +1 -61
  138. package/dist/http/routes/memory-policy.js +9 -99
  139. package/dist/http/routes/notify-wake.js +3 -37
  140. package/dist/http/routes/observability.js +2 -19
  141. package/dist/http/routes/retention-ops.js +2 -34
  142. package/dist/http/routes/rules.js +1 -93
  143. package/dist/http/routes/runs.js +64 -873
  144. package/dist/http/routes/session-sync.js +19 -258
  145. package/dist/http/routes/sessions-list.js +17 -43
  146. package/dist/http/routes/sessions.js +34 -226
  147. package/dist/http/routes/shared-memory.js +5 -36
  148. package/dist/http/routes/side-query.js +1 -87
  149. package/dist/http/routes/tasks.js +52 -722
  150. package/dist/http/routes/trace-usage.js +32 -195
  151. package/dist/http/routes/workflows.js +19 -195
  152. package/dist/http/run-meta.js +0 -6
  153. package/dist/http/send.js +0 -32
  154. package/dist/http/server.js +92 -1597
  155. package/dist/http/sse-lifecycle.js +2 -13
  156. package/dist/http/sse-log.js +3 -48
  157. package/dist/http/tar.js +5 -21
  158. package/dist/http/verify-rounds.js +0 -5
  159. package/dist/http/wire-gate.js +0 -9
  160. package/dist/http/workspace-content.js +0 -10
  161. package/dist/images/bake-validate.js +1 -70
  162. package/dist/images/manifest.js +1 -6
  163. package/dist/index.js +0 -21
  164. package/dist/key-resolver.js +2 -17
  165. package/dist/leader/diffout.js +1 -20
  166. package/dist/leader/diffup.js +0 -47
  167. package/dist/leader/endpoint.js +2 -57
  168. package/dist/leader/fanout.js +3 -45
  169. package/dist/leader/grader-env-factory.js +3 -72
  170. package/dist/leader/leader.js +5 -156
  171. package/dist/leader/merge.js +8 -115
  172. package/dist/leader/planner.js +3 -54
  173. package/dist/leader/repair-oracle.js +1 -60
  174. package/dist/leader/repair-wire.js +2 -79
  175. package/dist/leader/wire.js +8 -307
  176. package/dist/lsp/e2b-bridge.js +4 -64
  177. package/dist/lsp/e2b-manager.js +6 -94
  178. package/dist/lsp/lsp-frames.js +0 -12
  179. package/dist/lsp/manager.js +4 -96
  180. package/dist/lsp/ws-transport.js +5 -55
  181. package/dist/lsp-evict.js +1 -15
  182. package/dist/main.js +57 -765
  183. package/dist/memory-bundle-engine.js +0 -55
  184. package/dist/memory-export.js +0 -4
  185. package/dist/memory-posture.js +1 -15
  186. package/dist/memory-scope.js +11 -148
  187. package/dist/memory-sync-client.js +2 -44
  188. package/dist/memory-sync.js +1 -80
  189. package/dist/model-select.js +3 -80
  190. package/dist/observability/cost-quota.js +1 -17
  191. package/dist/observability/cost-taxonomy.js +0 -34
  192. package/dist/observability/fail-open.js +7 -86
  193. package/dist/observability/logger.js +0 -6
  194. package/dist/observability/metrics.js +0 -94
  195. package/dist/observability/otel-exporter.js +3 -13
  196. package/dist/observability/principal-context.js +0 -9
  197. package/dist/observability/prompt-manifest.js +1 -37
  198. package/dist/observability/rate-limit.js +0 -4
  199. package/dist/observability/secret-env-scrub.js +2 -56
  200. package/dist/observability/tool-trace.js +1 -70
  201. package/dist/orchestration/hardened-vm-runner.js +4 -118
  202. package/dist/orchestration/hardened-vm-worker-runner.js +1 -26
  203. package/dist/orchestration/hardened-vm-worker.js +0 -27
  204. package/dist/orchestration/subagent-steer.js +1 -45
  205. package/dist/orchestration/workflow-agent-steer.js +1 -80
  206. package/dist/orchestration/workflow-completion-inbox.js +32 -285
  207. package/dist/orchestration/workflow-notify-journal.js +16 -259
  208. package/dist/org-memory-admission.js +3 -47
  209. package/dist/parent-watch.js +2 -48
  210. package/dist/parked-decide.js +1 -109
  211. package/dist/per-task-image.js +0 -57
  212. package/dist/plan-cache-probe.js +3 -27
  213. package/dist/plugins/adoption-log-sql.js +2 -119
  214. package/dist/plugins/approval-ask-store-memory.js +3 -38
  215. package/dist/plugins/approval-ask-store-sql.js +6 -188
  216. package/dist/plugins/approval-exemption-store.js +2 -28
  217. package/dist/plugins/background-agent-store-sql.js +4 -105
  218. package/dist/plugins/background-shell-support.js +14 -122
  219. package/dist/plugins/blob-backend.js +6 -169
  220. package/dist/plugins/breaker-state-sql.js +8 -46
  221. package/dist/plugins/caching-session-store.js +4 -106
  222. package/dist/plugins/checkpoint-store-sql.js +18 -505
  223. package/dist/plugins/e2b-orphan-reclaim.js +0 -45
  224. package/dist/plugins/file-outcome-sink.js +0 -9
  225. package/dist/plugins/file-resume-anchor-store.js +4 -43
  226. package/dist/plugins/file-run-store.js +26 -364
  227. package/dist/plugins/file-snapshot-store-sql.js +10 -181
  228. package/dist/plugins/fork-routing-session-store.js +8 -111
  229. package/dist/plugins/host-platform.js +2 -91
  230. package/dist/plugins/image-bake-store-sql.js +7 -250
  231. package/dist/plugins/image-index-sql.js +4 -123
  232. package/dist/plugins/k8s-bg-scripts.js +4 -88
  233. package/dist/plugins/k8s-exec-protocol.js +0 -41
  234. package/dist/plugins/leader-run-store-sql.js +0 -101
  235. package/dist/plugins/local-checkpoint-store.js +8 -128
  236. package/dist/plugins/local-session-store.js +34 -296
  237. package/dist/plugins/local-task-attachment-store.js +2 -16
  238. package/dist/plugins/mailbox-store-sql.js +8 -65
  239. package/dist/plugins/memory-embedder-fingerprint.js +5 -166
  240. package/dist/plugins/memory-embedder.js +4 -70
  241. package/dist/plugins/memory-engine-pg.js +6 -170
  242. package/dist/plugins/memory-engine-tidb.js +7 -155
  243. package/dist/plugins/memory-engine-vector-util.js +0 -10
  244. package/dist/plugins/memory-key-guards.js +0 -34
  245. package/dist/plugins/memory-origin-law.js +0 -187
  246. package/dist/plugins/memory-resume-anchor-store.js +0 -17
  247. package/dist/plugins/memory-run-store.js +12 -89
  248. package/dist/plugins/memory-session-policy-store.js +0 -17
  249. package/dist/plugins/memory-sync-store-pg.js +4 -49
  250. package/dist/plugins/memory-sync-store-tidb.js +3 -35
  251. package/dist/plugins/outcome-ledger-sql.js +3 -97
  252. package/dist/plugins/permission-rule-store-file.js +5 -133
  253. package/dist/plugins/permission-rule-store-sql.d.ts +3 -0
  254. package/dist/plugins/permission-rule-store-sql.js +50 -307
  255. package/dist/plugins/pg-cost-quota.js +0 -7
  256. package/dist/plugins/pg-pool.js +0 -92
  257. package/dist/plugins/pg-rate-limiter.js +2 -13
  258. package/dist/plugins/pg-safe-json.js +4 -40
  259. package/dist/plugins/pg-session-storage.js +25 -189
  260. package/dist/plugins/posix-shell-fs.js +1 -31
  261. package/dist/plugins/remote-env-adb.js +12 -101
  262. package/dist/plugins/remote-env-e2b.js +40 -371
  263. package/dist/plugins/remote-env-file-error.js +0 -37
  264. package/dist/plugins/remote-env-host.js +63 -483
  265. package/dist/plugins/remote-env-k8s.js +32 -326
  266. package/dist/plugins/remote-env-local-docker.js +24 -157
  267. package/dist/plugins/remote-env-ssh.js +20 -128
  268. package/dist/plugins/remote-scratchpad.js +2 -32
  269. package/dist/plugins/remote-shell.js +1 -32
  270. package/dist/plugins/resume-anchor-store-sql.js +0 -11
  271. package/dist/plugins/retention-lane-store-sql.js +0 -108
  272. package/dist/plugins/retention-store-sql.js +4 -383
  273. package/dist/plugins/roster-store-sql.js +0 -55
  274. package/dist/plugins/run-store-sql.js +14 -251
  275. package/dist/plugins/s3-presign.js +2 -49
  276. package/dist/plugins/scheduler-support.js +3 -80
  277. package/dist/plugins/send-file-ledger.js +4 -53
  278. package/dist/plugins/send-user-file.js +4 -94
  279. package/dist/plugins/session-placement.js +1 -89
  280. package/dist/plugins/session-policy-store-sql.js +3 -81
  281. package/dist/plugins/session-store.js +0 -57
  282. package/dist/plugins/shared-memory-store-sql.js +4 -167
  283. package/dist/plugins/sql-driver.js +0 -17
  284. package/dist/plugins/sql-errors.js +0 -7
  285. package/dist/plugins/sql-escape.js +0 -8
  286. package/dist/plugins/sql-row-helpers.js +0 -25
  287. package/dist/plugins/store-backend.js +42 -222
  288. package/dist/plugins/store-contracts.js +2 -46
  289. package/dist/plugins/task-attachment-store.js +3 -49
  290. package/dist/plugins/task-list-store-sql.js +0 -79
  291. package/dist/plugins/tidb-cost-quota.js +1 -4
  292. package/dist/plugins/tidb-pool.js +1 -207
  293. package/dist/plugins/tidb-rate-limiter.js +3 -9
  294. package/dist/plugins/tidb-session-storage.js +4 -70
  295. package/dist/plugins/tidb-session-store.js +19 -341
  296. package/dist/plugins/tool-result-store-sql.js +4 -179
  297. package/dist/plugins/usage-window-store-sql.js +0 -8
  298. package/dist/plugins/web-search.js +10 -132
  299. package/dist/plugins/workflow-journal-store-sql.js +2 -58
  300. package/dist/plugins/workflow-run-store-sql.js +6 -91
  301. package/dist/plugins/worktree-isolation.js +6 -126
  302. package/dist/plugins/write-behind-counter.js +16 -75
  303. package/dist/principal-jwt.js +5 -60
  304. package/dist/project-memory.js +15 -146
  305. package/dist/prompts-domain-validate.js +1 -51
  306. package/dist/question.js +2 -111
  307. package/dist/resource-suspend.js +0 -18
  308. package/dist/router/route-orchestration.js +0 -77
  309. package/dist/rules-consent.d.ts +44 -5
  310. package/dist/rules-consent.js +75 -215
  311. package/dist/run-local.js +14 -381
  312. package/dist/runs.js +29 -617
  313. package/dist/runtime-caps-resolver.js +6 -132
  314. package/dist/runtime-governance.js +1 -232
  315. package/dist/sandbox-pkg-source.js +0 -37
  316. package/dist/sealed-key.js +3 -68
  317. package/dist/security.js +6 -291
  318. package/dist/session-leaf-bus.js +0 -32
  319. package/dist/session-sync-content.js +1 -69
  320. package/dist/session-sync-kernel.js +3 -60
  321. package/dist/session-sync.js +3 -66
  322. package/dist/session-titler.js +7 -41
  323. package/dist/session-watch.js +9 -73
  324. package/dist/shared-memory-scope-authorizer.js +0 -18
  325. package/dist/sighup-idle.js +1 -12
  326. package/dist/spec-fields.js +4 -143
  327. package/dist/store-live-probe.js +3 -49
  328. package/dist/task-a2a.js +1 -126
  329. package/dist/task-cwd.js +1 -103
  330. package/dist/task-mcp.js +1 -89
  331. package/dist/task-settings.js +10 -300
  332. package/dist/task-workflow.js +8 -75
  333. package/dist/tool-approval.d.ts +28 -1
  334. package/dist/tool-approval.js +70 -1430
  335. package/dist/trace/artifacts.js +5 -20
  336. package/dist/trace/engine-notice-wire.js +6 -138
  337. package/dist/trace/ledger-sink.js +7 -96
  338. package/dist/trace/project.js +4 -448
  339. package/dist/trace/redact.js +9 -77
  340. package/dist/turn-activity.js +1 -27
  341. package/dist/usage-analytics.js +4 -34
  342. package/dist/wall-clock-jump-guard.js +1 -68
  343. package/package.json +3 -3
  344. package/dist/capabilities/scenario-alias.d.ts +0 -27
  345. package/dist/capabilities/scenario-alias.js +0 -61
@@ -1,40 +1,3 @@
1
- /**
2
- * ConfigProvider — the dual-mode seam over WHERE the effective config comes from (see
3
- * sema-registry docs/DUAL-MODE-DESIGN.md §4).
4
- *
5
- * The service consumes the config-center through EXACTLY two transport calls — `fetchEffective` (pull the
6
- * effective config, ETag-conditional) and `fetchSkillContent` (lazy-pull one skill body by content hash).
7
- * Everything downstream (applyEffective / applyRuntimeGates / resolveMcpServers / mcpForScenario / the
8
- * skill overlay) is transport-agnostic: it operates on the returned `EffectiveConfig` / skill string.
9
- *
10
- * STATUS — FULLY provider-routed (提示词装配协议 §9.5-1/-3): boot AND the 60s refresh loop both pull
11
- * through `configProvider.fetchEffective` (main.ts), so `CONFIG_PROVIDER=local` gets the same ongoing
12
- * poll as the fleet path — a config.d edit lands within one poll (the local etag is the store's raws
13
- * hash). The caller runs a whole-candidate gate over `domainErrors` (§9.5-5): on refresh an invalid
14
- * domain rejects the candidate and the last-known-good keeps serving; boot stays tolerant per-domain
15
- * (no LKG exists yet).
16
- *
17
- * This module factors those two calls behind a `ConfigProvider` interface with two backends:
18
- *
19
- * - {@link RemoteConfigProvider} — the existing behaviour. DELEGATES verbatim to the exported
20
- * `facade.fetchEffective` / `facade.fetchSkillContent` (HTTP + Bearer + ETag + hash
21
- * verify). No HTTP is reimplemented here; this is a thin wrapper that binds baseUrl/token/worker.
22
- *
23
- * - {@link LocalConfigProvider} — reads the SAME config contract from the local filesystem via
24
- * `@sema-agent/registry-core/node` `FileConfigStore` (`.env` + `config.d/<domain>.json` → an
25
- * `EffectiveConfig` through the SAME resolver the center uses). The registry `EffectiveConfig`
26
- * is a structural SUPERSET of the service-local `EffectiveConfig` the consumers expect, so we map
27
- * it down to EXACTLY that shape (see `mapToServiceEffective`). Skills are stored locally WITH their
28
- * bodies (the local store doesn't split content into a manifest), so `fetchSkillContent` is a
29
- * content-addressed lookup over the local skills domain (absent → undefined, mirroring a remote 404).
30
- *
31
- * SECRET BOUNDARY (unchanged in both modes): the config plane carries only env-NAME refs — `apiKeyEnv`,
32
- * `envRefs`/`headerRefs`, `tokenEnv`. The real secret VALUE is never stored in config.d/<domain>.json and
33
- * never read by this module; it is resolved from `process.env` downstream (config-center/facade.ts
34
- * `applyEffective`/`resolveMcpServers`). The local store is symmetric with the remote center on this: it
35
- * ships NAMEs only. (Unit test asserts the local path resolves env-NAME→value via process.env and never
36
- * persists a value.)
37
- */
38
1
  import { createHmac, randomBytes } from "node:crypto";
39
2
  import { FileConfigStore } from "@sema-agent/registry-core/node";
40
3
  import { findSkillContent, skillContentHash, refIntegrityIssues, siblingResolver, } from "@sema-agent/registry-core";
@@ -42,35 +5,14 @@ import { redactSecrets } from "./trace/redact.js";
42
5
  import { fetchEffective as remoteFetchEffective, fetchSkillContent as remoteFetchSkillContent, ConfigCenterHttpError, } from "./config-center/facade.js";
43
6
  import { createLogger } from "./observability/logger.js";
44
7
  const logger = createLogger();
45
- /**
46
- * domainError strings must not echo raw config operands (self-review, information-surface lens):
47
- * ref-integrity messages quote the referenced value verbatim, and tolerant-read parse failures carry
48
- * zod/JSON.parse fragments of the file text — a controlled value pasted into the wrong slot (say, a
49
- * credential in a model-ref position) would otherwise ride `config_candidate_rejected` /
50
- * `config_domain_invalid` into the structured log stream. This runs at the producing boundary (the
51
- * local provider is the only domainErrors producer): shared secret-shape redaction first, then every
52
- * quoted operand becomes a short one-way fingerprint — keyed per process so the fingerprint is not a
53
- * dictionary-comparable digest of the value, while equal operands still correlate within one log
54
- * stream. The issue `path` stays clear; it is how the operator locates the entry.
55
- */
56
8
  const OPERAND_FINGERPRINT_KEY = randomBytes(16);
57
9
  function redactConfigError(text) {
58
10
  return redactSecrets(text).replace(/"[^"]*"|'[^']*'/g, (m) => `"#${createHmac("sha256", OPERAND_FINGERPRINT_KEY).update(m.slice(1, -1)).digest("hex").slice(0, 8)}"`);
59
11
  }
60
- /** Sentinel returned by {@link raceBootFetch} when the boot pull outlived its budget — the caller
61
- * starts serving on the env fallback and the SAME promise settles in the background (never cancelled). */
62
12
  export const BOOT_FETCH_DEFERRED = Symbol("boot-fetch-deferred");
63
- /**
64
- * Race the boot config pull against a wall-clock budget (clay 2026-07-17: a black-holed center made
65
- * the SYNCHRONOUS boot pull hang ~5.7s on the TOC lane — the "local server takes 5s to start" report).
66
- * Inside the budget → the fetch result verbatim (the healthy-center fast path is unchanged, typically
67
- * <300ms). Past it → {@link BOOT_FETCH_DEFERRED}; the fetch is NOT aborted — the caller chains a
68
- * background continuation that triggers a refresh tick when it finally settles. The timer is unref'd
69
- * (never holds the loop) and cleared as soon as the fetch wins.
70
- */
71
13
  export function raceBootFetch(fetch, budgetMs) {
72
14
  if (budgetMs <= 0)
73
- return Promise.resolve(BOOT_FETCH_DEFERRED); // explicit "never block boot" posture
15
+ return Promise.resolve(BOOT_FETCH_DEFERRED);
74
16
  let timer;
75
17
  const budget = new Promise((res) => {
76
18
  timer = setTimeout(() => res(BOOT_FETCH_DEFERRED), budgetMs);
@@ -78,11 +20,6 @@ export function raceBootFetch(fetch, budgetMs) {
78
20
  });
79
21
  return Promise.race([fetch.finally(() => clearTimeout(timer)), budget]);
80
22
  }
81
- /**
82
- * RemoteConfigProvider — DELEGATES to the exported config-center HTTP functions. No HTTP is reimplemented;
83
- * baseUrl/token/worker are bound once and passed through. The two delegate fns are injectable (defaulting
84
- * to the real config-center exports) so a unit test can assert delegation without module-mocking.
85
- */
86
23
  export class RemoteConfigProvider {
87
24
  cc;
88
25
  deps;
@@ -93,22 +30,13 @@ export class RemoteConfigProvider {
93
30
  }
94
31
  async fetchEffective(etag) {
95
32
  const fn = this.deps.fetchEffective ?? remoteFetchEffective;
96
- // 5th arg = worker scope; transport (fetchImpl) stays the config-center's default.
97
33
  const r = await fn(this.cc.baseUrl, this.cc.token, etag, undefined, this.cc.worker);
98
34
  if (r === null || r.domainErrors === undefined)
99
35
  return r;
100
- // [2281] 裁B:远程腿从此也产 domainErrors(http-client 消费端校验)。与本地腿同一条产出边界纪律:
101
- // error 文本先过 redactConfigError(zod 错误会回声违规值——operand 指纹化,防受控值经
102
- // config_candidate_rejected/config_domain_invalid 进结构化日志流)。
103
36
  return { ...r, domainErrors: r.domainErrors.map((de) => ({ domain: de.domain, error: redactConfigError(de.error) })) };
104
37
  }
105
38
  async fetchSkillContent(contentHash) {
106
39
  const fn = this.deps.fetchSkillContent ?? remoteFetchSkillContent;
107
- // Honor the ConfigProvider contract symmetrically with the local backend: an UNKNOWN hash → undefined
108
- // (caller keeps its baseline), and ONLY a hard error (non-404 HTTP / hash mismatch) throws. The remote
109
- // transport throws a ConfigCenterHttpError(status=404) for an unknown hash; we translate that single
110
- // case to undefined and re-throw everything else, so both backends return the same thing for the same
111
- // "unknown hash" input (substitutability — the whole point of this seam).
112
40
  try {
113
41
  return await fn(this.cc.baseUrl, this.cc.token, contentHash);
114
42
  }
@@ -119,20 +47,10 @@ export class RemoteConfigProvider {
119
47
  }
120
48
  }
121
49
  }
122
- /**
123
- * LocalConfigProvider — reads the SAME config contract from disk via `FileConfigStore`. `getEffective()`
124
- * returns the registry `EffectiveConfig` (all domains, defaults filled); `getVersion()` returns a
125
- * stable change-detector. We map that down to the service-local `EffectiveConfig` shape and surface the
126
- * version as the etag (so the caller's "skip re-apply if etag unchanged" works locally too).
127
- */
128
50
  export class LocalConfigProvider {
129
51
  kind = "local";
130
52
  store;
131
- /** [875]b 可观测性:config_loaded 日志要能回答「到底读的哪个目录」——复验实录:只设 LOCAL_DATA_ROOT 时
132
- * config.d 静默读不到且 0 模型无告警(CONFIG_LOCAL_DIR 才是本 lane 的选目录旋钮)。 */
133
53
  root;
134
- /** 注入 store(测试缝)时保持其自带行为;自建时 fetchEffective 每次按调用铸新 store 挂 warning 座
135
- * (见 fetchEffective 头注)。 */
136
54
  #injectedStore;
137
55
  constructor(root, store) {
138
56
  this.root = root;
@@ -140,29 +58,12 @@ export class LocalConfigProvider {
140
58
  this.store = store ?? new FileConfigStore(root);
141
59
  }
142
60
  async fetchEffective(etag) {
143
- // SINGLE store read: derive BOTH the etag AND the mapped payload from ONE atomic raws snapshot. Reading
144
- // getVersion() and getEffective() separately would pair an etag from snapshot A with a payload from
145
- // snapshot B if config.d is rewritten between the two awaits — a consumer could then cache etag=A bound
146
- // to payload-B and, once files settle back to A, skip re-applying the now-correct config (304-skip
147
- // staleness). `eff.version` IS the authoritative version of THIS payload (file-store getEffective()
148
- // invariant), so it is the only correct source for the etag. Cost: we compute `eff` even on an
149
- // unchanged poll, but that preserves snapshot consistency — see finding #3.
150
- // [898] tolerant read(0.10.12):catalog 域坏文件 ⇒ 该域 default+domainErrors 单列(不再连坐整包回落
151
- // env);gate 域坏文件仍 throw(走 caller 的整包 catch)。坏文件文本 hash 参与 version(坏≠absent、
152
- // 坏→修好均 bump),304-skip 纪律不漏拍——所以坏域场景下 etag 对比照旧安全。
153
- // [3073]#204④:判形失败(schema 坏形/重名条目)走的是 buildEffective 的 `onWarning`(parse 层落
154
- // default),不走 READ 层 throw——不接这个座,domainErrors 恒空,域被静默清空而排障 hint 只能谎报
155
- // 「文件空」。warning 座是 store 构造级而 fetch 可能重叠(boot 超窗后台腿 vs 首拍 refresh),
156
- // 共享缓冲会把别次快照的警告错记到本次结果(codex F2)——故自建形每次 fetch 铸新 store 配本地
157
- // 收集器(FileConfigStore 无跨调用状态,按次构造零成本);注入 store(测试缝)保持其自带行为。
158
61
  const parseWarnings = [];
159
62
  const store = this.#injectedStore ??
160
63
  new FileConfigStore(this.root, {
161
64
  onWarning: (w) => {
162
65
  if (w.kind === "domain-defaulted")
163
66
  parseWarnings.push({ domain: w.domain, error: w.error instanceof Error ? w.error.message : String(w.error) });
164
- // registry-core 0.19.0 响亮化三 kind(LANDING-7.38 接线件③):dropped/unread=operator 写了但没生效
165
- // (与 defaulted 同级),carried=承运但键表方(stage-limits)才认——都入诊断面,禁静默丢。
166
67
  else if (w.kind === "unknown-keys-dropped")
167
68
  parseWarnings.push({ domain: w.domain, error: `unknown keys dropped by domain schema: ${w.keys.join(", ")}` });
168
69
  else if (w.kind === "unknown-keys-carried")
@@ -174,46 +75,25 @@ export class LocalConfigProvider {
174
75
  const { effective: eff, domainErrors } = await store.getEffective({ tolerant: true });
175
76
  const tag = String(eff.version);
176
77
  if (etag !== undefined && etag === tag)
177
- return null; // unchanged → mirror remote 304
178
- // 提示词装配协议 §9.5-4 read-side cross-domain reference validation: dangling refs (a roster naming a
179
- // model that isn't in the catalog, …) fold into domainErrors, so the caller's candidate gate rejects
180
- // the tree whole on refresh (boot warns and proceeds — no LKG exists yet). Write-side zod is
181
- // per-domain only and the center runs this check on its write path; the local lane never had it.
182
- // The resolver gets THIS snapshot's domain values as `pending` (builder output is default-filled for
183
- // every domain), so the check never re-reads config.d — the one-atomic-snapshot invariant above holds.
78
+ return null;
184
79
  const refErrors = [];
185
80
  const resolve = siblingResolver(store, eff);
186
81
  for (const d of ["rosters", "workers", "models", "collab", "systems", "entitlement"]) {
187
82
  const issues = await refIntegrityIssues(d, eff[d], resolve);
188
- // path CLEAR (locates the entry) + message operand-fingerprinted (see redactConfigError).
189
83
  if (issues.length > 0)
190
84
  refErrors.push({ domain: d, error: issues.map((i) => `${i.path.join(".")}: ${redactConfigError(i.message)}`).join("; ") });
191
85
  }
192
- // parse 层判形失败与 READ 层坏文件同渠道:两者都是「坏域落 default」,候选门(§9.5-5)与排障 hint
193
- // 需要同样看见——此前判形失败静默(domainErrors 空+域被清空),比坏文件更隐蔽。
194
86
  const parseErrors = parseWarnings.map((w) => ({ domain: w.domain, error: redactConfigError(w.error) }));
195
87
  const errors = [...domainErrors.map((de) => ({ domain: de.domain, error: redactConfigError(de.error) })), ...parseErrors, ...refErrors];
196
88
  return { effective: mapToServiceEffective(eff, eff.version), etag: tag, ...(errors.length > 0 ? { domainErrors: errors } : {}) };
197
89
  }
198
90
  async fetchSkillContent(contentHash) {
199
- // The local store keeps skill BODIES inline (no manifest split), so this is a content-addressed lookup
200
- // over the skills domain. Absent hash → undefined (mirrors a remote 404 → caller keeps the baseline).
201
91
  const skills = await this.store.getDomain("skills");
202
92
  if (!skills)
203
93
  return undefined;
204
94
  return findSkillContent(skills, contentHash);
205
95
  }
206
96
  }
207
- /**
208
- * Map the registry `EffectiveConfig` (superset, all domains) → the service-local `EffectiveConfig`
209
- * the consumers (`applyEffective`, `resolveMcpServers`, …) expect. The two are structurally compatible
210
- * for every field the consumers read; this projection makes that explicit (and drops control-plane-only
211
- * domains the service never consumes: rosters, systems, workers, hosts, integrations, access).
212
- *
213
- * Skills are mapped to the MANIFEST shape (name/description/scenarios/contentHash/enabled) — the same
214
- * shape RemoteConfigProvider's `/effective` ships — so the lazy `fetchSkillContent`-by-hash path is
215
- * identical in both modes. The local content hash is the `contentHash` the store already computed.
216
- */
217
97
  export function mapToServiceEffective(eff, version) {
218
98
  return {
219
99
  version,
@@ -226,62 +106,33 @@ export function mapToServiceEffective(eff, version) {
226
106
  api: m.api,
227
107
  ...(m.baseUrl !== undefined ? { baseUrl: m.baseUrl } : {}),
228
108
  ...(m.apiKeyEnv !== undefined ? { apiKeyEnv: m.apiKeyEnv } : {}),
229
- // RL-1(P4 A0 发现,2026-08-02;autoCompactTokens/promptGuidance 同类病族):CLOSED 投影剥掉
230
- // sealedApiKey 会让本地 lane 的 sealed 模型绕过 applyEffective 的毒丸臂(严格互斥纪律)⇒
231
- // 静默烧网关共享 key——正是毒丸臂声称杜绝的事故。携带它,无 opener 时毒丸自然接管(fail-loud)。
232
109
  ...(m.sealedApiKey !== undefined ? { sealedApiKey: m.sealedApiKey } : {}),
233
- // 同族连带:quotaWeight 被剥 ⇒ 本地 lane 配额倍率静默归 1(weight-at-burn 面失真)。
234
110
  ...(m.quotaWeight !== undefined ? { quotaWeight: m.quotaWeight } : {}),
235
111
  tier: m.tier,
236
112
  reasoning: m.reasoning,
237
113
  vision: m.vision,
238
114
  ...(m.contextWindow !== undefined ? { contextWindow: m.contextWindow } : {}),
239
115
  ...(m.maxTokens !== undefined ? { maxTokens: m.maxTokens } : {}),
240
- // codex F5 ([818]① 1M dual-window): an EXPLICIT `autoCompactTokens` must survive this CLOSED
241
- // projection. [2373]B-6d:registry-core 0.13.0 已把它收进 ModelEntry schema(types.d.ts:157/212)
242
- // ——旧注的「strip-mode 会在上游丢值」的 honest gap 已随那次 schema addition 关闭,结构读改类型直读。
243
116
  ...(typeof m.autoCompactTokens === "number" ? { autoCompactTokens: m.autoCompactTokens } : {}),
244
- // A-067 C2-M1(F1a,本函数第 6 例同形丢字段):charsPerToken 远程腿 toModel 一直消费
245
- // (apply-effective charsPerTokenOf 判形),本 CLOSED 投影此前剥掉 ⇒ 本地 lane 的 token
246
- // 估算静默退回 env 默认/core 4。判形归 toModel 单点(此处只过境,不重判)。
247
117
  ...(typeof m.charsPerToken === "number" ? { charsPerToken: m.charsPerToken } : {}),
248
118
  ...(m.cost !== undefined ? { cost: m.cost } : {}),
249
119
  ...(m.extraBody !== undefined ? { extraBody: m.extraBody } : {}),
250
- // registry-core 0.10.13 promptGuidance ([998]⑤c): the CLOSED projection must pass it through or
251
- // the local lane silently drops the configured sentences (autoCompactTokens 同类病).
252
120
  ...(m.promptGuidance !== undefined ? { promptGuidance: m.promptGuidance } : {}),
253
121
  enabled: m.enabled,
254
122
  })),
255
123
  roles: eff.models.roles ?? {},
256
- // [874] registry-core 0.10.11:池结构级 `default?`(catalog name 目录键,与 roles.default 角色词两回事)
257
- // 本 mapper 是 CLOSED 投影——不直通则本地 lane 静默丢键(autoCompactTokens 同类病),applyEffective 的
258
- // resolveDefaultModelName 第一优先级在本地 lane 永远点不亮。写面悬空 ref 由 registry-core superRefine
259
- // fail-loud;存量/未经 schema 的路径仍由消费方 warn 降级(config-center/facade.ts resolveDefaultModelName)。
260
- ...(eff.models.default !== undefined ? { default: eff.models.default } : {}), // [2373]B-6c:0.13.0 类型直读(types.d.ts:641)
124
+ ...(eff.models.default !== undefined ? { default: eff.models.default } : {}),
261
125
  ...(eff.models.atModelAllowlist !== undefined ? { atModelAllowlist: eff.models.atModelAllowlist } : {}),
262
- // registry-core 0.9.0 档位组: verbatim passthrough — applyEffective's resolveActiveTiers reads
263
- // these structurally off eff.models (the remote lane ships them JSON-verbatim; the local lane must too).
264
- // [2373]B-6b:0.13.0 类型直读(EffectiveConfig.models 面已声明四键,宽铸删)。本地 lane 的
265
- // eff 来自 FileConfigStore 原始 JSON(非 zod 输出),tierGroups 的 ZodDefault 恒在场性不适用——门保留。
266
126
  ...(eff.models.tierGroups !== undefined ? { tierGroups: eff.models.tierGroups } : {}),
267
127
  ...(eff.models.activeTierGroup !== undefined ? { activeTierGroup: eff.models.activeTierGroup } : {}),
268
128
  },
269
- // registry-core 0.7 DELETED the teams domain (BREAKING, no compat key) — the local lane ships an EMPTY
270
- // teams face: applyEffective's teams branch no-ops and the team scenario falls back to the builtin
271
- // TEAM_PERSONAS base (a permanent base, not a stopgap). Its successor is `collab` below.
272
129
  teams: { teams: [] },
273
- // collab domain: verbatim structural passthrough — FileConfigStore reads
274
- // config.d/collab.json (PORTABLE_DOMAINS includes collab since 0.7) and applyEffective's
275
- // projectCollabToTeams consumes the same shape on both lanes. Optional-chained against shape drift.
276
130
  ...(eff.collab?.templates?.length ? { collab: { templates: eff.collab.templates } } : {}),
277
131
  skills: {
278
132
  skills: (eff.skills.skills ?? []).map((s) => ({
279
133
  name: s.name,
280
134
  description: s.description,
281
135
  scenarios: s.scenarios ?? [],
282
- // The local store keeps the body inline; content-address it HERE so the manifest carries the same
283
- // `sha256:<hex>` the remote /effective ships — and `fetchSkillContent` (findSkillContent) resolves
284
- // the same hash back to the body. (skillContentHash is byte-identical to the center's hash.)
285
136
  contentHash: skillContentHash(s.content),
286
137
  enabled: s.enabled,
287
138
  })),
@@ -293,8 +144,6 @@ export function mapToServiceEffective(eff, version) {
293
144
  scenarios: s.scenarios ?? [],
294
145
  enabled: s.enabled,
295
146
  ...(s.allowTools !== undefined ? { allowTools: s.allowTools } : {}),
296
- // E23: carry the per-server inbound-elicitation opt-in (default OFF). Typed end-to-end since
297
- // registry-core 0.1.34 added `McpServerSpec.elicitation?: boolean`.
298
147
  ...(s.elicitation !== undefined ? { elicitation: s.elicitation } : {}),
299
148
  };
300
149
  if (s.transport.kind === "stdio") {
@@ -319,22 +168,13 @@ export function mapToServiceEffective(eff, version) {
319
168
  };
320
169
  }),
321
170
  },
322
- // prompts 域投影(a 实现班车,[985]a §3/[1234]① 位):**catalog 轴打通 local lane**——catalog 是
323
- // center 铸好的 immutable envelope(免 covering 解析,server 零解析义务红线 [1042]②b 不破),
324
- // config.d/prompts.json 携带 `catalog` 即以 wire 双轴形(registry-core `EffectivePromptsWire`)下发,
325
- // 与 remote lane 的 additive prompts key 同门(adoptCenterPrompts→validatePromptsDomain,core verify
326
- // 全管线)。bindings(declaration 轴原料)仍不投影:covering 解析半场恒在 center,local lane 的
327
- // declaration 轴维持不透传(那不是遗漏,是分工)。
328
171
  ...(eff.prompts?.catalog !== undefined
329
172
  ? { prompts: { schemaVersion: 1, catalog: eff.prompts.catalog } }
330
173
  : {}),
331
174
  scenarios: {
332
- // ([1057] 注记保留:declaration 轴 remote lane only——covering 解析半场在 center(web),
333
- // local FileConfigStore 只有 bindings 原文而 server 零解析义务([1042]②b 红线)。)
334
175
  scenarios: (eff.scenarios.scenarios ?? []).map((sc) => ({
335
176
  name: sc.name,
336
177
  toolset: sc.toolset,
337
- // ([1053] 0.10.15:ScenarioEntry.prompt 字段已删——scenario 级提示词走 center prompts binding)
338
178
  enabled: sc.enabled,
339
179
  })),
340
180
  },
@@ -345,39 +185,16 @@ export function mapToServiceEffective(eff, version) {
345
185
  ...(eff.runtime.maxPrincipalCostUsd !== undefined ? { maxPrincipalCostUsd: eff.runtime.maxPrincipalCostUsd } : {}),
346
186
  ...(eff.runtime.costQuotaWindowSec !== undefined ? { costQuotaWindowSec: eff.runtime.costQuotaWindowSec } : {}),
347
187
  },
348
- // #322 批1(registry-core 0.19.0 第 17 域):`limits` 整包透传——本地腿的最后一米在此收口;漏了
349
- // 这行,14 键在 local lane 整域消失、继续吃 env 基线(LANDING-7.38 接线件②的事故形)。
350
188
  ...(eff.limits !== undefined ? { limits: eff.limits } : {}),
351
- // Governance trio (autonomy/commandPolicy/approvalRequire): moved OUT of runtime into the dedicated
352
- // governance domain (registry-core 0.6, runtime double-write mirror removed in 0.7.1 — buildEffective
353
- // still READ-lifts legacy raw runtime values into governance, so old on-disk config keeps working).
354
- // Mapped to the service-local `governance` slot; applyEffective's gatesView consumes it with priority.
355
- // The registry shapes are IDENTICAL to the service's Autonomy/CommandRule declarations (straight passthrough).
356
189
  governance: {
357
190
  ...(eff.governance.autonomy !== undefined ? { autonomy: eff.governance.autonomy } : {}),
358
191
  ...(eff.governance.commandPolicy !== undefined ? { commandPolicy: eff.governance.commandPolicy } : {}),
359
192
  ...(eff.governance.approvalRequire !== undefined ? { approvalRequire: eff.governance.approvalRequire } : {}),
360
193
  },
361
- // NOTE: entitlement is NOT mapped — the ruling is that the local lane never carries it (by design;
362
- // TOB governance concept) and the fleet scenario ruling rides center's caps view, not /effective.
363
194
  };
364
195
  }
365
- /**
366
- * Pick the backend off a CLOSED `provider` enum (`local` | `remote` | undefined): LOCAL when
367
- * `CONFIG_PROVIDER=local`, OR when no config-center URL is configured (a lone box with config.d/ on disk
368
- * and no control plane). REMOTE otherwise (a configured center URL, the default fleet posture). A
369
- * `CONFIG_PROVIDER=remote` with no URL is a misconfiguration — we fall through to local rather than
370
- * constructing a remote provider with no endpoint (the caller would have skipped the remote pull entirely
371
- * under the old code path; local-with-empty-config.d degrades to env the same way). An UNRECOGNIZED value
372
- * (typo / wrong case) is NOT treated as remote: it defaults to local (non-network) with a warn, so a
373
- * fat-fingered knob can never silently source config from an unintended/stale network endpoint.
374
- */
375
196
  export function createConfigProvider(input) {
376
197
  const p = input.provider;
377
- // Closed enum: only `local` | `remote` | undefined are valid. An unrecognized/typo'd value (`Local`,
378
- // `LOCAL`, ` local`, garbage) must NOT silently fall through to the network source — pick the non-network
379
- // safe default (local) and warn, so a misconfigured knob never sources config (incl. env-NAME refs that
380
- // gate secret wiring) from a possibly-stale remote URL the operator didn't intend. See finding #4.
381
198
  if (p !== undefined && p !== "local" && p !== "remote") {
382
199
  logger.warn("config_provider_unrecognized", {
383
200
  provider: p,
@@ -1,7 +1,2 @@
1
- /**
2
- * #270 §4 —— 托管留存的**灰度档**闭集。`as const` 数组是词表的唯一真源(config 解析、能力位、审计行
3
- * 的 `mode` 列共读它);两词之外的值在启动期响亮拒 —— 一个拼错的档位静默落回 `audit-only` 会让运维
4
- * 以为在删、其实没删,而拼成别的方向就是反过来那件更坏的事。
5
- */
6
1
  export const RETENTION_MODES = ["audit-only", "enforce"];
7
2
  //# sourceMappingURL=config-types.js.map