@archmax-ai/harness 0.0.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 (351) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +219 -0
  3. package/dist/agent.d.ts +174 -0
  4. package/dist/agent.js +140 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/assembly/compose.d.ts +170 -0
  7. package/dist/assembly/compose.js +391 -0
  8. package/dist/assembly/compose.js.map +1 -0
  9. package/dist/assembly/delegation-registry.d.ts +5 -0
  10. package/dist/assembly/delegation-registry.js +118 -0
  11. package/dist/assembly/delegation-registry.js.map +1 -0
  12. package/dist/assembly/index.d.ts +192 -0
  13. package/dist/assembly/index.js +265 -0
  14. package/dist/assembly/index.js.map +1 -0
  15. package/dist/assembly/plain.d.ts +7 -0
  16. package/dist/assembly/plain.js +41 -0
  17. package/dist/assembly/plain.js.map +1 -0
  18. package/dist/authoring-skill/archmax-harness/README.md +76 -0
  19. package/dist/authoring-skill/archmax-harness/SKILL.md +241 -0
  20. package/dist/authoring-skill/archmax-harness/references/backend-integration.md +626 -0
  21. package/dist/authoring-skill/archmax-harness/references/cases.md +41 -0
  22. package/dist/authoring-skill/archmax-harness/references/diagnostics.md +51 -0
  23. package/dist/authoring-skill/archmax-harness/references/hook-and-test-scripts.md +1070 -0
  24. package/dist/authoring-skill/archmax-harness/references/hooks-and-scripts.md +82 -0
  25. package/dist/authoring-skill/archmax-harness/references/wiring.md +101 -0
  26. package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +1631 -0
  27. package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +241 -0
  28. package/dist/behaviour/support.d.ts +232 -0
  29. package/dist/behaviour/support.js +339 -0
  30. package/dist/behaviour/support.js.map +1 -0
  31. package/dist/cli/banner.d.ts +11 -0
  32. package/dist/cli/banner.js +29 -0
  33. package/dist/cli/banner.js.map +1 -0
  34. package/dist/cli/bootstrap.d.ts +33 -0
  35. package/dist/cli/bootstrap.js +153 -0
  36. package/dist/cli/bootstrap.js.map +1 -0
  37. package/dist/cli/command.d.ts +39 -0
  38. package/dist/cli/command.js +97 -0
  39. package/dist/cli/command.js.map +1 -0
  40. package/dist/cli/state-flow.d.ts +46 -0
  41. package/dist/cli/state-flow.js +268 -0
  42. package/dist/cli/state-flow.js.map +1 -0
  43. package/dist/cli/style.d.ts +41 -0
  44. package/dist/cli/style.js +64 -0
  45. package/dist/cli/style.js.map +1 -0
  46. package/dist/cli/turn.d.ts +41 -0
  47. package/dist/cli/turn.js +161 -0
  48. package/dist/cli/turn.js.map +1 -0
  49. package/dist/cli.d.ts +10 -0
  50. package/dist/cli.js +426 -0
  51. package/dist/cli.js.map +1 -0
  52. package/dist/core/code-description.d.ts +22 -0
  53. package/dist/core/code-description.js +38 -0
  54. package/dist/core/code-description.js.map +1 -0
  55. package/dist/core/deepagents.d.ts +183 -0
  56. package/dist/core/deepagents.js +128 -0
  57. package/dist/core/deepagents.js.map +1 -0
  58. package/dist/core/events.d.ts +350 -0
  59. package/dist/core/events.js +205 -0
  60. package/dist/core/events.js.map +1 -0
  61. package/dist/core/frontmatter.d.ts +15 -0
  62. package/dist/core/frontmatter.js +32 -0
  63. package/dist/core/frontmatter.js.map +1 -0
  64. package/dist/core/listing-redact.d.ts +37 -0
  65. package/dist/core/listing-redact.js +88 -0
  66. package/dist/core/listing-redact.js.map +1 -0
  67. package/dist/core/match.d.ts +26 -0
  68. package/dist/core/match.js +75 -0
  69. package/dist/core/match.js.map +1 -0
  70. package/dist/core/message-readers.d.ts +84 -0
  71. package/dist/core/message-readers.js +159 -0
  72. package/dist/core/message-readers.js.map +1 -0
  73. package/dist/core/messages.d.ts +49 -0
  74. package/dist/core/messages.js +85 -0
  75. package/dist/core/messages.js.map +1 -0
  76. package/dist/core/mount-prompt.d.ts +28 -0
  77. package/dist/core/mount-prompt.js +55 -0
  78. package/dist/core/mount-prompt.js.map +1 -0
  79. package/dist/core/mount-redact.d.ts +28 -0
  80. package/dist/core/mount-redact.js +32 -0
  81. package/dist/core/mount-redact.js.map +1 -0
  82. package/dist/core/mounts.d.ts +88 -0
  83. package/dist/core/mounts.js +147 -0
  84. package/dist/core/mounts.js.map +1 -0
  85. package/dist/core/path-mapping.d.ts +52 -0
  86. package/dist/core/path-mapping.js +113 -0
  87. package/dist/core/path-mapping.js.map +1 -0
  88. package/dist/core/platform-prompt.generated.d.ts +2 -0
  89. package/dist/core/platform-prompt.generated.js +4 -0
  90. package/dist/core/platform-prompt.generated.js.map +1 -0
  91. package/dist/core/prompt.d.ts +42 -0
  92. package/dist/core/prompt.js +75 -0
  93. package/dist/core/prompt.js.map +1 -0
  94. package/dist/core/session-id.d.ts +38 -0
  95. package/dist/core/session-id.js +61 -0
  96. package/dist/core/session-id.js.map +1 -0
  97. package/dist/core/session-store.d.ts +85 -0
  98. package/dist/core/session-store.js +149 -0
  99. package/dist/core/session-store.js.map +1 -0
  100. package/dist/core/session-zone.d.ts +54 -0
  101. package/dist/core/session-zone.js +82 -0
  102. package/dist/core/session-zone.js.map +1 -0
  103. package/dist/core/skill-prompt.d.ts +31 -0
  104. package/dist/core/skill-prompt.js +54 -0
  105. package/dist/core/skill-prompt.js.map +1 -0
  106. package/dist/core/skill-redact.d.ts +15 -0
  107. package/dist/core/skill-redact.js +27 -0
  108. package/dist/core/skill-redact.js.map +1 -0
  109. package/dist/core/skills.d.ts +172 -0
  110. package/dist/core/skills.js +214 -0
  111. package/dist/core/skills.js.map +1 -0
  112. package/dist/core/tool-mocks.d.ts +23 -0
  113. package/dist/core/tool-mocks.js +39 -0
  114. package/dist/core/tool-mocks.js.map +1 -0
  115. package/dist/core/tool-telemetry.d.ts +16 -0
  116. package/dist/core/tool-telemetry.js +40 -0
  117. package/dist/core/tool-telemetry.js.map +1 -0
  118. package/dist/core/usage.d.ts +114 -0
  119. package/dist/core/usage.js +226 -0
  120. package/dist/core/usage.js.map +1 -0
  121. package/dist/core/workspace-context.d.ts +136 -0
  122. package/dist/core/workspace-context.js +178 -0
  123. package/dist/core/workspace-context.js.map +1 -0
  124. package/dist/core/workspace-prompt.d.ts +7 -0
  125. package/dist/core/workspace-prompt.js +102 -0
  126. package/dist/core/workspace-prompt.js.map +1 -0
  127. package/dist/core/workspace-router.d.ts +61 -0
  128. package/dist/core/workspace-router.js +145 -0
  129. package/dist/core/workspace-router.js.map +1 -0
  130. package/dist/core/workspace.d.ts +85 -0
  131. package/dist/core/workspace.js +193 -0
  132. package/dist/core/workspace.js.map +1 -0
  133. package/dist/core/zones.d.ts +181 -0
  134. package/dist/core/zones.js +202 -0
  135. package/dist/core/zones.js.map +1 -0
  136. package/dist/env.d.ts +99 -0
  137. package/dist/env.js +271 -0
  138. package/dist/env.js.map +1 -0
  139. package/dist/index.d.ts +265 -0
  140. package/dist/index.js +197 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/kernel/kernel.d.ts +192 -0
  143. package/dist/kernel/kernel.js +751 -0
  144. package/dist/kernel/kernel.js.map +1 -0
  145. package/dist/lifecycle/hook-shape.d.ts +44 -0
  146. package/dist/lifecycle/hook-shape.js +66 -0
  147. package/dist/lifecycle/hook-shape.js.map +1 -0
  148. package/dist/lifecycle/runner.d.ts +177 -0
  149. package/dist/lifecycle/runner.js +372 -0
  150. package/dist/lifecycle/runner.js.map +1 -0
  151. package/dist/lifecycle/transcript.d.ts +27 -0
  152. package/dist/lifecycle/transcript.js +43 -0
  153. package/dist/lifecycle/transcript.js.map +1 -0
  154. package/dist/machine/allow.d.ts +65 -0
  155. package/dist/machine/allow.js +107 -0
  156. package/dist/machine/allow.js.map +1 -0
  157. package/dist/machine/delegation.d.ts +9 -0
  158. package/dist/machine/delegation.js +10 -0
  159. package/dist/machine/delegation.js.map +1 -0
  160. package/dist/machine/diagnostic.d.ts +14 -0
  161. package/dist/machine/diagnostic.js +2 -0
  162. package/dist/machine/diagnostic.js.map +1 -0
  163. package/dist/machine/lint-spec.d.ts +4 -0
  164. package/dist/machine/lint-spec.js +266 -0
  165. package/dist/machine/lint-spec.js.map +1 -0
  166. package/dist/machine/load-spec.d.ts +90 -0
  167. package/dist/machine/load-spec.js +120 -0
  168. package/dist/machine/load-spec.js.map +1 -0
  169. package/dist/machine/machine.d.ts +273 -0
  170. package/dist/machine/machine.js +551 -0
  171. package/dist/machine/machine.js.map +1 -0
  172. package/dist/machine/mount-grants.d.ts +25 -0
  173. package/dist/machine/mount-grants.js +24 -0
  174. package/dist/machine/mount-grants.js.map +1 -0
  175. package/dist/machine/slug.d.ts +14 -0
  176. package/dist/machine/slug.js +17 -0
  177. package/dist/machine/slug.js.map +1 -0
  178. package/dist/machine/spec-schema.d.ts +662 -0
  179. package/dist/machine/spec-schema.js +717 -0
  180. package/dist/machine/spec-schema.js.map +1 -0
  181. package/dist/machine/tool-names.d.ts +98 -0
  182. package/dist/machine/tool-names.js +144 -0
  183. package/dist/machine/tool-names.js.map +1 -0
  184. package/dist/machine/triggers.d.ts +114 -0
  185. package/dist/machine/triggers.js +165 -0
  186. package/dist/machine/triggers.js.map +1 -0
  187. package/dist/machine/types.d.ts +186 -0
  188. package/dist/machine/types.js +12 -0
  189. package/dist/machine/types.js.map +1 -0
  190. package/dist/machine/validate-spec.d.ts +42 -0
  191. package/dist/machine/validate-spec.js +29 -0
  192. package/dist/machine/validate-spec.js.map +1 -0
  193. package/dist/machine/variables.d.ts +196 -0
  194. package/dist/machine/variables.js +415 -0
  195. package/dist/machine/variables.js.map +1 -0
  196. package/dist/public/cli.d.ts +15 -0
  197. package/dist/public/cli.js +14 -0
  198. package/dist/public/cli.js.map +1 -0
  199. package/dist/public/messages.d.ts +33 -0
  200. package/dist/public/messages.js +33 -0
  201. package/dist/public/messages.js.map +1 -0
  202. package/dist/public/sandbox.d.ts +99 -0
  203. package/dist/public/sandbox.js +32 -0
  204. package/dist/public/sandbox.js.map +1 -0
  205. package/dist/public/spec.d.ts +147 -0
  206. package/dist/public/spec.js +149 -0
  207. package/dist/public/spec.js.map +1 -0
  208. package/dist/public/testing.d.ts +71 -0
  209. package/dist/public/testing.js +39 -0
  210. package/dist/public/testing.js.map +1 -0
  211. package/dist/rubrics/rubrics.d.ts +135 -0
  212. package/dist/rubrics/rubrics.js +145 -0
  213. package/dist/rubrics/rubrics.js.map +1 -0
  214. package/dist/runtime/contract.d.ts +73 -0
  215. package/dist/runtime/contract.js +96 -0
  216. package/dist/runtime/contract.js.map +1 -0
  217. package/dist/sandbox/assets/parts/core.js +22 -0
  218. package/dist/sandbox/assets/parts/lifecycle-hook.js +47 -0
  219. package/dist/sandbox/bridge.d.ts +16 -0
  220. package/dist/sandbox/bridge.js +95 -0
  221. package/dist/sandbox/bridge.js.map +1 -0
  222. package/dist/sandbox/executor.d.ts +46 -0
  223. package/dist/sandbox/executor.js +119 -0
  224. package/dist/sandbox/executor.js.map +1 -0
  225. package/dist/sandbox/imports.d.ts +33 -0
  226. package/dist/sandbox/imports.js +67 -0
  227. package/dist/sandbox/imports.js.map +1 -0
  228. package/dist/sandbox/prelude.d.ts +12 -0
  229. package/dist/sandbox/prelude.js +51 -0
  230. package/dist/sandbox/prelude.js.map +1 -0
  231. package/dist/sandbox/ptc-gateway.d.ts +104 -0
  232. package/dist/sandbox/ptc-gateway.js +167 -0
  233. package/dist/sandbox/ptc-gateway.js.map +1 -0
  234. package/dist/sandbox/runtime.d.ts +59 -0
  235. package/dist/sandbox/runtime.js +51 -0
  236. package/dist/sandbox/runtime.js.map +1 -0
  237. package/dist/sandbox/tools.d.ts +34 -0
  238. package/dist/sandbox/tools.js +147 -0
  239. package/dist/sandbox/tools.js.map +1 -0
  240. package/dist/sessions/operations.d.ts +79 -0
  241. package/dist/sessions/operations.js +121 -0
  242. package/dist/sessions/operations.js.map +1 -0
  243. package/dist/sessions/resolve.d.ts +97 -0
  244. package/dist/sessions/resolve.js +145 -0
  245. package/dist/sessions/resolve.js.map +1 -0
  246. package/dist/sessions/resume.d.ts +242 -0
  247. package/dist/sessions/resume.js +288 -0
  248. package/dist/sessions/resume.js.map +1 -0
  249. package/dist/sessions/scope.d.ts +99 -0
  250. package/dist/sessions/scope.js +145 -0
  251. package/dist/sessions/scope.js.map +1 -0
  252. package/dist/sessions/summary.d.ts +65 -0
  253. package/dist/sessions/summary.js +56 -0
  254. package/dist/sessions/summary.js.map +1 -0
  255. package/dist/testing/assertions.d.ts +30 -0
  256. package/dist/testing/assertions.js +231 -0
  257. package/dist/testing/assertions.js.map +1 -0
  258. package/dist/testing/case-document.d.ts +141 -0
  259. package/dist/testing/case-document.js +51 -0
  260. package/dist/testing/case-document.js.map +1 -0
  261. package/dist/testing/case-schema.d.ts +29 -0
  262. package/dist/testing/case-schema.js +519 -0
  263. package/dist/testing/case-schema.js.map +1 -0
  264. package/dist/testing/discovery.d.ts +10 -0
  265. package/dist/testing/discovery.js +24 -0
  266. package/dist/testing/discovery.js.map +1 -0
  267. package/dist/testing/driver.d.ts +78 -0
  268. package/dist/testing/driver.js +117 -0
  269. package/dist/testing/driver.js.map +1 -0
  270. package/dist/testing/grade.d.ts +116 -0
  271. package/dist/testing/grade.js +261 -0
  272. package/dist/testing/grade.js.map +1 -0
  273. package/dist/testing/interpreter.d.ts +55 -0
  274. package/dist/testing/interpreter.js +103 -0
  275. package/dist/testing/interpreter.js.map +1 -0
  276. package/dist/testing/mock-middleware.d.ts +5 -0
  277. package/dist/testing/mock-middleware.js +33 -0
  278. package/dist/testing/mock-middleware.js.map +1 -0
  279. package/dist/testing/runner.d.ts +205 -0
  280. package/dist/testing/runner.js +266 -0
  281. package/dist/testing/runner.js.map +1 -0
  282. package/dist/testing/target.d.ts +27 -0
  283. package/dist/testing/target.js +21 -0
  284. package/dist/testing/target.js.map +1 -0
  285. package/dist/validate/validate.d.ts +41 -0
  286. package/dist/validate/validate.js +669 -0
  287. package/dist/validate/validate.js.map +1 -0
  288. package/dist/workflow/agent-tools.d.ts +10 -0
  289. package/dist/workflow/agent-tools.js +10 -0
  290. package/dist/workflow/agent-tools.js.map +1 -0
  291. package/dist/workflow/checkpointer.d.ts +52 -0
  292. package/dist/workflow/checkpointer.js +200 -0
  293. package/dist/workflow/checkpointer.js.map +1 -0
  294. package/dist/workflow/control-tools.d.ts +174 -0
  295. package/dist/workflow/control-tools.js +468 -0
  296. package/dist/workflow/control-tools.js.map +1 -0
  297. package/dist/workflow/governance.d.ts +104 -0
  298. package/dist/workflow/governance.js +546 -0
  299. package/dist/workflow/governance.js.map +1 -0
  300. package/dist/workflow/middleware.d.ts +85 -0
  301. package/dist/workflow/middleware.js +283 -0
  302. package/dist/workflow/middleware.js.map +1 -0
  303. package/dist/workflow/on-error.d.ts +25 -0
  304. package/dist/workflow/on-error.js +58 -0
  305. package/dist/workflow/on-error.js.map +1 -0
  306. package/dist/workflow/parks.d.ts +46 -0
  307. package/dist/workflow/parks.js +513 -0
  308. package/dist/workflow/parks.js.map +1 -0
  309. package/dist/workflow/paths.d.ts +67 -0
  310. package/dist/workflow/paths.js +108 -0
  311. package/dist/workflow/paths.js.map +1 -0
  312. package/dist/workflow/prompt-cache.d.ts +70 -0
  313. package/dist/workflow/prompt-cache.js +103 -0
  314. package/dist/workflow/prompt-cache.js.map +1 -0
  315. package/dist/workflow/prompt-pruning.d.ts +20 -0
  316. package/dist/workflow/prompt-pruning.js +83 -0
  317. package/dist/workflow/prompt-pruning.js.map +1 -0
  318. package/dist/workflow/render-prompt.d.ts +45 -0
  319. package/dist/workflow/render-prompt.js +140 -0
  320. package/dist/workflow/render-prompt.js.map +1 -0
  321. package/dist/workflow/runtime-config.d.ts +7 -0
  322. package/dist/workflow/runtime-config.js +9 -0
  323. package/dist/workflow/runtime-config.js.map +1 -0
  324. package/dist/workflow/session-artifacts.d.ts +90 -0
  325. package/dist/workflow/session-artifacts.js +134 -0
  326. package/dist/workflow/session-artifacts.js.map +1 -0
  327. package/dist/workflow/session-view.d.ts +31 -0
  328. package/dist/workflow/session-view.js +94 -0
  329. package/dist/workflow/session-view.js.map +1 -0
  330. package/dist/workflow/snapshot.d.ts +14 -0
  331. package/dist/workflow/snapshot.js +97 -0
  332. package/dist/workflow/snapshot.js.map +1 -0
  333. package/dist/workflow/state.d.ts +347 -0
  334. package/dist/workflow/state.js +322 -0
  335. package/dist/workflow/state.js.map +1 -0
  336. package/dist/workflow/sub-workflow.d.ts +174 -0
  337. package/dist/workflow/sub-workflow.js +392 -0
  338. package/dist/workflow/sub-workflow.js.map +1 -0
  339. package/dist/workflow/tool-service.d.ts +48 -0
  340. package/dist/workflow/tool-service.js +291 -0
  341. package/dist/workflow/tool-service.js.map +1 -0
  342. package/dist/workflow/turn-boundary.d.ts +39 -0
  343. package/dist/workflow/turn-boundary.js +128 -0
  344. package/dist/workflow/turn-boundary.js.map +1 -0
  345. package/dist/workflow/turn-runner.d.ts +40 -0
  346. package/dist/workflow/turn-runner.js +122 -0
  347. package/dist/workflow/turn-runner.js.map +1 -0
  348. package/dist/workflow/workflow-tools.d.ts +46 -0
  349. package/dist/workflow/workflow-tools.js +90 -0
  350. package/dist/workflow/workflow-tools.js.map +1 -0
  351. package/package.json +119 -0
@@ -0,0 +1,372 @@
1
+ import { runContextFromMessages } from "../core/messages.js";
2
+ import { createSubagentBridgeDispatch } from "../sandbox/bridge.js";
3
+ import { PROCESS_SESSION, } from "../sandbox/executor.js";
4
+ import { resolvePtcTools } from "../sandbox/tools.js";
5
+ import { afterHookLabel, hookKind, hookMaxIterations, iterationKey } from "./hook-shape.js";
6
+ import { hookTranscript } from "./transcript.js";
7
+ import { buildRubricTaskDescription, isRubricVerdict, resolveRubricResponseFormat, rubricId, } from "../rubrics/rubrics.js";
8
+ import { createWorkflowEventEmitter, } from "../core/events.js";
9
+ import { decide, reduceHookFact } from "../kernel/kernel.js";
10
+ /**
11
+ * Interpret a lifecycle hook's return value into a decision, an error, or
12
+ * `null` (no opinion — proceed).
13
+ *
14
+ * **One contract for every hook kind**, the one `HookResult` declares: a verdict
15
+ * object decides, a bare `false` vetoes, returning nothing is `ok`, and any
16
+ * *other* object fails closed with its keys named. A hook's return value is its
17
+ * verdict and nothing else, so an object that is not one is a verdict its author
18
+ * got wrong; reading it as `ok` would silently permit what the hook meant to
19
+ * block, with nothing said.
20
+ *
21
+ * A **script** hook's value arrives already reduced — the sandbox wrapper
22
+ * applies the same rules and throws on the last one — so what reaches here from
23
+ * a script is a verdict or an error outcome. The rules are restated because a
24
+ * custom `hookExecutors` kind hands its value through raw, and a consumer's
25
+ * executor is held to the same contract as a script: one governance vocabulary,
26
+ * whoever implements the kind.
27
+ */
28
+ export function parseLifecycleDecision(outcome) {
29
+ if (!outcome.ok)
30
+ return { error: outcome.error?.message ?? "script error" };
31
+ const value = outcome.value;
32
+ if (isRubricVerdict(value)) {
33
+ return {
34
+ verdict: value.verdict,
35
+ reason: value.reason,
36
+ ...(value.rubric !== undefined ? { rubric: value.rubric } : {}),
37
+ };
38
+ }
39
+ if (value === false)
40
+ return { verdict: "veto", reason: "precondition not met" };
41
+ if (value !== null && typeof value === "object") {
42
+ return {
43
+ error: `hook returned ${describeNonVerdict(value)}, which is not a verdict — return ` +
44
+ `{ verdict: "ok" | "correct" | "veto", reason }, false, or nothing at all`,
45
+ };
46
+ }
47
+ return null;
48
+ }
49
+ /**
50
+ * Name a non-verdict object by its keys, never its values, so a diagnostic
51
+ * cannot leak what the hook was inspecting. Mirrors `__hookShape` in the
52
+ * sandbox prelude, which does the same for a script hook.
53
+ */
54
+ function describeNonVerdict(value) {
55
+ if (Array.isArray(value))
56
+ return "an array";
57
+ const keys = Object.keys(value);
58
+ if (keys.length === 0)
59
+ return "an object with no keys";
60
+ const shown = keys
61
+ .slice(0, 6)
62
+ .map((key) => `'${key}'`)
63
+ .join(", ");
64
+ return `an object with ${keys.length > 6 ? "keys including " : "keys "}${shown}`;
65
+ }
66
+ /** The built-in hook kinds, which consumer executors may not shadow. */
67
+ export const BUILTIN_HOOK_KINDS = ["script", "rubric"];
68
+ /** Short raw-output excerpt surfaced when a judge response cannot be parsed. */
69
+ function snippet(value) {
70
+ let text;
71
+ try {
72
+ text = typeof value === "string" ? value : JSON.stringify(value);
73
+ }
74
+ catch {
75
+ text = String(value);
76
+ }
77
+ if (text === undefined || text === "undefined")
78
+ text = "(no output)";
79
+ return text.length > 200 ? `${text.slice(0, 200)}…` : text;
80
+ }
81
+ /**
82
+ * Runs deterministic `before`/`after` hooks (scripts or grading rubrics) at the
83
+ * machine's fixed points, in the same backend-backed interpreter as the model's
84
+ * own sandbox tool calls.
85
+ */
86
+ export class LifecycleRunner {
87
+ machine;
88
+ executor;
89
+ rubrics;
90
+ ptcNames;
91
+ emit;
92
+ /** Hook kind → executor. Built-ins (`script`, `rubric`) plus registered custom kinds. */
93
+ hookExecutors;
94
+ /**
95
+ * Maps a hook's declared `script:` value to the path its source is read from.
96
+ * Injected so the runner stays ignorant of workspace layout: the harness binds
97
+ * it to the running workflow (workflow-relative, confined to `hooks/`). The
98
+ * identity default keeps a bare runner working.
99
+ */
100
+ resolveScript;
101
+ /** Deprecations already reported — each is said once per assembly. */
102
+ constructor(machine, executor, rubrics, ptcNames, hookExecutors, onEvent, opts = {}) {
103
+ this.machine = machine;
104
+ this.executor = executor;
105
+ this.rubrics = rubrics;
106
+ this.ptcNames = ptcNames;
107
+ this.emit = createWorkflowEventEmitter(onEvent);
108
+ this.resolveScript = opts.resolveScript ?? ((declared) => ({ ok: true, path: declared }));
109
+ // Built-ins first; consumer executors add kinds alongside them (built-ins
110
+ // are non-shadowable, enforced at assembly).
111
+ this.hookExecutors = new Map([
112
+ ["script", (hook, ctx, args) => this.runScript(String(hook.script), ctx, args)],
113
+ ]);
114
+ for (const [kind, exec] of Object.entries(hookExecutors ?? {})) {
115
+ this.hookExecutors.set(kind, exec);
116
+ }
117
+ }
118
+ resolvePtcTools(allTools) {
119
+ return resolvePtcTools(allTools, this.ptcNames);
120
+ }
121
+ /**
122
+ * The runtime's own dispatch for an inline grader, through the framework
123
+ * `task` tool. Reached only by {@link runRubric} — never wired into a script's
124
+ * sandbox, which has no name to dispatch by.
125
+ */
126
+ rubricDispatch(ctx, lifecycleArgs) {
127
+ if (!ctx.taskTool)
128
+ return undefined;
129
+ const base = createSubagentBridgeDispatch(ctx.taskTool, ctx.config, {
130
+ emit: this.emit,
131
+ ...(typeof lifecycleArgs.state === "string" ? { state: lifecycleArgs.state } : {}),
132
+ });
133
+ return async (input) => {
134
+ const rubric = this.rubrics.get(input.subagentType);
135
+ const description = input.description?.trim() ||
136
+ buildRubricTaskDescription({ ...lifecycleArgs, ...runContextFromMessages(ctx.messages) });
137
+ const responseSchema = input.responseSchema ?? (rubric ? resolveRubricResponseFormat(rubric) : undefined);
138
+ return base({
139
+ description,
140
+ subagentType: input.subagentType,
141
+ ...(responseSchema !== undefined
142
+ ? { responseSchema: responseSchema }
143
+ : {}),
144
+ });
145
+ };
146
+ }
147
+ async runScript(script, ctx, args) {
148
+ // A hook that cannot be placed is a hook that cannot be trusted: refusing
149
+ // here produces an error outcome, and an errored hook vetoes fail-closed —
150
+ // the same posture as a hook that throws.
151
+ const resolved = this.resolveScript(script);
152
+ if (!resolved.ok) {
153
+ return {
154
+ ok: false,
155
+ value: undefined,
156
+ logs: [],
157
+ error: { message: resolved.reason },
158
+ formatted: `error: ${resolved.reason}`,
159
+ };
160
+ }
161
+ return this.executor.runFile(resolved.path, {
162
+ sessionId: ctx.sessionId,
163
+ sessionNamespace: PROCESS_SESSION,
164
+ args,
165
+ tools: ctx.tools,
166
+ // No `task()` for a script hook: an inline rubric has no name a script
167
+ // could pass, so there is nothing to dispatch by. A script that wants a
168
+ // model verdict gets a `rubric` hook declared beside it in the same list.
169
+ lifecycle: true,
170
+ });
171
+ }
172
+ async runRubric(name, ctx, args) {
173
+ const dispatch = this.rubricDispatch(ctx, args);
174
+ if (!dispatch) {
175
+ const message = `rubric '${name}' could not be dispatched (no task tool)`;
176
+ return { ok: false, value: undefined, logs: [], error: { message }, formatted: `error: ${message}` };
177
+ }
178
+ const rubric = this.rubrics.get(name);
179
+ const responseSchema = rubric ? resolveRubricResponseFormat(rubric) : undefined;
180
+ try {
181
+ const value = await dispatch({
182
+ subagentType: name,
183
+ // The grader's payload keeps the compact `userRequest`/`history` view a
184
+ // rubric's `instructions` are written against.
185
+ description: buildRubricTaskDescription({ ...args, ...runContextFromMessages(ctx.messages) }),
186
+ ...(responseSchema !== undefined ? { responseSchema } : {}),
187
+ });
188
+ // Fail closed on unreadable grader output, exactly like a thrown error: a
189
+ // grader whose verdict cannot be read has approved nothing.
190
+ const verdict = value && typeof value === "object" && isRubricVerdict(value)
191
+ ? { ...value, rubric: name }
192
+ : {
193
+ verdict: "veto",
194
+ reason: `rubric '${name}' returned no parseable verdict: ${snippet(value)}`,
195
+ rubric: name,
196
+ };
197
+ return { ok: true, value: verdict, logs: [], formatted: JSON.stringify(verdict) };
198
+ }
199
+ catch (err) {
200
+ const message = err.message ?? String(err);
201
+ return { ok: false, value: undefined, logs: [], error: { message }, formatted: `error: ${message}` };
202
+ }
203
+ }
204
+ /**
205
+ * Dispatch a single tagged hook through its kind's registered executor.
206
+ * An unknown kind (no registered executor) produces an error outcome that
207
+ * reduces to a fail-closed veto — the same path as any hook execution error.
208
+ */
209
+ async runHook(hook, ctx, args, at) {
210
+ const kind = hookKind(hook);
211
+ // `rubric` is serviced here rather than through the executor map, because
212
+ // dispatching an inline grader needs the hook's *position* — that is the id
213
+ // the runtime registered it under, and a `HookExecutor` sees only the hook.
214
+ // The kind is still non-shadowable: assembly checks `BUILTIN_HOOK_KINDS`.
215
+ if (kind === "rubric") {
216
+ return this.runRubric(rubricId(at.state, at.phase, at.index), ctx, args);
217
+ }
218
+ const executor = kind ? this.hookExecutors.get(kind) : undefined;
219
+ if (!executor) {
220
+ const message = kind
221
+ ? `no executor registered for hook kind '${kind}'`
222
+ : `malformed hook (expected a single-key tagged object)`;
223
+ return { ok: false, value: undefined, logs: [], error: { message }, formatted: `error: ${message}` };
224
+ }
225
+ return executor(hook, ctx, args);
226
+ }
227
+ applyDecision(state, label, decision, ctx, opts) {
228
+ this.emit({
229
+ type: "hook-verdict",
230
+ state,
231
+ phase: opts.phase,
232
+ label,
233
+ verdict: decision.verdict,
234
+ reason: decision.reason,
235
+ });
236
+ const budget = iterationKey(state, opts.phase, opts.index);
237
+ const used = ctx.iterations[budget] ?? 0;
238
+ // Iteration budget, uniform across hook kinds: the hook-level
239
+ // `max_iterations` sidecar wins (it describes *this* state's retry loop); a
240
+ // rubric hook falls back to the rubric's own `max_iterations`; otherwise 0
241
+ // (a `correct` hard-vetoes).
242
+ const rubric = decision.rubric ? this.rubrics.get(decision.rubric) : undefined;
243
+ const maxIterations = opts.maxIterations ?? rubric?.max_iterations ?? 0;
244
+ // The reduction rule lives in the decision kernel; the runner only executes
245
+ // hooks and applies the verdict (correction bookkeeping + events).
246
+ const verdict = reduceHookFact({ ...decision, maxIterations, iterationsUsed: used }, { phase: opts.phase, veto: opts.veto, to: opts.to });
247
+ if (verdict.decision === "block") {
248
+ if (verdict.correctionConsumed)
249
+ ctx.iterations[budget] = used + 1;
250
+ const reason = verdict.reason ?? decision.reason;
251
+ this.emit({ type: "hook-rejected", state, phase: opts.phase, reason });
252
+ // Exhausted iteration budget (after-phase correction flow only) cannot be
253
+ // fixed by retrying in place; a deliberate veto, an in-budget correction,
254
+ // or a before-phase rejection can. The kernel decides which this is, from
255
+ // the same reduction that wrote the reason.
256
+ return { reason, terminal: verdict.budgetExhausted === true };
257
+ }
258
+ // Only this hook's own budget is released: a passing hook ahead of a
259
+ // correcting one must not hand the latter a fresh budget every attempt.
260
+ delete ctx.iterations[budget];
261
+ return null;
262
+ }
263
+ async runPhase(state, phase, ctx, extraArgs, veto = false) {
264
+ const hooks = this.machine.lifecycleHooks()[state];
265
+ const list = phase === "before" ? hooks?.before : hooks?.after;
266
+ if (!list || list.length === 0)
267
+ return null;
268
+ // The hook input (`HookArgs` in the sandbox): the trigger reaches a hook as
269
+ // its bare id — a run's *input* lives in `variables` — and the transcript as
270
+ // plain messages.
271
+ const scriptArgs = {
272
+ state,
273
+ phase,
274
+ ...(ctx.trigger ? { trigger: ctx.trigger.id } : {}),
275
+ variables: ctx.variables ?? {},
276
+ messages: hookTranscript(ctx.messages),
277
+ ...extraArgs,
278
+ };
279
+ const to = typeof extraArgs?.to === "string" ? extraArgs.to : undefined;
280
+ // Run hooks in declaration order, short-circuiting on the first that fails.
281
+ // The index travels: an inline rubric has no name, so its position in this
282
+ // list is its identity — for dispatch and for its own retry budget.
283
+ for (const [index, hook] of list.entries()) {
284
+ const reject = await this.runSingleHook(state, phase, hook, ctx, scriptArgs, { veto, to, index });
285
+ if (reject)
286
+ return reject;
287
+ }
288
+ return null;
289
+ }
290
+ async runSingleHook(state, phase, hook, ctx, scriptArgs, opts) {
291
+ const label = afterHookLabel(hook, opts.index);
292
+ this.emit({ type: "hook-start", state, phase, label });
293
+ const outcome = await this.runHook(hook, ctx, scriptArgs, {
294
+ state,
295
+ phase,
296
+ index: opts.index,
297
+ });
298
+ for (const line of outcome.logs) {
299
+ if (line.trim()) {
300
+ this.emit({ type: "hook-output", state, line: line.trimEnd() });
301
+ }
302
+ }
303
+ const parsed = parseLifecycleDecision(outcome);
304
+ if (parsed && "error" in parsed) {
305
+ this.emit({ type: "hook-rejected", state, phase, reason: parsed.error });
306
+ // A hook that could not execute is a terminal failure: retrying the
307
+ // same turn re-runs the same broken hook.
308
+ return { reason: parsed.error, terminal: true };
309
+ }
310
+ if (!parsed) {
311
+ if (phase === "before") {
312
+ this.emit({ type: "hook-passed", state, phase });
313
+ }
314
+ return null;
315
+ }
316
+ const maxIterations = hookMaxIterations(hook);
317
+ return this.applyDecision(state, label, parsed, ctx, {
318
+ phase,
319
+ veto: opts.veto,
320
+ to: opts.to,
321
+ index: opts.index,
322
+ ...(maxIterations !== undefined ? { maxIterations } : {}),
323
+ });
324
+ }
325
+ async attemptTransition(from, to, ctx, reason,
326
+ /**
327
+ * The tool call driving this attempt, when one is. Carried onto the `advance`
328
+ * event so a consumer can attribute the transition to the call that made it;
329
+ * a transition the runtime itself performs passes nothing.
330
+ */
331
+ options) {
332
+ // Work on a copy of the correction counts so the attempt never mutates the
333
+ // caller's context; the resulting counts are returned for the caller to
334
+ // commit to the checkpoint.
335
+ const corrections = { ...ctx.iterations };
336
+ const localCtx = { ...ctx, iterations: corrections };
337
+ // Edge validity is a pure, statically-decidable rule — route it through the
338
+ // decision kernel so runtime and `agent validate` agree. Hook reduction runs
339
+ // per-hook inside `runPhase` (also kernel-backed via `applyDecision`).
340
+ const edgeVerdict = decide(this.machine, { kind: "transition", from, to, hookFacts: [] }, [], undefined, ctx.variableStore ?? {});
341
+ if (edgeVerdict.decision === "block") {
342
+ return {
343
+ ok: false,
344
+ reason: edgeVerdict.reason ?? `cannot advance from '${from}' to '${to}'.`,
345
+ // An invalid edge is always recoverable: the agent picks a valid target.
346
+ terminal: false,
347
+ corrections,
348
+ };
349
+ }
350
+ const trimmedReason = reason?.trim();
351
+ const afterReject = await this.runPhase(from, "after", localCtx, { from, to, ...(trimmedReason ? { reason: trimmedReason } : {}) }, true);
352
+ if (afterReject) {
353
+ return { ok: false, reason: afterReject.reason, terminal: afterReject.terminal, corrections };
354
+ }
355
+ const beforeReject = await this.runPhase(to, "before", localCtx);
356
+ if (beforeReject) {
357
+ return { ok: false, reason: beforeReject.reason, terminal: beforeReject.terminal, corrections };
358
+ }
359
+ this.emit({
360
+ type: "advance",
361
+ from,
362
+ to,
363
+ ...(trimmedReason ? { reason: trimmedReason } : {}),
364
+ ...(options?.callId ? { callId: options.callId } : {}),
365
+ });
366
+ return { ok: true, from, to, corrections };
367
+ }
368
+ dispose(sessionId) {
369
+ this.executor.dispose(sessionId, PROCESS_SESSION);
370
+ }
371
+ }
372
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/lifecycle/runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EACL,eAAe,GAGhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,2BAA2B,EAC3B,QAAQ,GAET,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,0BAA0B,GAG3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAW7D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAsB;IAEtB,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,IAAI,cAAc,EAAE,CAAC;IAE5E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAChF,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO;YACL,KAAK,EACH,iBAAiB,kBAAkB,CAAC,KAAK,CAAC,oCAAoC;gBAC9E,0EAA0E;SAC7E,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACvD,MAAM,KAAK,GAAG,IAAI;SACf,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,kBAAkB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,EAAE,CAAC;AACnF,CAAC;AAmFD,wEAAwE;AACxE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAEhE,gFAAgF;AAChF,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,WAAW;QAAE,IAAI,GAAG,aAAa,CAAC;IACrE,OAAO,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAeP;IACA;IACA;IACA;IAjBF,IAAI,CAAuB;IAC5C,yFAAyF;IACxE,aAAa,CAA4B;IAE1D;;;;;OAKG;IACc,aAAa,CAAqB;IACnD,sEAAsE;IAEtE,YACmB,OAAwB,EACxB,QAAwB,EACxB,OAA4B,EAC5B,QAAkB,EACnC,aAA4C,EAC5C,OAA8B,EAC9B,OAA+C,EAAE;QANhC,YAAO,GAAP,OAAO,CAAiB;QACxB,aAAQ,GAAR,QAAQ,CAAgB;QACxB,YAAO,GAAP,OAAO,CAAqB;QAC5B,aAAQ,GAAR,QAAQ,CAAU;QAKnC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC1F,0EAA0E;QAC1E,6CAA6C;QAC7C,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,CAAuB;YACjD,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAE,IAA+B,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;SAC5G,CAAC,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,eAAe,CAAC,QAAmB;QACjC,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACK,cAAc,CAAC,GAAqB,EAAE,aAAsC;QAClF,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QACpC,MAAM,IAAI,GAAG,4BAA4B,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;YAClE,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,CAAC,OAAO,aAAa,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnF,CAAC,CAAC;QACH,OAAO,KAAK,EAAE,KAA+E,EAAE,EAAE;YAC/F,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACpD,MAAM,WAAW,GACf,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE;gBACzB,0BAA0B,CAAC,EAAE,GAAG,aAAa,EAAE,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC5F,MAAM,cAAc,GAClB,KAAK,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACrF,OAAO,IAAI,CAAC;gBACV,WAAW;gBACX,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,GAAG,CAAC,cAAc,KAAK,SAAS;oBAC9B,CAAC,CAAC,EAAE,cAAc,EAAE,cAAyC,EAAE;oBAC/D,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,MAAc,EACd,GAAqB,EACrB,IAA6B;QAE7B,0EAA0E;QAC1E,2EAA2E;QAC3E,0CAA0C;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,EAAE;gBACR,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE;gBACnC,SAAS,EAAE,UAAU,QAAQ,CAAC,MAAM,EAAE;aACvC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC1C,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,gBAAgB,EAAE,eAAe;YACjC,IAAI;YACJ,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,IAAY,EACZ,GAAqB,EACrB,IAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,WAAW,IAAI,0CAA0C,CAAC;YAC1E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QACvG,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChF,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC;gBAC3B,YAAY,EAAE,IAAI;gBAClB,wEAAwE;gBACxE,+CAA+C;gBAC/C,WAAW,EAAE,0BAA0B,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7F,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5D,CAAC,CAAC;YACH,0EAA0E;YAC1E,4DAA4D;YAC5D,MAAM,OAAO,GACX,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,eAAe,CAAC,KAAK,CAAC;gBAC1D,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;gBAC5B,CAAC,CAAC;oBACE,OAAO,EAAE,MAAe;oBACxB,MAAM,EAAE,WAAW,IAAI,oCAAoC,OAAO,CAAC,KAAK,CAAC,EAAE;oBAC3E,MAAM,EAAE,IAAI;iBACb,CAAC;YACR,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACpF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAI,GAAa,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;YACtD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QACvG,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,OAAO,CACnB,IAAU,EACV,GAAqB,EACrB,IAA6B,EAC7B,EAA+D;QAE/D,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,0EAA0E;QAC1E,4EAA4E;QAC5E,4EAA4E;QAC5E,0EAA0E;QAC1E,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,IAAI;gBAClB,CAAC,CAAC,yCAAyC,IAAI,GAAG;gBAClD,CAAC,CAAC,sDAAsD,CAAC;YAC3D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QACvG,CAAC;QACD,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAEO,aAAa,CACnB,KAAa,EACb,KAAa,EACb,QAA2B,EAC3B,GAAqB,EACrB,IAAsG;QAEtG,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,cAAc;YACpB,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK;YACL,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzC,8DAA8D;QAC9D,4EAA4E;QAC5E,2EAA2E;QAC3E,6BAA6B;QAC7B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/E,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,MAAM,EAAE,cAAc,IAAI,CAAC,CAAC;QACxE,4EAA4E;QAC5E,mEAAmE;QACnE,MAAM,OAAO,GAAG,cAAc,CAC5B,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,EACpD,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CACpD,CAAC;QACF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,IAAI,OAAO,CAAC,kBAAkB;gBAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YAClE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACvE,0EAA0E;YAC1E,0EAA0E;YAC1E,0EAA0E;YAC1E,4CAA4C;YAC5C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;QAChE,CAAC;QACD,qEAAqE;QACrE,wEAAwE;QACxE,OAAO,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,KAAa,EACb,KAAyB,EACzB,GAAqB,EACrB,SAAmC,EACnC,IAAI,GAAG,KAAK;QAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC;QAC/D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE5C,4EAA4E;QAC5E,6EAA6E;QAC7E,kBAAkB;QAClB,MAAM,UAAU,GAAG;YACjB,KAAK;YACL,KAAK;YACL,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;YAC9B,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;YACtC,GAAG,SAAS;SACb,CAAC;QACF,MAAM,EAAE,GAAG,OAAO,SAAS,EAAE,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAExE,4EAA4E;QAC5E,2EAA2E;QAC3E,oEAAoE;QACpE,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAClG,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,KAAa,EACb,KAAyB,EACzB,IAAU,EACV,GAAqB,EACrB,UAAmC,EACnC,IAAmD;QAEnD,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAEvD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE;YACxD,KAAK;YACL,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,MAAM,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACzE,oEAAoE;YACpE,0CAA0C;YAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE;YACnD,KAAK;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1D,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,IAAY,EACZ,EAAU,EACV,GAAqB,EACrB,MAAe;IACf;;;;OAIG;IACH,OAA6B;QAE7B,2EAA2E;QAC3E,wEAAwE;QACxE,4BAA4B;QAC5B,MAAM,WAAW,GAAG,EAAE,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAqB,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;QAEvE,4EAA4E;QAC5E,6EAA6E;QAC7E,uEAAuE;QACvE,MAAM,WAAW,GAAG,MAAM,CACxB,IAAI,CAAC,OAAO,EACZ,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAC/C,EAAE,EACF,SAAS,EACT,GAAG,CAAC,aAAa,IAAI,EAAE,CACxB,CAAC;QACF,IAAI,WAAW,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACrC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,wBAAwB,IAAI,SAAS,EAAE,IAAI;gBACzE,yEAAyE;gBACzE,QAAQ,EAAE,KAAK;gBACf,WAAW;aACZ,CAAC;QACJ,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,CACrC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EACjE,IAAI,CACL,CAAC;QACF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;QAChG,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjE,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;QAClG,CAAC;QAED,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,SAAS;YACf,IAAI;YACJ,EAAE;YACF,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD,CAAC,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * One transcript message as a hook reads it: plain data, no LangChain classes.
3
+ * `role` is `user`, `assistant`, `tool`, `system`, or `runtime` — the last for
4
+ * a note the runtime wrote (an arrival, a decision, an error route), which a
5
+ * model cannot read as a person speaking and a hook should not either.
6
+ */
7
+ export interface HookMessage {
8
+ role: string;
9
+ text: string;
10
+ /** Assistant messages only: the tool calls the message made. */
11
+ toolCalls?: {
12
+ name: string;
13
+ args: unknown;
14
+ }[];
15
+ /** Tool results only: the tool that produced the text. */
16
+ tool?: string;
17
+ /** Runtime notes only: which kind of note this is. */
18
+ note?: string;
19
+ }
20
+ /** How much of the transcript a hook is handed: the most recent messages. */
21
+ export declare const HOOK_TRANSCRIPT_LIMIT = 24;
22
+ /**
23
+ * The recent transcript as a hook receives it in `messages`, newest last. A
24
+ * runtime note is carried in the transcript as a tool-call pair; only the half
25
+ * holding the text is kept, as one `runtime` entry.
26
+ */
27
+ export declare function hookTranscript(messages: unknown[], limit?: number): HookMessage[];
@@ -0,0 +1,43 @@
1
+ import { contentToString, messageTypeOf, runtimeNoteKind } from "../core/messages.js";
2
+ const ROLE_BY_TYPE = {
3
+ human: "user",
4
+ ai: "assistant",
5
+ system: "system",
6
+ tool: "tool",
7
+ function: "tool",
8
+ };
9
+ /** How much of the transcript a hook is handed: the most recent messages. */
10
+ export const HOOK_TRANSCRIPT_LIMIT = 24;
11
+ /**
12
+ * The recent transcript as a hook receives it in `messages`, newest last. A
13
+ * runtime note is carried in the transcript as a tool-call pair; only the half
14
+ * holding the text is kept, as one `runtime` entry.
15
+ */
16
+ export function hookTranscript(messages, limit = HOOK_TRANSCRIPT_LIMIT) {
17
+ const out = [];
18
+ for (const raw of Array.isArray(messages) ? messages : []) {
19
+ const msg = raw;
20
+ const type = messageTypeOf(raw);
21
+ const text = contentToString(msg.content);
22
+ const note = runtimeNoteKind(raw);
23
+ if (note !== null) {
24
+ if (text.trim() === "")
25
+ continue;
26
+ out.push({ role: "runtime", text, note });
27
+ continue;
28
+ }
29
+ const entry = { role: ROLE_BY_TYPE[type] ?? (type || "unknown"), text };
30
+ const calls = msg.tool_calls;
31
+ if ((type === "ai" || type === "assistant") && Array.isArray(calls) && calls.length > 0) {
32
+ entry.toolCalls = calls.map((c) => {
33
+ const call = c;
34
+ return { name: String(call.name ?? ""), args: call.args ?? {} };
35
+ });
36
+ }
37
+ if (entry.role === "tool" && typeof msg.name === "string")
38
+ entry.tool = msg.name;
39
+ out.push(entry);
40
+ }
41
+ return out.slice(-limit);
42
+ }
43
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/lifecycle/transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAmBtF,MAAM,YAAY,GAA2B;IAC3C,KAAK,EAAE,MAAM;IACb,EAAE,EAAE,WAAW;IACf,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;CACjB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAmB,EAAE,KAAK,GAAG,qBAAqB;IAC/E,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAG,GAA8B,CAAC;QAC3C,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,SAAS;YACjC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAgB,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;QACrF,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,WAAW,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxF,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAChC,MAAM,IAAI,GAAG,CAA4B,CAAC;gBAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YAClE,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACjF,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,65 @@
1
+ import type { AllowEntry, MachineSpec } from "./types.js";
2
+ import { type VariableReference, type VariableStore } from "./variables.js";
3
+ /** Conventional path argument for file tools and `archmax_run`. */
4
+ export declare const DEFAULT_PATH_ARG = "file_path";
5
+ export interface NormalizedAllowEntry {
6
+ tool: string | undefined;
7
+ /** Per-argument glob matchers, or null to allow the tool with any arguments. */
8
+ argMatchers: Record<string, string[]> | null;
9
+ }
10
+ /**
11
+ * Whether a value matches any of the given globs. The value is canonicalized
12
+ * (`.`/`..`/`//` resolved) so a `./` or `.//` prefix cannot dodge a
13
+ * `forbid_paths` glob — the matcher sees the same path the backend resolves.
14
+ * Globs are leading-slash-normalized only, preserving their wildcards.
15
+ *
16
+ * `dot: true`: a workspace path is not a shell glob, and a governance glob that
17
+ * skipped dot-prefixed segments would read the same either way — `secrets/**`
18
+ * would miss `secrets/.env` on the deny side while `scratchpad/**` would refuse
19
+ * `scratchpad/.cache` on the allow side.
20
+ */
21
+ export declare function valueMatches(value: unknown, globs: string[]): boolean;
22
+ /**
23
+ * Normalize an `allow` entry into a tool name plus optional argument matchers.
24
+ * One shared derivation for the kernel, disclosure, and `validate`, so they
25
+ * cannot disagree about what an entry covers.
26
+ */
27
+ export declare function normalizeAllowEntry(entry: AllowEntry): NormalizedAllowEntry;
28
+ /**
29
+ * An unresolvable `${{…}}` reference in a guard. Not a mismatch: the harness
30
+ * could not evaluate the governance the author declared, so the caller turns
31
+ * this into a terminal run failure rather than a retryable block.
32
+ */
33
+ export interface GuardResolutionFailure {
34
+ reference: string;
35
+ detail: string;
36
+ }
37
+ /**
38
+ * Whether a tool call's arguments satisfy a normalized allow entry's matchers.
39
+ *
40
+ * `${{…}}` references are resolved against the run's variables per call, never
41
+ * cached: a `set_variables` later in the same turn must take effect on the very
42
+ * next call. An unresolvable reference makes the entry match nothing and reports
43
+ * why through `onUnresolved` — never the literal `${{…}}` text or a permissive
44
+ * pattern. A dotted argument key (`args.file_path`) is read with the same
45
+ * own-property traversal `${{…}}` paths use, never the prototype chain.
46
+ */
47
+ export declare function argsSatisfy(argMatchers: Record<string, string[]> | null, args: Record<string, unknown>, variables?: VariableStore, onUnresolved?: (failure: GuardResolutionFailure) => void): boolean;
48
+ /**
49
+ * One `${{…}}` reference found in a tool-argument guard, with enough context to
50
+ * name it in a diagnostic: which state (null for an `allow_always` entry, which
51
+ * binds in every state), which tool, and which argument.
52
+ */
53
+ export interface GuardVariableReference {
54
+ state: string | null;
55
+ tool: string | undefined;
56
+ arg: string;
57
+ glob: string;
58
+ reference: VariableReference;
59
+ }
60
+ /**
61
+ * Every `${{…}}` reference in the spec's tool-argument guards, with where it was
62
+ * found. Used at assembly to warn about a reference nothing guarantees, and by
63
+ * the spec lint for the same check minus the host's seeds.
64
+ */
65
+ export declare function guardReferences(spec: MachineSpec): GuardVariableReference[];
@@ -0,0 +1,107 @@
1
+ import picomatch from "picomatch";
2
+ import { canonicalizeRelPath, normalizeRelPath } from "../core/workspace.js";
3
+ import { hasVariableReference, parseReferences, resolveGlob, resolvePath, } from "./variables.js";
4
+ /** Conventional path argument for file tools and `archmax_run`. */
5
+ export const DEFAULT_PATH_ARG = "file_path";
6
+ /**
7
+ * Whether a value matches any of the given globs. The value is canonicalized
8
+ * (`.`/`..`/`//` resolved) so a `./` or `.//` prefix cannot dodge a
9
+ * `forbid_paths` glob — the matcher sees the same path the backend resolves.
10
+ * Globs are leading-slash-normalized only, preserving their wildcards.
11
+ *
12
+ * `dot: true`: a workspace path is not a shell glob, and a governance glob that
13
+ * skipped dot-prefixed segments would read the same either way — `secrets/**`
14
+ * would miss `secrets/.env` on the deny side while `scratchpad/**` would refuse
15
+ * `scratchpad/.cache` on the allow side.
16
+ */
17
+ export function valueMatches(value, globs) {
18
+ if (value == null || globs.length === 0)
19
+ return false;
20
+ return picomatch.isMatch(canonicalizeRelPath(String(value)).path, globs.map(normalizeRelPath), {
21
+ dot: true,
22
+ });
23
+ }
24
+ /**
25
+ * Normalize an `allow` entry into a tool name plus optional argument matchers.
26
+ * One shared derivation for the kernel, disclosure, and `validate`, so they
27
+ * cannot disagree about what an entry covers.
28
+ */
29
+ export function normalizeAllowEntry(entry) {
30
+ if (typeof entry === "string")
31
+ return { tool: entry, argMatchers: null };
32
+ if (!entry || typeof entry !== "object")
33
+ return { tool: undefined, argMatchers: null };
34
+ const tool = entry.tool;
35
+ if (entry.args && typeof entry.args === "object") {
36
+ const argMatchers = {};
37
+ for (const [name, globs] of Object.entries(entry.args)) {
38
+ argMatchers[name] = Array.isArray(globs) ? globs : [globs];
39
+ }
40
+ return { tool, argMatchers };
41
+ }
42
+ if (entry.paths !== undefined) {
43
+ const globs = Array.isArray(entry.paths) ? entry.paths : [entry.paths];
44
+ return { tool, argMatchers: { [DEFAULT_PATH_ARG]: globs } };
45
+ }
46
+ return { tool, argMatchers: null };
47
+ }
48
+ /**
49
+ * Whether a tool call's arguments satisfy a normalized allow entry's matchers.
50
+ *
51
+ * `${{…}}` references are resolved against the run's variables per call, never
52
+ * cached: a `set_variables` later in the same turn must take effect on the very
53
+ * next call. An unresolvable reference makes the entry match nothing and reports
54
+ * why through `onUnresolved` — never the literal `${{…}}` text or a permissive
55
+ * pattern. A dotted argument key (`args.file_path`) is read with the same
56
+ * own-property traversal `${{…}}` paths use, never the prototype chain.
57
+ */
58
+ export function argsSatisfy(argMatchers, args, variables, onUnresolved) {
59
+ if (!argMatchers)
60
+ return true;
61
+ return Object.entries(argMatchers).every(([name, globs]) => {
62
+ const resolved = [];
63
+ for (const glob of globs) {
64
+ if (!hasVariableReference(glob)) {
65
+ resolved.push(glob);
66
+ continue;
67
+ }
68
+ const result = resolveGlob(glob, variables ?? {});
69
+ if (!result.ok) {
70
+ onUnresolved?.({ reference: result.reference, detail: result.detail });
71
+ return false;
72
+ }
73
+ resolved.push(result.pattern);
74
+ }
75
+ return valueMatches(resolvePath(args, name.split(".")), resolved);
76
+ });
77
+ }
78
+ /**
79
+ * Every `${{…}}` reference in the spec's tool-argument guards, with where it was
80
+ * found. Used at assembly to warn about a reference nothing guarantees, and by
81
+ * the spec lint for the same check minus the host's seeds.
82
+ */
83
+ export function guardReferences(spec) {
84
+ const found = [];
85
+ const collect = (entries, state) => {
86
+ for (const entry of entries ?? []) {
87
+ const { tool, argMatchers } = normalizeAllowEntry(entry);
88
+ if (!argMatchers)
89
+ continue;
90
+ for (const [arg, globs] of Object.entries(argMatchers)) {
91
+ for (const glob of globs) {
92
+ for (const ref of parseReferences(glob)) {
93
+ found.push({ state, tool, arg, glob, reference: ref });
94
+ }
95
+ }
96
+ }
97
+ }
98
+ };
99
+ collect(spec.tools?.allow_always, null);
100
+ collect(spec.tools?.forbid_always, null);
101
+ for (const [slug, state] of Object.entries(spec.states)) {
102
+ collect(state.tools?.allow, slug);
103
+ collect(state.tools?.forbid, slug);
104
+ }
105
+ return found;
106
+ }
107
+ //# sourceMappingURL=allow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allow.js","sourceRoot":"","sources":["../../src/machine/allow.ts"],"names":[],"mappings":"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"}