@relayflows/sdk 2.0.30 → 2.0.32

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 (347) hide show
  1. package/dist/agent-artifacts.d.ts.map +1 -1
  2. package/dist/agent-artifacts.js +2 -9
  3. package/dist/agent-artifacts.js.map +1 -1
  4. package/dist/agent-cwd.d.ts +69 -0
  5. package/dist/agent-cwd.d.ts.map +1 -0
  6. package/dist/agent-cwd.js +140 -0
  7. package/dist/agent-cwd.js.map +1 -0
  8. package/dist/artifact-scan-policy.d.ts +35 -0
  9. package/dist/artifact-scan-policy.d.ts.map +1 -0
  10. package/dist/artifact-scan-policy.js +49 -0
  11. package/dist/artifact-scan-policy.js.map +1 -0
  12. package/dist/authored-completion-record.d.ts +35 -0
  13. package/dist/authored-completion-record.d.ts.map +1 -0
  14. package/dist/authored-completion-record.js +92 -0
  15. package/dist/authored-completion-record.js.map +1 -0
  16. package/dist/authored-completion.d.ts +99 -0
  17. package/dist/authored-completion.d.ts.map +1 -0
  18. package/dist/authored-completion.js +184 -0
  19. package/dist/authored-completion.js.map +1 -0
  20. package/dist/authored-flow-error.d.ts +13 -1
  21. package/dist/authored-flow-error.d.ts.map +1 -1
  22. package/dist/authored-flow-error.js +12 -0
  23. package/dist/authored-flow-error.js.map +1 -1
  24. package/dist/authored-flow-executor.d.ts +7 -30
  25. package/dist/authored-flow-executor.d.ts.map +1 -1
  26. package/dist/authored-flow-executor.js +54 -47
  27. package/dist/authored-flow-executor.js.map +1 -1
  28. package/dist/authored-human.d.ts.map +1 -1
  29. package/dist/authored-human.js +1 -3
  30. package/dist/authored-human.js.map +1 -1
  31. package/dist/authored-node-entry.js +4 -1
  32. package/dist/authored-node-entry.js.map +1 -1
  33. package/dist/authored-node-runner.d.ts +9 -1
  34. package/dist/authored-node-runner.d.ts.map +1 -1
  35. package/dist/authored-node-runner.js +92 -17
  36. package/dist/authored-node-runner.js.map +1 -1
  37. package/dist/authored-preflight.d.ts +4 -0
  38. package/dist/authored-preflight.d.ts.map +1 -0
  39. package/dist/authored-preflight.js +50 -0
  40. package/dist/authored-preflight.js.map +1 -0
  41. package/dist/authored-root.d.ts +5 -0
  42. package/dist/authored-root.d.ts.map +1 -1
  43. package/dist/authored-root.js +20 -2
  44. package/dist/authored-root.js.map +1 -1
  45. package/dist/authored-step-output.d.ts +35 -10
  46. package/dist/authored-step-output.d.ts.map +1 -1
  47. package/dist/authored-step-output.js +108 -40
  48. package/dist/authored-step-output.js.map +1 -1
  49. package/dist/authored-verdict.d.ts +28 -0
  50. package/dist/authored-verdict.d.ts.map +1 -0
  51. package/dist/authored-verdict.js +79 -0
  52. package/dist/authored-verdict.js.map +1 -0
  53. package/dist/authored-worker-step.d.ts +5 -2
  54. package/dist/authored-worker-step.d.ts.map +1 -1
  55. package/dist/authored-worker-step.js +51 -13
  56. package/dist/authored-worker-step.js.map +1 -1
  57. package/dist/cli/check-worker-surface.d.ts +27 -0
  58. package/dist/cli/check-worker-surface.d.ts.map +1 -0
  59. package/dist/cli/check-worker-surface.js +63 -0
  60. package/dist/cli/check-worker-surface.js.map +1 -0
  61. package/dist/cli/check.d.ts +28 -3
  62. package/dist/cli/check.d.ts.map +1 -1
  63. package/dist/cli/check.js +27 -140
  64. package/dist/cli/check.js.map +1 -1
  65. package/dist/cli/cli-probe.d.ts +20 -0
  66. package/dist/cli/cli-probe.d.ts.map +1 -0
  67. package/dist/cli/cli-probe.js +166 -0
  68. package/dist/cli/cli-probe.js.map +1 -0
  69. package/dist/cli/cloud-format.d.ts +9 -0
  70. package/dist/cli/cloud-format.d.ts.map +1 -0
  71. package/dist/cli/cloud-format.js +77 -0
  72. package/dist/cli/cloud-format.js.map +1 -0
  73. package/dist/cli/cloud-live.d.ts +39 -0
  74. package/dist/cli/cloud-live.d.ts.map +1 -0
  75. package/dist/cli/cloud-live.js +325 -0
  76. package/dist/cli/cloud-live.js.map +1 -0
  77. package/dist/cli/cloud-mirror-session.d.ts +97 -0
  78. package/dist/cli/cloud-mirror-session.d.ts.map +1 -0
  79. package/dist/cli/cloud-mirror-session.js +264 -0
  80. package/dist/cli/cloud-mirror-session.js.map +1 -0
  81. package/dist/cli/cloud-read.d.ts +3 -7
  82. package/dist/cli/cloud-read.d.ts.map +1 -1
  83. package/dist/cli/cloud-read.js +14 -266
  84. package/dist/cli/cloud-read.js.map +1 -1
  85. package/dist/cli/cloud-refusal.d.ts +39 -0
  86. package/dist/cli/cloud-refusal.d.ts.map +1 -0
  87. package/dist/cli/cloud-refusal.js +95 -0
  88. package/dist/cli/cloud-refusal.js.map +1 -0
  89. package/dist/cli/cloud-status-view.d.ts +7 -0
  90. package/dist/cli/cloud-status-view.d.ts.map +1 -0
  91. package/dist/cli/cloud-status-view.js +214 -0
  92. package/dist/cli/cloud-status-view.js.map +1 -0
  93. package/dist/cli/direct-run.d.ts.map +1 -1
  94. package/dist/cli/direct-run.js +16 -2
  95. package/dist/cli/direct-run.js.map +1 -1
  96. package/dist/cli/hn-monitor.d.ts +0 -13
  97. package/dist/cli/hn-monitor.d.ts.map +1 -1
  98. package/dist/cli/hn-monitor.js +2 -1
  99. package/dist/cli/hn-monitor.js.map +1 -1
  100. package/dist/cli/local-agent-remedy.d.ts +80 -0
  101. package/dist/cli/local-agent-remedy.d.ts.map +1 -0
  102. package/dist/cli/local-agent-remedy.js +116 -0
  103. package/dist/cli/local-agent-remedy.js.map +1 -0
  104. package/dist/cli/observer-session.d.ts +41 -0
  105. package/dist/cli/observer-session.d.ts.map +1 -0
  106. package/dist/cli/observer-session.js +78 -0
  107. package/dist/cli/observer-session.js.map +1 -0
  108. package/dist/cli/run.d.ts +30 -2
  109. package/dist/cli/run.d.ts.map +1 -1
  110. package/dist/cli/run.js +186 -24
  111. package/dist/cli/run.js.map +1 -1
  112. package/dist/cli/status.d.ts +9 -0
  113. package/dist/cli/status.d.ts.map +1 -1
  114. package/dist/cli/status.js +31 -2
  115. package/dist/cli/status.js.map +1 -1
  116. package/dist/cli/step-evidence.d.ts +90 -0
  117. package/dist/cli/step-evidence.d.ts.map +1 -0
  118. package/dist/cli/step-evidence.js +259 -0
  119. package/dist/cli/step-evidence.js.map +1 -0
  120. package/dist/cli/step-failure.d.ts +14 -4
  121. package/dist/cli/step-failure.d.ts.map +1 -1
  122. package/dist/cli/step-failure.js +41 -76
  123. package/dist/cli/step-failure.js.map +1 -1
  124. package/dist/cli-commands.d.ts +12 -0
  125. package/dist/cli-commands.d.ts.map +1 -1
  126. package/dist/cli-commands.js +3 -0
  127. package/dist/cli-commands.js.map +1 -1
  128. package/dist/cli.d.ts +17 -0
  129. package/dist/cli.d.ts.map +1 -1
  130. package/dist/cli.js +134 -57
  131. package/dist/cli.js.map +1 -1
  132. package/dist/cloud-deploy.d.ts +1 -1
  133. package/dist/cloud-deploy.d.ts.map +1 -1
  134. package/dist/cloud-deploy.js +24 -8
  135. package/dist/cloud-deploy.js.map +1 -1
  136. package/dist/cloud-mirror-ledger.d.ts +40 -0
  137. package/dist/cloud-mirror-ledger.d.ts.map +1 -0
  138. package/dist/cloud-mirror-ledger.js +142 -0
  139. package/dist/cloud-mirror-ledger.js.map +1 -0
  140. package/dist/cloud-mirror-step.d.ts +168 -0
  141. package/dist/cloud-mirror-step.d.ts.map +1 -0
  142. package/dist/cloud-mirror-step.js +504 -0
  143. package/dist/cloud-mirror-step.js.map +1 -0
  144. package/dist/cloud-mirror-transport.d.ts +94 -0
  145. package/dist/cloud-mirror-transport.d.ts.map +1 -0
  146. package/dist/cloud-mirror-transport.js +163 -0
  147. package/dist/cloud-mirror-transport.js.map +1 -0
  148. package/dist/cloud-mirror.d.ts +132 -0
  149. package/dist/cloud-mirror.d.ts.map +1 -0
  150. package/dist/cloud-mirror.js +556 -0
  151. package/dist/cloud-mirror.js.map +1 -0
  152. package/dist/cloud-read.d.ts +15 -0
  153. package/dist/cloud-read.d.ts.map +1 -1
  154. package/dist/cloud-read.js +20 -1
  155. package/dist/cloud-read.js.map +1 -1
  156. package/dist/cloud-run-record.d.ts +27 -0
  157. package/dist/cloud-run-record.d.ts.map +1 -0
  158. package/dist/cloud-run-record.js +56 -0
  159. package/dist/cloud-run-record.js.map +1 -0
  160. package/dist/cloud-run.d.ts +2 -9
  161. package/dist/cloud-run.d.ts.map +1 -1
  162. package/dist/cloud-run.js +3 -20
  163. package/dist/cloud-run.js.map +1 -1
  164. package/dist/communication/local.d.ts.map +1 -1
  165. package/dist/communication/local.js +2 -1
  166. package/dist/communication/local.js.map +1 -1
  167. package/dist/communication/worker.d.ts +1 -1
  168. package/dist/communication/worker.d.ts.map +1 -1
  169. package/dist/communication/worker.js +13 -5
  170. package/dist/communication/worker.js.map +1 -1
  171. package/dist/compile.d.ts.map +1 -1
  172. package/dist/compile.js +28 -6
  173. package/dist/compile.js.map +1 -1
  174. package/dist/direct-input.d.ts.map +1 -1
  175. package/dist/direct-input.js +21 -1
  176. package/dist/direct-input.js.map +1 -1
  177. package/dist/failure-kinds.d.ts +96 -6
  178. package/dist/failure-kinds.d.ts.map +1 -1
  179. package/dist/failure-kinds.js +29 -2
  180. package/dist/failure-kinds.js.map +1 -1
  181. package/dist/flow-requirements.d.ts.map +1 -1
  182. package/dist/flow-requirements.js +24 -9
  183. package/dist/flow-requirements.js.map +1 -1
  184. package/dist/gate-contract.d.ts +7 -0
  185. package/dist/gate-contract.d.ts.map +1 -1
  186. package/dist/gate-contract.js +6 -1
  187. package/dist/gate-contract.js.map +1 -1
  188. package/dist/helper-preflight.d.ts.map +1 -1
  189. package/dist/helper-preflight.js +10 -3
  190. package/dist/helper-preflight.js.map +1 -1
  191. package/dist/helper-reference.d.ts +25 -0
  192. package/dist/helper-reference.d.ts.map +1 -0
  193. package/dist/helper-reference.js +129 -0
  194. package/dist/helper-reference.js.map +1 -0
  195. package/dist/hosted-extension-runtime.js +1 -1
  196. package/dist/index.d.ts +1 -1
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js.map +1 -1
  199. package/dist/journal-client.d.ts +3 -1
  200. package/dist/journal-client.d.ts.map +1 -1
  201. package/dist/journal-client.js +17 -2
  202. package/dist/journal-client.js.map +1 -1
  203. package/dist/journal-projection.d.ts +16 -0
  204. package/dist/journal-projection.d.ts.map +1 -0
  205. package/dist/journal-projection.js +108 -0
  206. package/dist/journal-projection.js.map +1 -0
  207. package/dist/llm-worker.js +1 -1
  208. package/dist/llm-worker.js.map +1 -1
  209. package/dist/local-agent.d.ts +1 -1
  210. package/dist/local-agent.d.ts.map +1 -1
  211. package/dist/local-agent.js +4 -3
  212. package/dist/local-agent.js.map +1 -1
  213. package/dist/named-gate-lowering.js +35 -5
  214. package/dist/named-gate-lowering.js.map +1 -1
  215. package/dist/named-gate-preflight.d.ts +27 -0
  216. package/dist/named-gate-preflight.d.ts.map +1 -0
  217. package/dist/named-gate-preflight.js +47 -0
  218. package/dist/named-gate-preflight.js.map +1 -0
  219. package/dist/named-gates.d.ts +1 -1
  220. package/dist/named-gates.d.ts.map +1 -1
  221. package/dist/named-gates.js +3 -0
  222. package/dist/named-gates.js.map +1 -1
  223. package/dist/observer-link.d.ts +7 -0
  224. package/dist/observer-link.d.ts.map +1 -1
  225. package/dist/observer-link.js +3 -1
  226. package/dist/observer-link.js.map +1 -1
  227. package/dist/package-version.d.ts +10 -0
  228. package/dist/package-version.d.ts.map +1 -0
  229. package/dist/package-version.js +22 -0
  230. package/dist/package-version.js.map +1 -0
  231. package/dist/preflight.d.ts +14 -0
  232. package/dist/preflight.d.ts.map +1 -1
  233. package/dist/preflight.js +25 -3
  234. package/dist/preflight.js.map +1 -1
  235. package/dist/protocol.d.ts +2 -0
  236. package/dist/protocol.d.ts.map +1 -1
  237. package/dist/redact.d.ts +42 -0
  238. package/dist/redact.d.ts.map +1 -1
  239. package/dist/redact.js +128 -0
  240. package/dist/redact.js.map +1 -1
  241. package/dist/relay-cli.d.ts.map +1 -1
  242. package/dist/relay-cli.js +1 -21
  243. package/dist/relay-cli.js.map +1 -1
  244. package/dist/run-projection.d.ts +83 -0
  245. package/dist/run-projection.d.ts.map +1 -0
  246. package/dist/run-projection.js +199 -0
  247. package/dist/run-projection.js.map +1 -0
  248. package/dist/shell-word.d.ts +19 -0
  249. package/dist/shell-word.d.ts.map +1 -0
  250. package/dist/shell-word.js +23 -0
  251. package/dist/shell-word.js.map +1 -0
  252. package/dist/spec.d.ts +52 -3
  253. package/dist/spec.d.ts.map +1 -1
  254. package/dist/spec.js.map +1 -1
  255. package/dist/step-fields.d.ts +1 -1
  256. package/dist/step-fields.js +1 -1
  257. package/dist/step-fields.js.map +1 -1
  258. package/dist/steps-green.d.ts +27 -0
  259. package/dist/steps-green.d.ts.map +1 -0
  260. package/dist/steps-green.js +164 -0
  261. package/dist/steps-green.js.map +1 -0
  262. package/dist/validate.d.ts.map +1 -1
  263. package/dist/validate.js +39 -8
  264. package/dist/validate.js.map +1 -1
  265. package/dist/worker-lease.d.ts +8 -1
  266. package/dist/worker-lease.d.ts.map +1 -1
  267. package/dist/worker-lease.js +34 -4
  268. package/dist/worker-lease.js.map +1 -1
  269. package/dist/worker.d.ts +8 -0
  270. package/dist/worker.d.ts.map +1 -1
  271. package/dist/worker.js +17 -9
  272. package/dist/worker.js.map +1 -1
  273. package/package.json +3 -7
  274. package/src/agent-artifacts.ts +2 -10
  275. package/src/agent-cwd.ts +139 -0
  276. package/src/artifact-scan-policy.ts +51 -0
  277. package/src/authored-completion-record.ts +119 -0
  278. package/src/authored-completion.ts +203 -0
  279. package/src/authored-flow-error.ts +13 -1
  280. package/src/authored-flow-executor.ts +91 -58
  281. package/src/authored-human.ts +1 -4
  282. package/src/authored-node-entry.ts +4 -1
  283. package/src/authored-node-runner.ts +96 -22
  284. package/src/authored-preflight.ts +46 -0
  285. package/src/authored-root.ts +20 -2
  286. package/src/authored-step-output.ts +139 -42
  287. package/src/authored-verdict.ts +87 -0
  288. package/src/authored-worker-step.ts +63 -14
  289. package/src/cli/check-worker-surface.ts +66 -0
  290. package/src/cli/check.ts +59 -166
  291. package/src/cli/cli-probe.ts +194 -0
  292. package/src/cli/cloud-format.ts +82 -0
  293. package/src/cli/cloud-live.ts +366 -0
  294. package/src/cli/cloud-mirror-session.ts +329 -0
  295. package/src/cli/cloud-read.ts +13 -282
  296. package/src/cli/cloud-refusal.ts +113 -0
  297. package/src/cli/cloud-status-view.ts +213 -0
  298. package/src/cli/direct-run.ts +19 -2
  299. package/src/cli/hn-monitor.ts +2 -1
  300. package/src/cli/local-agent-remedy.ts +160 -0
  301. package/src/cli/observer-session.ts +107 -0
  302. package/src/cli/run.ts +233 -28
  303. package/src/cli/status.ts +59 -3
  304. package/src/cli/step-evidence.ts +310 -0
  305. package/src/cli/step-failure.ts +57 -81
  306. package/src/cli-commands.ts +3 -0
  307. package/src/cli.ts +155 -60
  308. package/src/cloud-deploy.ts +26 -8
  309. package/src/cloud-mirror-ledger.ts +161 -0
  310. package/src/cloud-mirror-step.ts +618 -0
  311. package/src/cloud-mirror-transport.ts +261 -0
  312. package/src/cloud-mirror.ts +633 -0
  313. package/src/cloud-read.ts +25 -1
  314. package/src/cloud-run-record.ts +64 -0
  315. package/src/cloud-run.ts +5 -24
  316. package/src/communication/local.ts +2 -1
  317. package/src/communication/worker.ts +13 -5
  318. package/src/compile.ts +28 -6
  319. package/src/direct-input.ts +22 -1
  320. package/src/failure-kinds.ts +104 -2
  321. package/src/flow-requirements.ts +24 -9
  322. package/src/gate-contract.ts +13 -1
  323. package/src/helper-preflight.ts +10 -3
  324. package/src/helper-reference.ts +130 -0
  325. package/src/hosted-extension-runtime.ts +1 -1
  326. package/src/index.ts +2 -0
  327. package/src/journal-client.ts +19 -2
  328. package/src/journal-projection.ts +106 -0
  329. package/src/llm-worker.ts +1 -1
  330. package/src/local-agent.ts +4 -2
  331. package/src/named-gate-lowering.ts +35 -5
  332. package/src/named-gate-preflight.ts +47 -0
  333. package/src/named-gates.ts +3 -0
  334. package/src/observer-link.ts +10 -1
  335. package/src/package-version.ts +23 -0
  336. package/src/preflight.ts +38 -7
  337. package/src/protocol.ts +2 -0
  338. package/src/redact.ts +111 -0
  339. package/src/relay-cli.ts +1 -24
  340. package/src/run-projection.ts +247 -0
  341. package/src/shell-word.ts +24 -0
  342. package/src/spec.ts +54 -3
  343. package/src/step-fields.ts +1 -1
  344. package/src/steps-green.ts +168 -0
  345. package/src/validate.ts +35 -8
  346. package/src/worker-lease.ts +35 -5
  347. package/src/worker.ts +27 -11
@@ -17,19 +17,23 @@ export interface AuthoredStepContext {
17
17
  readonly stepEdges?: (step: string) => AuthoredStepEdges | undefined;
18
18
  }
19
19
  /**
20
- * Shared by every `f.*` verb that lowers to one kernel step run in isolation:
21
- * find its `step.completed` entry, record it, and refuse anything but a
20
+ * Shared by every `f.*` verb that lowers to its own kernel run: find the
21
+ * operation's `step.completed` entry, record it, and refuse anything but a
22
22
  * clean success before handing the raw `output` back for verb-specific
23
23
  * extraction (a plain string for `f.run`, an `AgentResult` for `f.agent`).
24
24
  *
25
- * Callers are responsible for having already established that the RUN
26
- * reached a terminal, successful state before calling this — `f.run`'s
27
- * caller relies on `runStart`'s own immediate response (the kernel drives a
28
- * deterministic step to completion inline, no race); `f.agent`'s caller
29
- * relies on `classifyOutcome` (cli/run.ts) having already polled to a true
30
- * terminal state. Given that, a single read from the start of this run's
31
- * (small, single-step) journal is enough — no polling here, and no run
32
- * outcome ever needs re-checking.
25
+ * Callers are responsible for having already waited for the run to reach a
26
+ * terminal state — `f.run`'s caller relies on `runStart`'s own immediate
27
+ * response (the kernel drives a deterministic step to completion inline, no
28
+ * race); `f.agent`'s caller relies on `classifyOutcome` (cli/run.ts) having
29
+ * already polled to one. Given that, a single read from the start of this
30
+ * run's small journal is enough, and no polling happens here.
31
+ *
32
+ * What is NOT delegated to the caller is the run's verdict. A child spec has
33
+ * more than one step whenever the author declared a `.gate()`, and that gate
34
+ * step runs after the producer, so the producer's own `success` is not the
35
+ * run's. Both are checked here, and the run-level check is what makes a failed
36
+ * gate reject the authored operation.
33
37
  *
34
38
  * A non-success completion used to throw `journal step "run-1" completed with
35
39
  * retries_exhausted` and stop there, discarding the evidence it was holding:
@@ -43,6 +47,27 @@ export interface AuthoredStepContext {
43
47
  */
44
48
  export declare function readCompletedStepOutput(journal: JournalClient, runId: string, stepId: string, journalSteps: AuthoredFlowJournalStep[], context?: AuthoredStepContext): Promise<unknown>;
45
49
  export declare function readSuccessfulOutput(journal: JournalClient, outcome: RunOutcome, stepId: string, journalSteps: AuthoredFlowJournalStep[], context?: AuthoredStepContext): Promise<string>;
50
+ /** What `f.run` resolves to under `onNonZero: 'record'` (surface `RunResult`). */
51
+ export interface RecordedRunOutcome {
52
+ ok: boolean;
53
+ exitCode: number;
54
+ output: string;
55
+ stdout: string;
56
+ stderr: string;
57
+ }
58
+ /**
59
+ * The read side of `onNonZero: 'record'`.
60
+ *
61
+ * A recorded red exit is a SUCCESSFUL step, so this takes the same path as
62
+ * `readSuccessfulOutput` and every field comes from the journaled envelope —
63
+ * nothing is re-run and nothing is re-measured. What still throws is what the
64
+ * policy never covered: a timeout, a signal, a step that never ran, or a
65
+ * declared content or schema gate that failed. The `-1` the executor writes
66
+ * for "no exit status" is refused rather than handed back as a plausible
67
+ * code, mirroring the kernel's own rule, so a malformed envelope can never
68
+ * reach an author's `if (!result.ok)` as a real verdict.
69
+ */
70
+ export declare function readRecordedOutcome(journal: JournalClient, outcome: RunOutcome, stepId: string, journalSteps: AuthoredFlowJournalStep[], context?: AuthoredStepContext): Promise<RecordedRunOutcome>;
46
71
  export declare function isSurfaceCompletionReason(value: unknown): value is ProtocolCompletionReason;
47
72
  export declare function isSurfaceRunCompletionReason(value: unknown): value is ProtocolRunCompletionReason;
48
73
  export declare function isSurfaceFlowCompletionReason(value: unknown): value is FlowCompletionReason;
@@ -1 +1 @@
1
- {"version":3,"file":"authored-step-output.d.ts","sourceRoot":"","sources":["../src/authored-step-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAErI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,IAAI,wBAAwB,EAAE,mBAAmB,IAAI,2BAA2B,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClJ,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAG3E,OAAO,EAAmC,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEnG;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;CACtE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,uBAAuB,EAAE,EACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC,CAoClB;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,uBAAuB,EAAE,EACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAqBD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAG3F;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,2BAA2B,CAGjG;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAG3F"}
1
+ {"version":3,"file":"authored-step-output.d.ts","sourceRoot":"","sources":["../src/authored-step-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAErI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,IAAI,wBAAwB,EAAE,mBAAmB,IAAI,2BAA2B,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClJ,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAG3E,OAAO,EAAmC,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEnG;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;CACtE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,uBAAuB,EAAE,EACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC,CA6BlB;AAsCD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,uBAAuB,EAAE,EACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,kFAAkF;AAClF,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,uBAAuB,EAAE,EACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAkB7B;AAiDD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAG3F;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,2BAA2B,CAGjG;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAG3F"}
@@ -3,19 +3,23 @@ import { AuthoredFlowExecutionError } from './authored-flow-error.js';
3
3
  import { inspectionHint, renderInspection, renderStepEvidence, stepFailureDetails } from './cli/step-failure.js';
4
4
  import { alsoRecord, recordAuthoredChild } from './authored-step-index.js';
5
5
  /**
6
- * Shared by every `f.*` verb that lowers to one kernel step run in isolation:
7
- * find its `step.completed` entry, record it, and refuse anything but a
6
+ * Shared by every `f.*` verb that lowers to its own kernel run: find the
7
+ * operation's `step.completed` entry, record it, and refuse anything but a
8
8
  * clean success before handing the raw `output` back for verb-specific
9
9
  * extraction (a plain string for `f.run`, an `AgentResult` for `f.agent`).
10
10
  *
11
- * Callers are responsible for having already established that the RUN
12
- * reached a terminal, successful state before calling this — `f.run`'s
13
- * caller relies on `runStart`'s own immediate response (the kernel drives a
14
- * deterministic step to completion inline, no race); `f.agent`'s caller
15
- * relies on `classifyOutcome` (cli/run.ts) having already polled to a true
16
- * terminal state. Given that, a single read from the start of this run's
17
- * (small, single-step) journal is enough — no polling here, and no run
18
- * outcome ever needs re-checking.
11
+ * Callers are responsible for having already waited for the run to reach a
12
+ * terminal state — `f.run`'s caller relies on `runStart`'s own immediate
13
+ * response (the kernel drives a deterministic step to completion inline, no
14
+ * race); `f.agent`'s caller relies on `classifyOutcome` (cli/run.ts) having
15
+ * already polled to one. Given that, a single read from the start of this
16
+ * run's small journal is enough, and no polling happens here.
17
+ *
18
+ * What is NOT delegated to the caller is the run's verdict. A child spec has
19
+ * more than one step whenever the author declared a `.gate()`, and that gate
20
+ * step runs after the producer, so the producer's own `success` is not the
21
+ * run's. Both are checked here, and the run-level check is what makes a failed
22
+ * gate reject the authored operation.
19
23
  *
20
24
  * A non-success completion used to throw `journal step "run-1" completed with
21
25
  * retries_exhausted` and stop there, discarding the evidence it was holding:
@@ -37,50 +41,100 @@ export async function readCompletedStepOutput(journal, runId, stepId, journalSte
37
41
  const edges = context.stepEdges?.(stepId);
38
42
  journalSteps.push(Object.freeze({ id: stepId, runId, completionReason: reason, ...edges }));
39
43
  if (reason !== 'success') {
40
- let message = `journal step "${stepId}" completed with ${reason}`;
41
- let details;
42
- try {
43
- details = await stepFailureDetails(journal, runId);
44
- }
45
- catch (error) {
46
- // Inspection must not erase the already known step failure; the two
47
- // failures stay separately visible, as in classifyOutcome.
48
- message += ` Could not inspect the failed step: ${errorMessage(error)}`;
49
- }
50
- if (details !== undefined)
51
- message += renderStepEvidence(details);
52
- // Appended whatever inspection found — including nothing. A failure shape
53
- // this reader does not recognise must still end with somewhere to go.
54
- const where = inspectionHint(runId, details?.stepId ?? stepId, context.dataDir);
55
- message += renderInspection(where);
56
- message += await alsoRecord(journal, context.rootRunId, {
57
- step: stepId, runId, state: 'completed', completionReason: reason,
58
- ...(details?.stepId === undefined ? {} : { kernelStep: details.stepId }),
59
- ...edges,
60
- });
61
- throw new AuthoredFlowExecutionError('step_failed', message, reason, runId, { ...details, ...where });
44
+ throw await stepFailure(journal, runId, stepId, reason, context, edges, `journal step "${stepId}" completed with ${reason}`);
45
+ }
46
+ // An authored operation does not always lower to ONE kernel step. A declared
47
+ // `.gate()` becomes its own barrier step that runs AFTER the producer
48
+ // (`lowerNamedGates`), so the producer's own success is not the run's
49
+ // verdict. Reading only the producer's entry let a failed gate resolve as
50
+ // though the command had passed — the `|| true` invisibility this module's
51
+ // recording policy exists to remove, reappearing one layer up.
52
+ const runReason = entries.map(runCompletionReason).find((value) => value !== undefined);
53
+ if (runReason !== undefined && runReason !== 'success') {
54
+ throw await stepFailure(journal, runId, stepId, runReason, context, edges, `journal run for step "${stepId}" completed with ${runReason}`);
62
55
  }
63
56
  await recordAuthoredChild(journal, context.rootRunId, {
64
57
  step: stepId, runId, state: 'completed', completionReason: reason, ...edges,
65
58
  });
66
59
  return completed.payload.output;
67
60
  }
61
+ /**
62
+ * The one `step_failed` grammar both the step-level and the run-level refusal
63
+ * report through: inspect the journal for the step that actually failed, render
64
+ * its evidence, name where to look, and index the child before throwing.
65
+ */
66
+ async function stepFailure(journal, runId, stepId, reason, context, edges, header) {
67
+ let message = header;
68
+ let details;
69
+ try {
70
+ details = await stepFailureDetails(journal, runId);
71
+ }
72
+ catch (error) {
73
+ // Inspection must not erase the already known step failure; the two
74
+ // failures stay separately visible, as in classifyOutcome.
75
+ message += ` Could not inspect the failed step: ${errorMessage(error)}`;
76
+ }
77
+ if (details !== undefined)
78
+ message += renderStepEvidence(details);
79
+ // Appended whatever inspection found — including nothing. A failure shape
80
+ // this reader does not recognise must still end with somewhere to go.
81
+ const where = inspectionHint(runId, details?.stepId ?? stepId, context.dataDir);
82
+ message += renderInspection(where);
83
+ message += await alsoRecord(journal, context.rootRunId, {
84
+ step: stepId, runId, state: 'completed', completionReason: reason,
85
+ ...(details?.stepId === undefined ? {} : { kernelStep: details.stepId }),
86
+ ...edges,
87
+ });
88
+ return new AuthoredFlowExecutionError('step_failed', message, reason, runId, { ...details, ...where });
89
+ }
68
90
  export async function readSuccessfulOutput(journal, outcome, stepId, journalSteps, context = {}) {
69
91
  const output = await readCompletedStepOutput(journal, outcome.run_id, stepId, journalSteps, context)
70
- .catch(error => {
92
+ .catch(relabelCommandTimeout(stepId));
93
+ if (!isRecord(output) || typeof output['stdout_tail'] !== 'string') {
94
+ throw protocolViolation(outcome.run_id, `step "${stepId}" has no string stdout_tail`);
95
+ }
96
+ return output['stdout_tail'];
97
+ }
98
+ /**
99
+ * The read side of `onNonZero: 'record'`.
100
+ *
101
+ * A recorded red exit is a SUCCESSFUL step, so this takes the same path as
102
+ * `readSuccessfulOutput` and every field comes from the journaled envelope —
103
+ * nothing is re-run and nothing is re-measured. What still throws is what the
104
+ * policy never covered: a timeout, a signal, a step that never ran, or a
105
+ * declared content or schema gate that failed. The `-1` the executor writes
106
+ * for "no exit status" is refused rather than handed back as a plausible
107
+ * code, mirroring the kernel's own rule, so a malformed envelope can never
108
+ * reach an author's `if (!result.ok)` as a real verdict.
109
+ */
110
+ export async function readRecordedOutcome(journal, outcome, stepId, journalSteps, context = {}) {
111
+ const envelope = await readCompletedStepOutput(journal, outcome.run_id, stepId, journalSteps, context)
112
+ .catch(relabelCommandTimeout(stepId));
113
+ const exitCode = isRecord(envelope) ? envelope['exit_code'] : undefined;
114
+ if (!isRecord(envelope) || typeof envelope['stdout_tail'] !== 'string'
115
+ || typeof envelope['stderr_tail'] !== 'string'
116
+ || typeof exitCode !== 'number' || !Number.isInteger(exitCode) || exitCode < 0) {
117
+ throw protocolViolation(outcome.run_id, `step "${stepId}" recorded no {exit_code, stdout_tail, stderr_tail} to report`);
118
+ }
119
+ const stdout = envelope['stdout_tail'];
120
+ const stderr = envelope['stderr_tail'];
121
+ return {
122
+ ok: exitCode === 0, exitCode, stdout, stderr,
123
+ // Concatenated, not interleaved: the two tails were captured separately,
124
+ // so joining them is a reading convenience and is documented as one.
125
+ output: stdout !== '' && stderr !== '' ? `${stdout}\n${stderr}` : stdout + stderr,
126
+ };
127
+ }
128
+ /** A timeout is still a failed command; re-labelling it must not delete its evidence. */
129
+ function relabelCommandTimeout(stepId) {
130
+ return (error) => {
71
131
  if (error instanceof AuthoredFlowExecutionError
72
132
  && (error.completionReason === 'timeout' || error.completionReason === 'lease_expired')) {
73
- // A timeout is still a failed command, and the evidence extracted for
74
- // it is the same evidence. Re-labelling the error must not delete it.
75
133
  throw new AuthoredFlowExecutionError('lease_exceeded', `f.run step "${stepId}" exceeded its command timeout.`
76
134
  + ` ${error.message.slice(`${error.code}: `.length)}`, error.completionReason, error.runId, error.details);
77
135
  }
78
136
  throw error;
79
- });
80
- if (!isRecord(output) || typeof output['stdout_tail'] !== 'string') {
81
- throw protocolViolation(outcome.run_id, `step "${stepId}" has no string stdout_tail`);
82
- }
83
- return output['stdout_tail'];
137
+ };
84
138
  }
85
139
  function isStepCompleted(value, stepId) {
86
140
  if (!isRecord(value) || value['entry_type'] !== 'step.completed' || value['step_id'] !== stepId) {
@@ -91,6 +145,20 @@ function isStepCompleted(value, stepId) {
91
145
  && isSurfaceCompletionReason(payload['completionReason'])
92
146
  && 'output' in payload;
93
147
  }
148
+ /**
149
+ * The run's own terminal reason, when this entry is the one carrying it.
150
+ *
151
+ * Anything else — including a `run.completed` whose payload this reader does
152
+ * not recognise — yields `undefined` and leaves the step-level verdict
153
+ * untouched, so an unfamiliar journal shape cannot invent a failure.
154
+ */
155
+ function runCompletionReason(entry) {
156
+ if (!isRecord(entry) || entry['entry_type'] !== 'run.completed')
157
+ return undefined;
158
+ const payload = entry['payload'];
159
+ const reason = isRecord(payload) ? payload['completionReason'] : undefined;
160
+ return isSurfaceRunCompletionReason(reason) ? reason : undefined;
161
+ }
94
162
  export function isSurfaceCompletionReason(value) {
95
163
  return typeof value === 'string'
96
164
  && COMPLETION_REASONS.includes(value);
@@ -1 +1 @@
1
- {"version":3,"file":"authored-step-output.js","sourceRoot":"","sources":["../src/authored-step-output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authored-step-output.js","sourceRoot":"","sources":["../src/authored-step-output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type LoweredCompletionReason } from './authored-completion.js';
2
+ import type { JournalEvent } from './journal-reader.js';
3
+ /** The `instruction` discriminator `authored-root.ts` writes into the root step. */
4
+ export declare const AUTHORED_ROOT_KIND = "relayflows.authored-root.v1";
5
+ export interface AuthoredVerdict {
6
+ readonly reason: LoweredCompletionReason;
7
+ /** Absent when the body called `done()` with one argument, as most do. */
8
+ readonly detail?: string;
9
+ }
10
+ /**
11
+ * The verdict an authored root attested, or `null` when this journal holds none.
12
+ *
13
+ * `null` is the answer for an ordinary run, for an authored run still in
14
+ * flight, and for one whose root output is malformed. The last of those
15
+ * matters: an ordinary flow may name a step `authored-root`, and a worker may
16
+ * journal anything into a step's output, so the step id alone attests nothing.
17
+ * A verdict is reported only when the run's own spec declares the authored
18
+ * root — carrying {@link AUTHORED_ROOT_KIND} metadata — and the root's last
19
+ * `step.completed` is a terminal kernel `success` whose output is a complete,
20
+ * in-bounds authored result. A retry or park completion is not terminal and a
21
+ * later attempt may still change the answer, so neither is promoted.
22
+ *
23
+ * This is a projection for a read-only view, so a malformed record yields no
24
+ * verdict rather than an error: refusing to render a whole status because one
25
+ * output field is the wrong type would replace the answer with a worse one.
26
+ */
27
+ export declare function authoredVerdictOf(events: readonly JournalEvent[]): AuthoredVerdict | null;
28
+ //# sourceMappingURL=authored-verdict.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-verdict.d.ts","sourceRoot":"","sources":["../src/authored-verdict.ts"],"names":[],"mappings":"AAcA,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,gCAAgC,CAAC;AAEhE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,eAAe,GAAG,IAAI,CAoBzF"}
@@ -0,0 +1,79 @@
1
+ // Project an authored flow's own verdict out of its root journal.
2
+ //
3
+ // `foldRunState` answers what the KERNEL recorded: the root step succeeded, so
4
+ // the run completed with `success`. That is true and must stay printed. It is
5
+ // also not what a reader asking "why did this fail?" needs when the body
6
+ // declared `step_failed` — a verdict the kernel's vocabulary cannot express on
7
+ // a step that succeeded, so it travels as output on the root's own
8
+ // `step.completed`.
9
+ //
10
+ // This is a separate, narrow projection rather than a branch inside the fold:
11
+ // the fold is generic over every run and has no business knowing what an
12
+ // authored root is, and the executor this vocabulary comes from must not
13
+ // become a dependency of `flows status`.
14
+ import { isDurableCompletionDetail, isLoweredCompletion, } from './authored-completion.js';
15
+ /** The `instruction` discriminator `authored-root.ts` writes into the root step. */
16
+ export const AUTHORED_ROOT_KIND = 'relayflows.authored-root.v1';
17
+ /**
18
+ * The verdict an authored root attested, or `null` when this journal holds none.
19
+ *
20
+ * `null` is the answer for an ordinary run, for an authored run still in
21
+ * flight, and for one whose root output is malformed. The last of those
22
+ * matters: an ordinary flow may name a step `authored-root`, and a worker may
23
+ * journal anything into a step's output, so the step id alone attests nothing.
24
+ * A verdict is reported only when the run's own spec declares the authored
25
+ * root — carrying {@link AUTHORED_ROOT_KIND} metadata — and the root's last
26
+ * `step.completed` is a terminal kernel `success` whose output is a complete,
27
+ * in-bounds authored result. A retry or park completion is not terminal and a
28
+ * later attempt may still change the answer, so neither is promoted.
29
+ *
30
+ * This is a projection for a read-only view, so a malformed record yields no
31
+ * verdict rather than an error: refusing to render a whole status because one
32
+ * output field is the wrong type would replace the answer with a worse one.
33
+ */
34
+ export function authoredVerdictOf(events) {
35
+ const spawned = events[0];
36
+ if (spawned === undefined || spawned.entry_type !== 'run.spawned')
37
+ return null;
38
+ if (!declaresAuthoredRoot(spawned))
39
+ return null;
40
+ const completed = [...events].reverse().find((event) => event.entry_type === 'step.completed' && event.step_id === 'authored-root');
41
+ const payload = record(completed?.payload);
42
+ if (payload === null || payload['completionReason'] !== 'success')
43
+ return null;
44
+ const disposition = payload['disposition'];
45
+ if (disposition !== undefined && disposition !== 'step_done')
46
+ return null;
47
+ const output = record(payload['output']);
48
+ if (output === null || typeof output['name'] !== 'string')
49
+ return null;
50
+ const reason = output['completionReason'];
51
+ if (!isLoweredCompletion(reason))
52
+ return null;
53
+ const detail = output['completionDetail'];
54
+ if (detail !== undefined && !isDurableCompletionDetail(detail))
55
+ return null;
56
+ return Object.freeze({ reason, ...(detail === undefined ? {} : { detail }) });
57
+ }
58
+ function declaresAuthoredRoot(spawned) {
59
+ const spec = record(record(spawned.payload)?.['spec']);
60
+ const steps = spec?.['steps'];
61
+ if (!Array.isArray(steps))
62
+ return false;
63
+ const step = record(steps[0]);
64
+ if (step === null || step['id'] !== 'authored-root')
65
+ return false;
66
+ if (typeof step['instruction'] !== 'string')
67
+ return false;
68
+ try {
69
+ return record(JSON.parse(step['instruction']))?.['kind'] === AUTHORED_ROOT_KIND;
70
+ }
71
+ catch {
72
+ return false;
73
+ }
74
+ }
75
+ function record(value) {
76
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
77
+ ? value : null;
78
+ }
79
+ //# sourceMappingURL=authored-verdict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-verdict.js","sourceRoot":"","sources":["../src/authored-verdict.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import type { AuthoredBudget } from './authored-budget.js';
2
2
  import type { AgentOptions, AgentResult, LlmOptions, NamedGate } from '@relayflows/surface';
3
3
  import { type RunLifecycleOptions } from './cli/run.js';
4
4
  import type { JournalClient } from './journal-client.js';
5
- import { type AuthoredStepContext } from './authored-step-output.js';
5
+ import { type AuthoredStepContext, type RecordedRunOutcome } from './authored-step-output.js';
6
6
  import type { AuthoredFlowJournalStep } from './authored-flow-executor.js';
7
7
  /** Agent and LLM calls share the exact declarative preflight and lease wait. */
8
8
  export declare function authoredWorkerRunner(definition: {
@@ -21,5 +21,8 @@ export declare function authoredWorkerRunner(definition: {
21
21
  * the worker runner builds; a failed `f.run` and a failed `f.agent` now report
22
22
  * through one grammar.
23
23
  */
24
- export declare function authoredDeterministicRunner(name: string, journal: JournalClient, journalSteps: AuthoredFlowJournalStep[], budget: AuthoredBudget, context?: AuthoredStepContext): (id: string, command: string, terminal?: boolean, leaseMs?: number, verification?: NamedGate) => Promise<string>;
24
+ export declare function authoredDeterministicRunner(name: string, journal: JournalClient, journalSteps: AuthoredFlowJournalStep[], budget: AuthoredBudget, context?: AuthoredStepContext): {
25
+ (id: string, command: string, terminal?: boolean, leaseMs?: number, verification?: NamedGate): Promise<string>;
26
+ recording(id: string, command: string, leaseMs?: number, verification?: NamedGate): Promise<RecordedRunOutcome>;
27
+ };
25
28
  //# sourceMappingURL=authored-worker-step.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authored-worker-step.d.ts","sourceRoot":"","sources":["../src/authored-worker-step.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG5F,OAAO,EAAmB,KAAK,mBAAmB,EAAkB,MAAM,cAAc,CAAC;AAGzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAA4E,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAC/I,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAS3E,gFAAgF;AAChF,wBAAgB,oBAAoB,CAClC,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EACtE,YAAY,EAAE,uBAAuB,EAAE,EAAE,WAAW,EAAE,mBAAmB,EACzE,gBAAgB,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,OAAO,EAC1E,SAAS,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC;IA0GvF,mFAAmF;iBACtE,OAAO,GAAG,IAAI;cAIX,MAAM,WAAW,YAAY,iBAAiB,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;YAiEhF,MAAM,UAAU,MAAM,YAAY,UAAU,iBAAiB,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;EAmB1G;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,cAAc,EACrG,OAAO,GAAE,mBAAwB,IAGnB,IAAI,MAAM,EAAE,SAAS,MAAM,EAAE,kBAAgB,EAAE,UAAU,MAAM,EAAE,eAAe,SAAS,KAAG,OAAO,CAAC,MAAM,CAAC,CAoB1H"}
1
+ {"version":3,"file":"authored-worker-step.d.ts","sourceRoot":"","sources":["../src/authored-worker-step.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG5F,OAAO,EAAmB,KAAK,mBAAmB,EAAkB,MAAM,cAAc,CAAC;AAIzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAiG,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC7L,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAS3E,gFAAgF;AAChF,wBAAgB,oBAAoB,CAClC,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EACtE,YAAY,EAAE,uBAAuB,EAAE,EAAE,WAAW,EAAE,mBAAmB,EACzE,gBAAgB,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,OAAO,EAC1E,SAAS,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC;IAmHvF,mFAAmF;iBACtE,OAAO,GAAG,IAAI;cAIX,MAAM,WAAW,YAAY,iBAAiB,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;YAqFhF,MAAM,UAAU,MAAM,YAAY,UAAU,iBAAiB,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;EAmB1G;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,cAAc,EACrG,OAAO,GAAE,mBAAwB;SAgCX,MAAM,WAAW,MAAM,gCAA8B,MAAM,iBAAiB,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;kBAInG,MAAM,WAAW,MAAM,YAAY,MAAM,iBAAiB,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC;EAI5H"}
@@ -1,11 +1,12 @@
1
- import { resolve } from 'node:path';
1
+ import { isAbsolute, relative, sep } from 'node:path';
2
2
  import { parseBudget } from './budget.js';
3
3
  import { compileSpec, toKernelSpec } from './compile.js';
4
- import { checkAuthoredFlow } from './cli/check.js';
4
+ import { authoredPreflight } from './authored-preflight.js';
5
5
  import { classifyOutcome } from './cli/run.js';
6
6
  import { AuthoredFlowExecutionError } from './authored-flow-error.js';
7
+ import { agentCwdDeclarationError, agentCwdTransportError } from './agent-cwd.js';
7
8
  import { SPEC_SCHEMA_VERSION } from './spec.js';
8
- import { isSurfaceCompletionReason, readCompletedStepOutput, readSuccessfulOutput } from './authored-step-output.js';
9
+ import { isSurfaceCompletionReason, readCompletedStepOutput, readRecordedOutcome, readSuccessfulOutput } from './authored-step-output.js';
9
10
  import { snapshotJsonValue } from './json-value.js';
10
11
  import { authoredChildAdmissionKey } from './authored-admission.js';
11
12
  import { alsoRecord, recordAuthoredChild } from './authored-step-index.js';
@@ -17,6 +18,7 @@ export function authoredWorkerRunner(definition, journal, flowPath, journalSteps
17
18
  // slot instead of being admitted and parked for want of a free worker.
18
19
  const slots = workerCapacity === undefined ? undefined
19
20
  : { agent: new WorkerSlots(workerCapacity), llm: new WorkerSlots(workerCapacity) };
21
+ const check = authoredPreflight(flowPath);
20
22
  const context = {
21
23
  ...(rootRunId === undefined ? {} : { rootRunId }),
22
24
  ...(waitOptions.dataDir === undefined ? {} : { dataDir: waitOptions.dataDir }),
@@ -30,7 +32,7 @@ export function authoredWorkerRunner(definition, journal, flowPath, journalSteps
30
32
  // (cli/check.ts), searching for the nearest flows.json from `flowPath`
31
33
  // and real-probing auth/model readiness. An authored agent step gets
32
34
  // nothing for free just because it was declared in TS instead of YAML.
33
- const { report, flow: resolved } = checkAuthoredFlow(authoring, flowPath);
35
+ const { report, flow: resolved } = await check(authoring);
34
36
  if (!report.ok || resolved === undefined) {
35
37
  const refusal = report.diagnostics.find((diagnostic) => diagnostic.severity === 'refusal');
36
38
  throw new AuthoredFlowExecutionError(refusal?.kind === 'budget_syntax_invalid' ? refusal.kind
@@ -58,10 +60,18 @@ export function authoredWorkerRunner(definition, journal, flowPath, journalSteps
58
60
  const execution = await classifyOutcome(journal, 'run', outcome, report, '', waitOptions);
59
61
  if (execution.exitCode === 3) {
60
62
  const parked = execution.report.parkedStep;
61
- throw new AuthoredFlowExecutionError(step.type === 'llm' ? 'llm_parked' : 'agent_parked', execution.report.diagnostics.at(-1)?.message
63
+ const error = new AuthoredFlowExecutionError(step.type === 'llm' ? 'llm_parked' : 'agent_parked', execution.report.diagnostics.at(-1)?.message
62
64
  ?? `flow "${definition.name}" step "${id}" parked`
63
65
  + (parked !== undefined ? ` (${parked.type})` : '')
64
66
  + ': no worker is attached to run it.', undefined, outcome.run_id);
67
+ // Both `agent_parked` and `llm_parked` cover two unrelated situations —
68
+ // nothing attached to run the step, and the kernel's `needs_human`
69
+ // recovery wait after a worker attempt failed — and only the first is
70
+ // fixed by attaching a worker. The child's classification already knows
71
+ // which; carry it so the CLI boundary can name a remedy without
72
+ // re-deriving one from this message's wording.
73
+ error.parkCause = execution.report.parkCause;
74
+ throw error;
65
75
  }
66
76
  if (execution.exitCode !== 0) {
67
77
  // `execution.report.completionReason` is the RUN's reason (normally
@@ -121,12 +131,30 @@ export function authoredWorkerRunner(definition, journal, flowPath, journalSteps
121
131
  if (options.model !== undefined && typeof options.model !== 'string') {
122
132
  throw new AuthoredFlowExecutionError('agent_cli_unresolved', `f.agent options.model must be a string when set (got ${typeof options.model}).`);
123
133
  }
124
- if (options.cwd !== undefined && typeof options.cwd !== 'string') {
125
- throw new AuthoredFlowExecutionError('agent_cli_unresolved', `f.agent options.cwd must be a string when set (got ${typeof options.cwd}).`);
134
+ // The same lexical rule the kernel and `flows check` apply, raised here
135
+ // so an authored body is refused before a run exists rather than at
136
+ // dispatch. Whether the directory is there is the worker's question.
137
+ // An absolute cwd is honored when it names a directory inside the run
138
+ // root — it lowers to the same relative declaration — and refused when
139
+ // it escapes, because a declaration this contract cannot contain is
140
+ // worse than none.
141
+ const declaredCwd = options.cwd === undefined || !isAbsolute(options.cwd) ? options.cwd
142
+ : relative(process.cwd(), options.cwd) || undefined;
143
+ if (options.cwd !== undefined && isAbsolute(options.cwd) && declaredCwd !== undefined
144
+ && (declaredCwd === '..' || declaredCwd.startsWith(`..${sep}`) || isAbsolute(declaredCwd))) {
145
+ throw new AuthoredFlowExecutionError('agent_cli_unresolved', `f.agent options.cwd must name a directory inside the run root ${JSON.stringify(process.cwd())} (got ${JSON.stringify(options.cwd)}).`);
146
+ }
147
+ const cwdProblem = declaredCwd === undefined ? undefined : agentCwdDeclarationError(declaredCwd);
148
+ if (cwdProblem !== undefined) {
149
+ throw new AuthoredFlowExecutionError('agent_cli_unresolved', `f.agent options.cwd: ${cwdProblem}.`);
126
150
  }
127
151
  if (options.transport !== undefined && options.transport !== 'direct' && options.transport !== 'relay') {
128
152
  throw new AuthoredFlowExecutionError('agent_cli_unresolved', `f.agent options.transport must be 'direct' or 'relay' (got ${JSON.stringify(options.transport)}).`);
129
153
  }
154
+ const cwdTransport = agentCwdTransportError(declaredCwd, options.transport);
155
+ if (cwdTransport !== undefined) {
156
+ throw new AuthoredFlowExecutionError('agent_cli_unresolved', `f.agent options.${cwdTransport}.`);
157
+ }
130
158
  const permissions = options.permissions;
131
159
  const permissionsSnapshot = permissions === undefined ? undefined
132
160
  : snapshotJsonValue(permissions, 'f.agent options.permissions');
@@ -137,8 +165,7 @@ export function authoredWorkerRunner(definition, journal, flowPath, journalSteps
137
165
  ...(options.workspace === undefined ? {} : { surfaces: { workspace: [{ surface: options.workspace }] } }),
138
166
  ...(options.cli === undefined ? {} : { cli: options.cli }),
139
167
  ...(options.model === undefined ? {} : { model: options.model }),
140
- // The kernel takes only an absolute cwd; a relative one means the runner's own directory.
141
- ...(options.cwd === undefined ? {} : { cwd: resolve(options.cwd) }),
168
+ ...(declaredCwd === undefined ? {} : { cwd: declaredCwd }),
142
169
  ...(options.transport === undefined ? {} : { transport: options.transport }),
143
170
  ...(verification === undefined ? {} : { verification }),
144
171
  });
@@ -184,13 +211,18 @@ export function authoredWorkerRunner(definition, journal, flowPath, journalSteps
184
211
  */
185
212
  export function authoredDeterministicRunner(name, journal, journalSteps, budget, context = {}) {
186
213
  const rootRunId = context.rootRunId;
187
- return async (id, command, terminal = false, leaseMs, verification) => {
214
+ // One lowering, two readers. `record` changes what the child run's verdict
215
+ // MEANS, so the reader changes with it; everything before the read — spec,
216
+ // admission key, budget, child index — is deliberately shared, because a
217
+ // recorded red command is still an ordinary child run.
218
+ function lower(id, command, terminal, leaseMs, verification, onNonZero, read) {
188
219
  const spec = toKernelSpec(compileSpec({
189
220
  version: SPEC_SCHEMA_VERSION,
190
221
  name: `${name}/${id}`,
191
222
  steps: [{
192
223
  id, type: 'deterministic', command,
193
224
  ...(leaseMs === undefined ? {} : { lease_ms: leaseMs }),
225
+ ...(onNonZero === undefined ? {} : { onNonZero }),
194
226
  ...(verification === undefined ? {} : { verification }),
195
227
  }],
196
228
  }));
@@ -199,12 +231,16 @@ export function authoredDeterministicRunner(name, journal, journalSteps, budget,
199
231
  await recordAuthoredChild(journal, rootRunId, {
200
232
  step: id, runId: outcome.run_id, state: 'admitted', ...context.stepEdges?.(id),
201
233
  });
202
- return readSuccessfulOutput(journal, outcome, id, journalSteps, context);
234
+ return read(outcome);
203
235
  };
204
236
  if (terminal)
205
- return consume(await journal.runStart(spec, undefined, admissionKey));
237
+ return journal.runStart(spec, undefined, admissionKey).then(consume);
206
238
  return budget.execute(journal, spec, consume, admissionKey);
207
- };
239
+ }
240
+ const lowerRun = (id, command, terminal = false, leaseMs, verification) => lower(id, command, terminal, leaseMs, verification, undefined, outcome => readSuccessfulOutput(journal, outcome, id, journalSteps, context));
241
+ /** `f.run(..., { onNonZero: 'record' })`: the exit code is the result, not a throw. */
242
+ lowerRun.recording = (id, command, leaseMs, verification) => lower(id, command, false, leaseMs, verification, 'record', outcome => readRecordedOutcome(journal, outcome, id, journalSteps, context));
243
+ return lowerRun;
208
244
  }
209
245
  /**
210
246
  * Lift the step-shaped fields off a run diagnostic.
@@ -233,6 +269,8 @@ function stepDetails(diagnostic) {
233
269
  ...(found.stderrTail === undefined ? {} : { stderrTail: found.stderrTail }),
234
270
  ...(found.detail === undefined ? {} : { detail: found.detail }),
235
271
  ...(found.transcriptPath === undefined ? {} : { transcriptPath: found.transcriptPath }),
272
+ ...(found.attempts === undefined ? {} : { attempts: found.attempts }),
273
+ ...(found.attemptEvidence === undefined ? {} : { attemptEvidence: found.attemptEvidence }),
236
274
  ...(found.hint === undefined ? {} : { hint: found.hint }),
237
275
  ...(found.journalPath === undefined ? {} : { journalPath: found.journalPath }),
238
276
  };