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
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Preflight: would every specialist on this team land on the same adapter?
3
+ *
4
+ * Harnery does not auto-spread. A specialist without an `adapter` pin inherits
5
+ * the run's default, so a team whose profiles all omit the pin puts every child
6
+ * on one adapter. That is legal and sometimes intended. It is a problem when the
7
+ * host is also `subscriptionOnly`, because then the concentration lands on one
8
+ * seat's session meter rather than on metered per-token billing: the seat hits
9
+ * its limit, and every specialist stops at once rather than the team degrading.
10
+ *
11
+ * The check is deliberately narrow, because a false refusal here is worse than
12
+ * the miss it prevents. It fires only when all four hold:
13
+ *
14
+ * 1. more than one specialist (a solo team cannot spread),
15
+ * 2. every specialist resolves to the same adapter,
16
+ * 3. `subscriptionOnly` is on (otherwise concentration is a cost curve, not a
17
+ * cliff), and
18
+ * 4. more than one adapter is ATTESTED REACHABLE.
19
+ *
20
+ * Condition 4 is the one worth insisting on. Counting *declared* adapters would
21
+ * suggest spreading onto a seat that cannot run — a dead adapter passes a
22
+ * declaration check and then fails every child it is handed. Only an
23
+ * attestation records that the adapter actually completed a turn on this
24
+ * machine, so only an attestation is grounds for telling someone to use it.
25
+ */
26
+ export interface AdapterSpreadInput {
27
+ /** Specialist id → its optional adapter pin. */
28
+ specialists: Readonly<Record<string, {
29
+ adapter?: string;
30
+ }>>;
31
+ /** The adapter an unpinned specialist inherits. */
32
+ defaultAdapter: string;
33
+ /** Adapters with a live attestation on this machine — proven to run, not
34
+ * merely registered. */
35
+ reachable: readonly string[];
36
+ /** Whether children are confined to subscription (logged-in) auth. */
37
+ subscriptionOnly: boolean;
38
+ }
39
+ export interface AdapterSpreadVerdict {
40
+ /** True when the team would put every child on one adapter AND that is worth
41
+ * refusing over. False both when the team spreads and when concentrating is
42
+ * unremarkable (single specialist, one reachable adapter, metered billing). */
43
+ concentrated: boolean;
44
+ /** The adapter everything would land on, when concentrated. */
45
+ adapter?: string;
46
+ /** Operator-facing explanation, present exactly when concentrated. */
47
+ reason?: string;
48
+ /** Attested-reachable adapters this team is not using. */
49
+ unused: string[];
50
+ }
51
+ export declare function inspectAdapterSpread(input: AdapterSpreadInput): AdapterSpreadVerdict;
52
+ //# sourceMappingURL=adapter-spread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-spread.d.ts","sourceRoot":"","sources":["../../../src/core/governor/adapter-spread.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC5D,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB;4BACwB;IACxB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,sEAAsE;IACtE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC;;mFAE+E;IAC/E,YAAY,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,kBAAkB,GAAG,oBAAoB,CA8BpF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Preflight: would every specialist on this team land on the same adapter?
3
+ *
4
+ * Harnery does not auto-spread. A specialist without an `adapter` pin inherits
5
+ * the run's default, so a team whose profiles all omit the pin puts every child
6
+ * on one adapter. That is legal and sometimes intended. It is a problem when the
7
+ * host is also `subscriptionOnly`, because then the concentration lands on one
8
+ * seat's session meter rather than on metered per-token billing: the seat hits
9
+ * its limit, and every specialist stops at once rather than the team degrading.
10
+ *
11
+ * The check is deliberately narrow, because a false refusal here is worse than
12
+ * the miss it prevents. It fires only when all four hold:
13
+ *
14
+ * 1. more than one specialist (a solo team cannot spread),
15
+ * 2. every specialist resolves to the same adapter,
16
+ * 3. `subscriptionOnly` is on (otherwise concentration is a cost curve, not a
17
+ * cliff), and
18
+ * 4. more than one adapter is ATTESTED REACHABLE.
19
+ *
20
+ * Condition 4 is the one worth insisting on. Counting *declared* adapters would
21
+ * suggest spreading onto a seat that cannot run — a dead adapter passes a
22
+ * declaration check and then fails every child it is handed. Only an
23
+ * attestation records that the adapter actually completed a turn on this
24
+ * machine, so only an attestation is grounds for telling someone to use it.
25
+ */
26
+ export function inspectAdapterSpread(input) {
27
+ const ids = Object.keys(input.specialists);
28
+ const resolved = ids.map((id) => input.specialists[id]?.adapter ?? input.defaultAdapter);
29
+ const distinct = [...new Set(resolved)];
30
+ const unused = input.reachable.filter((a) => !distinct.includes(a));
31
+ if (ids.length < 2 || distinct.length !== 1 || !input.subscriptionOnly || unused.length === 0) {
32
+ return { concentrated: false, unused };
33
+ }
34
+ const adapter = distinct[0];
35
+ const pinned = ids.filter((id) => input.specialists[id]?.adapter).length;
36
+ // Say which of the two shapes this is. "You wrote no pins" and "you pinned
37
+ // them all to one" need different corrections, and a single generic message
38
+ // would send half the readers looking in the wrong place.
39
+ const how = pinned === 0
40
+ ? `no specialist pins an adapter, so all ${ids.length} inherit the default (${adapter})`
41
+ : `all ${ids.length} specialists resolve to ${adapter}`;
42
+ return {
43
+ concentrated: true,
44
+ adapter,
45
+ unused,
46
+ reason: `${how}, and children are confined to subscription auth — so one seat carries the whole ` +
47
+ `team and every specialist stops together when it hits its limit. ` +
48
+ `${unused.length === 1 ? "This adapter is" : "These adapters are"} attested and idle: ` +
49
+ `${unused.join(", ")}. Pin some specialists onto ${unused.length === 1 ? "it" : "them"}, ` +
50
+ `or pass --allow-single-adapter if one seat is what you want.`,
51
+ };
52
+ }
@@ -0,0 +1,7 @@
1
+ export { approveGovernorPlan, findCompletedMissionGoverning, rejectGovernorPlan, reopenGovernorMission, retryGovernorPlan, } from "./plan-api.js";
2
+ export { readGovernorPlan, readGovernorPlanReviewReceipt, readGovernorPlans, } from "./plan-read.js";
3
+ export { type CreateGovernorPlanTemplateInput, type CreateGovernorReplanningInput, GOVERNOR_PLAN_SCHEMA_VERSION, type GovernorPlanEvent, type GovernorPlanEventType, type GovernorPlanHistory, type GovernorPlanMilestone, type GovernorPlanOutcome, type GovernorPlanProposal, type GovernorPlanRecord, type GovernorPlanRequest, type GovernorPlanReviewFinding, type GovernorPlanReviewReceipt, type GovernorPlanReviewReviewer, type GovernorPlanReviewRound, type GovernorPlanReviewStatus, type GovernorPlanReviewSummary, type GovernorPlanReviewVerdict, type GovernorPlanStatus, type GovernorPlanTemplate, type GovernorPlanWorkSpec, type GovernorReplanningPolicy, MAX_GOVERNOR_PLAN_REVIEWERS, MAX_GOVERNOR_PLAN_REVISION_ROUNDS, } from "./plan-types.js";
4
+ export { type GovernorDispatchOutcome, type GovernorRunReport, type GovernorStopReason, type RunGovernorInput, runGovernor, } from "./runner.js";
5
+ export { type ConfigureGovernorServiceInput, configureGovernorService, GOVERNOR_SERVICE_CONFIG_SCHEMA_VERSION, GOVERNOR_SERVICE_RUNTIME_SCHEMA_VERSION, GOVERNOR_SERVICE_STATUS_SCHEMA_VERSION, type GovernorServiceConfig, type GovernorServiceEngineConfig, type GovernorServiceGoalRuntime, type GovernorServiceGoalState, type GovernorServiceProcessState, type GovernorServiceRuntime, type GovernorServiceStatus, type GovernorServiceStatusRecord, type GovernorServiceSweepOutcome, type GovernorServiceSweepReport, governorServiceLogPath, type RunGovernorServiceDaemonInput, type RunGovernorServiceSweepInput, readGovernorServiceConfig, readGovernorServiceRuntime, readGovernorServiceStatus, requestGovernorServiceStop, runGovernorServiceDaemon, runGovernorServiceSweep, spawnGovernorService, } from "./service.js";
6
+ export { assertGovernorId, type CreateGovernorInput, type CreateGovernorMissionInput, collectGovernorWork, createGovernor, GOVERNOR_INTENT_SCHEMA_VERSION, type GovernorAutomationPolicy, type GovernorIntent, type GovernorLimits, type GovernorMission, type GovernorNextAction, type GovernorProjection, type GovernorRecord, type GovernorState, listGovernors, newGovernorId, readGovernor, } from "./state.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/governor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,6BAA6B,EAC7B,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EAClC,4BAA4B,EAC5B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,6BAA6B,EAClC,wBAAwB,EACxB,sCAAsC,EACtC,uCAAuC,EACvC,sCAAsC,EACtC,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,sBAAsB,EACtB,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,mBAAmB,EACnB,cAAc,EACd,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { approveGovernorPlan, findCompletedMissionGoverning, rejectGovernorPlan, reopenGovernorMission, retryGovernorPlan, } from "./plan-api.js";
2
+ export { readGovernorPlan, readGovernorPlanReviewReceipt, readGovernorPlans, } from "./plan-read.js";
3
+ export { GOVERNOR_PLAN_SCHEMA_VERSION, MAX_GOVERNOR_PLAN_REVIEWERS, MAX_GOVERNOR_PLAN_REVISION_ROUNDS, } from "./plan-types.js";
4
+ export { runGovernor, } from "./runner.js";
5
+ export { configureGovernorService, GOVERNOR_SERVICE_CONFIG_SCHEMA_VERSION, GOVERNOR_SERVICE_RUNTIME_SCHEMA_VERSION, GOVERNOR_SERVICE_STATUS_SCHEMA_VERSION, governorServiceLogPath, readGovernorServiceConfig, readGovernorServiceRuntime, readGovernorServiceStatus, requestGovernorServiceStop, runGovernorServiceDaemon, runGovernorServiceSweep, spawnGovernorService, } from "./service.js";
6
+ export { assertGovernorId, collectGovernorWork, createGovernor, GOVERNOR_INTENT_SCHEMA_VERSION, listGovernors, newGovernorId, readGovernor, } from "./state.js";
@@ -0,0 +1,38 @@
1
+ import type { GovernorPlanOutcome } from "./plan-types.js";
2
+ export declare function approveGovernorPlan(input: {
3
+ coordRoot: string;
4
+ goalId: string;
5
+ planId: string;
6
+ actor?: string;
7
+ reason?: string;
8
+ }): GovernorPlanOutcome;
9
+ export declare function rejectGovernorPlan(input: {
10
+ coordRoot: string;
11
+ goalId: string;
12
+ planId: string;
13
+ actor?: string;
14
+ reason: string;
15
+ }): GovernorPlanOutcome;
16
+ /** The goal of a succeeded mission that governs this work item, if there is one.
17
+ *
18
+ * A work item holds no back-reference to its goal, so this is a scan. It exists so
19
+ * `work reopen` can tell the difference between an item nothing is watching and one
20
+ * whose mission has already been declared complete — the case where reopening the
21
+ * item alone leaves it in `ready_work` that the governor will never dispatch. */
22
+ export declare function findCompletedMissionGoverning(coordRoot: string, workId: string): string | undefined;
23
+ /** ADR 0050: reopen an accepted mission completion by appending to the plan log.
24
+ * Held under the goal lease so it cannot race a foreground governor run. */
25
+ export declare function reopenGovernorMission(input: {
26
+ coordRoot: string;
27
+ goalId: string;
28
+ actor?: string;
29
+ reason: string;
30
+ }): GovernorPlanOutcome;
31
+ export declare function retryGovernorPlan(input: {
32
+ coordRoot: string;
33
+ goalId: string;
34
+ planId: string;
35
+ actor?: string;
36
+ reason: string;
37
+ }): GovernorPlanOutcome;
38
+ //# sourceMappingURL=plan-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-api.d.ts","sourceRoot":"","sources":["../../../src/core/governor/plan-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAS3D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,mBAAmB,CActB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,mBAAmB,CActB;AAED;;;;;iFAKiF;AACjF,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,SAAS,CAQpB;AAED;4EAC4E;AAC5E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,mBAAmB,CAatB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,mBAAmB,CActB"}
@@ -0,0 +1,83 @@
1
+ import { applyGovernorPlanProposal, rejectGovernorPlanProposal, reopenGovernorMissionPlan, retryGovernorPlanProposal, } from "./planning.js";
2
+ import { acquireGovernorLease, listGovernors, readGovernorIgnoringLease } from "./state.js";
3
+ export function approveGovernorPlan(input) {
4
+ const actor = input.actor?.trim() || `governor:${input.goalId}`;
5
+ const release = acquireGovernorLease(input.coordRoot, input.goalId);
6
+ try {
7
+ return applyGovernorPlanProposal({
8
+ coordRoot: input.coordRoot,
9
+ record: readGovernorIgnoringLease(input.coordRoot, input.goalId),
10
+ planId: input.planId,
11
+ actor,
12
+ reason: input.reason,
13
+ });
14
+ }
15
+ finally {
16
+ release();
17
+ }
18
+ }
19
+ export function rejectGovernorPlan(input) {
20
+ const actor = input.actor?.trim() || `governor:${input.goalId}`;
21
+ const release = acquireGovernorLease(input.coordRoot, input.goalId);
22
+ try {
23
+ return rejectGovernorPlanProposal({
24
+ coordRoot: input.coordRoot,
25
+ goalId: input.goalId,
26
+ planId: input.planId,
27
+ actor,
28
+ reason: input.reason,
29
+ });
30
+ }
31
+ finally {
32
+ release();
33
+ }
34
+ }
35
+ /** The goal of a succeeded mission that governs this work item, if there is one.
36
+ *
37
+ * A work item holds no back-reference to its goal, so this is a scan. It exists so
38
+ * `work reopen` can tell the difference between an item nothing is watching and one
39
+ * whose mission has already been declared complete — the case where reopening the
40
+ * item alone leaves it in `ready_work` that the governor will never dispatch. */
41
+ export function findCompletedMissionGoverning(coordRoot, workId) {
42
+ for (const record of listGovernors(coordRoot)) {
43
+ if (record.projection.state !== "succeeded" || !record.intent.mission)
44
+ continue;
45
+ if (record.projection.root_work_id === workId || record.projection.work_ids.includes(workId)) {
46
+ return record.intent.id;
47
+ }
48
+ }
49
+ return undefined;
50
+ }
51
+ /** ADR 0050: reopen an accepted mission completion by appending to the plan log.
52
+ * Held under the goal lease so it cannot race a foreground governor run. */
53
+ export function reopenGovernorMission(input) {
54
+ const actor = input.actor?.trim() || `governor:${input.goalId}`;
55
+ const release = acquireGovernorLease(input.coordRoot, input.goalId);
56
+ try {
57
+ return reopenGovernorMissionPlan({
58
+ coordRoot: input.coordRoot,
59
+ record: readGovernorIgnoringLease(input.coordRoot, input.goalId),
60
+ actor,
61
+ reason: input.reason,
62
+ });
63
+ }
64
+ finally {
65
+ release();
66
+ }
67
+ }
68
+ export function retryGovernorPlan(input) {
69
+ const actor = input.actor?.trim() || `governor:${input.goalId}`;
70
+ const release = acquireGovernorLease(input.coordRoot, input.goalId);
71
+ try {
72
+ return retryGovernorPlanProposal({
73
+ coordRoot: input.coordRoot,
74
+ record: readGovernorIgnoringLease(input.coordRoot, input.goalId),
75
+ planId: input.planId,
76
+ actor,
77
+ reason: input.reason,
78
+ });
79
+ }
80
+ finally {
81
+ release();
82
+ }
83
+ }
@@ -0,0 +1,5 @@
1
+ import { type GovernorPlanHistory, type GovernorPlanRecord, type GovernorPlanReviewReceipt } from "./plan-types.js";
2
+ export declare function readGovernorPlans(coordRootRaw: string, goalId: string, originalRootWorkId: string): GovernorPlanHistory;
3
+ export declare function readGovernorPlan(coordRootRaw: string, goalId: string, planId: string): GovernorPlanRecord;
4
+ export declare function readGovernorPlanReviewReceipt(coordRootRaw: string, goalId: string, planId: string): GovernorPlanReviewReceipt | undefined;
5
+ //# sourceMappingURL=plan-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-read.d.ts","sourceRoot":"","sources":["../../../src/core/governor/plan-read.ts"],"names":[],"mappings":"AAIA,OAAO,EAIL,KAAK,mBAAmB,EAExB,KAAK,kBAAkB,EAGvB,KAAK,yBAAyB,EAQ/B,MAAM,iBAAiB,CAAC;AA0BzB,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,MAAM,GACzB,mBAAmB,CAwErB;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,kBAAkB,CAsBpB;AAED,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,yBAAyB,GAAG,SAAS,CAWvC"}
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
3
3
  import { join, resolve } from "node:path";
4
4
  import { readWorkItem } from "../work/read.js";
5
- import { MAX_SUPERVISOR_PLAN_REVIEWERS, MAX_SUPERVISOR_PLAN_REVISION_ROUNDS, SUPERVISOR_PLAN_SCHEMA_VERSION, } from "./plan-types.js";
5
+ import { GOVERNOR_PLAN_SCHEMA_VERSION, MAX_GOVERNOR_PLAN_REVIEWERS, MAX_GOVERNOR_PLAN_REVISION_ROUNDS, } from "./plan-types.js";
6
6
  const PLAN_ID = /^plan-[0-9]{4}-[a-f0-9]{8}$/;
7
7
  const GOAL_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
8
8
  const WORK_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
@@ -24,9 +24,10 @@ const EVENT_TYPES = new Set([
24
24
  "plan.retry_requested",
25
25
  "plan.attention",
26
26
  "plan.failed",
27
+ "plan.reopened",
27
28
  ]);
28
- export function readSupervisorPlans(coordRootRaw, goalId, originalRootWorkId) {
29
- assertId(goalId, GOAL_ID, "supervisor id");
29
+ export function readGovernorPlans(coordRootRaw, goalId, originalRootWorkId) {
30
+ assertId(goalId, GOAL_ID, "governor id");
30
31
  assertId(originalRootWorkId, WORK_ID, "work id");
31
32
  const coordRoot = resolve(coordRootRaw);
32
33
  const root = plansRoot(coordRoot, goalId);
@@ -45,14 +46,14 @@ export function readSupervisorPlans(coordRootRaw, goalId, originalRootWorkId) {
45
46
  .filter((entry) => entry.isDirectory() && PLAN_ID.test(entry.name))
46
47
  .map((entry) => entry.name);
47
48
  if (entries.length > MAX_PLANS)
48
- throw new Error(`supervisor plan history exceeds ${MAX_PLANS}`);
49
+ throw new Error(`governor plan history exceeds ${MAX_PLANS}`);
49
50
  const plans = entries
50
- .map((planId) => readSupervisorPlan(coordRootRaw, goalId, planId))
51
+ .map((planId) => readGovernorPlan(coordRootRaw, goalId, planId))
51
52
  .sort((left, right) => left.request.sequence - right.request.sequence);
52
53
  const sequences = new Set();
53
54
  for (const plan of plans) {
54
55
  if (sequences.has(plan.request.sequence)) {
55
- throw new Error(`supervisor ${goalId} has duplicate plan sequence ${plan.request.sequence}`);
56
+ throw new Error(`governor ${goalId} has duplicate plan sequence ${plan.request.sequence}`);
56
57
  }
57
58
  sequences.add(plan.request.sequence);
58
59
  }
@@ -83,7 +84,7 @@ export function readSupervisorPlans(coordRootRaw, goalId, originalRootWorkId) {
83
84
  const completedPlans = plans.filter((plan) => plan.status === "completed");
84
85
  if (completedPlans.length > 1 ||
85
86
  (completedPlans.length === 1 && completedPlans[0] !== plans.at(-1))) {
86
- throw new Error(`supervisor ${goalId} has invalid completion history`);
87
+ throw new Error(`governor ${goalId} has invalid completion history`);
87
88
  }
88
89
  completed = completedPlans.length === 1;
89
90
  return {
@@ -97,9 +98,9 @@ export function readSupervisorPlans(coordRootRaw, goalId, originalRootWorkId) {
97
98
  latest: plans.at(-1),
98
99
  };
99
100
  }
100
- export function readSupervisorPlan(coordRootRaw, goalId, planId) {
101
- assertId(goalId, GOAL_ID, "supervisor id");
102
- assertId(planId, PLAN_ID, "supervisor plan id");
101
+ export function readGovernorPlan(coordRootRaw, goalId, planId) {
102
+ assertId(goalId, GOAL_ID, "governor id");
103
+ assertId(planId, PLAN_ID, "governor plan id");
103
104
  const coordRoot = resolve(coordRootRaw);
104
105
  const dir = planDir(coordRoot, goalId, planId);
105
106
  const request = readJson(join(dir, "request.json"), "plan request");
@@ -110,7 +111,7 @@ export function readSupervisorPlan(coordRootRaw, goalId, planId) {
110
111
  : undefined;
111
112
  if (proposal)
112
113
  validateProposalEnvelope(proposal, planId);
113
- const review = readSupervisorPlanReviewReceipt(coordRootRaw, goalId, planId);
114
+ const review = readGovernorPlanReviewReceipt(coordRootRaw, goalId, planId);
114
115
  const events = readEvents(join(dir, "events.jsonl"), planId);
115
116
  const derived = deriveStatus(coordRoot, events, proposal);
116
117
  return {
@@ -121,9 +122,9 @@ export function readSupervisorPlan(coordRootRaw, goalId, planId) {
121
122
  ...derived,
122
123
  };
123
124
  }
124
- export function readSupervisorPlanReviewReceipt(coordRootRaw, goalId, planId) {
125
- assertId(goalId, GOAL_ID, "supervisor id");
126
- assertId(planId, PLAN_ID, "supervisor plan id");
125
+ export function readGovernorPlanReviewReceipt(coordRootRaw, goalId, planId) {
126
+ assertId(goalId, GOAL_ID, "governor id");
127
+ assertId(planId, PLAN_ID, "governor plan id");
127
128
  const coordRoot = resolve(coordRootRaw);
128
129
  const path = join(planDir(coordRoot, goalId, planId), "review.json");
129
130
  if (!existsSync(path))
@@ -139,6 +140,16 @@ function deriveStatus(coordRoot, events, proposal) {
139
140
  const latest = events.at(-1);
140
141
  const completed = [...events].reverse().find((event) => event.event === "plan.completed");
141
142
  if (completed) {
143
+ // ADR 0050: an operator finding on work beneath a completed mission reopens
144
+ // the mission by APPENDING, never by rewriting. The accepted completion stays
145
+ // in the log verbatim; a later `plan.reopened` supersedes it, which is what
146
+ // drops `plans.completed` and lets the projection dispatch again.
147
+ const reopened = [...events]
148
+ .reverse()
149
+ .find((event) => event.event === "plan.reopened" && event.seq > completed.seq);
150
+ if (reopened) {
151
+ return { status: "reopened", work_ids: [], reason: reopened.reason };
152
+ }
142
153
  return { status: "completed", work_ids: [], reason: completed.reason };
143
154
  }
144
155
  const applied = [...events].reverse().find((event) => event.event === "plan.applied");
@@ -160,7 +171,10 @@ function deriveStatus(coordRoot, events, proposal) {
160
171
  return { status: "attention", work_ids: [], reason: latest.reason };
161
172
  }
162
173
  if (latest?.event === "plan.failed") {
163
- return { status: "failed", work_ids: [], reason: latest.reason };
174
+ // ADR 0046: carry the planner run's failure class so the projection can stop
175
+ // an environment failure and bound consecutive upstream ones, rather than
176
+ // replanning an unchanged environment to budget exhaustion.
177
+ return { status: "failed", work_ids: [], reason: latest.reason, class: latest.class };
164
178
  }
165
179
  const parked = [...events].reverse().find((event) => event.event === "plan.awaiting_approval");
166
180
  const resumedAfterPark = parked !== undefined &&
@@ -182,27 +196,27 @@ function readEvents(path, planId) {
182
196
  return [];
183
197
  const size = statSync(path).size;
184
198
  if (size > MAX_EVENTS_BYTES)
185
- throw new Error("supervisor plan events exceed their byte limit");
199
+ throw new Error("governor plan events exceed their byte limit");
186
200
  const body = readFileSync(path, "utf8");
187
201
  if (body && !body.endsWith("\n"))
188
- throw new Error(`supervisor plan ${planId} has a partial event`);
202
+ throw new Error(`governor plan ${planId} has a partial event`);
189
203
  const lines = body.split("\n").filter(Boolean);
190
204
  if (lines.length > MAX_EVENTS)
191
- throw new Error(`supervisor plan exceeds ${MAX_EVENTS} events`);
205
+ throw new Error(`governor plan exceeds ${MAX_EVENTS} events`);
192
206
  return lines.map((line, index) => {
193
207
  let event;
194
208
  try {
195
209
  event = JSON.parse(line);
196
210
  }
197
211
  catch (error) {
198
- throw new Error(`cannot parse supervisor plan ${planId} event ${index + 1}: ${error.message}`);
212
+ throw new Error(`cannot parse governor plan ${planId} event ${index + 1}: ${error.message}`);
199
213
  }
200
214
  validateEvent(event, planId, index + 1);
201
215
  return event;
202
216
  });
203
217
  }
204
218
  function validateRequest(request, goalId, planId) {
205
- if (request.schema_version !== SUPERVISOR_PLAN_SCHEMA_VERSION ||
219
+ if (request.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
206
220
  request.id !== planId ||
207
221
  request.goal_id !== goalId ||
208
222
  !Number.isSafeInteger(request.sequence) ||
@@ -216,11 +230,11 @@ function validateRequest(request, goalId, planId) {
216
230
  !WORK_ID.test(request.prior_root_work_id) ||
217
231
  !/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(request.workflow_run_id) ||
218
232
  !validTimestamp(request.created_at)) {
219
- throw new Error(`supervisor plan request ${planId} has an unsupported schema`);
233
+ throw new Error(`governor plan request ${planId} has an unsupported schema`);
220
234
  }
221
235
  }
222
236
  function validateProposalEnvelope(proposal, planId) {
223
- if (proposal.schema_version !== SUPERVISOR_PLAN_SCHEMA_VERSION ||
237
+ if (proposal.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
224
238
  proposal.plan_id !== planId ||
225
239
  !["apply", "complete", "attention"].includes(proposal.decision) ||
226
240
  typeof proposal.rationale !== "string" ||
@@ -231,7 +245,7 @@ function validateProposalEnvelope(proposal, planId) {
231
245
  typeof proposal.root !== "string" ||
232
246
  proposal.root.length > 32 ||
233
247
  !validTimestamp(proposal.proposed_at)) {
234
- throw new Error(`supervisor plan proposal ${planId} has an unsupported schema`);
248
+ throw new Error(`governor plan proposal ${planId} has an unsupported schema`);
235
249
  }
236
250
  if (proposal.milestone !== undefined) {
237
251
  const milestone = proposal.milestone;
@@ -248,12 +262,12 @@ function validateProposalEnvelope(proposal, planId) {
248
262
  milestone.acceptance.length < 1 ||
249
263
  milestone.acceptance.length > 50 ||
250
264
  milestone.acceptance.some((criterion) => typeof criterion !== "string" || criterion.length < 1 || criterion.length > 500)) {
251
- throw new Error(`supervisor plan proposal ${planId} milestone is invalid`);
265
+ throw new Error(`governor plan proposal ${planId} milestone is invalid`);
252
266
  }
253
267
  }
254
268
  if ((proposal.decision === "attention" || proposal.decision === "complete") &&
255
269
  (proposal.root !== "" || proposal.work.length > 0 || proposal.milestone !== undefined)) {
256
- throw new Error(`supervisor plan proposal ${planId} terminal decision contains work`);
270
+ throw new Error(`governor plan proposal ${planId} terminal decision contains work`);
257
271
  }
258
272
  for (const [index, spec] of proposal.work.entries()) {
259
273
  if (!spec ||
@@ -272,71 +286,71 @@ function validateProposalEnvelope(proposal, planId) {
272
286
  spec.dependencies.length > 50 ||
273
287
  spec.dependencies.some((value) => typeof value !== "string" || value.length > 100) ||
274
288
  !TEMPLATE_ID.test(spec.template)) {
275
- throw new Error(`supervisor plan proposal ${planId} work[${index}] is invalid`);
289
+ throw new Error(`governor plan proposal ${planId} work[${index}] is invalid`);
276
290
  }
277
291
  }
278
292
  }
279
293
  function validateReviewReceipt(receipt, planId) {
280
294
  if (!receipt ||
281
295
  typeof receipt !== "object" ||
282
- receipt.schema_version !== SUPERVISOR_PLAN_SCHEMA_VERSION ||
296
+ receipt.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
283
297
  receipt.plan_id !== planId ||
284
298
  !["passed", "revision_exhausted", "attention", "failed"].includes(receipt.status) ||
285
299
  !/^[a-f0-9]{64}$/.test(receipt.candidate_sha256) ||
286
300
  !Array.isArray(receipt.rounds) ||
287
301
  receipt.rounds.length < 1 ||
288
- receipt.rounds.length > MAX_SUPERVISOR_PLAN_REVISION_ROUNDS + 1) {
289
- throw new Error(`supervisor plan review ${planId} has an unsupported schema`);
302
+ receipt.rounds.length > MAX_GOVERNOR_PLAN_REVISION_ROUNDS + 1) {
303
+ throw new Error(`governor plan review ${planId} has an unsupported schema`);
290
304
  }
291
305
  validateProposalEnvelope(receipt.final_candidate, planId);
292
306
  if (receipt.candidate_sha256 !== candidateDigest(receipt.final_candidate)) {
293
- throw new Error(`supervisor plan review ${planId} has invalid candidate digest`);
307
+ throw new Error(`governor plan review ${planId} has invalid candidate digest`);
294
308
  }
295
309
  receipt.rounds.forEach((round, index) => {
296
310
  validateReviewRound(round, planId, index + 1);
297
311
  });
298
312
  const finalRound = receipt.rounds.at(-1);
299
313
  if (finalRound?.candidate_sha256 !== receipt.candidate_sha256) {
300
- throw new Error(`supervisor plan review ${planId} final round does not match its candidate`);
314
+ throw new Error(`governor plan review ${planId} final round does not match its candidate`);
301
315
  }
302
316
  if (receipt.status === "passed" && finalRound?.outcome !== "approved") {
303
- throw new Error(`supervisor plan review ${planId} passed without approval`);
317
+ throw new Error(`governor plan review ${planId} passed without approval`);
304
318
  }
305
319
  if (receipt.status === "attention" && finalRound?.outcome === "approved") {
306
- throw new Error(`supervisor plan review ${planId} attention conflicts with approval`);
320
+ throw new Error(`governor plan review ${planId} attention conflicts with approval`);
307
321
  }
308
322
  }
309
323
  function readFrozenReviewPolicy(coordRoot, goalId) {
310
- const path = join(coordRoot, ".harnery", "supervisors", goalId, "intent.json");
324
+ const path = join(coordRoot, ".harnery", "governors", goalId, "intent.json");
311
325
  if (!existsSync(path))
312
326
  return undefined;
313
- const intent = readJson(path, "supervisor intent");
327
+ const intent = readJson(path, "governor intent");
314
328
  return intent.replanning?.review;
315
329
  }
316
330
  function validateReviewReceiptMatchesPolicy(receipt, planId, review) {
317
331
  if (receipt.rounds.length > review.max_revision_rounds + 1) {
318
- throw new Error(`supervisor plan review ${planId} exceeds the frozen review policy`);
332
+ throw new Error(`governor plan review ${planId} exceeds the frozen review policy`);
319
333
  }
320
334
  for (const round of receipt.rounds) {
321
335
  if (round.reviewers.length !== review.reviewer_specialists.length) {
322
- throw new Error(`supervisor plan review ${planId} does not match the frozen review policy`);
336
+ throw new Error(`governor plan review ${planId} does not match the frozen review policy`);
323
337
  }
324
338
  round.reviewers.forEach((reviewer, index) => {
325
339
  if (reviewer.specialist !== review.reviewer_specialists[index]) {
326
- throw new Error(`supervisor plan review ${planId} does not match the frozen review policy`);
340
+ throw new Error(`governor plan review ${planId} does not match the frozen review policy`);
327
341
  }
328
342
  });
329
343
  const outcome = aggregateReviewers(round.reviewers);
330
344
  if (round.outcome !== outcome) {
331
- throw new Error(`supervisor plan review ${planId} has an invalid reviewer outcome`);
345
+ throw new Error(`governor plan review ${planId} has an invalid reviewer outcome`);
332
346
  }
333
347
  }
334
348
  const finalRound = receipt.rounds.at(-1);
335
349
  if (receipt.status === "passed" && finalRound.outcome !== "approved") {
336
- throw new Error(`supervisor plan review ${planId} passed without policy approval`);
350
+ throw new Error(`governor plan review ${planId} passed without policy approval`);
337
351
  }
338
352
  if (receipt.status === "revision_exhausted" && finalRound.round <= review.max_revision_rounds) {
339
- throw new Error(`supervisor plan review ${planId} exhausted before the frozen review limit`);
353
+ throw new Error(`governor plan review ${planId} exhausted before the frozen review limit`);
340
354
  }
341
355
  }
342
356
  function aggregateReviewers(reviewers) {
@@ -373,11 +387,11 @@ function validateReviewRound(round, planId, sequence) {
373
387
  !/^[a-f0-9]{64}$/.test(round.candidate_sha256) ||
374
388
  !Array.isArray(round.reviewers) ||
375
389
  round.reviewers.length < 1 ||
376
- round.reviewers.length > MAX_SUPERVISOR_PLAN_REVIEWERS ||
390
+ round.reviewers.length > MAX_GOVERNOR_PLAN_REVIEWERS ||
377
391
  !["approved", "revise", "attention", "failed"].includes(round.outcome) ||
378
392
  (round.revision_workflow_run_id !== undefined &&
379
393
  !/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(round.revision_workflow_run_id))) {
380
- throw new Error(`supervisor plan review ${planId} round ${sequence} is invalid`);
394
+ throw new Error(`governor plan review ${planId} round ${sequence} is invalid`);
381
395
  }
382
396
  round.reviewers.forEach((reviewer, index) => {
383
397
  validateReviewReviewer(reviewer, planId, sequence, index);
@@ -395,7 +409,7 @@ function validateReviewReviewer(reviewer, planId, round, index) {
395
409
  reviewer.rationale.length > 2_000 ||
396
410
  !Array.isArray(reviewer.findings) ||
397
411
  reviewer.findings.length > 50) {
398
- throw new Error(`supervisor plan review ${planId} round ${round} reviewer ${index} is invalid`);
412
+ throw new Error(`governor plan review ${planId} round ${round} reviewer ${index} is invalid`);
399
413
  }
400
414
  reviewer.findings.forEach((finding, findingIndex) => {
401
415
  validateReviewFinding(finding, planId, round, index, findingIndex);
@@ -413,7 +427,7 @@ function validateReviewFinding(finding, planId, round, reviewerIndex, findingInd
413
427
  typeof finding.recommendation !== "string" ||
414
428
  finding.recommendation.length < 1 ||
415
429
  finding.recommendation.length > 1_000) {
416
- throw new Error(`supervisor plan review ${planId} round ${round} reviewer ${reviewerIndex} finding ${findingIndex} is invalid`);
430
+ throw new Error(`governor plan review ${planId} round ${round} reviewer ${reviewerIndex} finding ${findingIndex} is invalid`);
417
431
  }
418
432
  }
419
433
  function summarizeReview(receipt) {
@@ -427,7 +441,7 @@ function summarizeReview(receipt) {
427
441
  };
428
442
  }
429
443
  function validateEvent(event, planId, sequence) {
430
- if (event.schema_version !== SUPERVISOR_PLAN_SCHEMA_VERSION ||
444
+ if (event.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
431
445
  event.plan_id !== planId ||
432
446
  event.seq !== sequence ||
433
447
  !EVENT_TYPES.has(event.event) ||
@@ -438,19 +452,25 @@ function validateEvent(event, planId, sequence) {
438
452
  typeof event.reason !== "string" ||
439
453
  event.reason.length < 1 ||
440
454
  event.reason.length > 2_000) {
441
- throw new Error(`supervisor plan ${planId} event ${sequence} has an unsupported schema`);
455
+ throw new Error(`governor plan ${planId} event ${sequence} has an unsupported schema`);
442
456
  }
443
457
  if (event.approval_id !== undefined && !APPROVAL_ID.test(event.approval_id)) {
444
- throw new Error(`supervisor plan ${planId} event ${sequence} has an invalid approval id`);
458
+ throw new Error(`governor plan ${planId} event ${sequence} has an invalid approval id`);
445
459
  }
446
460
  if (event.root_work_id !== undefined && !WORK_ID.test(event.root_work_id)) {
447
- throw new Error(`supervisor plan ${planId} event ${sequence} has an invalid root work id`);
461
+ throw new Error(`governor plan ${planId} event ${sequence} has an invalid root work id`);
448
462
  }
449
463
  if (event.work_ids !== undefined) {
450
464
  if (!Array.isArray(event.work_ids) || event.work_ids.some((id) => !WORK_ID.test(id))) {
451
- throw new Error(`supervisor plan ${planId} event ${sequence} has invalid work ids`);
465
+ throw new Error(`governor plan ${planId} event ${sequence} has invalid work ids`);
452
466
  }
453
467
  }
468
+ if (event.class !== undefined &&
469
+ event.class !== "environment" &&
470
+ event.class !== "upstream" &&
471
+ event.class !== "decision") {
472
+ throw new Error(`governor plan ${planId} event ${sequence} has an unknown failure class`);
473
+ }
454
474
  }
455
475
  function approvalIsResolved(coordRoot, approvalId) {
456
476
  const path = join(coordRoot, ".harnery", "approvals", approvalId, "decision.json");
@@ -478,7 +498,7 @@ function readJson(path, label) {
478
498
  }
479
499
  }
480
500
  function plansRoot(coordRoot, goalId) {
481
- return join(coordRoot, ".harnery", "supervisors", goalId, "plans");
501
+ return join(coordRoot, ".harnery", "governors", goalId, "plans");
482
502
  }
483
503
  function planDir(coordRoot, goalId, planId) {
484
504
  return join(plansRoot(coordRoot, goalId), planId);