harnery 0.29.0 → 0.31.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 (512) hide show
  1. package/README.md +4 -4
  2. package/dist/commander.d.ts +8 -0
  3. package/dist/commander.d.ts.map +1 -1
  4. package/dist/commander.js +14 -13
  5. package/dist/commands/adapter.d.ts +12 -0
  6. package/dist/commands/adapter.d.ts.map +1 -0
  7. package/dist/commands/{harness.js → adapter.js} +35 -35
  8. package/dist/commands/agents.d.ts +3 -2
  9. package/dist/commands/agents.d.ts.map +1 -1
  10. package/dist/commands/agents.js +61 -60
  11. package/dist/commands/artifacts.d.ts +4 -0
  12. package/dist/commands/artifacts.d.ts.map +1 -0
  13. package/dist/commands/artifacts.js +143 -0
  14. package/dist/commands/backup.d.ts +1 -1
  15. package/dist/commands/backup.d.ts.map +1 -1
  16. package/dist/commands/backup.js +5 -2
  17. package/dist/commands/browse.d.ts.map +1 -1
  18. package/dist/commands/browse.js +310 -7
  19. package/dist/commands/checkpoint.d.ts +12 -0
  20. package/dist/commands/checkpoint.d.ts.map +1 -0
  21. package/dist/commands/checkpoint.js +162 -0
  22. package/dist/commands/context.d.ts +2 -2
  23. package/dist/commands/context.d.ts.map +1 -1
  24. package/dist/commands/context.js +3 -151
  25. package/dist/commands/decision.d.ts.map +1 -1
  26. package/dist/commands/decision.js +31 -7
  27. package/dist/commands/deinit.d.ts +2 -2
  28. package/dist/commands/deinit.js +15 -15
  29. package/dist/commands/doctor.js +23 -23
  30. package/dist/commands/governor.d.ts +4 -0
  31. package/dist/commands/governor.d.ts.map +1 -0
  32. package/dist/commands/{supervisor.js → governor.js} +133 -108
  33. package/dist/commands/init.d.ts +12 -12
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +44 -30
  36. package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
  37. package/dist/commands/journal.d.ts.map +1 -0
  38. package/dist/commands/{scratch.js → journal.js} +47 -47
  39. package/dist/commands/policy.js +1 -1
  40. package/dist/commands/presence.js +2 -2
  41. package/dist/commands/sync.d.ts +1 -1
  42. package/dist/commands/sync.js +3 -3
  43. package/dist/commands/tunnel.d.ts +16 -0
  44. package/dist/commands/tunnel.d.ts.map +1 -1
  45. package/dist/commands/tunnel.js +193 -23
  46. package/dist/commands/web-fetch.js +1 -1
  47. package/dist/commands/web.d.ts +19 -0
  48. package/dist/commands/web.d.ts.map +1 -1
  49. package/dist/commands/web.js +51 -0
  50. package/dist/commands/work.d.ts +2 -1
  51. package/dist/commands/work.d.ts.map +1 -1
  52. package/dist/commands/work.js +55 -25
  53. package/dist/commands/workflow.d.ts.map +1 -1
  54. package/dist/commands/workflow.js +35 -28
  55. package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
  56. package/dist/core/adapters/attest-projection.d.ts.map +1 -0
  57. package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
  58. package/dist/core/adapters/attest.d.ts.map +1 -0
  59. package/dist/core/{harnesses → adapters}/attest.js +9 -9
  60. package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
  61. package/dist/core/adapters/attestation.d.ts.map +1 -0
  62. package/dist/core/{harnesses → adapters}/attestation.js +20 -20
  63. package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
  64. package/dist/core/adapters/bench.d.ts.map +1 -0
  65. package/dist/core/{harnesses → adapters}/bench.js +12 -12
  66. package/dist/core/adapters/index.d.ts +13 -0
  67. package/dist/core/adapters/index.d.ts.map +1 -0
  68. package/dist/core/adapters/index.js +6 -0
  69. package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
  70. package/dist/core/adapters/profiles.d.ts.map +1 -0
  71. package/dist/core/{harnesses → adapters}/profiles.js +11 -11
  72. package/dist/core/adapters/registry.d.ts +15 -0
  73. package/dist/core/adapters/registry.d.ts.map +1 -0
  74. package/dist/core/{harnesses → adapters}/registry.js +11 -11
  75. package/dist/core/{harnesses → adapters}/types.d.ts +28 -23
  76. package/dist/core/adapters/types.d.ts.map +1 -0
  77. package/dist/core/{harnesses → adapters}/types.js +1 -1
  78. package/dist/core/agents/canonical-emit.d.ts +4 -4
  79. package/dist/core/agents/canonical-emit.js +5 -5
  80. package/dist/core/agents/cli-emit.js +1 -1
  81. package/dist/core/agents/cli.js +30 -26
  82. package/dist/core/agents/codex-replay.d.ts +1 -1
  83. package/dist/core/agents/codex-replay.js +6 -6
  84. package/dist/core/agents/coord-client.d.ts +21 -2
  85. package/dist/core/agents/coord-client.d.ts.map +1 -1
  86. package/dist/core/agents/coord-client.js +122 -27
  87. package/dist/core/agents/events/consume.d.ts +1 -1
  88. package/dist/core/agents/events/emit.d.ts +5 -6
  89. package/dist/core/agents/events/emit.d.ts.map +1 -1
  90. package/dist/core/agents/events/emit.js +2 -2
  91. package/dist/core/agents/render/prompt-context.d.ts +21 -9
  92. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  93. package/dist/core/agents/render/prompt-context.js +82 -30
  94. package/dist/core/agents/render/session-context.d.ts +1 -1
  95. package/dist/core/agents/render/session-context.js +5 -5
  96. package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
  97. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  98. package/dist/core/agents/rules/claim-conflict.js +1 -1
  99. package/dist/core/agents/rules/commit-conflict.js +98 -22
  100. package/dist/core/agents/rules/stop-hook.d.ts +9 -9
  101. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  102. package/dist/core/agents/rules/stop-hook.js +23 -5
  103. package/dist/core/agents/rules/verdict.d.ts +14 -0
  104. package/dist/core/agents/rules/verdict.d.ts.map +1 -0
  105. package/dist/core/agents/rules/verdict.js +1 -0
  106. package/dist/core/agents/session-events.js +3 -3
  107. package/dist/core/agents/state/council.d.ts +1 -1
  108. package/dist/core/agents/state/council.js +1 -1
  109. package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
  110. package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
  111. package/dist/core/agents/state/heartbeat-projector.js +14 -10
  112. package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
  113. package/dist/core/agents/state/heartbeat-writer.js +12 -12
  114. package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
  115. package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
  116. package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
  117. package/dist/core/agents/state/pidmap.d.ts +28 -4
  118. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  119. package/dist/core/agents/state/pidmap.js +130 -15
  120. package/dist/core/agents/state/proc-start.d.ts +95 -0
  121. package/dist/core/agents/state/proc-start.d.ts.map +1 -0
  122. package/dist/core/agents/state/proc-start.js +199 -0
  123. package/dist/core/agents/state/shell-mutation.d.ts +1 -1
  124. package/dist/core/agents/state/shell-mutation.js +1 -1
  125. package/dist/core/agents/state/stale-sweep.js +7 -7
  126. package/dist/core/artifacts/index.d.ts +86 -0
  127. package/dist/core/artifacts/index.d.ts.map +1 -0
  128. package/dist/core/artifacts/index.js +421 -0
  129. package/dist/core/config.d.ts +9 -2
  130. package/dist/core/config.d.ts.map +1 -1
  131. package/dist/core/config.js +26 -2
  132. package/dist/core/context/index.d.ts +12 -12
  133. package/dist/core/context/index.js +10 -10
  134. package/dist/core/governor/adapter-spread.d.ts +52 -0
  135. package/dist/core/governor/adapter-spread.d.ts.map +1 -0
  136. package/dist/core/governor/adapter-spread.js +52 -0
  137. package/dist/core/governor/index.d.ts +7 -0
  138. package/dist/core/governor/index.d.ts.map +1 -0
  139. package/dist/core/governor/index.js +6 -0
  140. package/dist/core/governor/plan-api.d.ts +38 -0
  141. package/dist/core/governor/plan-api.d.ts.map +1 -0
  142. package/dist/core/governor/plan-api.js +83 -0
  143. package/dist/core/governor/plan-read.d.ts +5 -0
  144. package/dist/core/governor/plan-read.d.ts.map +1 -0
  145. package/dist/core/{supervisor → governor}/plan-read.js +71 -51
  146. package/dist/core/governor/plan-types.d.ts +181 -0
  147. package/dist/core/governor/plan-types.d.ts.map +1 -0
  148. package/dist/core/{supervisor → governor}/plan-types.js +4 -4
  149. package/dist/core/governor/planning.d.ts +48 -0
  150. package/dist/core/governor/planning.d.ts.map +1 -0
  151. package/dist/core/{supervisor → governor}/planning.js +143 -94
  152. package/dist/core/governor/read.d.ts +6 -0
  153. package/dist/core/governor/read.d.ts.map +1 -0
  154. package/dist/core/governor/read.js +4 -0
  155. package/dist/core/governor/runner.d.ts +37 -0
  156. package/dist/core/governor/runner.d.ts.map +1 -0
  157. package/dist/core/{supervisor → governor}/runner.js +15 -15
  158. package/dist/core/governor/service-read.d.ts +6 -0
  159. package/dist/core/governor/service-read.d.ts.map +1 -0
  160. package/dist/core/{supervisor → governor}/service-read.js +12 -12
  161. package/dist/core/governor/service.d.ts +114 -0
  162. package/dist/core/governor/service.d.ts.map +1 -0
  163. package/dist/core/{supervisor → governor}/service.js +57 -57
  164. package/dist/core/governor/state.d.ts +116 -0
  165. package/dist/core/governor/state.d.ts.map +1 -0
  166. package/dist/core/{supervisor → governor}/state.js +290 -116
  167. package/dist/core/hooks/adapter/detect.d.ts +9 -0
  168. package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
  169. package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
  170. package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
  171. package/dist/core/hooks/adapter/events.d.ts.map +1 -0
  172. package/dist/core/hooks/{harness → adapter}/events.js +5 -5
  173. package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
  174. package/dist/core/hooks/adapter/output.d.ts.map +1 -0
  175. package/dist/core/hooks/{harness → adapter}/output.js +30 -22
  176. package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
  177. package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
  178. package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
  179. package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
  180. package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
  181. package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
  182. package/dist/core/hooks/cli.d.ts +3 -3
  183. package/dist/core/hooks/cli.js +175 -151
  184. package/dist/core/hooks/effects/image-capture.d.ts +5 -5
  185. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  186. package/dist/core/hooks/effects/image-capture.js +3 -3
  187. package/dist/core/hooks/effects/index.d.ts +12 -12
  188. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  189. package/dist/core/hooks/effects/index.js +17 -17
  190. package/dist/core/hooks/events/emit.d.ts +2 -2
  191. package/dist/core/hooks/events/emit.d.ts.map +1 -1
  192. package/dist/core/hooks/events/emit.js +1 -1
  193. package/dist/core/hooks/events/rotate.js +1 -1
  194. package/dist/core/hooks/events/schema.d.ts +13 -5
  195. package/dist/core/hooks/events/schema.d.ts.map +1 -1
  196. package/dist/core/hooks/guard-path.d.ts +2 -2
  197. package/dist/core/hooks/guard-path.js +2 -2
  198. package/dist/core/hooks/index.d.ts +1 -1
  199. package/dist/core/hooks/index.d.ts.map +1 -1
  200. package/dist/core/hooks/resolve/anchor.d.ts +14 -5
  201. package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
  202. package/dist/core/hooks/resolve/anchor.js +64 -7
  203. package/dist/core/hooks/resolve/coord-root.d.ts +3 -3
  204. package/dist/core/hooks/resolve/coord-root.js +4 -4
  205. package/dist/core/hooks/resolve/intent.js +1 -1
  206. package/dist/core/hooks/resolve/owner.d.ts +1 -1
  207. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  208. package/dist/core/hooks/resolve/owner.js +11 -5
  209. package/dist/core/{scratch → journal}/index.d.ts +25 -25
  210. package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
  211. package/dist/core/{scratch → journal}/index.js +38 -38
  212. package/dist/core/policy/evaluate.d.ts +1 -1
  213. package/dist/core/policy/evaluate.d.ts.map +1 -1
  214. package/dist/core/policy/evaluate.js +7 -7
  215. package/dist/core/policy/types.d.ts +3 -3
  216. package/dist/core/policy/types.d.ts.map +1 -1
  217. package/dist/core/work/runner.d.ts.map +1 -1
  218. package/dist/core/work/runner.js +11 -2
  219. package/dist/core/work/state.d.ts +28 -3
  220. package/dist/core/work/state.d.ts.map +1 -1
  221. package/dist/core/work/state.js +148 -16
  222. package/dist/core/workflow/adapters.d.ts +17 -0
  223. package/dist/core/workflow/adapters.d.ts.map +1 -0
  224. package/dist/core/workflow/adapters.js +21 -0
  225. package/dist/core/workflow/approvals.js +6 -6
  226. package/dist/core/workflow/billing.d.ts +9 -9
  227. package/dist/core/workflow/billing.js +9 -9
  228. package/dist/core/workflow/child-env.d.ts +10 -2
  229. package/dist/core/workflow/child-env.d.ts.map +1 -1
  230. package/dist/core/workflow/child-env.js +12 -4
  231. package/dist/core/workflow/engine.d.ts +15 -5
  232. package/dist/core/workflow/engine.d.ts.map +1 -1
  233. package/dist/core/workflow/engine.js +151 -83
  234. package/dist/core/workflow/evidence-preflight.d.ts +24 -0
  235. package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
  236. package/dist/core/workflow/evidence-preflight.js +134 -0
  237. package/dist/core/workflow/index.d.ts +3 -2
  238. package/dist/core/workflow/index.d.ts.map +1 -1
  239. package/dist/core/workflow/index.js +2 -1
  240. package/dist/core/workflow/proof.d.ts +28 -5
  241. package/dist/core/workflow/proof.d.ts.map +1 -1
  242. package/dist/core/workflow/proof.js +77 -34
  243. package/dist/core/workflow/run-state.d.ts +1 -1
  244. package/dist/core/workflow/run-state.js +7 -7
  245. package/dist/core/workflow/sandbox-projection.d.ts +6 -6
  246. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  247. package/dist/core/workflow/sandbox-projection.js +11 -11
  248. package/dist/core/workflow/spawn-claude.d.ts +3 -3
  249. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  250. package/dist/core/workflow/spawn-claude.js +28 -8
  251. package/dist/core/workflow/spawn-codex.d.ts +4 -4
  252. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  253. package/dist/core/workflow/spawn-codex.js +26 -8
  254. package/dist/core/workflow/spawn-cursor.d.ts +4 -4
  255. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  256. package/dist/core/workflow/spawn-cursor.js +27 -8
  257. package/dist/core/workflow/spawn-failure.d.ts +15 -1
  258. package/dist/core/workflow/spawn-failure.d.ts.map +1 -1
  259. package/dist/core/workflow/spawn-failure.js +35 -1
  260. package/dist/core/workflow/specialists.js +2 -2
  261. package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
  262. package/dist/core/workflow/transcript.d.ts.map +1 -0
  263. package/dist/core/workflow/{journal.js → transcript.js} +14 -14
  264. package/dist/core/workflow/types.d.ts +119 -46
  265. package/dist/core/workflow/types.d.ts.map +1 -1
  266. package/dist/core/workflow/types.js +11 -1
  267. package/dist/core/workflow/validate.d.ts +1 -1
  268. package/dist/core/workflow/validate.js +1 -1
  269. package/dist/core/workflow/workspaces/cancellation.js +2 -2
  270. package/dist/core/workflow/workspaces/cleanup.js +2 -2
  271. package/dist/core/workflow/workspaces/execution.js +6 -6
  272. package/dist/core/workflow/workspaces/inspect.js +9 -9
  273. package/dist/core/workflow/workspaces/integration.js +14 -14
  274. package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
  275. package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
  276. package/dist/core/workflow/workspaces/lifecycle.js +9 -9
  277. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  278. package/dist/core/workflow/workspaces/local-git.js +39 -5
  279. package/dist/core/workflow/workspaces/recovery.js +3 -3
  280. package/dist/core/workflow/workspaces/state.d.ts +1 -1
  281. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  282. package/dist/core/workflow/workspaces/state.js +3 -3
  283. package/dist/core/workflow/workspaces/types.d.ts +1 -1
  284. package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
  285. package/dist/lib/browser/asserts.d.ts +28 -0
  286. package/dist/lib/browser/asserts.d.ts.map +1 -0
  287. package/dist/lib/browser/asserts.js +152 -0
  288. package/dist/lib/browser/client.d.ts +49 -0
  289. package/dist/lib/browser/client.d.ts.map +1 -1
  290. package/dist/lib/browser/client.js +155 -14
  291. package/dist/lib/browser/content-checks.d.ts +108 -0
  292. package/dist/lib/browser/content-checks.d.ts.map +1 -0
  293. package/dist/lib/browser/content-checks.js +474 -0
  294. package/dist/lib/browser/critique.d.ts +91 -0
  295. package/dist/lib/browser/critique.d.ts.map +1 -0
  296. package/dist/lib/browser/critique.js +167 -0
  297. package/dist/lib/browser/geometry.d.ts +32 -0
  298. package/dist/lib/browser/geometry.d.ts.map +1 -1
  299. package/dist/lib/browser/geometry.js +244 -1
  300. package/dist/lib/browser/index.d.ts +4 -1
  301. package/dist/lib/browser/index.d.ts.map +1 -1
  302. package/dist/lib/browser/index.js +2 -0
  303. package/dist/lib/claude-desktop.d.ts.map +1 -1
  304. package/dist/lib/claude-desktop.js +4 -1
  305. package/dist/lib/council/index.d.ts +6 -6
  306. package/dist/lib/council/index.d.ts.map +1 -1
  307. package/dist/lib/council/index.js +8 -8
  308. package/dist/lib/exec.d.ts +7 -0
  309. package/dist/lib/exec.d.ts.map +1 -1
  310. package/dist/lib/exec.js +6 -3
  311. package/dist/lib/identities/assume.d.ts +2 -2
  312. package/dist/lib/identities/assume.js +7 -7
  313. package/dist/lib/instructions/apply.d.ts +3 -3
  314. package/dist/lib/instructions/apply.d.ts.map +1 -1
  315. package/dist/lib/instructions/apply.js +75 -27
  316. package/dist/lib/instructions/host-addendum.d.ts +54 -0
  317. package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
  318. package/dist/lib/instructions/host-addendum.js +107 -0
  319. package/dist/lib/instructions/templates.d.ts +10 -3
  320. package/dist/lib/instructions/templates.d.ts.map +1 -1
  321. package/dist/lib/instructions/templates.js +41 -12
  322. package/dist/lib/machine.d.ts +2 -2
  323. package/dist/lib/machine.js +2 -2
  324. package/package.json +26 -21
  325. package/schemas/config.schema.json +26 -1
  326. package/src/commander.ts +22 -13
  327. package/src/commands/{harness.ts → adapter.ts} +46 -46
  328. package/src/commands/agents.ts +71 -64
  329. package/src/commands/artifacts.ts +168 -0
  330. package/src/commands/backup.ts +47 -33
  331. package/src/commands/browse.ts +438 -2
  332. package/src/commands/checkpoint.ts +196 -0
  333. package/src/commands/context.ts +3 -176
  334. package/src/commands/decision.ts +41 -7
  335. package/src/commands/deinit.ts +16 -16
  336. package/src/commands/doctor.ts +28 -28
  337. package/src/commands/{supervisor.ts → governor.ts} +184 -154
  338. package/src/commands/init.ts +50 -34
  339. package/src/commands/{scratch.ts → journal.ts} +60 -60
  340. package/src/commands/policy.ts +1 -1
  341. package/src/commands/presence.ts +2 -2
  342. package/src/commands/sync.ts +3 -3
  343. package/src/commands/tunnel.ts +237 -34
  344. package/src/commands/web-fetch.ts +1 -1
  345. package/src/commands/web.ts +56 -1
  346. package/src/commands/work.ts +72 -38
  347. package/src/commands/workflow.ts +43 -34
  348. package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
  349. package/src/core/{harnesses → adapters}/attest.ts +27 -27
  350. package/src/core/{harnesses → adapters}/attestation.ts +41 -41
  351. package/src/core/{harnesses → adapters}/bench.ts +34 -43
  352. package/src/core/adapters/index.ts +56 -0
  353. package/src/core/{harnesses → adapters}/profiles.ts +16 -16
  354. package/src/core/{harnesses → adapters}/registry.ts +23 -23
  355. package/src/core/{harnesses → adapters}/types.ts +28 -23
  356. package/src/core/agents/canonical-emit.ts +6 -6
  357. package/src/core/agents/cli-emit.ts +1 -1
  358. package/src/core/agents/cli.ts +30 -28
  359. package/src/core/agents/codex-replay.ts +6 -6
  360. package/src/core/agents/coord-client.ts +119 -28
  361. package/src/core/agents/events/consume.ts +1 -1
  362. package/src/core/agents/events/emit.ts +7 -6
  363. package/src/core/agents/render/prompt-context.ts +107 -31
  364. package/src/core/agents/render/session-context.ts +6 -6
  365. package/src/core/agents/rules/claim-conflict.ts +4 -7
  366. package/src/core/agents/rules/commit-conflict.ts +103 -22
  367. package/src/core/agents/rules/stop-hook.ts +33 -17
  368. package/src/core/agents/rules/verdict.ts +13 -0
  369. package/src/core/agents/session-events.ts +4 -4
  370. package/src/core/agents/state/council.ts +1 -1
  371. package/src/core/agents/state/heartbeat-projector.ts +16 -12
  372. package/src/core/agents/state/heartbeat-writer.ts +12 -12
  373. package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
  374. package/src/core/agents/state/pidmap.ts +130 -15
  375. package/src/core/agents/state/proc-start.ts +208 -0
  376. package/src/core/agents/state/shell-mutation.ts +1 -1
  377. package/src/core/agents/state/stale-sweep.ts +7 -7
  378. package/src/core/artifacts/index.ts +557 -0
  379. package/src/core/config.ts +30 -2
  380. package/src/core/context/index.ts +15 -15
  381. package/src/core/governor/adapter-spread.ts +82 -0
  382. package/src/core/governor/index.ts +91 -0
  383. package/src/core/governor/plan-api.ts +115 -0
  384. package/src/core/{supervisor → governor}/plan-read.ts +120 -96
  385. package/src/core/{supervisor → governor}/plan-types.ts +64 -50
  386. package/src/core/{supervisor → governor}/planning.ts +240 -188
  387. package/src/core/governor/read.ts +59 -0
  388. package/src/core/{supervisor → governor}/runner.ts +39 -39
  389. package/src/core/{supervisor → governor}/service-read.ts +22 -22
  390. package/src/core/{supervisor → governor}/service.ts +117 -119
  391. package/src/core/{supervisor → governor}/state.ts +389 -174
  392. package/src/core/hooks/adapter/detect.ts +30 -0
  393. package/src/core/hooks/{harness → adapter}/events.ts +16 -14
  394. package/src/core/hooks/{harness → adapter}/output.ts +31 -23
  395. package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
  396. package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
  397. package/src/core/hooks/cli.ts +185 -162
  398. package/src/core/hooks/effects/image-capture.ts +6 -6
  399. package/src/core/hooks/effects/index.ts +17 -17
  400. package/src/core/hooks/events/emit.ts +3 -3
  401. package/src/core/hooks/events/rotate.ts +1 -1
  402. package/src/core/hooks/events/schema.ts +15 -7
  403. package/src/core/hooks/guard-path.ts +2 -2
  404. package/src/core/hooks/index.ts +1 -1
  405. package/src/core/hooks/resolve/anchor.ts +63 -8
  406. package/src/core/hooks/resolve/coord-root.ts +4 -4
  407. package/src/core/hooks/resolve/intent.ts +1 -1
  408. package/src/core/hooks/resolve/owner.ts +11 -5
  409. package/src/core/{scratch → journal}/index.ts +53 -53
  410. package/src/core/policy/evaluate.ts +8 -8
  411. package/src/core/policy/types.ts +3 -3
  412. package/src/core/work/runner.ts +11 -2
  413. package/src/core/work/state.ts +185 -21
  414. package/src/core/workflow/adapters.ts +33 -0
  415. package/src/core/workflow/approvals.ts +7 -7
  416. package/src/core/workflow/billing.ts +12 -12
  417. package/src/core/workflow/child-env.ts +13 -4
  418. package/src/core/workflow/engine.ts +166 -90
  419. package/src/core/workflow/evidence-preflight.ts +165 -0
  420. package/src/core/workflow/index.ts +6 -3
  421. package/src/core/workflow/proof.ts +94 -48
  422. package/src/core/workflow/run-state.ts +7 -7
  423. package/src/core/workflow/sandbox-projection.ts +16 -16
  424. package/src/core/workflow/spawn-claude.ts +34 -12
  425. package/src/core/workflow/spawn-codex.ts +30 -12
  426. package/src/core/workflow/spawn-cursor.ts +31 -12
  427. package/src/core/workflow/spawn-failure.ts +41 -1
  428. package/src/core/workflow/specialists.ts +2 -2
  429. package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
  430. package/src/core/workflow/types.ts +130 -46
  431. package/src/core/workflow/validate.ts +1 -1
  432. package/src/core/workflow/workspaces/cancellation.ts +2 -2
  433. package/src/core/workflow/workspaces/cleanup.ts +2 -2
  434. package/src/core/workflow/workspaces/execution.ts +6 -6
  435. package/src/core/workflow/workspaces/inspect.ts +14 -11
  436. package/src/core/workflow/workspaces/integration.ts +18 -14
  437. package/src/core/workflow/workspaces/lifecycle.ts +10 -10
  438. package/src/core/workflow/workspaces/local-git.ts +47 -5
  439. package/src/core/workflow/workspaces/recovery.ts +3 -3
  440. package/src/core/workflow/workspaces/state.ts +4 -3
  441. package/src/core/workflow/workspaces/types.ts +1 -1
  442. package/src/lib/browser/asserts.ts +177 -0
  443. package/src/lib/browser/client.ts +189 -14
  444. package/src/lib/browser/content-checks.ts +571 -0
  445. package/src/lib/browser/critique.ts +231 -0
  446. package/src/lib/browser/geometry.ts +297 -1
  447. package/src/lib/browser/index.ts +34 -0
  448. package/src/lib/claude-desktop.ts +4 -1
  449. package/src/lib/council/index.ts +9 -9
  450. package/src/lib/exec.ts +13 -3
  451. package/src/lib/identities/assume.ts +7 -7
  452. package/src/lib/instructions/apply.ts +87 -25
  453. package/src/lib/instructions/host-addendum.ts +126 -0
  454. package/src/lib/instructions/templates.ts +44 -15
  455. package/src/lib/machine.ts +2 -2
  456. package/dist/commands/harness.d.ts +0 -12
  457. package/dist/commands/harness.d.ts.map +0 -1
  458. package/dist/commands/scratch.d.ts +0 -4
  459. package/dist/commands/scratch.d.ts.map +0 -1
  460. package/dist/commands/session.d.ts.map +0 -1
  461. package/dist/commands/session.js +0 -162
  462. package/dist/commands/supervisor.d.ts +0 -4
  463. package/dist/commands/supervisor.d.ts.map +0 -1
  464. package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
  465. package/dist/core/harnesses/attest.d.ts.map +0 -1
  466. package/dist/core/harnesses/attestation.d.ts.map +0 -1
  467. package/dist/core/harnesses/bench.d.ts.map +0 -1
  468. package/dist/core/harnesses/index.d.ts +0 -13
  469. package/dist/core/harnesses/index.d.ts.map +0 -1
  470. package/dist/core/harnesses/index.js +0 -6
  471. package/dist/core/harnesses/profiles.d.ts.map +0 -1
  472. package/dist/core/harnesses/registry.d.ts +0 -15
  473. package/dist/core/harnesses/registry.d.ts.map +0 -1
  474. package/dist/core/harnesses/types.d.ts.map +0 -1
  475. package/dist/core/hooks/harness/detect.d.ts +0 -9
  476. package/dist/core/hooks/harness/events.d.ts.map +0 -1
  477. package/dist/core/hooks/harness/output.d.ts.map +0 -1
  478. package/dist/core/supervisor/index.d.ts +0 -7
  479. package/dist/core/supervisor/index.d.ts.map +0 -1
  480. package/dist/core/supervisor/index.js +0 -6
  481. package/dist/core/supervisor/plan-api.d.ts +0 -23
  482. package/dist/core/supervisor/plan-api.d.ts.map +0 -1
  483. package/dist/core/supervisor/plan-api.js +0 -50
  484. package/dist/core/supervisor/plan-read.d.ts +0 -5
  485. package/dist/core/supervisor/plan-read.d.ts.map +0 -1
  486. package/dist/core/supervisor/plan-types.d.ts +0 -170
  487. package/dist/core/supervisor/plan-types.d.ts.map +0 -1
  488. package/dist/core/supervisor/planning.d.ts +0 -33
  489. package/dist/core/supervisor/planning.d.ts.map +0 -1
  490. package/dist/core/supervisor/read.d.ts +0 -6
  491. package/dist/core/supervisor/read.d.ts.map +0 -1
  492. package/dist/core/supervisor/read.js +0 -4
  493. package/dist/core/supervisor/runner.d.ts +0 -37
  494. package/dist/core/supervisor/runner.d.ts.map +0 -1
  495. package/dist/core/supervisor/service-read.d.ts +0 -6
  496. package/dist/core/supervisor/service-read.d.ts.map +0 -1
  497. package/dist/core/supervisor/service.d.ts +0 -114
  498. package/dist/core/supervisor/service.d.ts.map +0 -1
  499. package/dist/core/supervisor/state.d.ts +0 -95
  500. package/dist/core/supervisor/state.d.ts.map +0 -1
  501. package/dist/core/workflow/harnesses.d.ts +0 -17
  502. package/dist/core/workflow/harnesses.d.ts.map +0 -1
  503. package/dist/core/workflow/harnesses.js +0 -21
  504. package/dist/core/workflow/journal.d.ts.map +0 -1
  505. package/src/commands/session.ts +0 -187
  506. package/src/core/harnesses/index.ts +0 -56
  507. package/src/core/hooks/harness/detect.ts +0 -30
  508. package/src/core/supervisor/index.ts +0 -89
  509. package/src/core/supervisor/plan-api.ts +0 -73
  510. package/src/core/supervisor/read.ts +0 -59
  511. package/src/core/workflow/harnesses.ts +0 -33
  512. /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Project the host's filesystem policy into a harness's own vendor sandbox
2
+ * Project the host's filesystem policy into a adapter's own vendor sandbox
3
3
  * (ADR 0039).
4
4
  *
5
5
  * Harnery decides where a workflow child may write. Until this existed it never
@@ -14,12 +14,12 @@
14
14
  * not, which is worse than refusing and worse than never offering the feature.
15
15
  */
16
16
  export class SandboxProjectionError extends Error {
17
- harness;
17
+ adapter;
18
18
  reason;
19
- constructor(harness, reason, message) {
19
+ constructor(adapter, reason, message) {
20
20
  super(message);
21
21
  this.name = "SandboxProjectionError";
22
- this.harness = harness;
22
+ this.adapter = adapter;
23
23
  this.reason = reason;
24
24
  }
25
25
  }
@@ -27,23 +27,23 @@ export class SandboxProjectionError extends Error {
27
27
  * Resolve a requested policy against what the adapter declares it can carry.
28
28
  * Throws rather than degrading; see the module note.
29
29
  */
30
- export function resolveSandboxProjection(harness, declaration, policy) {
30
+ export function resolveSandboxProjection(adapter, declaration, policy) {
31
31
  if (!declaration) {
32
- throw new SandboxProjectionError(harness, "no_projection", `${harness} cannot project a filesystem policy into its sandbox; remove the policy or use a harness that can`);
32
+ throw new SandboxProjectionError(adapter, "no_projection", `${adapter} cannot project a filesystem policy into its sandbox; remove the policy or use a adapter that can`);
33
33
  }
34
34
  const nativeMode = declaration.modes[policy.mode];
35
35
  if (!nativeMode) {
36
- throw new SandboxProjectionError(harness, "mode_unrepresentable", `${harness} does not distinguish the "${policy.mode}" filesystem mode, so it cannot be enforced`);
36
+ throw new SandboxProjectionError(adapter, "mode_unrepresentable", `${adapter} does not distinguish the "${policy.mode}" filesystem mode, so it cannot be enforced`);
37
37
  }
38
38
  const writableRoots = policy.writableRoots ?? [];
39
39
  if (writableRoots.length > 0 && !declaration.writableRoots) {
40
- throw new SandboxProjectionError(harness, "writable_roots_unrepresentable", `${harness} does not accept an explicit writable-root set, so ${writableRoots.length} declared path(s) could not be enforced`);
40
+ throw new SandboxProjectionError(adapter, "writable_roots_unrepresentable", `${adapter} does not accept an explicit writable-root set, so ${writableRoots.length} declared path(s) could not be enforced`);
41
41
  }
42
42
  for (const root of writableRoots) {
43
43
  // Relative paths cannot be validated against the provider's roots and are
44
44
  // resolved differently by every vendor, so they are refused outright.
45
45
  if (typeof root !== "string" || !root.startsWith("/")) {
46
- throw new SandboxProjectionError(harness, "writable_roots_unrepresentable", `writable root ${JSON.stringify(root)} must be an absolute path`);
46
+ throw new SandboxProjectionError(adapter, "writable_roots_unrepresentable", `writable root ${JSON.stringify(root)} must be an absolute path`);
47
47
  }
48
48
  }
49
49
  return { nativeMode, writableRoots };
@@ -62,10 +62,10 @@ function isWithin(root, candidate) {
62
62
  * the provider never sanctioned would let a projection quietly widen the blast
63
63
  * radius of a run that the workspace lifecycle believes it has contained.
64
64
  */
65
- export function assertProjectionWithinWorkspace(harness, allowedRootRealpath, writableRoots) {
65
+ export function assertProjectionWithinWorkspace(adapter, allowedRootRealpath, writableRoots) {
66
66
  for (const root of writableRoots) {
67
67
  if (!isWithin(allowedRootRealpath, root)) {
68
- throw new SandboxProjectionError(harness, "writable_root_escapes_workspace", `writable root ${JSON.stringify(root)} is outside the workspace root ${JSON.stringify(allowedRootRealpath)} the provider validated`);
68
+ throw new SandboxProjectionError(adapter, "writable_root_escapes_workspace", `writable root ${JSON.stringify(root)} is outside the workspace root ${JSON.stringify(allowedRootRealpath)} the provider validated`);
69
69
  }
70
70
  }
71
71
  }
@@ -17,9 +17,9 @@
17
17
  * gets HARNERY_WORKFLOW_CHILD=1 and the stop-hook rule exempts it
18
18
  * (stop-hook.ts), keeping heartbeats + events on.
19
19
  */
20
- import type { HarnessInvocation, HarnessRawResult } from "../harnesses/types.js";
20
+ import type { AdapterInvocation, AdapterRawResult } from "../adapters/types.js";
21
21
  import type { Spawner, SpawnRequest, SpawnResult } from "./types.js";
22
- export declare function buildClaudeInvocation(req: SpawnRequest): HarnessInvocation;
23
- export declare function normalizeClaudeResult(raw: HarnessRawResult): SpawnResult;
22
+ export declare function buildClaudeInvocation(req: SpawnRequest): AdapterInvocation;
23
+ export declare function normalizeClaudeResult(raw: AdapterRawResult): SpawnResult;
24
24
  export declare const claudeCodeSpawner: Spawner;
25
25
  //# sourceMappingURL=spawn-claude.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spawn-claude.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAKjF,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAYrE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CAsB1E;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,CAwDxE;AAED,eAAO,MAAM,iBAAiB,EAAE,OAc/B,CAAC"}
1
+ {"version":3,"file":"spawn-claude.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAKhF,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAYrE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CAsB1E;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,CA2ExE;AAED,eAAO,MAAM,iBAAiB,EAAE,OAiB/B,CAAC"}
@@ -18,16 +18,16 @@
18
18
  * (stop-hook.ts), keeping heartbeats + events on.
19
19
  */
20
20
  import { exec } from "../../lib/exec.js";
21
- import { builtinHarnessProfile, validateHarnessEffort } from "../harnesses/profiles.js";
21
+ import { builtinAdapterProfile, validateAdapterEffort } from "../adapters/profiles.js";
22
+ import { notFoundError } from "./adapters.js";
22
23
  import { buildChildEnv } from "./child-env.js";
23
- import { notFoundError } from "./harnesses.js";
24
24
  import { resolveSandboxProjection } from "./sandbox-projection.js";
25
- import { vendorFailureText } from "./spawn-failure.js";
25
+ import { isUpstreamFailureText, vendorFailureText } from "./spawn-failure.js";
26
26
  export function buildClaudeInvocation(req) {
27
- validateHarnessEffort("claude-code", req.effort);
27
+ validateAdapterEffort("claude-code", req.effort);
28
28
  if (req.filesystemPolicy) {
29
29
  // Declared unrepresentable: refuse rather than drop it silently (ADR 0039).
30
- resolveSandboxProjection("claude-code", builtinHarnessProfile("claude-code")?.sandboxProjection, req.filesystemPolicy);
30
+ resolveSandboxProjection("claude-code", builtinAdapterProfile("claude-code")?.sandboxProjection, req.filesystemPolicy);
31
31
  }
32
32
  const argv = [
33
33
  "claude",
@@ -53,7 +53,20 @@ export function normalizeClaudeResult(raw) {
53
53
  error: `claude timed out after ${raw.durationMs}ms and was killed`,
54
54
  };
55
55
  }
56
+ // Structural environment signal: the binary was never there (spawned directly,
57
+ // so a missing binary surfaces as ENOENT). Uncharged and not retried.
58
+ if (raw.spawnErrno === "ENOENT") {
59
+ return {
60
+ ok: false,
61
+ text: "",
62
+ durationMs: raw.durationMs,
63
+ error: notFoundError("claude-code"),
64
+ class: "environment",
65
+ };
66
+ }
56
67
  if (raw.exitCode === 127) {
68
+ // A bare 127 with no errno is a shell/vendor 127, indistinguishable from a
69
+ // legitimate one — charged as work rather than classed environment.
57
70
  return {
58
71
  ok: false,
59
72
  text: "",
@@ -62,11 +75,13 @@ export function normalizeClaudeResult(raw) {
62
75
  };
63
76
  }
64
77
  if (raw.exitCode !== 0) {
78
+ const failureText = vendorFailureText(raw);
65
79
  return {
66
80
  ok: false,
67
81
  text: "",
68
82
  durationMs: raw.durationMs,
69
- error: `claude exited ${raw.exitCode}: ${vendorFailureText(raw)}`,
83
+ error: `claude exited ${raw.exitCode}: ${failureText}`,
84
+ ...(isUpstreamFailureText(failureText) ? { class: "upstream" } : {}),
70
85
  };
71
86
  }
72
87
  let envelope;
@@ -82,13 +97,15 @@ export function normalizeClaudeResult(raw) {
82
97
  };
83
98
  }
84
99
  if (envelope.is_error) {
100
+ const envelopeError = `${envelope.subtype ?? ""} ${(envelope.errors ?? []).join("; ")} ${String(envelope.result ?? "")}`;
85
101
  return {
86
102
  ok: false,
87
103
  text: String(envelope.result ?? ""),
88
104
  sessionId: envelope.session_id,
89
105
  costUsd: envelope.total_cost_usd,
90
106
  durationMs: raw.durationMs,
91
- error: `harness error (${envelope.subtype ?? "unknown"}): ${(envelope.errors ?? []).join("; ") || "see envelope"}`,
107
+ error: `adapter error (${envelope.subtype ?? "unknown"}): ${(envelope.errors ?? []).join("; ") || "see envelope"}`,
108
+ ...(isUpstreamFailureText(envelopeError) ? { class: "upstream" } : {}),
92
109
  };
93
110
  }
94
111
  return {
@@ -110,7 +127,10 @@ export const claudeCodeSpawner = async (req) => {
110
127
  }
111
128
  const r = await exec(invocation.argv, {
112
129
  cwd: req.cwd,
113
- env: buildChildEnv(req.runId, { subscriptionOnly: req.subscriptionOnly }),
130
+ env: buildChildEnv(req.runId, {
131
+ subscriptionOnly: req.subscriptionOnly,
132
+ agentId: req.agentId,
133
+ }),
114
134
  timeout: req.timeoutMs,
115
135
  });
116
136
  return normalizeClaudeResult({ ...r, durationMs: Date.now() - t0 });
@@ -3,7 +3,7 @@
3
3
  * subprocess.
4
4
  *
5
5
  * Contract notes (LIVE-VERIFIED 2026-07-16 against codex-cli 0.144.5: flags
6
- * present, schema-gated triage + text stages round-trip via `--harness codex`):
6
+ * present, schema-gated triage + text stages round-trip via `--adapter codex`):
7
7
  * - `codex exec "<prompt>"` is the non-interactive mode.
8
8
  * - The final assistant message is captured via `--output-last-message <file>`
9
9
  * (a temp file), which is far more drift-tolerant than parsing the
@@ -14,9 +14,9 @@
14
14
  * - No max-turns equivalent → `maxTurns` is accepted and ignored (documented
15
15
  * in the CLI docs page).
16
16
  */
17
- import type { HarnessInvocation, HarnessRawResult } from "../harnesses/types.js";
17
+ import type { AdapterInvocation, AdapterRawResult } from "../adapters/types.js";
18
18
  import type { Spawner, SpawnRequest, SpawnResult } from "./types.js";
19
- export declare function buildCodexInvocation(req: SpawnRequest, resultFile?: string): HarnessInvocation;
20
- export declare function normalizeCodexResult(raw: HarnessRawResult): SpawnResult;
19
+ export declare function buildCodexInvocation(req: SpawnRequest, resultFile?: string): AdapterInvocation;
20
+ export declare function normalizeCodexResult(raw: AdapterRawResult): SpawnResult;
21
21
  export declare const codexSpawner: Spawner;
22
22
  //# sourceMappingURL=spawn-codex.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spawn-codex.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAQH,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAKjF,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAErE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,iBAAiB,CA8B9F;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,CAyBvE;AAED,eAAO,MAAM,YAAY,EAAE,OA2B1B,CAAC"}
1
+ {"version":3,"file":"spawn-codex.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAQH,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAKhF,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAErE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,iBAAiB,CA8B9F;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,CAwCvE;AAED,eAAO,MAAM,YAAY,EAAE,OA8B1B,CAAC"}
@@ -3,7 +3,7 @@
3
3
  * subprocess.
4
4
  *
5
5
  * Contract notes (LIVE-VERIFIED 2026-07-16 against codex-cli 0.144.5: flags
6
- * present, schema-gated triage + text stages round-trip via `--harness codex`):
6
+ * present, schema-gated triage + text stages round-trip via `--adapter codex`):
7
7
  * - `codex exec "<prompt>"` is the non-interactive mode.
8
8
  * - The final assistant message is captured via `--output-last-message <file>`
9
9
  * (a temp file), which is far more drift-tolerant than parsing the
@@ -19,18 +19,18 @@ import { existsSync, readFileSync, rmSync } from "node:fs";
19
19
  import { tmpdir } from "node:os";
20
20
  import { join } from "node:path";
21
21
  import { exec } from "../../lib/exec.js";
22
- import { builtinHarnessProfile, validateHarnessEffort } from "../harnesses/profiles.js";
22
+ import { builtinAdapterProfile, validateAdapterEffort } from "../adapters/profiles.js";
23
+ import { notFoundError } from "./adapters.js";
23
24
  import { buildChildEnv } from "./child-env.js";
24
- import { notFoundError } from "./harnesses.js";
25
25
  import { resolveSandboxProjection } from "./sandbox-projection.js";
26
- import { vendorFailureText } from "./spawn-failure.js";
26
+ import { isUpstreamFailureText, vendorFailureText } from "./spawn-failure.js";
27
27
  export function buildCodexInvocation(req, resultFile) {
28
- validateHarnessEffort("codex", req.effort);
28
+ validateAdapterEffort("codex", req.effort);
29
29
  if (!resultFile)
30
30
  throw new Error("codex adapter requires a final-message result file");
31
31
  // Default stays workspace-write so an unprojected request is unchanged.
32
32
  const projection = req.filesystemPolicy
33
- ? resolveSandboxProjection("codex", builtinHarnessProfile("codex")?.sandboxProjection, req.filesystemPolicy)
33
+ ? resolveSandboxProjection("codex", builtinAdapterProfile("codex")?.sandboxProjection, req.filesystemPolicy)
34
34
  : undefined;
35
35
  const argv = [
36
36
  "codex",
@@ -60,15 +60,30 @@ export function normalizeCodexResult(raw) {
60
60
  error: `codex timed out after ${raw.durationMs}ms and was killed`,
61
61
  };
62
62
  }
63
+ // Structural environment signal: the binary was never there (spawned directly,
64
+ // so a missing binary surfaces as ENOENT). Uncharged and not retried.
65
+ if (raw.spawnErrno === "ENOENT") {
66
+ return {
67
+ ok: false,
68
+ text: "",
69
+ durationMs: raw.durationMs,
70
+ error: notFoundError("codex"),
71
+ class: "environment",
72
+ };
73
+ }
63
74
  if (raw.exitCode === 127) {
75
+ // A bare 127 with no errno is a shell/vendor 127, indistinguishable from a
76
+ // legitimate one — charged as work rather than classed environment.
64
77
  return { ok: false, text: "", durationMs: raw.durationMs, error: notFoundError("codex") };
65
78
  }
66
79
  if (raw.exitCode !== 0) {
80
+ const failureText = vendorFailureText(raw);
67
81
  return {
68
82
  ok: false,
69
83
  text: "",
70
84
  durationMs: raw.durationMs,
71
- error: `codex exited ${raw.exitCode}: ${vendorFailureText(raw)}`,
85
+ error: `codex exited ${raw.exitCode}: ${failureText}`,
86
+ ...(isUpstreamFailureText(failureText) ? { class: "upstream" } : {}),
72
87
  };
73
88
  }
74
89
  return {
@@ -90,7 +105,10 @@ export const codexSpawner = async (req) => {
90
105
  }
91
106
  const r = await exec(invocation.argv, {
92
107
  cwd: req.cwd,
93
- env: buildChildEnv(req.runId, { subscriptionOnly: req.subscriptionOnly }),
108
+ env: buildChildEnv(req.runId, {
109
+ subscriptionOnly: req.subscriptionOnly,
110
+ agentId: req.agentId,
111
+ }),
94
112
  timeout: req.timeoutMs,
95
113
  });
96
114
  return normalizeCodexResult({
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Contract notes (LIVE-VERIFIED 2026-07-17 against cursor-agent
6
6
  * 2026.07.16-899851b: schema-gated triage + text stages round-trip via
7
- * `--harness cursor`, session_id parses from the envelope):
7
+ * `--adapter cursor`, session_id parses from the envelope):
8
8
  * - `cursor-agent -p "<prompt>" --output-format json` prints a single result
9
9
  * envelope modeled on Claude Code's (`{type: "result", is_error, result,
10
10
  * session_id, …}`).
@@ -18,7 +18,7 @@
18
18
  * - No per-run cost surface → undefined. No max-turns equivalent → `maxTurns`
19
19
  * accepted and ignored (documented in the CLI docs page).
20
20
  */
21
- import type { HarnessInvocation, HarnessRawResult } from "../harnesses/types.js";
21
+ import type { AdapterInvocation, AdapterRawResult } from "../adapters/types.js";
22
22
  import type { Spawner, SpawnRequest, SpawnResult } from "./types.js";
23
23
  /** Exported for unit tests (no live binary to test against). */
24
24
  export declare function parseCursorOutput(stdout: string): {
@@ -26,7 +26,7 @@ export declare function parseCursorOutput(stdout: string): {
26
26
  sessionId?: string;
27
27
  isError: boolean;
28
28
  };
29
- export declare function buildCursorInvocation(req: SpawnRequest): HarnessInvocation;
30
- export declare function normalizeCursorResult(raw: HarnessRawResult): SpawnResult;
29
+ export declare function buildCursorInvocation(req: SpawnRequest): AdapterInvocation;
30
+ export declare function normalizeCursorResult(raw: AdapterRawResult): SpawnResult;
31
31
  export declare const cursorSpawner: Spawner;
32
32
  //# sourceMappingURL=spawn-cursor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spawn-cursor.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAKjF,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AASrE,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,CAWA;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CAkB1E;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,CAqCxE;AAED,eAAO,MAAM,aAAa,EAAE,OAe3B,CAAC"}
1
+ {"version":3,"file":"spawn-cursor.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAKhF,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AASrE,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,CAWA;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CAkB1E;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,CAqDxE;AAED,eAAO,MAAM,aAAa,EAAE,OAkB3B,CAAC"}
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Contract notes (LIVE-VERIFIED 2026-07-17 against cursor-agent
6
6
  * 2026.07.16-899851b: schema-gated triage + text stages round-trip via
7
- * `--harness cursor`, session_id parses from the envelope):
7
+ * `--adapter cursor`, session_id parses from the envelope):
8
8
  * - `cursor-agent -p "<prompt>" --output-format json` prints a single result
9
9
  * envelope modeled on Claude Code's (`{type: "result", is_error, result,
10
10
  * session_id, …}`).
@@ -19,11 +19,11 @@
19
19
  * accepted and ignored (documented in the CLI docs page).
20
20
  */
21
21
  import { exec } from "../../lib/exec.js";
22
- import { builtinHarnessProfile, validateHarnessEffort } from "../harnesses/profiles.js";
22
+ import { builtinAdapterProfile, validateAdapterEffort } from "../adapters/profiles.js";
23
+ import { notFoundError } from "./adapters.js";
23
24
  import { buildChildEnv } from "./child-env.js";
24
- import { notFoundError } from "./harnesses.js";
25
25
  import { resolveSandboxProjection } from "./sandbox-projection.js";
26
- import { vendorFailureText } from "./spawn-failure.js";
26
+ import { isUpstreamFailureText, vendorFailureText } from "./spawn-failure.js";
27
27
  /** Exported for unit tests (no live binary to test against). */
28
28
  export function parseCursorOutput(stdout) {
29
29
  try {
@@ -39,10 +39,10 @@ export function parseCursorOutput(stdout) {
39
39
  }
40
40
  }
41
41
  export function buildCursorInvocation(req) {
42
- validateHarnessEffort("cursor", req.effort);
42
+ validateAdapterEffort("cursor", req.effort);
43
43
  if (req.filesystemPolicy) {
44
44
  // Declared unrepresentable: refuse rather than drop it silently (ADR 0039).
45
- resolveSandboxProjection("cursor", builtinHarnessProfile("cursor")?.sandboxProjection, req.filesystemPolicy);
45
+ resolveSandboxProjection("cursor", builtinAdapterProfile("cursor")?.sandboxProjection, req.filesystemPolicy);
46
46
  }
47
47
  // --trust: headless cursor-agent refuses untrusted workspaces (exit 1,
48
48
  // "Workspace Trust Required"). --force: a print-mode child has no interactive
@@ -63,15 +63,30 @@ export function normalizeCursorResult(raw) {
63
63
  error: `cursor timed out after ${raw.durationMs}ms and was killed`,
64
64
  };
65
65
  }
66
+ // Structural environment signal: the binary was never there (spawned directly,
67
+ // so a missing binary surfaces as ENOENT). Uncharged and not retried.
68
+ if (raw.spawnErrno === "ENOENT") {
69
+ return {
70
+ ok: false,
71
+ text: "",
72
+ durationMs: raw.durationMs,
73
+ error: notFoundError("cursor"),
74
+ class: "environment",
75
+ };
76
+ }
66
77
  if (raw.exitCode === 127) {
78
+ // A bare 127 with no errno is a shell/vendor 127, indistinguishable from a
79
+ // legitimate one — charged as work rather than classed environment.
67
80
  return { ok: false, text: "", durationMs: raw.durationMs, error: notFoundError("cursor") };
68
81
  }
69
82
  if (raw.exitCode !== 0) {
83
+ const failureText = vendorFailureText(raw);
70
84
  return {
71
85
  ok: false,
72
86
  text: "",
73
87
  durationMs: raw.durationMs,
74
- error: `cursor-agent exited ${raw.exitCode}: ${vendorFailureText(raw)}`,
88
+ error: `cursor-agent exited ${raw.exitCode}: ${failureText}`,
89
+ ...(isUpstreamFailureText(failureText) ? { class: "upstream" } : {}),
75
90
  };
76
91
  }
77
92
  const parsed = parseCursorOutput(raw.stdout);
@@ -82,6 +97,7 @@ export function normalizeCursorResult(raw) {
82
97
  sessionId: parsed.sessionId,
83
98
  durationMs: raw.durationMs,
84
99
  error: `cursor-agent reported is_error: ${parsed.text.slice(0, 300)}`,
100
+ ...(isUpstreamFailureText(parsed.text) ? { class: "upstream" } : {}),
85
101
  };
86
102
  }
87
103
  return {
@@ -102,7 +118,10 @@ export const cursorSpawner = async (req) => {
102
118
  }
103
119
  const r = await exec(invocation.argv, {
104
120
  cwd: req.cwd,
105
- env: buildChildEnv(req.runId, { subscriptionOnly: req.subscriptionOnly }),
121
+ env: buildChildEnv(req.runId, {
122
+ subscriptionOnly: req.subscriptionOnly,
123
+ agentId: req.agentId,
124
+ }),
106
125
  timeout: req.timeoutMs,
107
126
  });
108
127
  return normalizeCursorResult({ ...r, durationMs: Date.now() - t0 });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Shared failure-text extraction for the harness spawn adapters.
2
+ * Shared failure-text extraction for the adapter spawn adapters.
3
3
  *
4
4
  * A vendor CLI prints its banner, resolved config, and startup warnings first,
5
5
  * and the reason it actually failed last. Every adapter used to keep the FIRST
@@ -15,4 +15,18 @@ export declare function vendorFailureText(raw: {
15
15
  stdout?: string;
16
16
  stderr?: string;
17
17
  }, maxChars?: number): string;
18
+ /**
19
+ * Whether failure text names an UPSTREAM refusal — the vendor was reached and
20
+ * refused (a 5xx/429 status or circuit-open wording), as opposed to a work
21
+ * failure (the model ran and produced a wrong or incomplete result).
22
+ *
23
+ * There is no structural upstream signal the way ENOENT structurally marks a
24
+ * missing binary, so this is the one text match in the classifier. It is kept
25
+ * SHORT and documented on purpose: a per-vendor regex zoo would rot, and a
26
+ * false positive here wrongly withholds a charge, so both the phrase list and
27
+ * the numeric match stay tight — the number must sit in HTTP-status context, not
28
+ * merely fall in the 429/5xx range. Anything it does not match falls through to
29
+ * a charged work failure.
30
+ */
31
+ export declare function isUpstreamFailureText(text: string): boolean;
18
32
  //# sourceMappingURL=spawn-failure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spawn-failure.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,mEAAmE;AACnE,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACzC,QAAQ,SAAoB,GAC3B,MAAM,CAQR"}
1
+ {"version":3,"file":"spawn-failure.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/spawn-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,mEAAmE;AACnE,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACzC,QAAQ,SAAoB,GAC3B,MAAM,CAQR;AAyBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Shared failure-text extraction for the harness spawn adapters.
2
+ * Shared failure-text extraction for the adapter spawn adapters.
3
3
  *
4
4
  * A vendor CLI prints its banner, resolved config, and startup warnings first,
5
5
  * and the reason it actually failed last. Every adapter used to keep the FIRST
@@ -22,3 +22,37 @@ export function vendorFailureText(raw, maxChars = DEFAULT_MAX_CHARS) {
22
22
  const combined = parts.join("\n");
23
23
  return combined.length > maxChars ? `…${combined.slice(-maxChars)}` : combined;
24
24
  }
25
+ // A 429 or 5xx status, but only where it sits in HTTP-status CONTEXT — not any
26
+ // digits that merely happen to fall in that range. A bare-number match treats a
27
+ // line number ("at line 500"), an item count ("got 429 items"), or a duration
28
+ // ("after 502 seconds") as an upstream refusal, which wrongly withholds a charge
29
+ // for a failure that was entirely our code. Three recognized shapes:
30
+ // 1. after an "HTTP" label: "HTTP 429", "HTTP/1.1 503 Service Unavailable"
31
+ // 2. after a "status" label: "status 500", "status: 429", "status code 502"
32
+ // 3. a bare status line: "503 Service Unavailable" (code at line start,
33
+ // then a reason phrase) — the classic "<code> <Reason-Phrase>" shape.
34
+ // The trailing `(?![0-9])` and the label/line-start anchors also keep a status
35
+ // embedded in a longer number ("4295"/"5031") out. All 5xx are server-side; 429
36
+ // is the only 4xx that means "reached and refused, retry later".
37
+ const STATUS = "(?:429|5[0-9]{2})";
38
+ const UPSTREAM_STATUS = new RegExp(`(?:\\bHTTP\\b[/0-9. ]*|\\bstatus(?:\\s*code)?\\b[\\s:=]*)${STATUS}(?![0-9])` +
39
+ `|(?:^|\\n)\\s*${STATUS}\\s+[A-Za-z]`, "i");
40
+ // Explicit vendor wording for the same conditions when a numeric status is
41
+ // absent. Deliberately short — see isUpstreamFailureText.
42
+ const UPSTREAM_PHRASES = /circuit[ _-]?open|service unavailable|too many requests|rate[ _-]?limit|overloaded|bad gateway|gateway time-?out|internal server error/i;
43
+ /**
44
+ * Whether failure text names an UPSTREAM refusal — the vendor was reached and
45
+ * refused (a 5xx/429 status or circuit-open wording), as opposed to a work
46
+ * failure (the model ran and produced a wrong or incomplete result).
47
+ *
48
+ * There is no structural upstream signal the way ENOENT structurally marks a
49
+ * missing binary, so this is the one text match in the classifier. It is kept
50
+ * SHORT and documented on purpose: a per-vendor regex zoo would rot, and a
51
+ * false positive here wrongly withholds a charge, so both the phrase list and
52
+ * the numeric match stay tight — the number must sit in HTTP-status context, not
53
+ * merely fall in the 429/5xx range. Anything it does not match falls through to
54
+ * a charged work failure.
55
+ */
56
+ export function isUpstreamFailureText(text) {
57
+ return UPSTREAM_STATUS.test(text) || UPSTREAM_PHRASES.test(text);
58
+ }
@@ -21,7 +21,7 @@ export function normalizeWorkflowSpecialists(input) {
21
21
  }
22
22
  normalized[id] = {
23
23
  instructions: bounded(profile.instructions, `workflow specialist ${id} instructions`, MAX_INSTRUCTIONS),
24
- harness: optional(profile.harness, `workflow specialist ${id} harness`),
24
+ adapter: optional(profile.adapter, `workflow specialist ${id} adapter`),
25
25
  model: optional(profile.model, `workflow specialist ${id} model`),
26
26
  effort: optional(profile.effort, `workflow specialist ${id} effort`),
27
27
  maxAttempts: positiveOptional(profile.maxAttempts, `workflow specialist ${id} maxAttempts`, 10),
@@ -44,7 +44,7 @@ export function resolveSpecialistAssignment(profiles, prompt, opts) {
44
44
  prompt: `${profile.instructions}\n\nAssignment:\n${prompt}`,
45
45
  opts: {
46
46
  specialist: opts.specialist,
47
- harness: opts.harness ?? profile.harness,
47
+ adapter: opts.adapter ?? profile.adapter,
48
48
  model: opts.model ?? profile.model,
49
49
  effort: opts.effort ?? profile.effort,
50
50
  maxAttempts: opts.maxAttempts ?? profile.maxAttempts,
@@ -1,14 +1,14 @@
1
- export declare const WORKFLOW_JOURNAL_EVENT_BYTES: number;
1
+ export declare const WORKFLOW_TRANSCRIPT_EVENT_BYTES: number;
2
2
  /** Key under which a shrunk record names the fields it had to drop. */
3
- export declare const WORKFLOW_JOURNAL_OMITTED = "omitted_fields";
4
- export interface WorkflowJournalOmission {
3
+ export declare const WORKFLOW_TRANSCRIPT_OMITTED = "omitted_fields";
4
+ export interface WorkflowTranscriptOmission {
5
5
  field: string;
6
6
  bytes: number;
7
7
  sha256: string;
8
8
  }
9
- export declare function workflowJournalPath(coordRoot: string, runId: string): string;
9
+ export declare function workflowTranscriptPath(coordRoot: string, runId: string): string;
10
10
  /**
11
- * Append one journal record, always.
11
+ * Append one transcript record, always.
12
12
  *
13
13
  * A record that would exceed what a reader accepts has its largest fields
14
14
  * replaced by a digest and a byte count until it fits, and it names what it
@@ -20,11 +20,11 @@ export declare function workflowJournalPath(coordRoot: string, runId: string): s
20
20
  * this limit by construction. Losing detail from a record is recoverable.
21
21
  * Losing the run that was writing it is not.
22
22
  */
23
- export declare function appendWorkflowJournalEvent(coordRoot: string, runId: string, event: string, data: Record<string, unknown>): void;
23
+ export declare function appendWorkflowTranscriptEvent(coordRoot: string, runId: string, event: string, data: Record<string, unknown>): void;
24
24
  /**
25
25
  * Shrink a record to the reader's limit by dropping its largest fields first.
26
26
  * The envelope is never dropped, so a record keeps its run id, timestamp, and
27
27
  * event name however much detail it loses. Exported for tests.
28
28
  */
29
- export declare function fitWorkflowJournalRecord(envelope: Record<string, unknown>, data: Record<string, unknown>): Record<string, unknown>;
30
- //# sourceMappingURL=journal.d.ts.map
29
+ export declare function fitWorkflowTranscriptRecord(envelope: Record<string, unknown>, data: Record<string, unknown>): Record<string, unknown>;
30
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/transcript.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,+BAA+B,QAAY,CAAC;AAEzD,uEAAuE;AACvE,eAAO,MAAM,2BAA2B,mBAAmB,CAAC;AAI5D,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,IAAI,CAiBN;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBzB"}
@@ -2,18 +2,18 @@ import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, writeFileSync }
2
2
  import { dirname, join, resolve } from "node:path";
3
3
  import { fsyncParentDirectory, stableDigest } from "./durable-record.js";
4
4
  // Limit for the JSON record body. The trailing newline delimiter is outside the
5
- // record and is not counted by readers after splitting journal lines.
6
- export const WORKFLOW_JOURNAL_EVENT_BYTES = 16 * 1024;
5
+ // record and is not counted by readers after splitting transcript lines.
6
+ export const WORKFLOW_TRANSCRIPT_EVENT_BYTES = 16 * 1024;
7
7
  /** Key under which a shrunk record names the fields it had to drop. */
8
- export const WORKFLOW_JOURNAL_OMITTED = "omitted_fields";
8
+ export const WORKFLOW_TRANSCRIPT_OMITTED = "omitted_fields";
9
9
  const RUN_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
10
- export function workflowJournalPath(coordRoot, runId) {
10
+ export function workflowTranscriptPath(coordRoot, runId) {
11
11
  if (!RUN_ID.test(runId))
12
12
  throw new Error(`invalid workflow run id ${JSON.stringify(runId)}`);
13
- return join(resolve(coordRoot), ".harnery", "workflows", runId, "journal.jsonl");
13
+ return join(resolve(coordRoot), ".harnery", "workflows", runId, "transcript.jsonl");
14
14
  }
15
15
  /**
16
- * Append one journal record, always.
16
+ * Append one transcript record, always.
17
17
  *
18
18
  * A record that would exceed what a reader accepts has its largest fields
19
19
  * replaced by a digest and a byte count until it fits, and it names what it
@@ -25,9 +25,9 @@ export function workflowJournalPath(coordRoot, runId) {
25
25
  * this limit by construction. Losing detail from a record is recoverable.
26
26
  * Losing the run that was writing it is not.
27
27
  */
28
- export function appendWorkflowJournalEvent(coordRoot, runId, event, data) {
29
- const path = workflowJournalPath(coordRoot, runId);
30
- const record = fitWorkflowJournalRecord({ schema_version: 1, run_id: runId, ts: new Date().toISOString(), event }, data);
28
+ export function appendWorkflowTranscriptEvent(coordRoot, runId, event, data) {
29
+ const path = workflowTranscriptPath(coordRoot, runId);
30
+ const record = fitWorkflowTranscriptRecord({ schema_version: 1, run_id: runId, ts: new Date().toISOString(), event }, data);
31
31
  const line = `${JSON.stringify(record)}\n`;
32
32
  mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
33
33
  const existed = existsSync(path);
@@ -47,9 +47,9 @@ export function appendWorkflowJournalEvent(coordRoot, runId, event, data) {
47
47
  * The envelope is never dropped, so a record keeps its run id, timestamp, and
48
48
  * event name however much detail it loses. Exported for tests.
49
49
  */
50
- export function fitWorkflowJournalRecord(envelope, data) {
50
+ export function fitWorkflowTranscriptRecord(envelope, data) {
51
51
  const candidate = { ...envelope, ...data };
52
- if (Buffer.byteLength(JSON.stringify(candidate)) <= WORKFLOW_JOURNAL_EVENT_BYTES) {
52
+ if (Buffer.byteLength(JSON.stringify(candidate)) <= WORKFLOW_TRANSCRIPT_EVENT_BYTES) {
53
53
  return candidate;
54
54
  }
55
55
  const kept = { ...data };
@@ -60,11 +60,11 @@ export function fitWorkflowJournalRecord(envelope, data) {
60
60
  for (const { field, bytes } of bySize) {
61
61
  omitted.push({ field, bytes, sha256: stableDigest(data[field]) });
62
62
  delete kept[field];
63
- const next = { ...envelope, ...kept, [WORKFLOW_JOURNAL_OMITTED]: omitted };
64
- if (Buffer.byteLength(JSON.stringify(next)) <= WORKFLOW_JOURNAL_EVENT_BYTES)
63
+ const next = { ...envelope, ...kept, [WORKFLOW_TRANSCRIPT_OMITTED]: omitted };
64
+ if (Buffer.byteLength(JSON.stringify(next)) <= WORKFLOW_TRANSCRIPT_EVENT_BYTES)
65
65
  return next;
66
66
  }
67
67
  // Every field dropped and still over: the omission list is itself the excess.
68
68
  // Keep the envelope and a count so the record stays parseable and honest.
69
- return { ...envelope, [WORKFLOW_JOURNAL_OMITTED]: omitted.length };
69
+ return { ...envelope, [WORKFLOW_TRANSCRIPT_OMITTED]: omitted.length };
70
70
  }