@sema-agent/server 7.131.0 → 7.132.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 (256) hide show
  1. package/MIGRATION.md +309 -0
  2. package/README.md +5 -1
  3. package/README.zh-CN.md +3 -1
  4. package/USAGE.md +163 -54
  5. package/dist/approval-card.d.ts +3 -1
  6. package/dist/approval-card.js +2 -3
  7. package/dist/audit.d.ts +7 -10
  8. package/dist/auth-bridge.d.ts +4 -0
  9. package/dist/auth-bridge.js +10 -11
  10. package/dist/boot/deployment-mods.d.ts +31 -0
  11. package/dist/boot/deployment-mods.js +26 -0
  12. package/dist/boot/execution-env.d.ts +1 -1
  13. package/dist/boot/execution-env.js +19 -6
  14. package/dist/boot/memory-boundary.d.ts +2 -2
  15. package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
  16. package/dist/boot/read-deny-anchor-audit.js +36 -0
  17. package/dist/boot/resolve-spec.d.ts +1 -5
  18. package/dist/boot/resolve-spec.js +19 -47
  19. package/dist/boot/runner-deps.d.ts +19 -8
  20. package/dist/boot/runner-deps.js +14 -2
  21. package/dist/boot/session-faces.d.ts +1 -7
  22. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  23. package/dist/boot/stage-03-store-backend.js +2 -2
  24. package/dist/boot/stage-04-stores.d.ts +1 -1
  25. package/dist/boot/stage-05-execution-env.d.ts +4 -4
  26. package/dist/boot/stage-05-execution-env.js +7 -10
  27. package/dist/boot/stage-06-runners.d.ts +2 -2
  28. package/dist/boot/stage-06-runners.js +5 -4
  29. package/dist/boot/stage-07-capability-layer.d.ts +2 -2
  30. package/dist/boot/stage-07-capability-layer.js +3 -3
  31. package/dist/boot/stage-08-reapers.d.ts +2 -2
  32. package/dist/boot/stage-09-leader.d.ts +3 -9
  33. package/dist/boot/stage-10-http-server.d.ts +3 -9
  34. package/dist/boot/stage-10-http-server.js +6 -7
  35. package/dist/boot/stores.d.ts +1 -1
  36. package/dist/boot/stores.js +5 -6
  37. package/dist/boot/web-admin.d.ts +0 -3
  38. package/dist/boot/web-admin.js +35 -35
  39. package/dist/brain.js +17 -22
  40. package/dist/budget.js +5 -4
  41. package/dist/caller-text-echo.d.ts +20 -0
  42. package/dist/caller-text-echo.js +24 -0
  43. package/dist/capabilities/brand-identity.d.ts +26 -0
  44. package/dist/capabilities/brand-identity.js +27 -0
  45. package/dist/capabilities/center-plugins.js +1 -1
  46. package/dist/capabilities/center-prompts.d.ts +32 -59
  47. package/dist/capabilities/center-prompts.js +18 -32
  48. package/dist/capabilities/engine-capabilities.js +2 -1
  49. package/dist/capabilities/hands-lane.d.ts +9 -6
  50. package/dist/capabilities/hands-lane.js +1 -1
  51. package/dist/capabilities/mcp-probe.d.ts +14 -1
  52. package/dist/capabilities/mcp-probe.js +22 -133
  53. package/dist/capabilities/scenarios.d.ts +34 -40
  54. package/dist/capabilities/scenarios.js +16 -33
  55. package/dist/capabilities/skills.d.ts +19 -4
  56. package/dist/capabilities/skills.js +30 -10
  57. package/dist/config-catalog.js +6 -6
  58. package/dist/config-lkg.d.ts +9 -9
  59. package/dist/config-lkg.js +20 -4
  60. package/dist/config-provider.d.ts +3 -1
  61. package/dist/config-provider.js +12 -4
  62. package/dist/config-types.d.ts +7 -9
  63. package/dist/config.js +17 -4
  64. package/dist/device-ws-protocol.d.ts +1 -1
  65. package/dist/device-ws-protocol.js +1 -0
  66. package/dist/env-name-allowlist-knobs.d.ts +12 -2
  67. package/dist/env-name-allowlist-knobs.js +5 -4
  68. package/dist/exec-bounds.d.ts +15 -3
  69. package/dist/exec-bounds.js +4 -0
  70. package/dist/execution-lane-caps.d.ts +9 -2
  71. package/dist/execution-lane-caps.js +11 -0
  72. package/dist/hooks/classic-stations.d.ts +86 -0
  73. package/dist/hooks/classic-stations.js +27 -0
  74. package/dist/hooks/hook-llm.d.ts +8 -5
  75. package/dist/hooks/hook-llm.js +78 -35
  76. package/dist/hooks/hook-runner.d.ts +232 -80
  77. package/dist/hooks/hook-runner.js +218 -312
  78. package/dist/http/admission.d.ts +8 -2
  79. package/dist/http/admission.js +101 -57
  80. package/dist/http/approval-sweeps.js +57 -16
  81. package/dist/http/checkpoint-ctx.d.ts +25 -8
  82. package/dist/http/checkpoint-ctx.js +11 -7
  83. package/dist/http/claimed-run.d.ts +13 -0
  84. package/dist/http/claimed-run.js +15 -0
  85. package/dist/http/device-placement.js +5 -10
  86. package/dist/http/dispatch.d.ts +0 -4
  87. package/dist/http/dispatch.js +5 -9
  88. package/dist/http/durable-run-leg.d.ts +2 -1
  89. package/dist/http/durable-run-leg.js +5 -3
  90. package/dist/http/health-self-report.d.ts +7 -5
  91. package/dist/http/health-self-report.js +4 -18
  92. package/dist/http/principal-gate.d.ts +23 -6
  93. package/dist/http/principal-gate.js +24 -5
  94. package/dist/http/refusal-body.d.ts +21 -0
  95. package/dist/http/refusal-body.js +4 -0
  96. package/dist/http/request-guards.d.ts +27 -0
  97. package/dist/http/request-guards.js +24 -3
  98. package/dist/http/resume-legs.d.ts +25 -0
  99. package/dist/http/resume-legs.js +43 -22
  100. package/dist/http/routes/capabilities.js +1 -1
  101. package/dist/http/routes/diagnostics.js +1 -1
  102. package/dist/http/routes/rules.js +2 -2
  103. package/dist/http/routes/runs.js +7 -7
  104. package/dist/http/routes/session-sync.js +4 -2
  105. package/dist/http/routes/sessions.js +1 -1
  106. package/dist/http/routes/shared-memory.js +2 -13
  107. package/dist/http/routes/side-query.js +2 -3
  108. package/dist/http/routes/tasks.js +19 -9
  109. package/dist/http/send.d.ts +9 -7
  110. package/dist/http/send.js +7 -2
  111. package/dist/http/server.d.ts +21 -11
  112. package/dist/http/server.js +28 -2
  113. package/dist/http/submit-ctx.d.ts +25 -0
  114. package/dist/http/submit-ctx.js +39 -0
  115. package/dist/http/wire-types.d.ts +1 -1
  116. package/dist/index.d.ts +1 -1
  117. package/dist/index.js +1 -1
  118. package/dist/lane-home-probe.d.ts +43 -0
  119. package/dist/lane-home-probe.js +35 -0
  120. package/dist/limit-refusal.d.ts +47 -0
  121. package/dist/limit-refusal.js +12 -0
  122. package/dist/main.js +1 -1
  123. package/dist/mcp-assertion-header.d.ts +1 -9
  124. package/dist/mcp-assertion-header.js +0 -6
  125. package/dist/mcp-tool-faces.d.ts +5 -0
  126. package/dist/mcp-tool-faces.js +5 -1
  127. package/dist/memory-scope.d.ts +1 -1
  128. package/dist/model-provider.d.ts +39 -12
  129. package/dist/model-provider.js +19 -2
  130. package/dist/model-route-endpoint.d.ts +1 -1
  131. package/dist/model-route-endpoint.js +5 -5
  132. package/dist/observability/cost-taxonomy.d.ts +7 -7
  133. package/dist/observability/fail-open.d.ts +42 -6
  134. package/dist/observability/fail-open.js +42 -6
  135. package/dist/observability/metrics.js +3 -1
  136. package/dist/observability/prompt-manifest.d.ts +47 -82
  137. package/dist/observability/prompt-manifest.js +119 -17
  138. package/dist/observability/run-terminal.js +14 -6
  139. package/dist/observability/secret-env-scrub.d.ts +13 -1
  140. package/dist/observability/secret-env-scrub.js +13 -1
  141. package/dist/observability/tool-trace.d.ts +16 -21
  142. package/dist/observability/tool-trace.js +51 -42
  143. package/dist/per-task-image.d.ts +7 -1
  144. package/dist/per-task-image.js +3 -3
  145. package/dist/plain-string-record.d.ts +25 -0
  146. package/dist/plain-string-record.js +32 -0
  147. package/dist/plugins/blob-backend.d.ts +68 -13
  148. package/dist/plugins/blob-backend.js +53 -10
  149. package/dist/plugins/checkpoint-store-sql.d.ts +14 -4
  150. package/dist/plugins/checkpoint-store-sql.js +39 -26
  151. package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
  152. package/dist/plugins/k8s-bg-scripts.js +22 -0
  153. package/dist/plugins/local-checkpoint-store.js +5 -2
  154. package/dist/plugins/local-session-store.js +1 -1
  155. package/dist/plugins/one-time-migrations.d.ts +137 -90
  156. package/dist/plugins/one-time-migrations.js +356 -207
  157. package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
  158. package/dist/plugins/permission-rule-store-sql.js +4 -18
  159. package/dist/plugins/pg-session-storage.d.ts +4 -5
  160. package/dist/plugins/pg-session-storage.js +7 -17
  161. package/dist/plugins/remote-env-adb.d.ts +6 -0
  162. package/dist/plugins/remote-env-adb.js +9 -4
  163. package/dist/plugins/remote-env-device.js +3 -0
  164. package/dist/plugins/remote-env-e2b.d.ts +1 -1
  165. package/dist/plugins/remote-env-e2b.js +21 -9
  166. package/dist/plugins/remote-env-host.d.ts +9 -9
  167. package/dist/plugins/remote-env-host.js +10 -32
  168. package/dist/plugins/remote-env-k8s.d.ts +95 -26
  169. package/dist/plugins/remote-env-k8s.js +265 -90
  170. package/dist/plugins/remote-env-local-docker.d.ts +20 -1
  171. package/dist/plugins/remote-env-local-docker.js +77 -9
  172. package/dist/plugins/remote-env-ssh.d.ts +15 -0
  173. package/dist/plugins/remote-env-ssh.js +109 -3
  174. package/dist/plugins/remote-shell.d.ts +0 -1
  175. package/dist/plugins/remote-shell.js +1 -2
  176. package/dist/plugins/retention-store-sql.js +6 -2
  177. package/dist/plugins/schema-consistency.d.ts +54 -0
  178. package/dist/plugins/schema-consistency.js +52 -0
  179. package/dist/plugins/session-epoch-anchor.d.ts +13 -0
  180. package/dist/plugins/session-epoch-anchor.js +23 -0
  181. package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
  182. package/dist/plugins/shared-memory-store-sql.js +5 -16
  183. package/dist/plugins/sql-driver.d.ts +141 -0
  184. package/dist/plugins/sql-driver.js +115 -1
  185. package/dist/plugins/sql-errors.d.ts +41 -0
  186. package/dist/plugins/sql-errors.js +36 -0
  187. package/dist/plugins/store-backend.js +2 -1
  188. package/dist/plugins/tidb-session-storage.d.ts +7 -11
  189. package/dist/plugins/tidb-session-storage.js +6 -16
  190. package/dist/plugins/tidb-session-store.js +1 -1
  191. package/dist/prompts-domain-validate.d.ts +17 -61
  192. package/dist/prompts-domain-validate.js +9 -119
  193. package/dist/request-key-closure.d.ts +2 -2
  194. package/dist/request-key-closure.js +2 -4
  195. package/dist/rule-entry-list.d.ts +12 -9
  196. package/dist/rule-entry-list.js +37 -21
  197. package/dist/run-local.js +19 -19
  198. package/dist/runs.d.ts +6 -0
  199. package/dist/runs.js +16 -0
  200. package/dist/server-secret-env.d.ts +44 -18
  201. package/dist/server-secret-env.js +49 -8
  202. package/dist/session-incarnation.d.ts +15 -5
  203. package/dist/session-incarnation.js +16 -9
  204. package/dist/session-titler.js +12 -2
  205. package/dist/spec-fields.d.ts +28 -16
  206. package/dist/spec-fields.js +46 -53
  207. package/dist/sql-engine-posture.d.ts +29 -4
  208. package/dist/sql-engine-posture.js +36 -1
  209. package/dist/stored-request-tool-axes-m19.d.ts +19 -4
  210. package/dist/stored-request-tool-axes-m19.js +30 -2
  211. package/dist/task-a2a.d.ts +9 -1
  212. package/dist/task-a2a.js +73 -47
  213. package/dist/task-mcp.d.ts +46 -58
  214. package/dist/task-mcp.js +99 -65
  215. package/dist/task-settings.d.ts +7 -21
  216. package/dist/task-settings.js +7 -36
  217. package/dist/text-bidi.d.ts +3 -46
  218. package/dist/text-bidi.js +3 -3
  219. package/dist/tool-approval.d.ts +1 -1
  220. package/dist/trace/core-keyset-guard.d.ts +24 -4
  221. package/dist/trace/engine-notice-wire.d.ts +11 -3
  222. package/dist/trace/engine-notice-wire.js +8 -1
  223. package/dist/trace/ledger-events.d.ts +3 -1
  224. package/dist/trace/ledger-sink.js +4 -1
  225. package/dist/trace/model-segment.js +1 -1
  226. package/dist/trace/project.d.ts +19 -6
  227. package/dist/trace/project.js +57 -22
  228. package/dist/trace/wire-projection-faces.d.ts +79 -1
  229. package/dist/trace/wire-projection-faces.js +22 -0
  230. package/dist/web-admin-client/candidate-gate.d.ts +6 -6
  231. package/dist/web-admin-client/candidate-gate.js +3 -3
  232. package/dist/web-admin-client/http-client.js +0 -6
  233. package/dist/web-admin-client/read-warnings.d.ts +13 -0
  234. package/dist/web-admin-client/read-warnings.js +10 -0
  235. package/dist/web-admin-client/skills-mcp.d.ts +3 -0
  236. package/dist/web-admin-client/skills-mcp.js +9 -6
  237. package/dist/web-admin-client/types.d.ts +2 -3
  238. package/dist/workspace-cache.d.ts +35 -0
  239. package/dist/workspace-cache.js +36 -0
  240. package/dist/workspace-space.d.ts +3 -2
  241. package/dist/workspace-space.js +2 -0
  242. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +8 -1
  243. package/package.json +4 -4
  244. package/scripts/drain-check-local.mjs +34 -1
  245. package/scripts/drain-check.mysql.sql +30 -2
  246. package/scripts/drain-check.pg.sql +29 -2
  247. package/dist/capabilities/memory-notice.d.ts +0 -138
  248. package/dist/capabilities/memory-notice.js +0 -64
  249. package/dist/capabilities/prompt.d.ts +0 -17
  250. package/dist/capabilities/prompt.js +0 -6
  251. package/dist/mcp-content-origin.d.ts +0 -34
  252. package/dist/mcp-content-origin.js +0 -10
  253. package/dist/tool-axis-words.d.ts +0 -27
  254. package/dist/tool-axis-words.js +0 -9
  255. package/dist/wire-name-bound.d.ts +0 -14
  256. package/dist/wire-name-bound.js +0 -13
@@ -16,7 +16,7 @@
16
16
  * 同文件 G1 e2e 的全码扇出夹具、以及契约文档附录 D.3 那张表(含**小节标题里的码数** —— 那道门本批
17
17
  * 刚立,立完就在下一次加码时自己咬住了)。
18
18
  */
19
- export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable", "task.interrupt_unconsumed", "approval.read_root_granted", "approval.read_root_grant_rejected", "instructions.source_changed", "session.records_skipped", "server.model_unreachable", "permission.entry_mode_clamped", "classifier.unavailable", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.rule_row_dropped", "permission.allowed_tool_not_granted", "task.tool_turn_incomplete", "route.finish_reason_unknown", "route.stream_end_ignored"];
19
+ export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable", "task.interrupt_unconsumed", "approval.read_root_granted", "approval.read_root_grant_rejected", "instructions.source_changed", "session.records_skipped", "server.model_unreachable", "permission.entry_mode_clamped", "classifier.unavailable", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.rule_row_dropped", "permission.allowed_tool_not_granted", "task.tool_turn_incomplete", "route.finish_reason_unknown", "route.stream_end_ignored", "route.credential_origin_mismatch", "mods.registration_refused", "config.session_rules_earlier_grammar"];
20
20
  export type EngineNoticeWireCode = (typeof ENGINE_NOTICE_WIRE_CODES)[number];
21
21
  /** 白名单谓词(单点):路由与门都读这一个,不许第二处手抄码串。 */
22
22
  export declare function isEngineNoticeWireCode(code: string): code is EngineNoticeWireCode;
@@ -47,6 +47,13 @@ export interface EngineNoticeWireRow {
47
47
  /** **服务端观察时刻**(ms epoch)——`EngineNotice` 自身不带时间戳,这是本仓收到它的那一拍,不是 core 铸它的那一拍。 */
48
48
  ts: number;
49
49
  }
50
+ /**
51
+ * 上 wire 的**注册方写的自由文本**的唯一出口纪律:`redactSecrets` + 截到 {@link NOTICE_TEXT_MAX}。
52
+ * 同一个事实(一张扩展注册被判拒、一个判官被跳过)有两个出口 —— 通告 `mods.registration_refused` 的 `detail`(经 {@link sanitizeNoticeDetail})与
53
+ * `wiring_manifest.mods[]` 的行(`trace/project.ts`)—— 两个出口的每一个串都过这一只,所以同一个串在两边逐字节相等;
54
+ * 规则只在这里写一次,`mods[]` 行不另造第二份脱敏 / 截长。
55
+ */
56
+ export declare function sanitizeWireText(text: string): string;
50
57
  /**
51
58
  * `detail` 消毒(设计稿 ②:`redactSecrets` + 尺寸 bound;`workspaceChangedEventData` 先例)。
52
59
  *
@@ -54,7 +61,7 @@ export interface EngineNoticeWireRow {
54
61
  * ——§E1 的既有姿态:上 wire 的自由文本一律经本仓的脱敏器,不因为上游说过一次就免检。
55
62
  *
56
63
  * 契约(逐条,门在 `test/engine-notice-wire.test.ts`):
57
- * · 串 ⇒ `redactSecrets` + 截到 {@link NOTICE_TEXT_MAX};
64
+ * · 串 ⇒ {@link sanitizeWireText}(`redactSecrets` + 截到 {@link NOTICE_TEXT_MAX});
58
65
  * · 有限 number / boolean / null ⇒ 逐字(harvest 的 count/moved/escalated 是判据数字,不许变形);
59
66
  * · 非有限 number(NaN/Infinity)⇒ **丢键**(JSON 里它们会变成 `null`,一个看起来合法的假读数);
60
67
  * · 数组 ⇒ 逐项消毒,超 {@link DETAIL_MAX_ITEMS} 截断;对象 ⇒ 逐键消毒,超 {@link DETAIL_MAX_KEYS} 丢尾键;
@@ -91,7 +98,8 @@ export declare function redactNoticeMessage(message: unknown): string;
91
98
  * 通告 `detail` 里的**规则文本**换成条目的脱敏原值({@link redactListEntry}:凭据换记号,不加引号、不转义 —— 机读位不是显示面,显示形只属于人读句)。
92
99
  * 会话流行(经 {@link engineNoticeEventData},之后照常过 {@link sanitizeNoticeDetail})与运维日志行(`boot/runner-deps.ts` 的转发席,其余字段逐字)
93
100
  * 同调这一只 ⇒ 两条出路上同一条规则文本逐字节同(会话流行另有 detail 串的 {@link NOTICE_TEXT_MAX} 字上限,超长的那一截只在日志行上),两只码里同一条
94
- * 规则文本也同(引擎交来的两形本身一致时 —— `rule_row_dropped` 交的是引擎中和过的形,空白 / 超长的条目两只码今天不同,上游缝)。其余字段、其余码原样。
101
+ * 规则文本也同 —— core 7.53.0(#1884)起引擎交来的两形就是同一只读法的产物(原串,长于 1 024 码点的截到 1 024 + 一枚截断记号;修前 `rule_row_dropped`
102
+ * 交中和形,空白 / 超长的条目两只码不同)。其余字段、其余码原样。
95
103
  */
96
104
  export declare function redactNoticeRuleText(code: string, detail: Record<string, unknown> | undefined): Record<string, unknown> | undefined;
97
105
  export declare function engineNoticeEventData(notice: {
@@ -40,6 +40,9 @@ export const ENGINE_NOTICE_WIRE_CODES = [
40
40
  "task.tool_turn_incomplete",
41
41
  "route.finish_reason_unknown",
42
42
  "route.stream_end_ignored",
43
+ "route.credential_origin_mismatch",
44
+ "mods.registration_refused",
45
+ "config.session_rules_earlier_grammar",
43
46
  ];
44
47
  const WIRE_CODES = new Set(ENGINE_NOTICE_WIRE_CODES);
45
48
  export function isEngineNoticeWireCode(code) {
@@ -53,6 +56,9 @@ export function engineNoticeSessionId(notice) {
53
56
  return typeof fromDetail === "string" && fromDetail.length > 0 ? fromDetail : undefined;
54
57
  }
55
58
  const NOTICE_TEXT_MAX = 1000;
59
+ export function sanitizeWireText(text) {
60
+ return redactSecrets(text).slice(0, NOTICE_TEXT_MAX);
61
+ }
56
62
  const DETAIL_MAX_DEPTH = 4;
57
63
  const DETAIL_MAX_KEYS = 32;
58
64
  const DETAIL_MAX_ITEMS = 32;
@@ -64,7 +70,7 @@ function sanitizeValue(v, depth) {
64
70
  if (v === null)
65
71
  return null;
66
72
  if (typeof v === "string")
67
- return redactSecrets(v).slice(0, NOTICE_TEXT_MAX);
73
+ return sanitizeWireText(v);
68
74
  if (typeof v === "number")
69
75
  return Number.isFinite(v) ? v : undefined;
70
76
  if (typeof v === "boolean")
@@ -99,6 +105,7 @@ function sanitizeValue(v, depth) {
99
105
  export const RULE_TEXT_DETAIL_FIELDS = {
100
106
  "permission.allowed_tool_not_granted": { array: "entries", field: "entry" },
101
107
  "permission.rule_row_dropped": { array: "rows", field: "rule" },
108
+ "config.session_rules_earlier_grammar": { array: "entries", field: "entry" },
102
109
  };
103
110
  export function redactNoticeMessage(message) {
104
111
  return redactSecrets(String(message));
@@ -31,7 +31,9 @@
31
31
  * 的 `switch (ev.type)` 白名单臂(差集门 `test/durable-append-arm-parity.test.ts` 看守两腿一致);
32
32
  * · **腿自己的带外行**:park/终局/失败/建议/用量/装配自证(不来自流事件)。
33
33
  */
34
- export type LedgerEventType = "reasoning" | "text" | "tool_start" | "tool_end" | "status" | "context_usage" | "compacted" | "diagnostics" | "steering_injected" | "compaction_outcome" | "workspace_changed" | "wiring_manifest"
34
+ export type LedgerEventType = "reasoning" | "text" | "tool_start" | "tool_end" | "status" | "context_usage" | "compacted" | "diagnostics" | "steering_injected" | "compaction_outcome"
35
+ /** S-1732(core 7.53.0 #2008):压缩 pass 的开始帧(`{ trigger, pass, startedAt }`;结束帧带同一个 `pass`)。原样落账,两条 durable 腿同源。 */
36
+ | "compaction_started" | "workspace_changed" | "wiring_manifest"
35
37
  /** S-212(7.71.0):运行期名册变更(core 7.8.0 [ref] ⑪)。**快照语义**——`delta.roster` 是整只
36
38
  * 变更后名册,消费端收到即整只替换,所以回放不需要任何合并;它的耐久面因此不是 `wiring_manifest.tools`
37
39
  * 的重复,而是那份开腿快照**之后**的每一次改动(修前两条 durable 腿零 case ⇒ 回放只见开头一版)。 */
@@ -1,7 +1,7 @@
1
1
  import {} from "@sema-agent/core";
2
2
  import { outwardPlane } from "../terminal.js";
3
3
  import { recordFailOpen } from "../observability/fail-open.js";
4
- import { modelTextEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, toolDisclosureEventData, humanInputEventData, turnEndEventData, contextUsageEventData } from "./project.js";
4
+ import { modelTextEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, toolDisclosureEventData, humanInputEventData, turnEndEventData, contextUsageEventData } from "./project.js";
5
5
  import { NotifiedKeys, taskNotificationStreamKeyOf } from "../orchestration/workflow-completion-inbox.js";
6
6
  import { isParkLedgerEventType } from "./ledger-events.js";
7
7
  import { isModelSegmentBoundary, reasoningDeltaBytes, reasoningSegmentEventId } from "./model-segment.js";
@@ -108,6 +108,9 @@ export function createLedgerSink(opts) {
108
108
  case "compaction_outcome":
109
109
  await append("compaction_outcome", compactionOutcomeEventData(ev));
110
110
  break;
111
+ case "compaction_started":
112
+ await append("compaction_started", compactionStartedEventData(ev));
113
+ break;
111
114
  case "workspace_changed":
112
115
  await append("workspace_changed", workspaceChangedEventData(ev));
113
116
  break;
@@ -2,7 +2,7 @@ import { reasoningEndEventData } from "./project.js";
2
2
  const BOUNDARY = new Set([
3
3
  "tool_start", "tool_end", "status", "context_usage", "compacted", "diagnostics",
4
4
  "steering_injected", "compaction_outcome", "workspace_changed", "wiring_manifest",
5
- "tool_roster_delta", "human_input", "task_notification", "turn_end", "tool_disclosure",
5
+ "tool_roster_delta", "human_input", "task_notification", "turn_end", "tool_disclosure", "compaction_started",
6
6
  ]);
7
7
  export function isModelSegmentBoundary(type) {
8
8
  return BOUNDARY.has(type);
@@ -113,11 +113,7 @@ export type TraceBlock = {
113
113
  parentToolCallId?: string;
114
114
  } | {
115
115
  type: "prompt-assembled";
116
- constitution: string;
117
- totalChars: number;
118
- blocks: unknown;
119
- sections?: unknown;
120
- tools?: unknown;
116
+ readonly [member: string]: unknown;
121
117
  };
122
118
  /**
123
119
  * 🔴 **模型自由文本账本行(`text` / `reasoning`)的唯一载荷铸点**(B-106 / S-268,7.75.1)。
@@ -543,6 +539,21 @@ export declare function compactionOutcomeEventData(ev: {
543
539
  outcome?: unknown;
544
540
  trigger?: unknown;
545
541
  reason?: unknown;
542
+ pass?: unknown;
543
+ eventId?: unknown;
544
+ parentToolCallId?: unknown;
545
+ }): Record<string, unknown>;
546
+ /**
547
+ * `compaction_started`(S-1732,core 7.53.0 #2008)—— 一次压缩 pass 在提交点(触发闸过了、切点在、`preCompact` 没拦)宣告开始,先于摘要调用:
548
+ * 一次在供应方重试表里等很久的摘要(core 实测 503 × 11、173 s)从此在流上不是静默的。**原样投影**:`{ trigger, pass, startedAt }` + 身份两键,
549
+ * 不自铸相位、不铸 run / session id(那是流的,不是帧的键)。三键都是引擎铸的闭形值:`trigger` 闭集词(`auto` / `manual` / `forced`,与结束帧同一张词表)、
550
+ * `pass` 不透明 id(结束这次 pass 的那一帧 —— `compacted` 或 `compaction_outcome` —— 带同一个 `pass`)、`startedAt` 引擎时钟 epoch 毫秒 ⇒ 不脱敏、逐字;
551
+ * 形不合即缺席(与 {@link compactionOutcomeEventData} 同款守卫,不编值)。三条消费腿(live 帧、两条 durable 腿)共用这一只。
552
+ */
553
+ export declare function compactionStartedEventData(ev: {
554
+ trigger?: unknown;
555
+ pass?: unknown;
556
+ startedAt?: unknown;
546
557
  eventId?: unknown;
547
558
  parentToolCallId?: unknown;
548
559
  }): Record<string, unknown>;
@@ -806,7 +817,7 @@ export declare function wiringManifestEventData(ev: {
806
817
  * `core-keyset-guard.ts` ⑥b `WiringSectionExcluded`)。**present-iff 武装**:
807
818
  * · 整段缺席 ⇒ **未武装**,不铸键、不计数(正面事实,不是「未知」,更不是 `{onRecommendation:false}`);
808
819
  * · 在场且 `onRecommendation === true` ⇒ 逐字铸出(core 的在场形只有这一个,构造期门已拒掉「武装但跑不起来」);
809
- * · 在场但读不出那个形 ⇒ `dropProjectedFace` 留痕并整段缺席(与 `writeProtection` / `lsp` / `hooks` 同一条
820
+ * · 在场但读不出那个形 ⇒ `dropProjectedFace` 留痕并整段缺席(与 `writeProtection` / `lsp` / `mods` 同一条
810
821
  * 族规:「在场但读不出 ⇒ 计一次并丢弃」;**不**自造第三态,词表/形的属主在 core)。
811
822
  * 🔴 代价如实登记,与 `writeProtection` 那一格逐字同源:wire 上「读不出」与「真未武装」是**同一个形**,
812
823
  * 分得开它们的只有 `server.trace.projection-input-malformed` 这只计数 —— 而这一格比那一格更该说清楚,
@@ -932,6 +943,8 @@ export declare function compactedEventData(ev: {
932
943
  persistMs?: number;
933
944
  ptlRetries?: number;
934
945
  };
946
+ /** S-1732(core 7.53.0 #2008):这次落地的压缩 pass 的 id —— 与它的 `compaction_started` 帧同一个值(引擎在每次落地上都设;型上可选)。逐字。 */
947
+ pass?: string;
935
948
  }): Record<string, unknown>;
936
949
  export interface TraceTurn {
937
950
  /** per-task seq = the turn's terminating event seq (so history-up-to-H splices with stream seq>H). */
@@ -3,6 +3,7 @@ import { MCP_DELIVERY_VERDICTS, MCP_LIVENESS_STATES, screenGateOutcome, TEAM_ROL
3
3
  import { Value } from "typebox/value";
4
4
  import { recordFailOpen } from "../observability/fail-open.js";
5
5
  import { redactSecrets, redactDeep } from "./redact.js";
6
+ import { sanitizeWireText } from "./engine-notice-wire.js";
6
7
  import { projectToolOutput, projectToolStructured } from "./tool-output-media.js";
7
8
  import { injectionTierOrAbsent } from "./injection-tier.js";
8
9
  import { semaProvenanceOrAbsent } from "./sema-provenance.js";
@@ -380,6 +381,16 @@ export function compactionOutcomeEventData(ev) {
380
381
  ...(s(ev.outcome) !== undefined ? { outcome: s(ev.outcome) } : {}),
381
382
  ...(s(ev.trigger) !== undefined ? { trigger: s(ev.trigger) } : {}),
382
383
  ...(ev.reason !== undefined ? { reason: redactSecrets(String(ev.reason)) } : {}),
384
+ ...(s(ev.pass) !== undefined ? { pass: s(ev.pass) } : {}),
385
+ ...identityFields(ev),
386
+ };
387
+ }
388
+ export function compactionStartedEventData(ev) {
389
+ const s = (v) => (typeof v === "string" ? v : undefined);
390
+ return {
391
+ ...(s(ev.trigger) !== undefined ? { trigger: s(ev.trigger) } : {}),
392
+ ...(s(ev.pass) !== undefined ? { pass: s(ev.pass) } : {}),
393
+ ...(typeof ev.startedAt === "number" && Number.isFinite(ev.startedAt) ? { startedAt: ev.startedAt } : {}),
383
394
  ...identityFields(ev),
384
395
  };
385
396
  }
@@ -513,26 +524,55 @@ export function wiringManifestEventData(ev, instructions) {
513
524
  })();
514
525
  const toolsIn = m.tools;
515
526
  const tools = toolsIn === undefined ? undefined : Value.Check(ToolRoster, toolsIn) ? toolsIn : (recordFailOpen("server.trace.tool-roster-malformed", "wiring_manifest.tools did not fit core ToolRoster"), undefined);
516
- const hooksIn = m.hooks;
517
- const hooks = (() => {
518
- if (hooksIn === undefined)
527
+ const strList = (v) => (Array.isArray(v) && v.every((x) => typeof x === "string") ? [...v] : undefined);
528
+ const registrantText = (v) => {
529
+ const t = str(v);
530
+ return t === undefined ? undefined : sanitizeWireText(t);
531
+ };
532
+ const modsIn = m.mods;
533
+ const mods = (() => {
534
+ if (modsIn === undefined)
519
535
  return undefined;
520
- if (!Array.isArray(hooksIn))
521
- return dropProjectedFace("wiring_manifest.hooks is not an array");
536
+ if (!Array.isArray(modsIn))
537
+ return dropProjectedFace("wiring_manifest.mods is not an array");
522
538
  const rows = [];
523
- for (const raw of hooksIn) {
539
+ for (const raw of modsIn) {
524
540
  const e = sec(raw);
525
- if (e === undefined) {
526
- dropProjectedFace("wiring_manifest.hooks[] row is not an object");
541
+ const name = registrantText(e?.name);
542
+ const seat = str(e?.seat);
543
+ const tier = str(e?.tier);
544
+ if (e === undefined || name === undefined || seat === undefined || tier === undefined) {
545
+ dropProjectedFace("wiring_manifest.mods[] row is missing name/seat/tier");
546
+ continue;
547
+ }
548
+ const refusedBy = registrantText(e.refusedBy);
549
+ const reason = registrantText(e.reason);
550
+ if (refusedBy !== undefined && reason !== undefined) {
551
+ rows.push({ name, seat, tier, refusedBy, reason });
527
552
  continue;
528
553
  }
529
- const family = str(e.family);
530
- const owner = str(e.owner);
531
- if (family === undefined || owner === undefined) {
532
- dropProjectedFace("wiring_manifest.hooks[] row is missing family/owner");
554
+ const events = strList(e.events);
555
+ if (events === undefined) {
556
+ dropProjectedFace("wiring_manifest.mods[] row is neither a mounted nor a refused record");
533
557
  continue;
534
558
  }
535
- rows.push({ family, owner, ...(e.observational === true ? { observational: true } : {}) });
559
+ const observe = e.observe === undefined ? undefined : (strList(e.observe) ?? dropProjectedFace("wiring_manifest.mods[].observe is not a list of strings"));
560
+ const skipped = e.skipped === undefined
561
+ ? undefined
562
+ : Array.isArray(e.skipped)
563
+ ? e.skipped.flatMap((x) => {
564
+ const k = sec(x);
565
+ const registration = registrantText(k?.registration);
566
+ const cause = registrantText(k?.cause);
567
+ const why = registrantText(k?.reason);
568
+ if (registration === undefined || cause === undefined || why === undefined) {
569
+ dropProjectedFace("wiring_manifest.mods[].skipped[] element is missing registration/cause/reason");
570
+ return [];
571
+ }
572
+ return [{ registration, cause, reason: why }];
573
+ })
574
+ : dropProjectedFace("wiring_manifest.mods[].skipped is not an array");
575
+ rows.push({ name, seat, tier, events, ...(observe !== undefined ? { observe } : {}), ...(skipped !== undefined && skipped.length > 0 ? { skipped } : {}) });
536
576
  }
537
577
  return rows.length > 0 ? rows : undefined;
538
578
  })();
@@ -606,7 +646,7 @@ export function wiringManifestEventData(ev, instructions) {
606
646
  ...(autoMode !== undefined ? { autoMode } : {}),
607
647
  ...(tools !== undefined ? { tools } : {}),
608
648
  ...(mcp !== undefined ? { mcp } : {}),
609
- ...(hooks !== undefined ? { hooks } : {}),
649
+ ...(mods !== undefined ? { mods } : {}),
610
650
  ...(lsp !== undefined ? { lsp } : {}),
611
651
  ...(hands !== undefined ? { hands } : {}),
612
652
  ...(writeProtection !== undefined ? { writeProtection } : {}),
@@ -758,6 +798,7 @@ export function compactedEventData(ev) {
758
798
  })(),
759
799
  ...(num(ev.durationMs) !== undefined ? { durationMs: num(ev.durationMs) } : {}),
760
800
  ...(phaseDurations !== undefined ? { phaseDurations } : {}),
801
+ ...(typeof ev.pass === "string" ? { pass: ev.pass } : {}),
761
802
  };
762
803
  }
763
804
  export function contextUsageEventData(ev) {
@@ -880,14 +921,7 @@ export function projectEvents(events, opts = {}) {
880
921
  }
881
922
  case "prompt_assembled":
882
923
  firstTs ??= ev.ts;
883
- blocks.push({
884
- type: "prompt-assembled",
885
- constitution: String(d.constitution ?? ""),
886
- totalChars: Number(d.totalChars ?? 0),
887
- blocks: d.blocks,
888
- ...(d.sections !== undefined ? { sections: d.sections } : {}),
889
- ...(d.tools !== undefined ? { tools: d.tools } : {}),
890
- });
924
+ blocks.push({ ...d, type: "prompt-assembled" });
891
925
  break;
892
926
  case "turn_end":
893
927
  flushTurn(ev.seq, ev.ts, toContractTokens(d.usage, d.usageMissing));
@@ -966,6 +1000,7 @@ function mapTraceEventInner(type, seq, data) {
966
1000
  return { event: "error", data: { type: "error", errorCode: "WORKER_DOWN", message: redactErrorMessage(String(data.errorMessage ?? "run failed")) ?? "run failed" } };
967
1001
  case "context_usage":
968
1002
  case "compaction_outcome":
1003
+ case "compaction_started":
969
1004
  case "wiring_manifest":
970
1005
  case "human_input":
971
1006
  case "tool_roster_delta":
@@ -54,7 +54,7 @@ export interface WireProjectionFace {
54
54
  */
55
55
  export declare const FRAME_ENVELOPE_KEYS: readonly ["type", "sourceTaskId", "bgAgentId"];
56
56
  /** 探针文件要从 `@sema-agent/core` 具名导入的类型(`coreType` 表达式里用到的全部名字)。 */
57
- export declare const WIRE_PROJECTION_CORE_IMPORTS: readonly ["TaskEvent", "TaskNotificationPayload", "WiringManifest", "EngineNotice", "MemoryImportReport", "OriginClearanceRow", "OriginClearanceEvent", "MemoryEntryOrigin"];
57
+ export declare const WIRE_PROJECTION_CORE_IMPORTS: readonly ["TaskEvent", "TaskNotificationPayload", "WiringManifest", "EngineNotice", "MemoryImportReport", "OriginClearanceRow", "OriginClearanceEvent", "MemoryEntryOrigin", "TraceEvent", "PromptManifestIdentity", "PromptIdentityLayers", "PromptManifestSelectors", "PromptManifestSection", "PromptChainLink", "SupersededOverlay", "ToolDisclosureManifest"];
58
58
  /**
59
59
  * `wiring_manifest` 的 **operator 面多投的那几段**(`wiringManifestOperatorEventData` 在租户形之上加的段)。
60
60
  * operator 行的 `excluded` = 租户行减本常量(派生);四段各自的受众裁定在 `core-keyset-guard.ts` ⑥b。
@@ -158,6 +158,12 @@ export declare const WIRE_PROJECTION_FACES: {
158
158
  readonly excluded: readonly [];
159
159
  readonly minted: readonly [];
160
160
  };
161
+ readonly compaction_started: {
162
+ readonly projector: "compactionStartedEventData";
163
+ readonly coreType: string;
164
+ readonly excluded: readonly [];
165
+ readonly minted: readonly [];
166
+ };
161
167
  readonly human_input: {
162
168
  readonly projector: "humanInputEventData";
163
169
  readonly coreType: string;
@@ -216,6 +222,78 @@ export declare const WIRE_PROJECTION_FACES: {
216
222
  readonly excluded: readonly [];
217
223
  readonly minted: readonly [];
218
224
  };
225
+ readonly prompt_manifest: {
226
+ readonly projector: "promptManifestRecordOf";
227
+ readonly coreType: "Extract<TraceEvent, { kind: \"prompt.assembled\" }>";
228
+ readonly excluded: readonly ["kind", "version", "taskId", "snapshot", "lowering", "ts"];
229
+ readonly minted: readonly [];
230
+ };
231
+ readonly prompt_manifest_identity: {
232
+ readonly projector: "promptManifestRecordOf";
233
+ readonly coreType: "PromptManifestIdentity";
234
+ readonly excluded: readonly [];
235
+ readonly minted: readonly [];
236
+ };
237
+ readonly prompt_manifest_identity_layers: {
238
+ readonly projector: "promptManifestRecordOf";
239
+ readonly coreType: "PromptIdentityLayers";
240
+ readonly excluded: readonly [];
241
+ readonly minted: readonly [];
242
+ };
243
+ readonly prompt_manifest_selectors: {
244
+ readonly projector: "promptManifestRecordOf";
245
+ readonly coreType: "PromptManifestSelectors";
246
+ readonly excluded: readonly [];
247
+ readonly minted: readonly [];
248
+ };
249
+ readonly prompt_manifest_selectors_host: {
250
+ readonly projector: "promptManifestRecordOf";
251
+ readonly coreType: "PromptManifestSelectors[\"host\"]";
252
+ readonly excluded: readonly [];
253
+ readonly minted: readonly [];
254
+ };
255
+ readonly prompt_manifest_block: {
256
+ readonly projector: "promptManifestRecordOf";
257
+ readonly coreType: "Extract<TraceEvent, { kind: \"prompt.assembled\" }>[\"blocks\"][number]";
258
+ readonly excluded: readonly [];
259
+ readonly minted: readonly [];
260
+ };
261
+ readonly prompt_manifest_section: {
262
+ readonly projector: "promptManifestRecordOf";
263
+ readonly coreType: "PromptManifestSection";
264
+ readonly excluded: readonly [];
265
+ readonly minted: readonly [];
266
+ };
267
+ readonly prompt_manifest_section_renderer: {
268
+ readonly projector: "promptManifestRecordOf";
269
+ readonly coreType: "NonNullable<PromptManifestSection[\"renderer\"]>";
270
+ readonly excluded: readonly [];
271
+ readonly minted: readonly [];
272
+ };
273
+ readonly prompt_manifest_chain_link: {
274
+ readonly projector: "promptManifestRecordOf";
275
+ readonly coreType: "PromptChainLink";
276
+ readonly excluded: readonly [];
277
+ readonly minted: readonly [];
278
+ };
279
+ readonly prompt_manifest_superseded: {
280
+ readonly projector: "promptManifestRecordOf";
281
+ readonly coreType: "SupersededOverlay";
282
+ readonly excluded: readonly [];
283
+ readonly minted: readonly [];
284
+ };
285
+ readonly prompt_manifest_tool: {
286
+ readonly projector: "promptManifestRecordOf";
287
+ readonly coreType: "NonNullable<Extract<TraceEvent, { kind: \"prompt.assembled\" }>[\"tools\"]>[number]";
288
+ readonly excluded: readonly [];
289
+ readonly minted: readonly [];
290
+ };
291
+ readonly prompt_manifest_tool_disclosure: {
292
+ readonly projector: "promptManifestRecordOf";
293
+ readonly coreType: "ToolDisclosureManifest";
294
+ readonly excluded: readonly [];
295
+ readonly minted: readonly [];
296
+ };
219
297
  };
220
298
  /** 面名。 */
221
299
  export type WireProjectionFaceName = keyof typeof WIRE_PROJECTION_FACES;
@@ -8,8 +8,17 @@ export const WIRE_PROJECTION_CORE_IMPORTS = [
8
8
  "OriginClearanceRow",
9
9
  "OriginClearanceEvent",
10
10
  "MemoryEntryOrigin",
11
+ "TraceEvent",
12
+ "PromptManifestIdentity",
13
+ "PromptIdentityLayers",
14
+ "PromptManifestSelectors",
15
+ "PromptManifestSection",
16
+ "PromptChainLink",
17
+ "SupersededOverlay",
18
+ "ToolDisclosureManifest",
11
19
  ];
12
20
  const arm = (name) => `Extract<TaskEvent, { type: "${name}" }>`;
21
+ const MANIFEST_FRAME = `Extract<TraceEvent, { kind: "prompt.assembled" }>`;
13
22
  export const WIRING_MANIFEST_OPERATOR_ONLY_SECTIONS = ["governance", "configFingerprint", "autoConsolidation", "readDeny"];
14
23
  function withoutSections(all, drop) {
15
24
  return all.filter((k) => !drop.includes(k));
@@ -30,6 +39,7 @@ export const WIRE_PROJECTION_FACES = {
30
39
  context_usage: { projector: "contextUsageEventData", coreType: arm("context_usage"), excluded: [], minted: [] },
31
40
  turn_end: { projector: "turnEndEventData", coreType: arm("turn_end"), excluded: [], minted: [] },
32
41
  compaction_outcome: { projector: "compactionOutcomeEventData", coreType: arm("compaction_outcome"), excluded: [], minted: [] },
42
+ compaction_started: { projector: "compactionStartedEventData", coreType: arm("compaction_started"), excluded: [], minted: [] },
33
43
  human_input: { projector: "humanInputEventData", coreType: arm("human_input"), excluded: ["principal"], minted: [] },
34
44
  task_notification: {
35
45
  projector: "taskNotificationEventData",
@@ -67,5 +77,17 @@ export const WIRE_PROJECTION_FACES = {
67
77
  },
68
78
  origin_clearance_origin: { projector: "buildClearanceRowWire", coreType: "MemoryEntryOrigin", excluded: [], minted: [] },
69
79
  origin_clearance_event: { projector: "buildClearanceRowWire", coreType: "OriginClearanceEvent", excluded: [], minted: [] },
80
+ prompt_manifest: { projector: "promptManifestRecordOf", coreType: MANIFEST_FRAME, excluded: ["kind", "version", "taskId", "snapshot", "lowering", "ts"], minted: [] },
81
+ prompt_manifest_identity: { projector: "promptManifestRecordOf", coreType: "PromptManifestIdentity", excluded: [], minted: [] },
82
+ prompt_manifest_identity_layers: { projector: "promptManifestRecordOf", coreType: "PromptIdentityLayers", excluded: [], minted: [] },
83
+ prompt_manifest_selectors: { projector: "promptManifestRecordOf", coreType: "PromptManifestSelectors", excluded: [], minted: [] },
84
+ prompt_manifest_selectors_host: { projector: "promptManifestRecordOf", coreType: `PromptManifestSelectors["host"]`, excluded: [], minted: [] },
85
+ prompt_manifest_block: { projector: "promptManifestRecordOf", coreType: `${MANIFEST_FRAME}["blocks"][number]`, excluded: [], minted: [] },
86
+ prompt_manifest_section: { projector: "promptManifestRecordOf", coreType: "PromptManifestSection", excluded: [], minted: [] },
87
+ prompt_manifest_section_renderer: { projector: "promptManifestRecordOf", coreType: `NonNullable<PromptManifestSection["renderer"]>`, excluded: [], minted: [] },
88
+ prompt_manifest_chain_link: { projector: "promptManifestRecordOf", coreType: "PromptChainLink", excluded: [], minted: [] },
89
+ prompt_manifest_superseded: { projector: "promptManifestRecordOf", coreType: "SupersededOverlay", excluded: [], minted: [] },
90
+ prompt_manifest_tool: { projector: "promptManifestRecordOf", coreType: `NonNullable<${MANIFEST_FRAME}["tools"]>[number]`, excluded: [], minted: [] },
91
+ prompt_manifest_tool_disclosure: { projector: "promptManifestRecordOf", coreType: "ToolDisclosureManifest", excluded: [], minted: [] },
70
92
  };
71
93
  //# sourceMappingURL=wire-projection-faces.js.map
@@ -2,7 +2,7 @@
2
2
  * 配置候选的**唯一判官**:一份候选(中心有效视图,或本地 `config.d` 读出的那份)能不能收 —— 只有这一种判法。
3
3
  *
4
4
  * 判据(三件,任一即拒;每条拒因带成因词,闭集 {@link CandidateRejectReason}):读腿交出的 `domainErrors`(某个域读不懂 / 拼错键 / 坏文件:那个域已落
5
- * schema 缺省)与 prompts 面的判形(`validatePromptsDomain`;坏形的 pack 会让 core 在每个任务的装配期抛)—— 成因 `domain_invalid`;读腿交出的
5
+ * schema 缺省)与 prompts 面的判官(`judgePromptsWire`:契约包的 wire 形再交引擎 verify —— 中心层只有一种形)—— 成因 `domain_invalid`;读腿交出的
6
6
  * `retiredDomains`(带事实的退役域文档,契约包的墓碑;拒句点名退役版本与一次性迁移)—— 成因 `retired_domain`。任一 ⇒ `rejected`:
7
7
  * **整份候选不收**,一个域都不应用。退役域此前在读腿整包抛、走「源不可达」那条臂(版本读不到、没有拒判行、刷新拍算失败);现在读腿只交数据,
8
8
  * 坏候选只有本判官一种判法。
@@ -22,11 +22,11 @@
22
22
  * `domains` 排序去重:收集器的顺序没有承诺,它是拒行去重键的一部分(同一份候选、同一组坏域只响一次)。`errors` 原样逐条
23
23
  * (读腿的诊断在前、prompts 在后)—— 那是可操作的诊断,不是键。纯函数:不改入参,不读环境。
24
24
  *
25
- * **判官交值**:`clean` 判决带着 prompts 面的已判形值(`prompts`;候选不带 prompts 键 ⇒ `undefined`)。采纳 prompts 的各处(起服 / 刷新 /
26
- * 迟到起服 / LKG 起服 / `run-local`)直接用这一份值,不再自己判第二遍 —— `validatePromptsDomain` 在 src 里只有本判官一个调用点
25
+ * **判官交值**:`clean` 判决带着 prompts 面的判官结论(`prompts` = 引擎 verify 过的发布形 artifact;候选不带 prompts 键 ⇒ `undefined`)。采纳 prompts 的各处
26
+ * (起服 / 刷新 / 迟到起服 / LKG 起服 / `run-local`)直接用这一份值,不再自己判第二遍 —— `judgePromptsWire` 在 src 里只有本判官一个调用点
27
27
  * (盘上 LKG 的读回复判也经本判官,`config-lkg.ts`)。
28
28
  */
29
- import { type PromptsDomainFaces } from "../prompts-domain-validate.js";
29
+ import type { PublishedPromptArtifact } from "@sema-agent/core";
30
30
  import type { EffectiveConfig } from "./types.js";
31
31
  /** 读腿交出的一条域级诊断(与 `FetchEffectiveResult.domainErrors` 同形;error 文案已在产出边界脱敏)。 */
32
32
  export interface CandidateDomainError {
@@ -46,10 +46,10 @@ export interface ConfigCandidateRead {
46
46
  readonly retiredDomains?: readonly CandidateDomainError[];
47
47
  }
48
48
  export type ConfigCandidateVerdict =
49
- /** `prompts` = 候选 prompts 面的已判形值(候选不带 prompts 键 ⇒ `undefined` = 撤回中心包、内置提示词服务)。 */
49
+ /** `prompts` = 候选的中心层(引擎 verify 过的发布形 artifact;候选不带 prompts 键 ⇒ `undefined` = 撤下中心层、内置提示词服务)。 */
50
50
  {
51
51
  readonly verdict: "clean";
52
- readonly prompts: PromptsDomainFaces | undefined;
52
+ readonly prompts: PublishedPromptArtifact | undefined;
53
53
  } | {
54
54
  readonly verdict: "rejected";
55
55
  readonly domains: readonly string[];
@@ -1,14 +1,14 @@
1
- import { validatePromptsDomain } from "../prompts-domain-validate.js";
1
+ import { judgePromptsWire } from "../prompts-domain-validate.js";
2
2
  export function judgeConfigCandidate(r) {
3
3
  const prompts = r.effective.prompts;
4
- const promptsGate = prompts === undefined ? undefined : validatePromptsDomain(prompts);
4
+ const promptsGate = prompts === undefined ? undefined : judgePromptsWire(prompts);
5
5
  const errors = [
6
6
  ...(r.domainErrors ?? []).map((de) => ({ domain: de.domain, error: de.error, reason: "domain_invalid" })),
7
7
  ...(promptsGate !== undefined && !promptsGate.ok ? [{ domain: "prompts", error: promptsGate.error, reason: "domain_invalid" }] : []),
8
8
  ...(r.retiredDomains ?? []).map((rd) => ({ domain: rd.domain, error: rd.error, reason: "retired_domain" })),
9
9
  ];
10
10
  if (errors.length === 0)
11
- return { verdict: "clean", prompts: promptsGate?.ok ? promptsGate.value : undefined };
11
+ return { verdict: "clean", prompts: promptsGate?.ok ? promptsGate.artifact : undefined };
12
12
  return { verdict: "rejected", domains: [...new Set(errors.map((e) => e.domain))].sort(), errors };
13
13
  }
14
14
  export function buildCandidateRejectedFields(r, verdict, leg, ctx) {
@@ -1,6 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { readEffectiveWire, PrincipalCapsWire } from "@sema-agent/settings-schema";
3
- import { centerPromptsFromEffective } from "../prompts-domain-validate.js";
4
3
  import { separateRetiredDomains, splitFoldedReadWarnings, withDroppedCatalogEntries } from "./read-warnings.js";
5
4
  import { CENTER_PULL_TIMEOUT_MS, centerFetch } from "./center-request.js";
6
5
  import { answerStillCurrent } from "../center-credential.js";
@@ -13,11 +12,6 @@ export async function fetchEffective(center, etag, fetchImpl = fetch, worker) {
13
12
  const warnings = [];
14
13
  const { body, retiredDomains } = separateRetiredDomains(await res.json());
15
14
  const wire = readEffectiveWire(body, (w) => warnings.push(w));
16
- const centerPrompts = centerPromptsFromEffective(wire);
17
- if (centerPrompts === undefined)
18
- delete wire.prompts;
19
- else
20
- wire.prompts = centerPrompts;
21
15
  const { domainErrors, droppedEntries, droppedCatalogEntries, unreadFiles } = splitFoldedReadWarnings(warnings, "center");
22
16
  const effective = withDroppedCatalogEntries(wire, droppedCatalogEntries);
23
17
  return {
@@ -70,6 +70,19 @@ export type UnreadConfigFile = {
70
70
  readonly why: "not-a-domain" | "non-portable-domain";
71
71
  readonly domain?: string;
72
72
  };
73
+ /**
74
+ * `config.d` 里一份**被读**的文件中、本地读腿结构上**不读**的一键(本服务铸,不是契约告警):今天只有 `prompts.json` 的 `workers` —— 本地腿没有
75
+ * worker 身份,中心层的唯一选择读法(`promptArtifactFor`)对它恒以 `null` 读,只交 `artifact`。写了不生效要响:调用方在采纳路径上一键一行 `config_unread_key`
76
+ * (与 `config_unread_file` 同频:起服与之后每次采纳一份变了的候选),不判拒。
77
+ */
78
+ export type UnreadConfigKey = {
79
+ readonly file: string;
80
+ readonly domain: string;
81
+ readonly key: string;
82
+ readonly names: readonly string[];
83
+ };
84
+ /** `config_unread_key` 一行的体(纯数据;起服 / 刷新 / 迟到起服与 `run-local` 同一体):`dir` = 本地读腿的配置根。 */
85
+ export declare function buildUnreadConfigKeyFields(k: UnreadConfigKey, dir: string | undefined): Record<string, unknown>;
73
86
  /** `config_unread_file` 一行的体(纯数据;起服 / 刷新 / 迟到起服与 `run-local` 同一体):`dir` = 本地读腿的配置根。 */
74
87
  export declare function buildUnreadConfigFileFields(f: UnreadConfigFile, dir: string | undefined): Record<string, unknown>;
75
88
  /** 逐条丢弃面的一行(两条读腿的 `droppedEntries` 同形,`config_entry_dropped` 日志行读它):`entry` = 被丢那条的出门形坐标(`models.1`),
@@ -22,6 +22,16 @@ export function separateRetiredDomains(body) {
22
22
  }
23
23
  return findings.length === 0 ? { body, retiredDomains: [] } : { body: rest, retiredDomains: findings };
24
24
  }
25
+ export function buildUnreadConfigKeyFields(k, dir) {
26
+ return {
27
+ ...(dir !== undefined ? { dir } : {}),
28
+ file: k.file,
29
+ domain: k.domain,
30
+ key: k.key,
31
+ names: k.names,
32
+ note: "the local config read has no worker identity, so this key is never read — prompts.json `workers` entries are not delivered, only `artifact` is; put the artifact this engine should run under `artifact` (or remove the key if it is meant for the center)",
33
+ };
34
+ }
25
35
  export function buildUnreadConfigFileFields(f, dir) {
26
36
  return {
27
37
  ...(dir !== undefined ? { dir } : {}),
@@ -18,6 +18,9 @@ export type SkillBodySource = Pick<ConfigProvider, "fetchSkillContent" | "skillB
18
18
  * hash, deduped in memory (same hash read once). A skill whose body is absent at the source or fails to read (incl. the
19
19
  * remote transport's hash check) is NOT installed — exactly one `web_admin_skill_failed` warn names it (`reason`:
20
20
  * `body_absent` | `read_failed`), the baseline of that name (if any) stays, and boot is never blocked.
21
+ * 🔴 **「正文在场」只有一条判据:非空串**({@link skillBodyPresent})。配置源答 `undefined`(没有这个 hash)与答 `""`(空正文)同为缺席 ⇒ `body_absent`:
22
+ * 一条空正文的技能是**惰性无提示**(名册里有它、模型调用回空、零行日志),不是「装了个什么都不说的技能」。本地腿尤其:settings-schema 把缺省的 `content`
23
+ * 补成 `""`,本地配置源因此**永远答得出**(空串)—— 没有这一条,`body_absent` 臂只在中心形上可达。本地 / 中心 / 盘缓存三个来源同过这一只判据。
21
24
  * Restart-to-apply: this runs at boot, before `buildScenarios` bakes skills into scenarios.
22
25
  */
23
26
  export declare function applySkillsManifest(baseline: LoadedSkill[], manifest: {