@sema-agent/core 7.54.1 → 7.55.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 (399) hide show
  1. package/CHANGELOG.md +437 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -1
  3. package/dist/agents/builtin-agents.d.ts +12 -14
  4. package/dist/agents/cc-peer-directory.d.ts +36 -0
  5. package/dist/agents/cc-peer-directory.js +138 -0
  6. package/dist/agents/cc-peer-wire.d.ts +105 -0
  7. package/dist/agents/cc-peer-wire.js +98 -0
  8. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  9. package/dist/agents/cc-uds-peer-channel.js +457 -0
  10. package/dist/agents/cross-session-envelope.d.ts +4 -1
  11. package/dist/agents/cross-session-envelope.js +8 -1
  12. package/dist/agents/cross-session-judge.d.ts +2 -2
  13. package/dist/agents/list-agents-tool.js +2 -1
  14. package/dist/agents/observer.d.ts +4 -5
  15. package/dist/agents/observer.js +2 -1
  16. package/dist/agents/peer-admission.d.ts +6 -0
  17. package/dist/agents/peer-admission.js +4 -1
  18. package/dist/agents/peer-directory.d.ts +43 -9
  19. package/dist/agents/peer-directory.js +66 -23
  20. package/dist/agents/peer-notices.d.ts +1 -1
  21. package/dist/agents/peer-session-drain.d.ts +3 -1
  22. package/dist/agents/peer-session-drain.js +1 -0
  23. package/dist/agents/read-inbox-tool.js +2 -1
  24. package/dist/agents/retain-ledger.d.ts +1 -1
  25. package/dist/agents/roster-store.d.ts +1 -1
  26. package/dist/agents/send-message-tool.d.ts +10 -0
  27. package/dist/agents/send-message-tool.js +34 -5
  28. package/dist/agents/subagent.d.ts +34 -79
  29. package/dist/agents/subagent.js +45 -46
  30. package/dist/agents/tool-filter.d.ts +29 -46
  31. package/dist/agents/tool-filter.js +8 -31
  32. package/dist/agents/verify.d.ts +3 -3
  33. package/dist/brain/anthropic.js +14 -9
  34. package/dist/brain/errors.d.ts +15 -0
  35. package/dist/brain/errors.js +10 -0
  36. package/dist/brain/model-presets.d.ts +4 -4
  37. package/dist/brain/open-responses.js +15 -10
  38. package/dist/brain/openai.js +17 -12
  39. package/dist/brain/provider-dialect.d.ts +39 -3
  40. package/dist/brain/provider-dialect.js +28 -0
  41. package/dist/brain/reasoning.d.ts +1 -1
  42. package/dist/brain/request-params.d.ts +55 -5
  43. package/dist/brain/request-params.js +35 -3
  44. package/dist/brain/retry.d.ts +1 -1
  45. package/dist/brain/route-adjudicator.d.ts +15 -0
  46. package/dist/brain/route-adjudicator.js +15 -0
  47. package/dist/brain/stream-engine.js +6 -5
  48. package/dist/brain/stream-shared.d.ts +1 -1
  49. package/dist/core/advisor-verdict.d.ts +120 -0
  50. package/dist/core/advisor-verdict.js +92 -0
  51. package/dist/core/agent-definition.d.ts +7 -8
  52. package/dist/core/allow-entry.d.ts +49 -23
  53. package/dist/core/allow-entry.js +57 -32
  54. package/dist/core/allow-rule-shadow.d.ts +7 -0
  55. package/dist/core/approval-object.d.ts +2 -1
  56. package/dist/core/approval-object.js +6 -6
  57. package/dist/core/ask-origin.d.ts +63 -11
  58. package/dist/core/ask-origin.js +27 -5
  59. package/dist/core/ask-question.js +10 -4
  60. package/dist/core/auto-compaction.d.ts +11 -8
  61. package/dist/core/auto-compaction.js +4 -2
  62. package/dist/core/auto-mode-arming.d.ts +2 -2
  63. package/dist/core/auto-mode-defaults.d.ts +8 -8
  64. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  65. package/dist/core/auto-mode-prompt.d.ts +1 -1
  66. package/dist/core/auto-mode.d.ts +17 -9
  67. package/dist/core/auto-mode.js +9 -6
  68. package/dist/core/background-agent-store.d.ts +3 -3
  69. package/dist/core/canonical-json.d.ts +1 -1
  70. package/dist/core/canonical-json.js +2 -2
  71. package/dist/core/checkpoint-requirements.d.ts +6 -3
  72. package/dist/core/checkpoint-requirements.js +4 -14
  73. package/dist/core/checkpoint-store.d.ts +80 -51
  74. package/dist/core/checkpoint-store.js +56 -74
  75. package/dist/core/child-clamp-seats.d.ts +6 -0
  76. package/dist/core/child-clamp-seats.js +3 -16
  77. package/dist/core/compliance.d.ts +2 -2
  78. package/dist/core/context-edit.d.ts +6 -7
  79. package/dist/core/cross-boundary-taint.d.ts +9 -3
  80. package/dist/core/cross-boundary-taint.js +5 -3
  81. package/dist/core/decision-receipt.js +2 -2
  82. package/dist/core/effective-path-target.d.ts +1 -1
  83. package/dist/core/engine-notice.d.ts +19 -5
  84. package/dist/core/exec-output-tail.d.ts +1 -1
  85. package/dist/core/file-history-retention.d.ts +1 -1
  86. package/dist/core/file-history-store.d.ts +59 -9
  87. package/dist/core/file-history-store.js +35 -17
  88. package/dist/core/gate-fold.js +3 -2
  89. package/dist/core/gate-lanes.js +12 -8
  90. package/dist/core/gate-outcome.d.ts +17 -4
  91. package/dist/core/gate-outcome.js +30 -0
  92. package/dist/core/governance-codes.d.ts +13 -3
  93. package/dist/core/governance-codes.js +10 -0
  94. package/dist/core/hands-band.d.ts +1 -1
  95. package/dist/core/hooks.d.ts +4 -4
  96. package/dist/core/host-target.d.ts +49 -0
  97. package/dist/core/host-target.js +59 -0
  98. package/dist/core/image-downsample.d.ts +1 -1
  99. package/dist/core/lsp-diagnostics.d.ts +4 -4
  100. package/dist/core/lsp.d.ts +3 -3
  101. package/dist/core/mailbox-store.d.ts +4 -0
  102. package/dist/core/mcp-connection-pool.d.ts +18 -2
  103. package/dist/core/mcp-connection-pool.js +53 -6
  104. package/dist/core/mcp-failure.d.ts +23 -4
  105. package/dist/core/mcp-failure.js +26 -11
  106. package/dist/core/mcp-listing-drift.d.ts +10 -0
  107. package/dist/core/mcp-listing-drift.js +6 -0
  108. package/dist/core/mcp-server-link.d.ts +173 -0
  109. package/dist/core/mcp-server-link.js +127 -0
  110. package/dist/core/mcp-server-spec.d.ts +4 -2
  111. package/dist/core/mcp-session-end.d.ts +26 -0
  112. package/dist/core/mcp-session-end.js +29 -0
  113. package/dist/core/mcp-startup-request.d.ts +17 -0
  114. package/dist/core/mcp-startup-request.js +17 -0
  115. package/dist/core/mcp.d.ts +13 -13
  116. package/dist/core/mcp.js +187 -162
  117. package/dist/core/media-byte-cap.d.ts +1 -1
  118. package/dist/core/memory-engine/engine.d.ts +9 -9
  119. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  120. package/dist/core/memory-engine/tools.js +4 -1
  121. package/dist/core/mode-policy.d.ts +1 -1
  122. package/dist/core/namespaced-rule-name.d.ts +33 -7
  123. package/dist/core/namespaced-rule-name.js +39 -25
  124. package/dist/core/output-style.d.ts +1 -1
  125. package/dist/core/param-rule-reach.d.ts +15 -0
  126. package/dist/core/param-rule-reach.js +30 -0
  127. package/dist/core/parent-spec-seat.d.ts +8 -1
  128. package/dist/core/parent-spec-seat.js +4 -0
  129. package/dist/core/pause-registry.d.ts +16 -5
  130. package/dist/core/pause-registry.js +6 -2
  131. package/dist/core/peer-channel.d.ts +70 -0
  132. package/dist/core/peer-channel.js +1 -0
  133. package/dist/core/permission-rule-consent.d.ts +11 -5
  134. package/dist/core/permission-rule-consent.js +37 -30
  135. package/dist/core/permission-rule-model.d.ts +233 -64
  136. package/dist/core/permission-rule-model.js +384 -85
  137. package/dist/core/permission-rule-provider.d.ts +2 -1
  138. package/dist/core/permission-rule-store.d.ts +20 -25
  139. package/dist/core/permission-rule-store.js +1 -4
  140. package/dist/core/permission-rule-sync.d.ts +11 -2
  141. package/dist/core/permission-rule-sync.js +8 -1
  142. package/dist/core/permission-rules.d.ts +49 -11
  143. package/dist/core/permission-rules.js +123 -89
  144. package/dist/core/persisted-rule-arms.d.ts +4 -2
  145. package/dist/core/present-plan-tool.js +3 -1
  146. package/dist/core/protocol-naming.d.ts +2 -2
  147. package/dist/core/read-only-shell-table.d.ts +1 -1
  148. package/dist/core/read-only-shell.d.ts +1 -1
  149. package/dist/core/roles.d.ts +6 -2
  150. package/dist/core/roles.js +45 -44
  151. package/dist/core/rule-offer-read.d.ts +53 -0
  152. package/dist/core/rule-offer-read.js +146 -0
  153. package/dist/core/rule-owner.d.ts +46 -0
  154. package/dist/core/rule-owner.js +28 -0
  155. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  156. package/dist/core/runner/advisor-instructions.js +61 -0
  157. package/dist/core/runner/advisor-tool.d.ts +33 -0
  158. package/dist/core/runner/advisor-tool.js +112 -0
  159. package/dist/core/runner/announce-once-ledger.d.ts +4 -26
  160. package/dist/core/runner/announce-once-ledger.js +14 -46
  161. package/dist/core/runner/approval-feedback.js +6 -3
  162. package/dist/core/runner/assemble-result.d.ts +1 -1
  163. package/dist/core/runner/caller-roster.d.ts +7 -0
  164. package/dist/core/runner/caller-roster.js +11 -0
  165. package/dist/core/runner/classifier-ladder.d.ts +27 -5
  166. package/dist/core/runner/classifier-ladder.js +12 -11
  167. package/dist/core/runner/compaction-restate.d.ts +10 -6
  168. package/dist/core/runner/compaction-restate.js +9 -3
  169. package/dist/core/runner/contracts.d.ts +13 -9
  170. package/dist/core/runner/conversation-segment.d.ts +28 -0
  171. package/dist/core/runner/conversation-segment.js +42 -0
  172. package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
  173. package/dist/core/runner/cross-boundary-lane.js +26 -15
  174. package/dist/core/runner/decide-continuation.d.ts +7 -4
  175. package/dist/core/runner/decide-continuation.js +2 -2
  176. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  177. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  178. package/dist/core/runner/derived-route-fallback.js +9 -7
  179. package/dist/core/runner/gate-exit.d.ts +6 -0
  180. package/dist/core/runner/gate-exit.js +7 -2
  181. package/dist/core/runner/initial-run-state.js +1 -1
  182. package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
  183. package/dist/core/runner/permission-rule-lanes.js +14 -7
  184. package/dist/core/runner/person-path-rows.js +1 -1
  185. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  186. package/dist/core/runner/prepare-advisor.js +77 -0
  187. package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
  188. package/dist/core/runner/prepare-config-doors.d.ts +6 -4
  189. package/dist/core/runner/prepare-config-doors.js +18 -12
  190. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  191. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  192. package/dist/core/runner/prepare-file-history.js +39 -39
  193. package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
  194. package/dist/core/runner/prepare-gate-stations.js +2 -7
  195. package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
  196. package/dist/core/runner/prepare-inherited-gate.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.js +7 -7
  198. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  199. package/dist/core/runner/prepare-policy-chain.js +4 -10
  200. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  201. package/dist/core/runner/prepare-project-context.js +6 -3
  202. package/dist/core/runner/prepare-prompt-inputs.js +1 -1
  203. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
  204. package/dist/core/runner/prepare-protocol-tools.js +3 -2
  205. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  206. package/dist/core/runner/prepare-safety-scan.js +8 -6
  207. package/dist/core/runner/prepare-task.js +15 -18
  208. package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
  209. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
  210. package/dist/core/runner/prepare-wiring-manifest.js +2 -2
  211. package/dist/core/runner/resume-policy-outcome.js +1 -1
  212. package/dist/core/runner/retired-runner-deps.js +1 -1
  213. package/dist/core/runner/run-attachment-seats.js +0 -1
  214. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  215. package/dist/core/runner/run-compaction-machinery.js +2 -12
  216. package/dist/core/runner/run-git-lane.d.ts +1 -0
  217. package/dist/core/runner/run-harness-handlers.js +2 -3
  218. package/dist/core/runner/run-leg.js +13 -0
  219. package/dist/core/runner/run-settle-and-teardown.js +1 -1
  220. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  221. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  222. package/dist/core/runner/run-turn-boundary.js +14 -12
  223. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  224. package/dist/core/runner/session-rule-policy.js +13 -28
  225. package/dist/core/runner/side-call-account.d.ts +32 -8
  226. package/dist/core/runner/side-call-account.js +23 -1
  227. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  228. package/dist/core/runner/sub-agent-deny-lists.js +4 -3
  229. package/dist/core/runner/synthetic-tools.d.ts +10 -13
  230. package/dist/core/runner/synthetic-tools.js +4 -2
  231. package/dist/core/runner/tool-disclosure.js +2 -1
  232. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  233. package/dist/core/runner/tool-face-overlay.js +17 -1
  234. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  235. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  236. package/dist/core/runner/turn-attachments.d.ts +60 -67
  237. package/dist/core/runner-deps.d.ts +37 -37
  238. package/dist/core/runtime-caps.d.ts +4 -4
  239. package/dist/core/safety-merge-corpus.js +17 -1
  240. package/dist/core/same-plain-value.d.ts +40 -0
  241. package/dist/core/same-plain-value.js +49 -0
  242. package/dist/core/scheduler.d.ts +1 -1
  243. package/dist/core/sensitive-path-policy.d.ts +1 -1
  244. package/dist/core/sensitive-path-policy.js +1 -1
  245. package/dist/core/session-policy-store.d.ts +77 -22
  246. package/dist/core/session-policy-store.js +56 -14
  247. package/dist/core/session-reconcile.d.ts +2 -2
  248. package/dist/core/session-store.d.ts +80 -30
  249. package/dist/core/session-store.js +118 -76
  250. package/dist/core/session.d.ts +24 -46
  251. package/dist/core/shared-memory/tools.js +3 -1
  252. package/dist/core/shared-memory/types.d.ts +1 -1
  253. package/dist/core/side-query.d.ts +10 -0
  254. package/dist/core/side-query.js +5 -0
  255. package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
  256. package/dist/core/store-contracts/file-history-store-contract.js +43 -3
  257. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  258. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  259. package/dist/core/store-contracts/session-repo-contract.js +125 -0
  260. package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
  261. package/dist/core/store-contracts/session-store-contract.js +215 -41
  262. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  263. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  264. package/dist/core/task-event.d.ts +10 -4
  265. package/dist/core/task-notification.d.ts +3 -3
  266. package/dist/core/task-registry-agent.d.ts +4 -4
  267. package/dist/core/task-registry-shared.d.ts +4 -4
  268. package/dist/core/task-registry-shared.js +1 -0
  269. package/dist/core/task-registry.d.ts +4 -4
  270. package/dist/core/task-registry.js +3 -1
  271. package/dist/core/task-result.d.ts +3 -3
  272. package/dist/core/task-spec.d.ts +52 -52
  273. package/dist/core/task-stream.d.ts +6 -6
  274. package/dist/core/task-tool-shape.d.ts +4 -4
  275. package/dist/core/tighten-task-spec.d.ts +1 -1
  276. package/dist/core/tool-catalog-entries.d.ts +19 -2
  277. package/dist/core/tool-catalog-entries.js +57 -42
  278. package/dist/core/tool-conformance.js +1 -0
  279. package/dist/core/tool-errors.d.ts +2 -2
  280. package/dist/core/tool-face-reader.js +5 -3
  281. package/dist/core/tool-face.d.ts +21 -2
  282. package/dist/core/tool-face.js +1 -1
  283. package/dist/core/tool-model-gate.d.ts +3 -3
  284. package/dist/core/tool-name-aliases.d.ts +29 -8
  285. package/dist/core/tool-name-aliases.js +27 -3
  286. package/dist/core/tool-name-readings.d.ts +5 -8
  287. package/dist/core/tool-name-readings.js +1 -2
  288. package/dist/core/tool-policy.d.ts +24 -5
  289. package/dist/core/tool-policy.js +34 -10
  290. package/dist/core/tool-registry.d.ts +14 -7
  291. package/dist/core/tool-registry.js +17 -7
  292. package/dist/core/tool-result-store.js +2 -1
  293. package/dist/core/tool-roster.d.ts +47 -18
  294. package/dist/core/tool-roster.js +53 -32
  295. package/dist/core/tool-spec-members.js +1 -1
  296. package/dist/core/tool-spec.d.ts +35 -21
  297. package/dist/core/tools.js +3 -2
  298. package/dist/core/trace.d.ts +4 -0
  299. package/dist/core/untrusted-egress.d.ts +1 -1
  300. package/dist/core/untrusted-text.d.ts +1 -1
  301. package/dist/core/warm-resume.d.ts +1 -1
  302. package/dist/core/wiring-manifest.d.ts +49 -0
  303. package/dist/core/wiring-manifest.js +13 -5
  304. package/dist/core/workflow-journal-store.d.ts +62 -0
  305. package/dist/core/workflow-journal-store.js +77 -1
  306. package/dist/core/workflow-run-store.d.ts +6 -0
  307. package/dist/core/workflow-run-store.js +2 -0
  308. package/dist/engine/compaction/compaction.d.ts +9 -9
  309. package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
  310. package/dist/engine/execution-env/node-execution-env.js +43 -22
  311. package/dist/engine/harness/agent-harness.d.ts +14 -8
  312. package/dist/engine/harness/agent-harness.js +33 -26
  313. package/dist/engine/harness/types.d.ts +29 -7
  314. package/dist/engine/harness/types.js +12 -1
  315. package/dist/engine/llm/types.d.ts +9 -9
  316. package/dist/engine/llm/validation.d.ts +4 -1
  317. package/dist/engine/llm/validation.js +13 -1
  318. package/dist/engine/loop/agent-loop.d.ts +1 -1
  319. package/dist/engine/loop/agent-loop.js +10 -8
  320. package/dist/engine/loop/types.d.ts +15 -13
  321. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  322. package/dist/engine/session/memory-repo.d.ts +10 -11
  323. package/dist/engine/session/memory-repo.js +13 -8
  324. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  325. package/dist/engine/session/parent-chain-guard.js +1 -1
  326. package/dist/engine/session/repo-utils.d.ts +31 -3
  327. package/dist/engine/session/repo-utils.js +42 -5
  328. package/dist/index.d.ts +27 -15
  329. package/dist/index.js +21 -11
  330. package/dist/internal/harness-types.d.ts +1 -1
  331. package/dist/internal/harness.d.ts +3 -3
  332. package/dist/internal/harness.js +2 -2
  333. package/dist/internal/llm.d.ts +1 -1
  334. package/dist/internal/llm.js +1 -1
  335. package/dist/orchestration/goal.js +2 -2
  336. package/dist/orchestration/run-workflow-tool.d.ts +2 -2
  337. package/dist/orchestration/run-workflow-tool.js +5 -3
  338. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  339. package/dist/orchestration/workflow-types.d.ts +18 -0
  340. package/dist/orchestration/workflow-types.js +6 -0
  341. package/dist/orchestration/workflow.d.ts +2 -13
  342. package/dist/orchestration/workflow.js +21 -31
  343. package/dist/prompt-assembly/event-registry.js +1 -0
  344. package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
  345. package/dist/prompt-assembly/tool-catalog.js +3 -0
  346. package/dist/prompts/default.d.ts +14 -14
  347. package/dist/scenarios/full-body.d.ts +4 -4
  348. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  349. package/dist/stores/file/adoption/adopt.js +24 -31
  350. package/dist/stores/file/adoption/marker.d.ts +6 -13
  351. package/dist/stores/file/adoption/marker.js +6 -15
  352. package/dist/stores/file/checkpoint-store.d.ts +3 -0
  353. package/dist/stores/file/checkpoint-store.js +9 -3
  354. package/dist/stores/file/file-history-store.d.ts +20 -19
  355. package/dist/stores/file/file-history-store.js +152 -135
  356. package/dist/stores/file/fs-atomic.d.ts +15 -0
  357. package/dist/stores/file/fs-atomic.js +89 -14
  358. package/dist/stores/file/index.d.ts +1 -1
  359. package/dist/stores/file/mailbox-store.d.ts +3 -0
  360. package/dist/stores/file/mailbox-store.js +3 -1
  361. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  362. package/dist/stores/file/permission-rule-adopt.js +15 -16
  363. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  364. package/dist/stores/file/permission-rule-store.js +21 -14
  365. package/dist/stores/file/session-policy-store.d.ts +3 -3
  366. package/dist/stores/file/session-store.d.ts +26 -11
  367. package/dist/stores/file/session-store.js +77 -40
  368. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  369. package/dist/stores/file/workflow-journal-store.js +28 -13
  370. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  371. package/dist/tools/artifact/artifact-tool.js +2 -1
  372. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  373. package/dist/tools/fs/fs-bash.d.ts +2 -2
  374. package/dist/tools/fs/fs-bash.js +3 -1
  375. package/dist/tools/fs/fs-shared.d.ts +8 -8
  376. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  377. package/dist/tools/fs/notebook.d.ts +2 -2
  378. package/dist/tools/fs/read-deny.d.ts +29 -7
  379. package/dist/tools/fs/read-deny.js +63 -22
  380. package/dist/tools/fs/removal-targets.d.ts +1 -1
  381. package/dist/tools/fs/safety.d.ts +9 -9
  382. package/dist/tools/fs/search.d.ts +6 -6
  383. package/dist/tools/fs/shell-read-check.js +6 -1
  384. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  385. package/dist/tools/fs/shell-read-judge.js +5 -2
  386. package/dist/tools/loop-tick.d.ts +2 -2
  387. package/dist/tools/scheduler-tools.js +5 -1
  388. package/dist/tools/task-list.d.ts +7 -7
  389. package/dist/tools/task-list.js +5 -1
  390. package/dist/tools/todo.js +2 -1
  391. package/dist/tools/web.d.ts +1 -1
  392. package/dist/tools/web.js +40 -37
  393. package/dist/tools/worktree.d.ts +3 -3
  394. package/dist/tools/worktree.js +3 -1
  395. package/package.json +1 -1
  396. package/test/export-surface.snapshot.json +5756 -5638
  397. package/wire-changes/core@7.55.0.json +3318 -0
  398. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  399. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -5,12 +5,15 @@ function catalogModel(ref, models) {
5
5
  const m = models != null && (typeof models === "object" || typeof models === "function") && Object.hasOwn(models, ref) ? models[ref] : undefined;
6
6
  return m || undefined;
7
7
  }
8
- function modelBindingRefusal(seat, reason, message) {
8
+ function modelBindingRefusal(field, reason, message) {
9
9
  const e = new Error(message);
10
10
  e.code = "config.unknown_role";
11
- e.detail = { field: seat, reason };
11
+ e.detail = { field, reason };
12
12
  return e;
13
13
  }
14
+ function isBindingObject(value) {
15
+ return (typeof value === "object" && value !== null) || typeof value === "function";
16
+ }
14
17
  function bindingShown(value) {
15
18
  if (typeof value === "string")
16
19
  return JSON.stringify(value.length > 80 ? `${value.slice(0, 80)}…` : value);
@@ -19,15 +22,27 @@ function bindingShown(value) {
19
22
  function unknownModelRefRefusal(ref, seat) {
20
23
  return modelBindingRefusal(seat, "unknown_model_ref", `Unknown model ref ${bindingShown(ref)} in ${seat}. Provide it in RunnerDeps.models or pass a Model object.`);
21
24
  }
22
- export function resolveModel(ref, models) {
23
- if (typeof ref !== "string") {
24
- return ref;
25
+ function modelOfBinding(value, models, seat, binds) {
26
+ assertModelBindingShape(value, seat, binds);
27
+ if (typeof value === "string") {
28
+ const held = catalogModel(value, models);
29
+ if (held === undefined)
30
+ throw unknownModelRefRefusal(value, seat);
31
+ return held;
25
32
  }
26
- const m = catalogModel(ref, models);
27
- if (!m) {
28
- throw new Error(`Unknown model ref "${ref}". Provide it in RunnerDeps.models or pass a Model object.`);
33
+ return value;
34
+ }
35
+ function assertModelBindingShape(value, seat, binds) {
36
+ if (typeof value === "string")
37
+ return;
38
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
39
+ throw modelBindingRefusal(seat, "not_a_model_ref", `${seat} is ${bindingShown(value)}, not a model reference — ${binds}.`);
29
40
  }
30
- return m;
41
+ }
42
+ const ROLE_BINDS = "a role binds a catalog model name or a Model object";
43
+ const roleModelSeat = (named, seat) => (typeof named === "string" ? seat : `${seat}.model`);
44
+ export function resolveModel(ref, models, seat = "model") {
45
+ return modelOfBinding(ref, models, seat, "a model is named by a catalog model name or a Model object");
31
46
  }
32
47
  export const DEFAULT_TIER_ORDER = ["ultra", "max", "pro", "flash", "lite"];
33
48
  export const CC_MODEL_TIER_ALIASES = {
@@ -53,17 +68,7 @@ export function expandTiers(models, tiers) {
53
68
  const b = Object.hasOwn(tiers, name) ? tiers[name] : undefined;
54
69
  if (b === undefined)
55
70
  return undefined;
56
- const seat = `tiers.${name}`;
57
- if (typeof b === "string") {
58
- const held = catalogModel(b, models);
59
- if (held === undefined)
60
- throw unknownModelRefRefusal(b, seat);
61
- return held;
62
- }
63
- if (typeof b !== "object" || b === null || Array.isArray(b)) {
64
- throw modelBindingRefusal(seat, "not_a_model_ref", `${seat} is ${bindingShown(b)}, not a model reference — a tier binds a catalog model name or a Model object.`);
65
- }
66
- return b;
71
+ return modelOfBinding(b, models, `tiers.${name}`, "a tier binds a catalog model name or a Model object");
67
72
  };
68
73
  const ownKey = (k) => models !== undefined && Object.hasOwn(models, k) && Boolean(models[k]);
69
74
  const landing = (t, self) => {
@@ -162,13 +167,13 @@ const FALLBACK = {
162
167
  consolidate: ["summarize"],
163
168
  };
164
169
  function specParts(s, seat = "a role seat") {
165
- if (s == null) {
170
+ if (s === undefined) {
166
171
  return {};
167
172
  }
168
173
  if (typeof s === "string") {
169
174
  return { model: s };
170
175
  }
171
- if (typeof s !== "object" && typeof s !== "function") {
176
+ if (!isBindingObject(s)) {
172
177
  throw modelBindingRefusal(seat, "not_a_model_ref", `${seat} is ${bindingShown(s)}, not a model reference — a role binds a catalog model name, a Model object or a { model, select, thinking, systemPrompt } record.`);
173
178
  }
174
179
  if ("id" in s && "api" in s) {
@@ -182,7 +187,7 @@ export function roleSpecNamesModel(spec) {
182
187
  return parts.model !== undefined || parts.select !== undefined;
183
188
  }
184
189
  function toConfig(s) {
185
- if (s == null) {
190
+ if (s === undefined) {
186
191
  return undefined;
187
192
  }
188
193
  if (typeof s === "string" || ("id" in s && "api" in s)) {
@@ -205,19 +210,25 @@ function mergeRoleSpec(base, over) {
205
210
  systemPrompt: o.systemPrompt ?? b.systemPrompt,
206
211
  };
207
212
  }
208
- function assertKnownRole(word, seat) {
213
+ function assertKnownRole(word, field, ofKey = false) {
209
214
  if (typeof word === "string" && MODEL_ROLES.includes(word))
210
215
  return;
211
216
  const shown = typeof word === "string" ? JSON.stringify(word).slice(0, 80) : `<${word === null ? "null" : typeof word}>`;
212
- const e = new Error(`${seat} names the model role ${shown}, which is not one of ${MODEL_ROLES.join(" / ")} — a word outside the vocabulary binds nothing and resolves nothing; bind the model on one of these roles, or name it on TaskSpec.model`);
213
- e.code = "config.unknown_role";
214
- throw e;
217
+ throw modelBindingRefusal(field, "unknown_role_word", `${ofKey ? `${field} key` : field} names the model role ${shown}, which is not one of ${MODEL_ROLES.join(" / ")} — a word outside the vocabulary binds nothing and resolves nothing; bind the model on one of these roles, or name it on TaskSpec.model`);
215
218
  }
216
219
  function mergeRoles(base, over) {
217
220
  for (const key of Object.keys(base ?? {}))
218
- assertKnownRole(key, "RunnerDeps.roles key");
221
+ assertKnownRole(key, "RunnerDeps.roles", true);
219
222
  for (const key of Object.keys(over ?? {}))
220
- assertKnownRole(key, "TaskSpec.roles key");
223
+ assertKnownRole(key, "TaskSpec.roles", true);
224
+ for (const roles of [base, over]) {
225
+ for (const [key, value] of Object.entries(roles ?? {})) {
226
+ const seat = `roles.${key}`;
227
+ const named = specParts(value, seat).model;
228
+ if (named !== undefined)
229
+ assertModelBindingShape(named, roleModelSeat(named, seat), ROLE_BINDS);
230
+ }
231
+ }
221
232
  const out = { ...base };
222
233
  for (const role of Object.keys(over ?? {})) {
223
234
  out[role] = mergeRoleSpec(base?.[role], over?.[role]);
@@ -225,8 +236,8 @@ function mergeRoles(base, over) {
225
236
  return out;
226
237
  }
227
238
  function partsModel(parts, models, seat = "a role seat") {
228
- if (parts.model) {
229
- return resolveModel(parts.model, models);
239
+ if (parts.model !== undefined) {
240
+ return modelOfBinding(parts.model, models, roleModelSeat(parts.model, seat), ROLE_BINDS);
230
241
  }
231
242
  if (parts.select) {
232
243
  const needs = parts.select.needs;
@@ -239,12 +250,12 @@ function partsModel(parts, models, seat = "a role seat") {
239
250
  return undefined;
240
251
  }
241
252
  export function resolveTaskModel(spec, deps) {
242
- const start = spec.modelRole ?? "default";
253
+ const start = spec.modelRole === undefined ? "default" : spec.modelRole;
243
254
  assertKnownRole(start, "modelRole");
244
- if (spec.model) {
255
+ if (spec.model !== undefined) {
245
256
  const startParts = specParts(mergeRoles(deps.roles, spec.roles)[start], `roles.${start}`);
246
257
  return {
247
- model: resolveModel(spec.model, deps.models),
258
+ model: resolveModel(spec.model, deps.models, "TaskSpec.model"),
248
259
  modelRef: spec.model,
249
260
  thinking: spec.thinking ?? startParts.thinking,
250
261
  systemPrompt: startParts.systemPrompt,
@@ -267,15 +278,5 @@ export function roleModelIfSet(role, spec, deps) {
267
278
  const merged = mergeRoles(deps.roles, spec.roles);
268
279
  const seat = `roles.${role}`;
269
280
  const parts = specParts(merged[role], seat);
270
- const named = parts.model;
271
- if (named) {
272
- if (typeof named === "string") {
273
- if (catalogModel(named, deps.models) === undefined)
274
- throw unknownModelRefRefusal(named, seat);
275
- }
276
- else if (typeof named !== "object" || Array.isArray(named)) {
277
- throw modelBindingRefusal(seat, "not_a_model_ref", `${seat}.model is ${bindingShown(named)}, not a model reference — a role binds a catalog model name or a Model object.`);
278
- }
279
- }
280
281
  return partsModel(parts, deps.models, seat) ?? roleTierModel(role, deps.models);
281
282
  }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The read-back judge of a stored rule-offer list: the {@link RuleOffer} array core mints beside an approval
3
+ * (`AskRequest.ruleOffers`, a parked row's `pendingAction.ruleOffers`). Core mints the shape, so its reading lives
4
+ * here; a backend or a surface that reads the list back calls {@link readRuleOffers} instead of keeping a schema of
5
+ * its own. Display caps (how many offers, members or detail rows a surface shows) stay with the surface.
6
+ */
7
+ import { type RuleOffer } from "./permission-rule-model.js";
8
+ /**
9
+ * Why a stored rule-offer value, or one element of it, is not read:
10
+ * · `not_an_array` — the value itself (present, and not a list): no element is read;
11
+ * · `unknown_word` — a closed-set member holds a word this engine does not know: the offer `kind`, a batch member's
12
+ * `kind`, a `match` (a newer minter, or another writer);
13
+ * · `malformed` — not an object, a member missing or of the wrong type, a batch with no members, an uncovered count
14
+ * that is not a non-negative safe integer.
15
+ * The first defect in reading order names the element's problem.
16
+ */
17
+ export declare const RULE_OFFER_SHAPE_PROBLEMS: readonly ["not_an_array", "unknown_word", "malformed"];
18
+ export type RuleOfferShapeProblem = (typeof RULE_OFFER_SHAPE_PROBLEMS)[number];
19
+ /** One element read. `index` is its position in the stored list — the selection key a card and its redemption keep. */
20
+ export interface RuleOfferRead {
21
+ readonly index: number;
22
+ /** A fresh object holding only the members the type declares (additive members the minter wrote are not copied). */
23
+ readonly offer: RuleOffer;
24
+ /** Present when the batch's `uncoveredDetail` seat was not one well-formed row per counted segment and was left out
25
+ * (the count is the truth source and an absent seat claims nothing); the caller owes that loss a disclosure. */
26
+ readonly uncoveredDetailDropped?: true;
27
+ /** Present when at least one batch member was read through the kind-less stored form (no `kind`, the four command
28
+ * text members). A backend counts these to know whether its rows still carry the form that retirement line
29
+ * RL-2164-kindless-batch-member waits on. */
30
+ readonly kindlessForm?: true;
31
+ }
32
+ /** One element not read, and why. The rest of the list is read regardless. */
33
+ export interface RuleOfferDropped {
34
+ readonly index: number;
35
+ readonly problem: Exclude<RuleOfferShapeProblem, "not_an_array">;
36
+ }
37
+ /** {@link readRuleOffers}' answer. */
38
+ export type RuleOffersReading = {
39
+ readonly offers: readonly RuleOfferRead[];
40
+ readonly dropped: readonly RuleOfferDropped[];
41
+ } | {
42
+ readonly problem: "not_an_array";
43
+ };
44
+ /**
45
+ * Read a stored rule-offer list. `undefined` (the member absent) reads as no offers; any other non-list is
46
+ * `not_an_array`. Each element is judged alone and keeps its original index: an element that is not an offer this
47
+ * engine reads is dropped WHOLE (a batch with one unreadable member is dropped, never shortened — a conjunction one
48
+ * member short would render "yes to N" as "yes to N−1") and its siblings stand. Every member is read once.
49
+ * The input domain is a decoded JSON value or a list core minted: a value carrying accessors or a Proxy is outside it,
50
+ * and such a value may be refused as malformed or may throw while it is read. A record is a plain one
51
+ * ({@link isPlainRecord}, the reading the risk-descriptor axes take too).
52
+ */
53
+ export declare function readRuleOffers(raw: unknown): RuleOffersReading;
@@ -0,0 +1,146 @@
1
+ import { PERSISTED_RULE_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_KINDS, UNCOVERED_SEGMENT_REASONS, } from "./permission-rule-model.js";
2
+ import { isPlainRecord } from "./checkpoint-store.js";
3
+ export const RULE_OFFER_SHAPE_PROBLEMS = Object.freeze(["not_an_array", "unknown_word", "malformed"]);
4
+ const MALFORMED = Object.freeze({ problem: "malformed" });
5
+ const UNKNOWN_WORD = Object.freeze({ problem: "unknown_word" });
6
+ export function readRuleOffers(raw) {
7
+ if (raw === undefined)
8
+ return { offers: [], dropped: [] };
9
+ if (!Array.isArray(raw))
10
+ return { problem: "not_an_array" };
11
+ const offers = [];
12
+ const dropped = [];
13
+ const length = raw.length;
14
+ for (let index = 0; index < length; index++) {
15
+ const verdict = readOfferElement(raw[index]);
16
+ if ("problem" in verdict)
17
+ dropped.push({ index, problem: verdict.problem });
18
+ else
19
+ offers.push({ index, ...verdict });
20
+ }
21
+ return { offers, dropped };
22
+ }
23
+ function wordOf(value, words) {
24
+ if (typeof value !== "string")
25
+ return MALFORMED;
26
+ return words.some((w) => w === value) ? value : UNKNOWN_WORD;
27
+ }
28
+ function readOfferElement(value) {
29
+ if (!isPlainRecord(value))
30
+ return MALFORMED;
31
+ const kind = wordOf(value.kind, RULE_OFFER_KINDS);
32
+ if (typeof kind !== "string")
33
+ return kind;
34
+ switch (kind) {
35
+ case "single": {
36
+ const rule = value.rule;
37
+ const match = wordOf(value.match, PERSISTED_RULE_MATCHES);
38
+ const command = value.command;
39
+ if (typeof rule !== "string")
40
+ return MALFORMED;
41
+ if (typeof match !== "string")
42
+ return match;
43
+ if (typeof command !== "string")
44
+ return MALFORMED;
45
+ return { offer: { kind: "single", rule, match, command } };
46
+ }
47
+ case "batch":
48
+ return readBatch(value);
49
+ default: {
50
+ const unhandled = kind;
51
+ return unhandled;
52
+ }
53
+ }
54
+ }
55
+ function readBatch(value) {
56
+ const rules = value.rules;
57
+ const count = value.uncoveredSegments;
58
+ const detail = value.uncoveredDetail;
59
+ if (!Array.isArray(rules))
60
+ return MALFORMED;
61
+ const length = rules.length;
62
+ if (length === 0)
63
+ return MALFORMED;
64
+ const members = [];
65
+ let kindless = false;
66
+ for (let i = 0; i < length; i++) {
67
+ const verdict = readBatchMember(rules[i]);
68
+ if ("problem" in verdict)
69
+ return verdict;
70
+ members.push(verdict.member);
71
+ if (verdict.kindlessForm === true)
72
+ kindless = true;
73
+ }
74
+ if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0)
75
+ return MALFORMED;
76
+ const offer = { kind: "batch", rules: members, uncoveredSegments: count };
77
+ const marks = kindless ? { kindlessForm: true } : {};
78
+ if (detail === undefined)
79
+ return { offer, ...marks };
80
+ const rows = detailRowsOf(detail, count);
81
+ return rows !== undefined ? { offer: { ...offer, uncoveredDetail: rows }, ...marks } : { offer, uncoveredDetailDropped: true, ...marks };
82
+ }
83
+ function readBatchMember(value) {
84
+ if (!isPlainRecord(value))
85
+ return MALFORMED;
86
+ if (!("kind" in value))
87
+ return readKindlessBatchMember(value);
88
+ const kind = wordOf(value.kind, RULE_OFFER_BATCH_MEMBER_KINDS);
89
+ if (typeof kind !== "string")
90
+ return kind;
91
+ switch (kind) {
92
+ case "command":
93
+ return commandMember(value.rule, value.match, value.command, value.segment);
94
+ case "directoryRead": {
95
+ const rule = value.rule;
96
+ const directory = value.directory;
97
+ const segment = value.segment;
98
+ if (typeof rule !== "string" || typeof directory !== "string" || typeof segment !== "string")
99
+ return MALFORMED;
100
+ return { member: { kind: "directoryRead", rule, directory, segment } };
101
+ }
102
+ default: {
103
+ const unhandled = kind;
104
+ return unhandled;
105
+ }
106
+ }
107
+ }
108
+ function readKindlessBatchMember(value) {
109
+ const rule = value.rule;
110
+ const match = value.match;
111
+ const command = value.command;
112
+ const segment = value.segment;
113
+ if (typeof rule !== "string" || typeof match !== "string" || typeof command !== "string" || typeof segment !== "string")
114
+ return MALFORMED;
115
+ const verdict = commandMember(rule, match, command, segment);
116
+ return "problem" in verdict ? verdict : { ...verdict, kindlessForm: true };
117
+ }
118
+ function commandMember(rule, rawMatch, command, segment) {
119
+ if (typeof rule !== "string")
120
+ return MALFORMED;
121
+ const match = wordOf(rawMatch, PERSISTED_RULE_MATCHES);
122
+ if (typeof match !== "string")
123
+ return match;
124
+ if (typeof command !== "string" || typeof segment !== "string")
125
+ return MALFORMED;
126
+ return { member: { kind: "command", rule, match, command, segment } };
127
+ }
128
+ function detailRowsOf(detail, count) {
129
+ if (!Array.isArray(detail))
130
+ return undefined;
131
+ const length = detail.length;
132
+ if (length !== count)
133
+ return undefined;
134
+ const rows = [];
135
+ for (let i = 0; i < length; i++) {
136
+ const row = detail[i];
137
+ if (!isPlainRecord(row))
138
+ return undefined;
139
+ const segment = row.segment;
140
+ const reason = wordOf(row.reason, UNCOVERED_SEGMENT_REASONS);
141
+ if (typeof segment !== "string" || typeof reason !== "string")
142
+ return undefined;
143
+ rows.push({ segment, reason });
144
+ }
145
+ return rows;
146
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Who a permission-rule bucket belongs to: the owner type, its discriminant words, the one reading of an owner from a
3
+ * value the engine did not just build, and the one equality between two owners.
4
+ *
5
+ * The faces that read an owner out of data — the two adoption markers read back from disk, the two adoption entries'
6
+ * source, a stored approval record's identity and the consent entries' `owner` option — read it through
7
+ * {@link readRuleOwner}, so the source an adoption entry writes into its marker is one that marker's reader reads back.
8
+ * Its one run-time import is the import-free record judge — the root adoption marker reader, which every file store
9
+ * loads, depends on this module and is kept free of the rule store's own imports.
10
+ */
11
+ import type { AssertAllKeysHandled } from "./ask-origin.js";
12
+ /**
13
+ * Who a rule bucket belongs to, as a STRUCTURAL position.
14
+ *
15
+ * Identity absence is spelled as a distinct union member, never as a sentinel string flowing through
16
+ * `forPrincipal` — every consumer of a principal string is an identity surface, and a made-up name on an
17
+ * identity surface is indistinguishable from a real one downstream. Cloud sync and cloud tickets accept
18
+ * ONLY the `principal` kind: syncing is an authenticated act, and a local-owner bucket has no cloud home
19
+ * until it is adopted (`adoptFilePermissionRuleStore`).
20
+ */
21
+ export type RuleOwner = {
22
+ kind: "principal";
23
+ principal: string;
24
+ } | {
25
+ kind: "local-owner";
26
+ };
27
+ /** The owner discriminants as a value: the `kind` words of {@link RuleOwner}, both directions fenced at compile time
28
+ * ({@link RuleOwnerKindsCoverEveryArm} / {@link RuleOwnerArmsCoverEveryKind}). */
29
+ export declare const RULE_OWNER_KINDS: readonly ["principal", "local-owner"];
30
+ /** Compile fence: an arm whose `kind` is not in {@link RULE_OWNER_KINDS} turns the argument into that word. */
31
+ export type RuleOwnerKindsCoverEveryArm = AssertAllKeysHandled<Exclude<RuleOwner["kind"], (typeof RULE_OWNER_KINDS)[number]>>;
32
+ /** Compile fence, the other direction: a word in {@link RULE_OWNER_KINDS} that no arm carries. */
33
+ export type RuleOwnerArmsCoverEveryKind = AssertAllKeysHandled<Exclude<(typeof RULE_OWNER_KINDS)[number], RuleOwner["kind"]>>;
34
+ /** Do two owners name the same bucket? */
35
+ export declare function sameRuleOwner(a: RuleOwner, b: RuleOwner): boolean;
36
+ /**
37
+ * Read an owner from a value the engine did not just build, or `undefined` when it is not one: not a plain record (an
38
+ * object whose prototype is `Object.prototype` or none, so no member comes from a prototype it was given), a `kind`
39
+ * outside {@link RULE_OWNER_KINDS}, or a `principal` arm whose name is not a string with a non-whitespace character (an
40
+ * identity-less bucket is the `local-owner` kind, never a blank name). Fail-closed: a caller treats `undefined` as
41
+ * "owns nothing" or refuses — never as either arm. The answer is a fresh object holding only the members the type
42
+ * declares; `kind` and `principal` are each read once.
43
+ */
44
+ export declare function readRuleOwner(raw: unknown): RuleOwner | undefined;
45
+ /** An owner as an operator's sentence names it: `principal "<name>"`, or `the local owner`. */
46
+ export declare function ruleOwnerText(owner: RuleOwner): string;
@@ -0,0 +1,28 @@
1
+ import { isPlainRecord } from "./mods/kernel/receive.js";
2
+ export const RULE_OWNER_KINDS = Object.freeze(["principal", "local-owner"]);
3
+ export function sameRuleOwner(a, b) {
4
+ return a.kind === "principal" ? b.kind === "principal" && a.principal === b.principal : b.kind === "local-owner";
5
+ }
6
+ export function readRuleOwner(raw) {
7
+ if (!isPlainRecord(raw))
8
+ return undefined;
9
+ const kind = raw.kind;
10
+ const word = RULE_OWNER_KINDS.find((k) => k === kind);
11
+ if (word === undefined)
12
+ return undefined;
13
+ switch (word) {
14
+ case "local-owner":
15
+ return { kind: "local-owner" };
16
+ case "principal": {
17
+ const principal = raw.principal;
18
+ return typeof principal === "string" && principal.trim() !== "" ? { kind: "principal", principal } : undefined;
19
+ }
20
+ default: {
21
+ const unhandled = word;
22
+ return unhandled;
23
+ }
24
+ }
25
+ }
26
+ export function ruleOwnerText(owner) {
27
+ return owner.kind === "principal" ? `principal "${owner.principal}"` : "the local owner";
28
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The advisor tool's instructions to the model — the reference's text, verbatim — its two short forms (a re-attach after a
3
+ * withdrawal, and the withdrawal), the one transition that says which a leg owes, and the leg's seat for them. The frame is
4
+ * the `advisor_tool` attachment kind: it rides a fresh leg's first request, and a compaction inside a leg that mounts the
5
+ * tool restates the full text right after it lands. Model lane only: no `steering_injected` echo.
6
+ */
7
+ import type { AnnouncedAdvisorState, AnnouncedListingSnapshotInput } from "../../internal/harness.js";
8
+ import type { PostureFrameRef } from "../auto-mode-directive.js";
9
+ import type { StoredSession } from "../session.js";
10
+ import type { FrameReceiptLedger } from "./contracts.js";
11
+ export declare const ADVISOR_TOOL_INSTRUCTIONS = "# Advisor Tool\n\nYou have access to an `advisor` tool backed by a stronger reviewer model. It takes NO parameters -- when you call advisor(), your entire conversation history is automatically forwarded. They see the task, every tool call you've made, every result you've seen.\n\nCall advisor BEFORE substantive work -- before writing, before committing to an interpretation, before building on an assumption. If the task requires orientation first (finding files, fetching a source, seeing what's there), do that, then call advisor. Orientation is not substantive work. Writing, editing, and declaring an answer are.\n\nAlso call advisor:\n- When you believe the task is complete. BEFORE this call, make your deliverable durable: write the file, save the result, commit the change. The advisor call takes time; if the session ends during it, a durable result persists and an unwritten one doesn't.\n- When stuck -- errors recurring, approach not converging, results that don't fit.\n- When considering a change of approach.\n\nOn tasks longer than a few steps, call advisor at least once before committing to an approach and once before declaring done. On short reactive tasks where the next action is dictated by tool output you just read, you don't need to keep calling -- the advisor adds most of its value on the first call, before the approach crystallizes.\n\nGive the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim (the file says X, the paper states Y), adapt. A passing self-test is not evidence the advice is wrong -- it's evidence your test doesn't check what the advice is checking.\n\nIf you've already retrieved data pointing one way and the advisor points another: don't silently switch. Surface the conflict in one more advisor call -- \"I found X, you suggest Y, which constraint breaks the tie?\" The advisor saw your evidence but may have underweighted it; a reconcile call is cheaper than committing to the wrong branch.";
12
+ export declare const ADVISOR_TOOL_ABBREVIATED = "The advisor tool is available; the advisor instructions announced earlier apply.";
13
+ export declare const ADVISOR_TOOL_REMOVED = "The advisor tool is no longer available; disregard the earlier advisor instructions.";
14
+ /** What the model has been told about the advisor in the conversation's current segment (since the latest compaction): the session record's own word. */
15
+ export type AdvisorInstructionState = AnnouncedAdvisorState["state"];
16
+ /**
17
+ * The advisor instructions a leg owes, from what the model was told and whether the tool is mounted now: nothing told and
18
+ * mounted ⇒ the full text; told and not mounted ⇒ the withdrawal; withdrawn and mounted again ⇒ the short re-attach; every
19
+ * other pair owes nothing. `state` is what the model has been told once the frame is delivered.
20
+ */
21
+ export declare function advisorInstructionFrame(told: AdvisorInstructionState | undefined, mounted: boolean): {
22
+ body: string;
23
+ state: AdvisorInstructionState;
24
+ } | undefined;
25
+ /** A leg's advisor-instructions seat: the frame its first request owes, the segment that was judged in, whether the tool is mounted. */
26
+ export interface AdvisorInstructionSeat {
27
+ owed?: {
28
+ readonly body: string;
29
+ readonly state: AdvisorInstructionState;
30
+ };
31
+ readonly segment: string | null;
32
+ readonly mounted: boolean;
33
+ }
34
+ /** The owed frame as one engine-marked reminder — what a fresh leg's first message and a resumed leg's continuation both
35
+ * carry — or `undefined` when nothing is owed. */
36
+ export declare function advisorFrameText(prepared: {
37
+ readonly advisorInstruction?: AdvisorInstructionSeat;
38
+ readonly reminderMark: string;
39
+ }): string | undefined;
40
+ /** Register the owed frame's receipt on the message that carries it (`text`, the exact first text block): its commit
41
+ * records what the model was told only once that message is in the transcript. Nothing owed ⇒ nothing registered. */
42
+ export declare function registerAdvisorReceipt(prepared: {
43
+ readonly advisorInstruction?: AdvisorInstructionSeat;
44
+ readonly announcedListingsRef: AnnouncedListingSnapshotInput;
45
+ readonly frameReceipts: FrameReceiptLedger;
46
+ }, text: string): void;
47
+ /** The owed frame was delivered (its carrying message is in the transcript): what the model was told is recorded for the
48
+ * segment it was told in, and the snapshot write is parked like every listing commit's. */
49
+ export declare function settleAdvisorInstruction(prepared: {
50
+ readonly advisorInstruction?: AdvisorInstructionSeat;
51
+ readonly announcedListingsRef: AnnouncedListingSnapshotInput;
52
+ readonly frameReceipts: {
53
+ listingSnapshotOwed: boolean;
54
+ };
55
+ }): void;
56
+ /**
57
+ * A compaction landed on a leg that mounts the advisor: the full instructions it summarized away are appended to the
58
+ * transcript as one engine-minted message, before any reader of the new baseline — the posture's compaction rule, halt
59
+ * included (no engine message enters the transcript ahead of a person's next words). The record is left as it was: it names
60
+ * the segment before this compaction, so the next leg tells the model again (a duplicate, never a gap). Never throws.
61
+ */
62
+ export declare function appendAdvisorRestate(prepared: {
63
+ readonly advisorInstruction?: AdvisorInstructionSeat;
64
+ readonly reminderMark: string;
65
+ readonly session: Pick<StoredSession, "appendMessage">;
66
+ readonly batchHaltRef: {
67
+ readonly current?: unknown;
68
+ };
69
+ readonly postureFrameRef: Pick<PostureFrameRef, "report">;
70
+ }): Promise<void>;
@@ -0,0 +1,61 @@
1
+ import { mintSystemReminder } from "../reminder-mint.js";
2
+ import { thrownText } from "../thrown-value.js";
3
+ export const ADVISOR_TOOL_INSTRUCTIONS = `# Advisor Tool
4
+
5
+ You have access to an \`advisor\` tool backed by a stronger reviewer model. It takes NO parameters -- when you call advisor(), your entire conversation history is automatically forwarded. They see the task, every tool call you've made, every result you've seen.
6
+
7
+ Call advisor BEFORE substantive work -- before writing, before committing to an interpretation, before building on an assumption. If the task requires orientation first (finding files, fetching a source, seeing what's there), do that, then call advisor. Orientation is not substantive work. Writing, editing, and declaring an answer are.
8
+
9
+ Also call advisor:
10
+ - When you believe the task is complete. BEFORE this call, make your deliverable durable: write the file, save the result, commit the change. The advisor call takes time; if the session ends during it, a durable result persists and an unwritten one doesn't.
11
+ - When stuck -- errors recurring, approach not converging, results that don't fit.
12
+ - When considering a change of approach.
13
+
14
+ On tasks longer than a few steps, call advisor at least once before committing to an approach and once before declaring done. On short reactive tasks where the next action is dictated by tool output you just read, you don't need to keep calling -- the advisor adds most of its value on the first call, before the approach crystallizes.
15
+
16
+ Give the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim (the file says X, the paper states Y), adapt. A passing self-test is not evidence the advice is wrong -- it's evidence your test doesn't check what the advice is checking.
17
+
18
+ If you've already retrieved data pointing one way and the advisor points another: don't silently switch. Surface the conflict in one more advisor call -- "I found X, you suggest Y, which constraint breaks the tie?" The advisor saw your evidence but may have underweighted it; a reconcile call is cheaper than committing to the wrong branch.`;
19
+ export const ADVISOR_TOOL_ABBREVIATED = "The advisor tool is available; the advisor instructions announced earlier apply.";
20
+ export const ADVISOR_TOOL_REMOVED = "The advisor tool is no longer available; disregard the earlier advisor instructions.";
21
+ export function advisorInstructionFrame(told, mounted) {
22
+ if (mounted && told === undefined)
23
+ return { body: ADVISOR_TOOL_INSTRUCTIONS, state: "announced" };
24
+ if (mounted && told === "withdrawn")
25
+ return { body: ADVISOR_TOOL_ABBREVIATED, state: "announced" };
26
+ if (!mounted && told === "announced")
27
+ return { body: ADVISOR_TOOL_REMOVED, state: "withdrawn" };
28
+ return undefined;
29
+ }
30
+ export function advisorFrameText(prepared) {
31
+ const owed = prepared.advisorInstruction?.owed;
32
+ return owed === undefined ? undefined : mintSystemReminder(owed.body, prepared.reminderMark);
33
+ }
34
+ export function registerAdvisorReceipt(prepared, text) {
35
+ if (prepared.advisorInstruction?.owed !== undefined)
36
+ prepared.frameReceipts.pending.push({ source: "advisor_tool", text, commit: () => settleAdvisorInstruction(prepared) });
37
+ }
38
+ export function settleAdvisorInstruction(prepared) {
39
+ const seat = prepared.advisorInstruction;
40
+ const owed = seat?.owed;
41
+ if (seat === undefined || owed === undefined)
42
+ return;
43
+ seat.owed = undefined;
44
+ prepared.announcedListingsRef.advisor = { state: owed.state, segment: seat.segment };
45
+ prepared.frameReceipts.listingSnapshotOwed = true;
46
+ }
47
+ export async function appendAdvisorRestate(prepared) {
48
+ if (prepared.advisorInstruction?.mounted !== true || prepared.batchHaltRef.current !== undefined)
49
+ return;
50
+ const text = mintSystemReminder(ADVISOR_TOOL_INSTRUCTIONS, prepared.reminderMark);
51
+ try {
52
+ await prepared.session.appendMessage({ role: "user", content: [{ type: "text", text }], timestamp: Date.now(), engineMinted: true });
53
+ }
54
+ catch (err) {
55
+ try {
56
+ prepared.postureFrameRef.report?.(new Error(`the advisor instructions could not be restated after compaction (the next leg states them): ${thrownText(err)}`));
57
+ }
58
+ catch {
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,33 @@
1
+ import type { AgentTool, SessionTreeEntry } from "../../internal/harness-types.js";
2
+ import type { Model } from "../../internal/llm.js";
3
+ import { type AdvisorFailure, type AdvisorOutcome } from "../advisor-verdict.js";
4
+ import type { CompactionForkContext } from "../auto-compaction.js";
5
+ import { type SideQueryResult } from "../side-query.js";
6
+ import type { Brain, TaskSpec } from "../types.js";
7
+ /** The advisor's own system prompt (the agent's system prompt follows it, marked as context). */
8
+ export declare const ADVISOR_SYSTEM_PROMPT = "You are the advisor: a stronger reviewer model consulted by an agent in the middle of its task. Above is the agent's conversation as it stood in the agent's last request \u2014 its task, every tool call it made and every result it saw \u2014 ending at the point where it asked for advice.\n\nReply in plain text only. Do not call tools: any tool call you make is discarded and counts as no answer. Be concrete and short: name the decision the agent is facing, say what you would do and why, point at the specific evidence in the conversation that supports it, and flag anything the agent has assumed without checking. If the agent asked before declaring the task done, review the deliverable against the task as stated and list what is missing or wrong. If something you need is not in the conversation, say what is missing and what the agent should check first \u2014 that is still guidance.";
9
+ /** The closing result the projection ends on: the asking call is answered, so both wire protocols take the list. */
10
+ export declare const ADVISOR_HANDOFF = "You are the advisor now. Review everything above and reply with your guidance.";
11
+ /** Everything one leg's advisor needs: the advisor model, the lane's accounted brain, and the leg's own readers. */
12
+ export interface AdvisorSeat {
13
+ readonly model: Model;
14
+ readonly brain: Brain;
15
+ /** The request the main lane last sent on this leg (the engine-level context, before provider serialization). */
16
+ readonly lastSentRequest: () => CompactionForkContext | undefined;
17
+ readonly readBranch: () => Promise<ReadonlyArray<SessionTreeEntry>>;
18
+ readonly getApiKeyAndHeaders: TaskSpec["getApiKeyAndHeaders"];
19
+ /** Marks the run's totals a lower bound: a thrown request spent an amount nobody learned. */
20
+ readonly markUsageUnknown: () => void;
21
+ }
22
+ /** The `tool_end.structured` card of one advisor call. */
23
+ export interface AdvisorCard extends AdvisorFailure {
24
+ readonly type: "advisor";
25
+ readonly outcome: AdvisorOutcome;
26
+ readonly model: string;
27
+ readonly servedModel?: string;
28
+ readonly stopReason?: string;
29
+ readonly hold?: true;
30
+ readonly usage?: SideQueryResult["usage"];
31
+ }
32
+ /** The leg's `advisor` tool over its seat; its label is the advisor model's id (it rides `tool_start` / `tool_end`). */
33
+ export declare function createAdvisorTool(seat: AdvisorSeat): AgentTool;