harnery 0.30.0 → 0.31.1

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 (517) 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 +185 -74
  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/grep.d.ts +1 -1
  34. package/dist/commands/grep.d.ts.map +1 -1
  35. package/dist/commands/grep.js +19 -2
  36. package/dist/commands/init.d.ts +12 -12
  37. package/dist/commands/init.d.ts.map +1 -1
  38. package/dist/commands/init.js +44 -30
  39. package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
  40. package/dist/commands/journal.d.ts.map +1 -0
  41. package/dist/commands/{scratch.js → journal.js} +47 -47
  42. package/dist/commands/policy.js +1 -1
  43. package/dist/commands/presence.js +2 -2
  44. package/dist/commands/sync.d.ts +1 -1
  45. package/dist/commands/sync.js +3 -3
  46. package/dist/commands/tunnel.d.ts +16 -0
  47. package/dist/commands/tunnel.d.ts.map +1 -1
  48. package/dist/commands/tunnel.js +213 -27
  49. package/dist/commands/web-fetch.js +1 -1
  50. package/dist/commands/web.d.ts +19 -0
  51. package/dist/commands/web.d.ts.map +1 -1
  52. package/dist/commands/web.js +51 -0
  53. package/dist/commands/work.d.ts.map +1 -1
  54. package/dist/commands/work.js +38 -22
  55. package/dist/commands/workflow.d.ts.map +1 -1
  56. package/dist/commands/workflow.js +35 -28
  57. package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
  58. package/dist/core/adapters/attest-projection.d.ts.map +1 -0
  59. package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
  60. package/dist/core/adapters/attest.d.ts.map +1 -0
  61. package/dist/core/{harnesses → adapters}/attest.js +9 -9
  62. package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
  63. package/dist/core/adapters/attestation.d.ts.map +1 -0
  64. package/dist/core/{harnesses → adapters}/attestation.js +20 -20
  65. package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
  66. package/dist/core/adapters/bench.d.ts.map +1 -0
  67. package/dist/core/{harnesses → adapters}/bench.js +12 -12
  68. package/dist/core/adapters/index.d.ts +13 -0
  69. package/dist/core/adapters/index.d.ts.map +1 -0
  70. package/dist/core/adapters/index.js +6 -0
  71. package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
  72. package/dist/core/adapters/profiles.d.ts.map +1 -0
  73. package/dist/core/{harnesses → adapters}/profiles.js +11 -11
  74. package/dist/core/adapters/registry.d.ts +15 -0
  75. package/dist/core/adapters/registry.d.ts.map +1 -0
  76. package/dist/core/{harnesses → adapters}/registry.js +11 -11
  77. package/dist/core/{harnesses → adapters}/types.d.ts +23 -23
  78. package/dist/core/adapters/types.d.ts.map +1 -0
  79. package/dist/core/{harnesses → adapters}/types.js +1 -1
  80. package/dist/core/agents/canonical-emit.d.ts +9 -14
  81. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  82. package/dist/core/agents/canonical-emit.js +15 -44
  83. package/dist/core/agents/cli-emit.js +1 -1
  84. package/dist/core/agents/cli.js +30 -26
  85. package/dist/core/agents/codex-replay.d.ts +1 -1
  86. package/dist/core/agents/codex-replay.js +6 -6
  87. package/dist/core/agents/coord-bin.d.ts +33 -0
  88. package/dist/core/agents/coord-bin.d.ts.map +1 -0
  89. package/dist/core/agents/coord-bin.js +89 -0
  90. package/dist/core/agents/coord-client.d.ts +78 -8
  91. package/dist/core/agents/coord-client.d.ts.map +1 -1
  92. package/dist/core/agents/coord-client.js +303 -75
  93. package/dist/core/agents/events/consume.d.ts +1 -1
  94. package/dist/core/agents/events/emit.d.ts +5 -6
  95. package/dist/core/agents/events/emit.d.ts.map +1 -1
  96. package/dist/core/agents/events/emit.js +2 -2
  97. package/dist/core/agents/paths.d.ts +5 -2
  98. package/dist/core/agents/paths.d.ts.map +1 -1
  99. package/dist/core/agents/paths.js +7 -13
  100. package/dist/core/agents/render/prompt-context.d.ts +21 -9
  101. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  102. package/dist/core/agents/render/prompt-context.js +82 -30
  103. package/dist/core/agents/render/session-context.d.ts +1 -1
  104. package/dist/core/agents/render/session-context.js +5 -5
  105. package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
  106. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  107. package/dist/core/agents/rules/claim-conflict.js +1 -1
  108. package/dist/core/agents/rules/commit-conflict.js +98 -22
  109. package/dist/core/agents/rules/stop-hook.d.ts +9 -9
  110. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  111. package/dist/core/agents/rules/stop-hook.js +23 -5
  112. package/dist/core/agents/rules/verdict.d.ts +14 -0
  113. package/dist/core/agents/rules/verdict.d.ts.map +1 -0
  114. package/dist/core/agents/rules/verdict.js +1 -0
  115. package/dist/core/agents/session-events.js +3 -3
  116. package/dist/core/agents/state/council.d.ts +1 -1
  117. package/dist/core/agents/state/council.js +1 -1
  118. package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
  119. package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
  120. package/dist/core/agents/state/heartbeat-projector.js +14 -10
  121. package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
  122. package/dist/core/agents/state/heartbeat-writer.js +12 -12
  123. package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
  124. package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
  125. package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
  126. package/dist/core/agents/state/pidmap.d.ts +28 -4
  127. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  128. package/dist/core/agents/state/pidmap.js +130 -15
  129. package/dist/core/agents/state/proc-start.d.ts +95 -0
  130. package/dist/core/agents/state/proc-start.d.ts.map +1 -0
  131. package/dist/core/agents/state/proc-start.js +199 -0
  132. package/dist/core/agents/state/shell-mutation.d.ts +1 -1
  133. package/dist/core/agents/state/shell-mutation.js +1 -1
  134. package/dist/core/agents/state/stale-sweep.js +7 -7
  135. package/dist/core/artifacts/index.d.ts +86 -0
  136. package/dist/core/artifacts/index.d.ts.map +1 -0
  137. package/dist/core/artifacts/index.js +421 -0
  138. package/dist/core/config.d.ts +9 -2
  139. package/dist/core/config.d.ts.map +1 -1
  140. package/dist/core/config.js +26 -2
  141. package/dist/core/context/index.d.ts +12 -12
  142. package/dist/core/context/index.js +10 -10
  143. package/dist/core/governor/adapter-spread.d.ts +52 -0
  144. package/dist/core/governor/adapter-spread.d.ts.map +1 -0
  145. package/dist/core/governor/adapter-spread.js +52 -0
  146. package/dist/core/governor/index.d.ts +7 -0
  147. package/dist/core/governor/index.d.ts.map +1 -0
  148. package/dist/core/governor/index.js +6 -0
  149. package/dist/core/governor/plan-api.d.ts +38 -0
  150. package/dist/core/governor/plan-api.d.ts.map +1 -0
  151. package/dist/core/governor/plan-api.js +83 -0
  152. package/dist/core/governor/plan-read.d.ts +5 -0
  153. package/dist/core/governor/plan-read.d.ts.map +1 -0
  154. package/dist/core/{supervisor → governor}/plan-read.js +66 -52
  155. package/dist/core/{supervisor → governor}/plan-types.d.ts +57 -56
  156. package/dist/core/governor/plan-types.d.ts.map +1 -0
  157. package/dist/core/{supervisor → governor}/plan-types.js +4 -4
  158. package/dist/core/governor/planning.d.ts +48 -0
  159. package/dist/core/governor/planning.d.ts.map +1 -0
  160. package/dist/core/{supervisor → governor}/planning.js +125 -94
  161. package/dist/core/governor/read.d.ts +6 -0
  162. package/dist/core/governor/read.d.ts.map +1 -0
  163. package/dist/core/governor/read.js +4 -0
  164. package/dist/core/governor/runner.d.ts +37 -0
  165. package/dist/core/governor/runner.d.ts.map +1 -0
  166. package/dist/core/{supervisor → governor}/runner.js +15 -15
  167. package/dist/core/governor/service-read.d.ts +6 -0
  168. package/dist/core/governor/service-read.d.ts.map +1 -0
  169. package/dist/core/{supervisor → governor}/service-read.js +12 -12
  170. package/dist/core/governor/service.d.ts +114 -0
  171. package/dist/core/governor/service.d.ts.map +1 -0
  172. package/dist/core/{supervisor → governor}/service.js +57 -57
  173. package/dist/core/governor/state.d.ts +116 -0
  174. package/dist/core/governor/state.d.ts.map +1 -0
  175. package/dist/core/{supervisor → governor}/state.js +228 -108
  176. package/dist/core/hooks/adapter/detect.d.ts +9 -0
  177. package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
  178. package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
  179. package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
  180. package/dist/core/hooks/adapter/events.d.ts.map +1 -0
  181. package/dist/core/hooks/{harness → adapter}/events.js +5 -5
  182. package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
  183. package/dist/core/hooks/adapter/output.d.ts.map +1 -0
  184. package/dist/core/hooks/{harness → adapter}/output.js +30 -22
  185. package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
  186. package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
  187. package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
  188. package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
  189. package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
  190. package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
  191. package/dist/core/hooks/cli.d.ts +3 -3
  192. package/dist/core/hooks/cli.js +187 -162
  193. package/dist/core/hooks/effects/image-capture.d.ts +5 -5
  194. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  195. package/dist/core/hooks/effects/image-capture.js +3 -3
  196. package/dist/core/hooks/effects/index.d.ts +12 -12
  197. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  198. package/dist/core/hooks/effects/index.js +19 -19
  199. package/dist/core/hooks/events/emit.d.ts +2 -2
  200. package/dist/core/hooks/events/emit.d.ts.map +1 -1
  201. package/dist/core/hooks/events/emit.js +1 -1
  202. package/dist/core/hooks/events/rotate.js +1 -1
  203. package/dist/core/hooks/events/schema.d.ts +13 -5
  204. package/dist/core/hooks/events/schema.d.ts.map +1 -1
  205. package/dist/core/hooks/guard-path.d.ts +2 -2
  206. package/dist/core/hooks/guard-path.js +2 -2
  207. package/dist/core/hooks/index.d.ts +1 -1
  208. package/dist/core/hooks/index.d.ts.map +1 -1
  209. package/dist/core/hooks/resolve/anchor.d.ts +14 -5
  210. package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
  211. package/dist/core/hooks/resolve/anchor.js +64 -7
  212. package/dist/core/hooks/resolve/coord-root.d.ts +16 -11
  213. package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
  214. package/dist/core/hooks/resolve/coord-root.js +18 -43
  215. package/dist/core/hooks/resolve/intent.js +1 -1
  216. package/dist/core/hooks/resolve/owner.d.ts +1 -1
  217. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  218. package/dist/core/hooks/resolve/owner.js +11 -5
  219. package/dist/core/{scratch → journal}/index.d.ts +25 -25
  220. package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
  221. package/dist/core/{scratch → journal}/index.js +38 -38
  222. package/dist/core/policy/evaluate.d.ts +1 -1
  223. package/dist/core/policy/evaluate.d.ts.map +1 -1
  224. package/dist/core/policy/evaluate.js +7 -7
  225. package/dist/core/policy/types.d.ts +3 -3
  226. package/dist/core/policy/types.d.ts.map +1 -1
  227. package/dist/core/work/state.d.ts +12 -4
  228. package/dist/core/work/state.d.ts.map +1 -1
  229. package/dist/core/work/state.js +50 -17
  230. package/dist/core/workflow/adapters.d.ts +17 -0
  231. package/dist/core/workflow/adapters.d.ts.map +1 -0
  232. package/dist/core/workflow/adapters.js +21 -0
  233. package/dist/core/workflow/approvals.js +6 -6
  234. package/dist/core/workflow/billing.d.ts +9 -9
  235. package/dist/core/workflow/billing.js +9 -9
  236. package/dist/core/workflow/child-env.d.ts +10 -2
  237. package/dist/core/workflow/child-env.d.ts.map +1 -1
  238. package/dist/core/workflow/child-env.js +12 -4
  239. package/dist/core/workflow/engine.d.ts +15 -5
  240. package/dist/core/workflow/engine.d.ts.map +1 -1
  241. package/dist/core/workflow/engine.js +138 -83
  242. package/dist/core/workflow/evidence-preflight.d.ts +24 -0
  243. package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
  244. package/dist/core/workflow/evidence-preflight.js +134 -0
  245. package/dist/core/workflow/index.d.ts +1 -1
  246. package/dist/core/workflow/index.d.ts.map +1 -1
  247. package/dist/core/workflow/proof.d.ts +11 -5
  248. package/dist/core/workflow/proof.d.ts.map +1 -1
  249. package/dist/core/workflow/proof.js +45 -36
  250. package/dist/core/workflow/run-state.d.ts +1 -1
  251. package/dist/core/workflow/run-state.js +7 -7
  252. package/dist/core/workflow/sandbox-projection.d.ts +6 -6
  253. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  254. package/dist/core/workflow/sandbox-projection.js +11 -11
  255. package/dist/core/workflow/spawn-claude.d.ts +3 -3
  256. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  257. package/dist/core/workflow/spawn-claude.js +9 -6
  258. package/dist/core/workflow/spawn-codex.d.ts +4 -4
  259. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  260. package/dist/core/workflow/spawn-codex.js +9 -6
  261. package/dist/core/workflow/spawn-cursor.d.ts +4 -4
  262. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  263. package/dist/core/workflow/spawn-cursor.js +9 -6
  264. package/dist/core/workflow/spawn-failure.d.ts +1 -1
  265. package/dist/core/workflow/spawn-failure.js +1 -1
  266. package/dist/core/workflow/specialists.js +2 -2
  267. package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
  268. package/dist/core/workflow/transcript.d.ts.map +1 -0
  269. package/dist/core/workflow/{journal.js → transcript.js} +14 -14
  270. package/dist/core/workflow/types.d.ts +98 -51
  271. package/dist/core/workflow/types.d.ts.map +1 -1
  272. package/dist/core/workflow/types.js +11 -1
  273. package/dist/core/workflow/validate.d.ts +1 -1
  274. package/dist/core/workflow/validate.js +1 -1
  275. package/dist/core/workflow/workspaces/cancellation.js +2 -2
  276. package/dist/core/workflow/workspaces/cleanup.js +2 -2
  277. package/dist/core/workflow/workspaces/execution.js +6 -6
  278. package/dist/core/workflow/workspaces/inspect.js +9 -9
  279. package/dist/core/workflow/workspaces/integration.js +14 -14
  280. package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
  281. package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
  282. package/dist/core/workflow/workspaces/lifecycle.js +9 -9
  283. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  284. package/dist/core/workflow/workspaces/local-git.js +39 -5
  285. package/dist/core/workflow/workspaces/recovery.js +3 -3
  286. package/dist/core/workflow/workspaces/state.d.ts +1 -1
  287. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  288. package/dist/core/workflow/workspaces/state.js +3 -3
  289. package/dist/core/workflow/workspaces/types.d.ts +1 -1
  290. package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
  291. package/dist/lib/browser/asserts.d.ts +28 -0
  292. package/dist/lib/browser/asserts.d.ts.map +1 -0
  293. package/dist/lib/browser/asserts.js +152 -0
  294. package/dist/lib/browser/client.d.ts +49 -0
  295. package/dist/lib/browser/client.d.ts.map +1 -1
  296. package/dist/lib/browser/client.js +155 -14
  297. package/dist/lib/browser/content-checks.d.ts +108 -0
  298. package/dist/lib/browser/content-checks.d.ts.map +1 -0
  299. package/dist/lib/browser/content-checks.js +474 -0
  300. package/dist/lib/browser/critique.d.ts +91 -0
  301. package/dist/lib/browser/critique.d.ts.map +1 -0
  302. package/dist/lib/browser/critique.js +167 -0
  303. package/dist/lib/browser/geometry.d.ts +32 -0
  304. package/dist/lib/browser/geometry.d.ts.map +1 -1
  305. package/dist/lib/browser/geometry.js +244 -1
  306. package/dist/lib/browser/index.d.ts +4 -1
  307. package/dist/lib/browser/index.d.ts.map +1 -1
  308. package/dist/lib/browser/index.js +2 -0
  309. package/dist/lib/claude-desktop.d.ts.map +1 -1
  310. package/dist/lib/claude-desktop.js +4 -1
  311. package/dist/lib/context/index.js +9 -2
  312. package/dist/lib/council/index.d.ts +6 -6
  313. package/dist/lib/council/index.d.ts.map +1 -1
  314. package/dist/lib/council/index.js +8 -8
  315. package/dist/lib/identities/assume.d.ts +2 -2
  316. package/dist/lib/identities/assume.js +7 -7
  317. package/dist/lib/instructions/apply.d.ts +3 -3
  318. package/dist/lib/instructions/apply.d.ts.map +1 -1
  319. package/dist/lib/instructions/apply.js +75 -27
  320. package/dist/lib/instructions/host-addendum.d.ts +54 -0
  321. package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
  322. package/dist/lib/instructions/host-addendum.js +107 -0
  323. package/dist/lib/instructions/templates.d.ts +10 -3
  324. package/dist/lib/instructions/templates.d.ts.map +1 -1
  325. package/dist/lib/instructions/templates.js +41 -12
  326. package/dist/lib/machine.d.ts +2 -2
  327. package/dist/lib/machine.js +2 -2
  328. package/package.json +26 -21
  329. package/schemas/config.schema.json +26 -1
  330. package/src/commander.ts +22 -13
  331. package/src/commands/{harness.ts → adapter.ts} +46 -46
  332. package/src/commands/agents.ts +200 -78
  333. package/src/commands/artifacts.ts +168 -0
  334. package/src/commands/backup.ts +47 -33
  335. package/src/commands/browse.ts +438 -2
  336. package/src/commands/checkpoint.ts +196 -0
  337. package/src/commands/context.ts +3 -176
  338. package/src/commands/decision.ts +41 -7
  339. package/src/commands/deinit.ts +16 -16
  340. package/src/commands/doctor.ts +28 -28
  341. package/src/commands/{supervisor.ts → governor.ts} +184 -154
  342. package/src/commands/grep.ts +19 -2
  343. package/src/commands/init.ts +50 -34
  344. package/src/commands/{scratch.ts → journal.ts} +60 -60
  345. package/src/commands/policy.ts +1 -1
  346. package/src/commands/presence.ts +2 -2
  347. package/src/commands/sync.ts +3 -3
  348. package/src/commands/tunnel.ts +256 -38
  349. package/src/commands/web-fetch.ts +1 -1
  350. package/src/commands/web.ts +56 -1
  351. package/src/commands/work.ts +50 -35
  352. package/src/commands/workflow.ts +43 -34
  353. package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
  354. package/src/core/{harnesses → adapters}/attest.ts +27 -27
  355. package/src/core/{harnesses → adapters}/attestation.ts +41 -41
  356. package/src/core/{harnesses → adapters}/bench.ts +34 -43
  357. package/src/core/adapters/index.ts +56 -0
  358. package/src/core/{harnesses → adapters}/profiles.ts +16 -16
  359. package/src/core/{harnesses → adapters}/registry.ts +23 -23
  360. package/src/core/{harnesses → adapters}/types.ts +23 -23
  361. package/src/core/agents/canonical-emit.ts +16 -43
  362. package/src/core/agents/cli-emit.ts +1 -1
  363. package/src/core/agents/cli.ts +30 -28
  364. package/src/core/agents/codex-replay.ts +6 -6
  365. package/src/core/agents/coord-bin.ts +92 -0
  366. package/src/core/agents/coord-client.ts +302 -78
  367. package/src/core/agents/events/consume.ts +1 -1
  368. package/src/core/agents/events/emit.ts +7 -6
  369. package/src/core/agents/paths.ts +7 -11
  370. package/src/core/agents/render/prompt-context.ts +107 -31
  371. package/src/core/agents/render/session-context.ts +6 -6
  372. package/src/core/agents/rules/claim-conflict.ts +4 -7
  373. package/src/core/agents/rules/commit-conflict.ts +103 -22
  374. package/src/core/agents/rules/stop-hook.ts +33 -17
  375. package/src/core/agents/rules/verdict.ts +13 -0
  376. package/src/core/agents/session-events.ts +4 -4
  377. package/src/core/agents/state/council.ts +1 -1
  378. package/src/core/agents/state/heartbeat-projector.ts +16 -12
  379. package/src/core/agents/state/heartbeat-writer.ts +12 -12
  380. package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
  381. package/src/core/agents/state/pidmap.ts +130 -15
  382. package/src/core/agents/state/proc-start.ts +208 -0
  383. package/src/core/agents/state/shell-mutation.ts +1 -1
  384. package/src/core/agents/state/stale-sweep.ts +7 -7
  385. package/src/core/artifacts/index.ts +557 -0
  386. package/src/core/config.ts +30 -2
  387. package/src/core/context/index.ts +15 -15
  388. package/src/core/governor/adapter-spread.ts +82 -0
  389. package/src/core/governor/index.ts +91 -0
  390. package/src/core/governor/plan-api.ts +115 -0
  391. package/src/core/{supervisor → governor}/plan-read.ts +112 -97
  392. package/src/core/{supervisor → governor}/plan-types.ts +59 -56
  393. package/src/core/{supervisor → governor}/planning.ts +223 -192
  394. package/src/core/governor/read.ts +59 -0
  395. package/src/core/{supervisor → governor}/runner.ts +39 -39
  396. package/src/core/{supervisor → governor}/service-read.ts +22 -22
  397. package/src/core/{supervisor → governor}/service.ts +117 -119
  398. package/src/core/{supervisor → governor}/state.ts +325 -167
  399. package/src/core/hooks/adapter/detect.ts +30 -0
  400. package/src/core/hooks/{harness → adapter}/events.ts +16 -14
  401. package/src/core/hooks/{harness → adapter}/output.ts +31 -23
  402. package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
  403. package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
  404. package/src/core/hooks/cli.ts +197 -173
  405. package/src/core/hooks/effects/image-capture.ts +6 -6
  406. package/src/core/hooks/effects/index.ts +19 -19
  407. package/src/core/hooks/events/emit.ts +3 -3
  408. package/src/core/hooks/events/rotate.ts +1 -1
  409. package/src/core/hooks/events/schema.ts +15 -7
  410. package/src/core/hooks/guard-path.ts +2 -2
  411. package/src/core/hooks/index.ts +1 -1
  412. package/src/core/hooks/resolve/anchor.ts +63 -8
  413. package/src/core/hooks/resolve/coord-root.ts +18 -40
  414. package/src/core/hooks/resolve/intent.ts +1 -1
  415. package/src/core/hooks/resolve/owner.ts +11 -5
  416. package/src/core/{scratch → journal}/index.ts +53 -53
  417. package/src/core/policy/evaluate.ts +8 -8
  418. package/src/core/policy/types.ts +3 -3
  419. package/src/core/work/state.ts +65 -23
  420. package/src/core/workflow/adapters.ts +33 -0
  421. package/src/core/workflow/approvals.ts +7 -7
  422. package/src/core/workflow/billing.ts +12 -12
  423. package/src/core/workflow/child-env.ts +13 -4
  424. package/src/core/workflow/engine.ts +155 -90
  425. package/src/core/workflow/evidence-preflight.ts +165 -0
  426. package/src/core/workflow/index.ts +3 -3
  427. package/src/core/workflow/proof.ts +60 -50
  428. package/src/core/workflow/run-state.ts +7 -7
  429. package/src/core/workflow/sandbox-projection.ts +16 -16
  430. package/src/core/workflow/spawn-claude.ts +13 -10
  431. package/src/core/workflow/spawn-codex.ts +13 -10
  432. package/src/core/workflow/spawn-cursor.ts +13 -10
  433. package/src/core/workflow/spawn-failure.ts +1 -1
  434. package/src/core/workflow/specialists.ts +2 -2
  435. package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
  436. package/src/core/workflow/types.ts +108 -51
  437. package/src/core/workflow/validate.ts +1 -1
  438. package/src/core/workflow/workspaces/cancellation.ts +2 -2
  439. package/src/core/workflow/workspaces/cleanup.ts +2 -2
  440. package/src/core/workflow/workspaces/execution.ts +6 -6
  441. package/src/core/workflow/workspaces/inspect.ts +14 -11
  442. package/src/core/workflow/workspaces/integration.ts +18 -14
  443. package/src/core/workflow/workspaces/lifecycle.ts +10 -10
  444. package/src/core/workflow/workspaces/local-git.ts +47 -5
  445. package/src/core/workflow/workspaces/recovery.ts +3 -3
  446. package/src/core/workflow/workspaces/state.ts +4 -3
  447. package/src/core/workflow/workspaces/types.ts +1 -1
  448. package/src/lib/browser/asserts.ts +177 -0
  449. package/src/lib/browser/client.ts +189 -14
  450. package/src/lib/browser/content-checks.ts +571 -0
  451. package/src/lib/browser/critique.ts +231 -0
  452. package/src/lib/browser/geometry.ts +297 -1
  453. package/src/lib/browser/index.ts +34 -0
  454. package/src/lib/claude-desktop.ts +4 -1
  455. package/src/lib/context/index.ts +11 -1
  456. package/src/lib/council/index.ts +9 -9
  457. package/src/lib/identities/assume.ts +7 -7
  458. package/src/lib/instructions/apply.ts +87 -25
  459. package/src/lib/instructions/host-addendum.ts +126 -0
  460. package/src/lib/instructions/templates.ts +44 -15
  461. package/src/lib/machine.ts +2 -2
  462. package/dist/commands/harness.d.ts +0 -12
  463. package/dist/commands/harness.d.ts.map +0 -1
  464. package/dist/commands/scratch.d.ts +0 -4
  465. package/dist/commands/scratch.d.ts.map +0 -1
  466. package/dist/commands/session.d.ts.map +0 -1
  467. package/dist/commands/session.js +0 -162
  468. package/dist/commands/supervisor.d.ts +0 -4
  469. package/dist/commands/supervisor.d.ts.map +0 -1
  470. package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
  471. package/dist/core/harnesses/attest.d.ts.map +0 -1
  472. package/dist/core/harnesses/attestation.d.ts.map +0 -1
  473. package/dist/core/harnesses/bench.d.ts.map +0 -1
  474. package/dist/core/harnesses/index.d.ts +0 -13
  475. package/dist/core/harnesses/index.d.ts.map +0 -1
  476. package/dist/core/harnesses/index.js +0 -6
  477. package/dist/core/harnesses/profiles.d.ts.map +0 -1
  478. package/dist/core/harnesses/registry.d.ts +0 -15
  479. package/dist/core/harnesses/registry.d.ts.map +0 -1
  480. package/dist/core/harnesses/types.d.ts.map +0 -1
  481. package/dist/core/hooks/harness/detect.d.ts +0 -9
  482. package/dist/core/hooks/harness/events.d.ts.map +0 -1
  483. package/dist/core/hooks/harness/output.d.ts.map +0 -1
  484. package/dist/core/supervisor/index.d.ts +0 -7
  485. package/dist/core/supervisor/index.d.ts.map +0 -1
  486. package/dist/core/supervisor/index.js +0 -6
  487. package/dist/core/supervisor/plan-api.d.ts +0 -23
  488. package/dist/core/supervisor/plan-api.d.ts.map +0 -1
  489. package/dist/core/supervisor/plan-api.js +0 -50
  490. package/dist/core/supervisor/plan-read.d.ts +0 -5
  491. package/dist/core/supervisor/plan-read.d.ts.map +0 -1
  492. package/dist/core/supervisor/plan-types.d.ts.map +0 -1
  493. package/dist/core/supervisor/planning.d.ts +0 -33
  494. package/dist/core/supervisor/planning.d.ts.map +0 -1
  495. package/dist/core/supervisor/read.d.ts +0 -6
  496. package/dist/core/supervisor/read.d.ts.map +0 -1
  497. package/dist/core/supervisor/read.js +0 -4
  498. package/dist/core/supervisor/runner.d.ts +0 -37
  499. package/dist/core/supervisor/runner.d.ts.map +0 -1
  500. package/dist/core/supervisor/service-read.d.ts +0 -6
  501. package/dist/core/supervisor/service-read.d.ts.map +0 -1
  502. package/dist/core/supervisor/service.d.ts +0 -114
  503. package/dist/core/supervisor/service.d.ts.map +0 -1
  504. package/dist/core/supervisor/state.d.ts +0 -95
  505. package/dist/core/supervisor/state.d.ts.map +0 -1
  506. package/dist/core/workflow/harnesses.d.ts +0 -17
  507. package/dist/core/workflow/harnesses.d.ts.map +0 -1
  508. package/dist/core/workflow/harnesses.js +0 -21
  509. package/dist/core/workflow/journal.d.ts.map +0 -1
  510. package/src/commands/session.ts +0 -187
  511. package/src/core/harnesses/index.ts +0 -56
  512. package/src/core/hooks/harness/detect.ts +0 -30
  513. package/src/core/supervisor/index.ts +0 -89
  514. package/src/core/supervisor/plan-api.ts +0 -73
  515. package/src/core/supervisor/read.ts +0 -59
  516. package/src/core/workflow/harnesses.ts +0 -33
  517. /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
@@ -5,9 +5,9 @@ import { dirname, isAbsolute, join, resolve } from "node:path";
5
5
  import { assertWorkId, readWorkItem } from "../work/read.js";
6
6
  import { workflowScriptDigest } from "../workflow/run-state.js";
7
7
  import { normalizeWorkflowSpecialists } from "../workflow/specialists.js";
8
- import { readSupervisorPlans } from "./plan-read.js";
9
- import { MAX_SUPERVISOR_PLAN_REVIEWERS, MAX_SUPERVISOR_PLAN_REVISION_ROUNDS, supervisorGraphFingerprint, } from "./plan-types.js";
10
- export const SUPERVISOR_INTENT_SCHEMA_VERSION = 1;
8
+ import { readGovernorPlans } from "./plan-read.js";
9
+ import { governorGraphFingerprint, MAX_GOVERNOR_PLAN_REVIEWERS, MAX_GOVERNOR_PLAN_REVISION_ROUNDS, } from "./plan-types.js";
10
+ export const GOVERNOR_INTENT_SCHEMA_VERSION = 1;
11
11
  const GOAL_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
12
12
  const MAX_TITLE = 200;
13
13
  const MAX_OBJECTIVE = 4_000;
@@ -23,16 +23,16 @@ const FOREIGN_LEASE_STALE_MS = 24 * 60 * 60 * 1_000;
23
23
  * rather than a policy field to keep the frozen replanning schema unchanged; an
24
24
  * environment failure self-bounds at one because it stops immediately. */
25
25
  const MAX_UNCHARGED_REPLANS = 3;
26
- export function createSupervisor(input) {
26
+ export function createGovernor(input) {
27
27
  const coordRoot = resolve(input.coordRoot);
28
- const id = input.id ?? newSupervisorId();
29
- assertSupervisorId(id);
28
+ const id = input.id ?? newGovernorId();
29
+ assertGovernorId(id);
30
30
  const mission = input.mission ? normalizeMission(input.mission) : undefined;
31
31
  if (mission && !input.replanning) {
32
- throw new Error("supervisor mission requires a replanning policy");
32
+ throw new Error("governor mission requires a replanning policy");
33
33
  }
34
34
  if (!input.rootWorkId && !mission) {
35
- throw new Error("supervisor creation without root work requires a mission and replanning policy");
35
+ throw new Error("governor creation without root work requires a mission and replanning policy");
36
36
  }
37
37
  if (input.rootWorkId)
38
38
  assertWorkId(input.rootWorkId);
@@ -48,9 +48,9 @@ export function createSupervisor(input) {
48
48
  throw new Error("objective-first mission max_replans must exceed max_milestones to reserve completion review");
49
49
  }
50
50
  const intent = {
51
- schema_version: SUPERVISOR_INTENT_SCHEMA_VERSION,
51
+ schema_version: GOVERNOR_INTENT_SCHEMA_VERSION,
52
52
  id,
53
- title: bounded(input.title ?? root?.intent.title ?? missionTitle(mission), "supervisor title", MAX_TITLE),
53
+ title: bounded(input.title ?? root?.intent.title ?? missionTitle(mission), "governor title", MAX_TITLE),
54
54
  root_work_id: input.rootWorkId ?? missionRootId(id),
55
55
  specialists: normalizeWorkflowSpecialists(input.specialists),
56
56
  limits,
@@ -59,39 +59,39 @@ export function createSupervisor(input) {
59
59
  ...(replanning ? { replanning } : {}),
60
60
  created_at: new Date().toISOString(),
61
61
  };
62
- const path = supervisorIntentPath(coordRoot, id);
62
+ const path = governorIntentPath(coordRoot, id);
63
63
  mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
64
64
  chmodSync(dirname(path), 0o700);
65
65
  writePrivateJson(path, intent);
66
- return readSupervisor(coordRoot, id);
66
+ return readGovernor(coordRoot, id);
67
67
  }
68
- export function readSupervisor(coordRoot, goalId) {
69
- return readSupervisorInternal(coordRoot, goalId, false);
68
+ export function readGovernor(coordRoot, goalId) {
69
+ return readGovernorInternal(coordRoot, goalId, false);
70
70
  }
71
- /** @internal Runner seam; ignores the lease held by this supervisor process. */
72
- export function readSupervisorIgnoringLease(coordRoot, goalId) {
73
- return readSupervisorInternal(coordRoot, goalId, true);
71
+ /** @internal Runner seam; ignores the lease held by this governor process. */
72
+ export function readGovernorIgnoringLease(coordRoot, goalId) {
73
+ return readGovernorInternal(coordRoot, goalId, true);
74
74
  }
75
- export function listSupervisors(coordRoot) {
76
- const base = join(resolve(coordRoot), ".harnery", "supervisors");
75
+ export function listGovernors(coordRoot) {
76
+ const base = join(resolve(coordRoot), ".harnery", "governors");
77
77
  if (!existsSync(base))
78
78
  return [];
79
79
  const records = [];
80
80
  for (const name of readdirSync(base)) {
81
- if (!GOAL_ID.test(name) || !existsSync(supervisorIntentPath(coordRoot, name)))
81
+ if (!GOAL_ID.test(name) || !existsSync(governorIntentPath(coordRoot, name)))
82
82
  continue;
83
- records.push(readSupervisor(coordRoot, name));
83
+ records.push(readGovernor(coordRoot, name));
84
84
  }
85
85
  return records.sort((left, right) => right.intent.created_at.localeCompare(left.intent.created_at));
86
86
  }
87
- export function collectSupervisorWork(coordRoot, rootWorkId) {
87
+ export function collectGovernorWork(coordRoot, rootWorkId) {
88
88
  const records = new Map();
89
89
  const visiting = new Set();
90
90
  const visit = (workId) => {
91
91
  if (records.has(workId))
92
92
  return;
93
93
  if (visiting.has(workId))
94
- throw new Error(`supervisor work graph contains a cycle at ${workId}`);
94
+ throw new Error(`governor work graph contains a cycle at ${workId}`);
95
95
  visiting.add(workId);
96
96
  const record = readWorkItem(coordRoot, workId);
97
97
  for (const dependency of record.intent.dependencies)
@@ -102,17 +102,17 @@ export function collectSupervisorWork(coordRoot, rootWorkId) {
102
102
  visit(rootWorkId);
103
103
  return Array.from(records.values());
104
104
  }
105
- export function assertSupervisorId(goalId) {
105
+ export function assertGovernorId(goalId) {
106
106
  if (!GOAL_ID.test(goalId))
107
- throw new Error(`invalid supervisor id ${JSON.stringify(goalId)}`);
107
+ throw new Error(`invalid governor id ${JSON.stringify(goalId)}`);
108
108
  }
109
- export function newSupervisorId() {
109
+ export function newGovernorId() {
110
110
  return `goal-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(3).toString("hex")}`;
111
111
  }
112
- /** @internal Runner seam; one exclusive crash-recoverable supervisor lease. */
113
- export function acquireSupervisorLease(coordRoot, goalId) {
114
- readSupervisorIntent(coordRoot, goalId);
115
- const path = join(supervisorDir(coordRoot, goalId), "lease.json");
112
+ /** @internal Runner seam; one exclusive crash-recoverable governor lease. */
113
+ export function acquireGovernorLease(coordRoot, goalId) {
114
+ readGovernorIntent(coordRoot, goalId);
115
+ const path = join(governorDir(coordRoot, goalId), "lease.json");
116
116
  const owner = {
117
117
  pid: process.pid,
118
118
  host: hostname(),
@@ -140,11 +140,11 @@ export function acquireSupervisorLease(coordRoot, goalId) {
140
140
  if (!acquire()) {
141
141
  const existing = readLease(path);
142
142
  if (existing && leaseIsLive(existing)) {
143
- throw new Error(`supervisor ${goalId} is already running under pid ${existing.pid} on ${existing.host}`);
143
+ throw new Error(`governor ${goalId} is already running under pid ${existing.pid} on ${existing.host}`);
144
144
  }
145
145
  unlinkSync(path);
146
146
  if (!acquire())
147
- throw new Error(`supervisor ${goalId} lease raced with another process`);
147
+ throw new Error(`governor ${goalId} lease raced with another process`);
148
148
  }
149
149
  return () => {
150
150
  try {
@@ -157,15 +157,15 @@ export function acquireSupervisorLease(coordRoot, goalId) {
157
157
  }
158
158
  };
159
159
  }
160
- function readSupervisorInternal(coordRootRaw, goalId, ignoreLease) {
160
+ function readGovernorInternal(coordRootRaw, goalId, ignoreLease) {
161
161
  const coordRoot = resolve(coordRootRaw);
162
- const intent = readSupervisorIntent(coordRoot, goalId);
163
- const plans = readSupervisorPlans(coordRoot, intent.id, intent.root_work_id);
162
+ const intent = readGovernorIntent(coordRoot, goalId);
163
+ const plans = readGovernorPlans(coordRoot, intent.id, intent.root_work_id);
164
164
  const activeRootExists = workIntentExists(coordRoot, plans.active_root_work_id);
165
165
  if (!activeRootExists && (!intent.mission || plans.generation > 0)) {
166
- throw new Error(`supervisor ${intent.id} root work is missing`);
166
+ throw new Error(`governor ${intent.id} root work is missing`);
167
167
  }
168
- const work = activeRootExists ? collectSupervisorWork(coordRoot, plans.active_root_work_id) : [];
168
+ const work = activeRootExists ? collectGovernorWork(coordRoot, plans.active_root_work_id) : [];
169
169
  const governed = collectGovernedWork(coordRoot, intent.root_work_id, plans, work);
170
170
  return {
171
171
  intent,
@@ -184,8 +184,13 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
184
184
  // Replans, like per-item attempts (ADR 0046), are budgeted by the CHARGED
185
185
  // count: an uncharged planner failure (environment/upstream) does not spend
186
186
  // max_replans. replans_used stays the raw count for display.
187
- const unchargedReplans = plans.plans.filter((plan) => plan.status === "failed" && (plan.class === "environment" || plan.class === "upstream")).length;
187
+ const unchargedReplans = plans.plans.filter((plan) => plan.status === "failed" && isUnchargedPlanClass(plan.class)).length;
188
188
  const chargedReplans = plans.plans.length - unchargedReplans;
189
+ // Attribute the consumed replans that did not advance the graph so the
190
+ // projection can distinguish planner no-proposal exhaustion from reviewer
191
+ // rejection through existing plan seams (review receipt presence), rather than
192
+ // reporting both as a single undifferentiated replan exhaustion.
193
+ const replanConsumption = classifyReplanConsumption(plans);
189
194
  const readyWork = work
190
195
  .filter((record) => record.projection.state === "ready")
191
196
  .map((record) => record.intent.id);
@@ -209,6 +214,15 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
209
214
  const terminalBlocked = work
210
215
  .filter((record) => record.projection.state === "blocked" && record.projection.next_action === "none")
211
216
  .map((record) => record.intent.id);
217
+ // Work stopped on a person, kept apart from the rest of terminalBlocked. Every
218
+ // other terminal block is something an agent could in principle clear; this one
219
+ // can only be cleared by a ruling, so it is the thing worth saying out loud.
220
+ const decisionBlocked = work
221
+ .filter((record) => record.projection.blocked_on_decision !== undefined)
222
+ .map((record) => ({
223
+ work_id: record.intent.id,
224
+ decision_id: record.projection.blocked_on_decision || undefined,
225
+ }));
212
226
  const attentionWork = unique([
213
227
  ...pendingApproval,
214
228
  ...(intent.automation.accept_passing_proof ? [] : reviews),
@@ -220,6 +234,12 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
220
234
  const initialRootAccepted = intent.mission !== undefined &&
221
235
  governed.some((record) => record.intent.id === intent.root_work_id && record.projection.state === "succeeded");
222
236
  const milestonesCompleted = plans.milestones_completed + (initialRootAccepted ? 1 : 0);
237
+ const resumableDispatchable = intent.automation.resume_approved ? resumableWork : [];
238
+ const attemptDispatchable = [
239
+ ...readyWork,
240
+ ...(intent.automation.retry_blocked ? retryableWork : []),
241
+ ];
242
+ const dispatchable = [...resumableDispatchable, ...attemptDispatchable];
223
243
  const base = {
224
244
  id: intent.id,
225
245
  title: intent.title,
@@ -230,6 +250,7 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
230
250
  resumable_work: resumableWork,
231
251
  retryable_work: retryableWork,
232
252
  attention_work: attentionWork,
253
+ decision_blocked_work: decisionBlocked,
233
254
  attempts_used: attemptsUsed,
234
255
  attempts_remaining: Math.max(0, intent.limits.max_total_attempts - chargedUsed),
235
256
  specialists: Object.keys(intent.specialists),
@@ -240,13 +261,14 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
240
261
  milestones_remaining: Math.max(0, (intent.mission?.max_milestones ?? 0) - milestonesCompleted),
241
262
  pending_plan_id: plans.latest?.status === "proposed" ? plans.latest.request.id : undefined,
242
263
  latest_plan_status: plans.latest?.status,
264
+ ...(replanConsumption.planner_no_proposal > 0 ? { replan_consumption: replanConsumption } : {}),
243
265
  governed_work_ids: governed.map((record) => record.intent.id),
244
266
  };
245
- if (!ignoreLease && supervisorLeaseIsLive(coordRoot, intent.id)) {
267
+ if (!ignoreLease && governorLeaseIsLive(coordRoot, intent.id)) {
246
268
  return {
247
269
  ...base,
248
270
  state: "running",
249
- reason: "the foreground supervisor holds the goal lease",
271
+ reason: "the foreground governor holds the goal lease",
250
272
  next_action: "wait_for_run",
251
273
  };
252
274
  }
@@ -258,6 +280,19 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
258
280
  next_action: "none",
259
281
  };
260
282
  }
283
+ // ADR 0050: a mission whose completion was reopened dispatches the reopened work
284
+ // before anything else. Without this the goal falls through to the milestone
285
+ // branch below, which still sees a succeeded root when the reopened item is one
286
+ // of its children, and would spend a replan reassessing a mission whose real
287
+ // remaining work is already sitting in ready_work.
288
+ if (intent.mission && plans.latest?.status === "reopened" && dispatchable.length > 0) {
289
+ return {
290
+ ...base,
291
+ state: "ready",
292
+ reason: `mission completion was reopened; ${dispatchable.length} work item${dispatchable.length === 1 ? " is" : "s are"} dispatchable`,
293
+ next_action: "run",
294
+ };
295
+ }
261
296
  if (plans.latest?.status === "proposed") {
262
297
  return {
263
298
  ...base,
@@ -298,6 +333,17 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
298
333
  next_action: "none",
299
334
  };
300
335
  }
336
+ if (plans.latest?.status === "failed" && plans.latest.class === "decision") {
337
+ // The planner concluded that a human must rule before this can be planned.
338
+ // Stop and say so. Replanning would re-ask a question the planner already
339
+ // answered correctly, which is how a goal spins without a person noticing.
340
+ return {
341
+ ...base,
342
+ state: "blocked",
343
+ reason: `planning is waiting on a human decision: ${plans.latest.reason ?? "the planner did not say which"}`,
344
+ next_action: "none",
345
+ };
346
+ }
301
347
  if (plans.latest?.status === "failed" && plans.latest.class === "upstream") {
302
348
  // The vendor refused. Uncharged replans do not spend max_replans, so the
303
349
  // only brake on an unending outage is this consecutive bound; at the limit
@@ -305,7 +351,7 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
305
351
  let trailingUncharged = 0;
306
352
  for (let index = plans.plans.length - 1; index >= 0; index--) {
307
353
  const plan = plans.plans[index];
308
- if (plan.status !== "failed" || (plan.class !== "environment" && plan.class !== "upstream")) {
354
+ if (plan.status !== "failed" || !isUnchargedPlanClass(plan.class)) {
309
355
  break;
310
356
  }
311
357
  trailingUncharged++;
@@ -322,7 +368,7 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
322
368
  // dispatchable — the vendor may have recovered. canReplan reads
323
369
  // chargedReplans, so these uncharged attempts do not exhaust max_replans.
324
370
  }
325
- const triggerFingerprint = supervisorGraphFingerprint({
371
+ const triggerFingerprint = governorGraphFingerprint({
326
372
  rootWorkId: plans.active_root_work_id,
327
373
  generation: plans.generation,
328
374
  work,
@@ -331,12 +377,15 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
331
377
  plans.latest.request.prior_root_work_id === plans.active_root_work_id &&
332
378
  plans.latest.status === "attention";
333
379
  if (latestHandledSameGraph && plans.latest) {
380
+ const canRetry = intent.replanning !== undefined && chargedReplans < intent.replanning.max_replans;
334
381
  return {
335
382
  ...base,
336
383
  state: "awaiting_attention",
337
- reason: plans.latest.reason ?? `plan ${plans.latest.request.id} requires attention`,
384
+ reason: canRetry
385
+ ? (plans.latest.reason ?? `plan ${plans.latest.request.id} requires attention`)
386
+ : exhaustedAttentionReason(plans.latest, replanConsumption),
338
387
  attention_plan_id: plans.latest.request.id,
339
- next_action: intent.replanning && chargedReplans < intent.replanning.max_replans ? "retry_plan" : "none",
388
+ next_action: canRetry ? "retry_plan" : "none",
340
389
  };
341
390
  }
342
391
  if (!root && intent.mission) {
@@ -344,7 +393,7 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
344
393
  return {
345
394
  ...base,
346
395
  state: "budget_exhausted",
347
- reason: "mission exhausted its planning budget before creating an initial milestone",
396
+ reason: replanBudgetReason("mission exhausted its planning budget before creating an initial milestone", replanConsumption),
348
397
  next_action: "none",
349
398
  };
350
399
  }
@@ -356,13 +405,13 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
356
405
  };
357
406
  }
358
407
  if (!root)
359
- throw new Error(`supervisor ${intent.id} root work is missing`);
408
+ throw new Error(`governor ${intent.id} root work is missing`);
360
409
  if (root.projection.state === "succeeded" && intent.mission) {
361
410
  if (!intent.replanning || chargedReplans >= intent.replanning.max_replans) {
362
411
  return {
363
412
  ...base,
364
413
  state: "budget_exhausted",
365
- reason: "mission exhausted its planning budget at a milestone boundary",
414
+ reason: replanBudgetReason("mission exhausted its planning budget at a milestone boundary", replanConsumption),
366
415
  next_action: "none",
367
416
  };
368
417
  }
@@ -381,12 +430,6 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
381
430
  next_action: "none",
382
431
  };
383
432
  }
384
- const resumableDispatchable = intent.automation.resume_approved ? resumableWork : [];
385
- const attemptDispatchable = [
386
- ...readyWork,
387
- ...(intent.automation.retry_blocked ? retryableWork : []),
388
- ];
389
- const dispatchable = [...resumableDispatchable, ...attemptDispatchable];
390
433
  if (intent.automation.accept_passing_proof && reviews.length > 0) {
391
434
  return {
392
435
  ...base,
@@ -479,45 +522,122 @@ function deriveProjection(coordRoot, intent, work, governed, plans, ignoreLease)
479
522
  return {
480
523
  ...base,
481
524
  state: "budget_exhausted",
482
- reason: `goal exhausted its ${intent.replanning.max_replans} replans`,
525
+ reason: replanBudgetReason(`goal exhausted its ${intent.replanning.max_replans} replans`, replanConsumption),
483
526
  next_action: "none",
484
527
  };
485
528
  }
486
529
  return {
487
530
  ...base,
488
531
  state: "blocked",
489
- reason: attentionWork.length > 0
490
- ? `${attentionWork.length} work item${attentionWork.length === 1 ? " needs" : "s need"} intervention`
491
- : "goal graph has no legal progress action",
532
+ // Lead with the decisions when there are any. "3 work items need
533
+ // intervention" reads as a queue an agent will get to; "waiting on you to
534
+ // rule on X" is the only phrasing that reaches the person who can clear it.
535
+ reason: decisionBlocked.length > 0
536
+ ? `${decisionBlocked.length} work item${decisionBlocked.length === 1 ? " is" : "s are"} waiting on a human decision: ${describeDecisionBlocks(decisionBlocked)}`
537
+ : attentionWork.length > 0
538
+ ? `${attentionWork.length} work item${attentionWork.length === 1 ? " needs" : "s need"} intervention`
539
+ : "goal graph has no legal progress action",
492
540
  next_action: "none",
493
541
  };
494
542
  }
495
- function readSupervisorIntent(coordRoot, goalId) {
496
- assertSupervisorId(goalId);
497
- const path = supervisorIntentPath(coordRoot, goalId);
543
+ /** Bounded, operator-readable list of what is waiting on a ruling. */
544
+ function describeDecisionBlocks(blocks) {
545
+ const shown = blocks
546
+ .slice(0, 3)
547
+ .map((b) => (b.decision_id ? `${b.work_id} (${b.decision_id})` : b.work_id))
548
+ .join(", ");
549
+ return blocks.length > 3 ? `${shown}, +${blocks.length - 3} more` : shown;
550
+ }
551
+ /**
552
+ * Classify each consumed replan that did not advance the graph, using existing
553
+ * plan seams only. A plan carries a review receipt exactly when a proposal was
554
+ * produced and independently reviewed, so its presence separates a reviewer
555
+ * rejection from a planner run that produced no reviewable proposal. Uncharged
556
+ * environment/upstream planner failures (ADR 0046) do not spend the replan
557
+ * budget and are attributed to their outside precondition, not counted here.
558
+ */
559
+ /** Whether a failed plan told us nothing about the plan, and so must not spend
560
+ * a replan (ADR 0046). All three classes mean "replanning this cannot help":
561
+ * the binary is missing, the vendor is down, or a person has to rule. */
562
+ function isUnchargedPlanClass(value) {
563
+ return value === "environment" || value === "upstream" || value === "decision";
564
+ }
565
+ function classifyReplanConsumption(plans) {
566
+ let reviewerRejection = 0;
567
+ let plannerNoProposal = 0;
568
+ for (const plan of plans.plans) {
569
+ if (plan.status === "failed" && isUnchargedPlanClass(plan.class)) {
570
+ continue;
571
+ }
572
+ if (plan.review && plan.review.status !== "passed") {
573
+ reviewerRejection++;
574
+ }
575
+ else if (!plan.review &&
576
+ (plan.status === "attention" ||
577
+ plan.status === "interrupted" ||
578
+ plan.status === "failed" ||
579
+ plan.status === "retry_requested")) {
580
+ // `retry_requested` is a planner no-proposal attention the operator asked to
581
+ // replan: the original run still produced no reviewable proposal and still
582
+ // spent a charged replan, so it belongs in this bucket even though a later
583
+ // plan superseded it. Omitting it would misattribute a retried no-proposal
584
+ // to nothing and let the reason read as pure review exhaustion.
585
+ plannerNoProposal++;
586
+ }
587
+ }
588
+ return { reviewer_rejection: reviewerRejection, planner_no_proposal: plannerNoProposal };
589
+ }
590
+ /**
591
+ * Reason for a goal held at `awaiting_attention/none` because its latest plan is
592
+ * an unresolved attention and no replan slot remains. The latest plan's own
593
+ * per-plan reason always leads (a reviewed-and-rejected latest reports its
594
+ * review-round exhaustion verbatim), then `replanBudgetReason` names the planner
595
+ * no-proposal share of the consumed budget. This keeps the `projection.reason`
596
+ * field carrying the same truth the operator-visible row does: a goal whose
597
+ * budget was mostly spent by planner no-proposal runs is not attributed wholesale
598
+ * to review just because its final, reviewed plan happened to be rejected.
599
+ */
600
+ function exhaustedAttentionReason(latest, consumption) {
601
+ const fallback = latest.reason ?? `plan ${latest.request.id} requires attention`;
602
+ return replanBudgetReason(fallback, consumption);
603
+ }
604
+ /**
605
+ * Append planner no-proposal attribution to a replan-exhaustion reason. Returns
606
+ * the base reason unchanged when no consumed replan was a planner no-proposal
607
+ * outcome, so goals without that history project exactly as before.
608
+ */
609
+ function replanBudgetReason(base, consumption) {
610
+ if (consumption.planner_no_proposal <= 0)
611
+ return base;
612
+ const count = consumption.planner_no_proposal;
613
+ return `${base}; ${count} replan${count === 1 ? "" : "s"} ended with the planner producing no proposal`;
614
+ }
615
+ function readGovernorIntent(coordRoot, goalId) {
616
+ assertGovernorId(goalId);
617
+ const path = governorIntentPath(coordRoot, goalId);
498
618
  if (!existsSync(path))
499
- throw new Error(`supervisor ${goalId} does not exist`);
619
+ throw new Error(`governor ${goalId} does not exist`);
500
620
  const size = statSync(path).size;
501
621
  if (size <= 0 || size > MAX_INTENT_BYTES) {
502
- throw new Error(`supervisor intent has invalid size ${size}`);
622
+ throw new Error(`governor intent has invalid size ${size}`);
503
623
  }
504
624
  let intent;
505
625
  try {
506
626
  intent = JSON.parse(readFileSync(path, "utf8"));
507
627
  }
508
628
  catch (error) {
509
- throw new Error(`cannot parse supervisor intent ${goalId}: ${error.message}`);
629
+ throw new Error(`cannot parse governor intent ${goalId}: ${error.message}`);
510
630
  }
511
631
  validateIntent(intent, goalId);
512
632
  return intent;
513
633
  }
514
634
  function validateIntent(intent, goalId) {
515
- if (intent.schema_version !== SUPERVISOR_INTENT_SCHEMA_VERSION ||
635
+ if (intent.schema_version !== GOVERNOR_INTENT_SCHEMA_VERSION ||
516
636
  intent.id !== goalId ||
517
637
  !validTimestamp(intent.created_at)) {
518
- throw new Error(`supervisor intent ${goalId} has an unsupported or mismatched schema`);
638
+ throw new Error(`governor intent ${goalId} has an unsupported or mismatched schema`);
519
639
  }
520
- bounded(intent.title, "supervisor title", MAX_TITLE);
640
+ bounded(intent.title, "governor title", MAX_TITLE);
521
641
  assertWorkId(intent.root_work_id);
522
642
  if (intent.mission) {
523
643
  const normalizedMission = normalizeMission({
@@ -526,40 +646,40 @@ function validateIntent(intent, goalId) {
526
646
  maxMilestones: intent.mission.max_milestones,
527
647
  });
528
648
  if (JSON.stringify(normalizedMission) !== JSON.stringify(intent.mission)) {
529
- throw new Error(`supervisor intent ${goalId} mission is not canonical`);
649
+ throw new Error(`governor intent ${goalId} mission is not canonical`);
530
650
  }
531
651
  if (!intent.replanning) {
532
- throw new Error(`supervisor intent ${goalId} mission requires replanning`);
652
+ throw new Error(`governor intent ${goalId} mission requires replanning`);
533
653
  }
534
654
  }
535
655
  const specialists = normalizeWorkflowSpecialists(intent.specialists);
536
656
  if (JSON.stringify(specialists) !== JSON.stringify(intent.specialists)) {
537
- throw new Error(`supervisor intent ${goalId} specialists are not canonical`);
657
+ throw new Error(`governor intent ${goalId} specialists are not canonical`);
538
658
  }
539
659
  if (JSON.stringify(normalizeLimits(intent.limits)) !== JSON.stringify(intent.limits)) {
540
- throw new Error(`supervisor intent ${goalId} limits are not canonical`);
660
+ throw new Error(`governor intent ${goalId} limits are not canonical`);
541
661
  }
542
662
  if (JSON.stringify(normalizeAutomation(intent.automation)) !== JSON.stringify(intent.automation)) {
543
- throw new Error(`supervisor intent ${goalId} automation policy is not canonical`);
663
+ throw new Error(`governor intent ${goalId} automation policy is not canonical`);
544
664
  }
545
665
  if (intent.replanning)
546
666
  validateReplanning(intent.replanning, specialists, intent.limits, goalId);
547
667
  }
548
668
  function normalizeMission(input) {
549
669
  if (!Array.isArray(input.acceptance)) {
550
- throw new Error("supervisor mission acceptance must be an array");
670
+ throw new Error("governor mission acceptance must be an array");
551
671
  }
552
672
  if (input.acceptance.length < 1 || input.acceptance.length > MAX_ACCEPTANCE) {
553
- throw new Error(`supervisor mission acceptance must contain 1 to ${MAX_ACCEPTANCE} criteria`);
673
+ throw new Error(`governor mission acceptance must contain 1 to ${MAX_ACCEPTANCE} criteria`);
554
674
  }
555
- const acceptance = input.acceptance.map((criterion, index) => bounded(criterion, `supervisor mission acceptance[${index}]`, 500));
675
+ const acceptance = input.acceptance.map((criterion, index) => bounded(criterion, `governor mission acceptance[${index}]`, 500));
556
676
  if (new Set(acceptance).size !== acceptance.length) {
557
- throw new Error("supervisor mission acceptance criteria must be unique");
677
+ throw new Error("governor mission acceptance criteria must be unique");
558
678
  }
559
679
  return {
560
- objective: bounded(input.objective, "supervisor mission objective", MAX_OBJECTIVE),
680
+ objective: bounded(input.objective, "governor mission objective", MAX_OBJECTIVE),
561
681
  acceptance,
562
- max_milestones: positive(input.maxMilestones ?? 4, "supervisor mission max_milestones", 20),
682
+ max_milestones: positive(input.maxMilestones ?? 4, "governor mission max_milestones", 20),
563
683
  };
564
684
  }
565
685
  function missionTitle(mission) {
@@ -569,12 +689,12 @@ function missionTitle(mission) {
569
689
  }
570
690
  function normalizeLimits(input) {
571
691
  return {
572
- max_cycles: positive(input?.max_cycles ?? 50, "supervisor max_cycles", 1_000),
573
- max_runtime_ms: positive(input?.max_runtime_ms ?? 4 * 60 * 60 * 1_000, "supervisor max_runtime_ms", 7 * 24 * 60 * 60 * 1_000),
574
- max_parallel_work: positive(input?.max_parallel_work ?? 1, "supervisor max_parallel_work", 20),
575
- max_total_attempts: positive(input?.max_total_attempts ?? 100, "supervisor max_total_attempts", 10_000),
576
- max_agents_per_work: positive(input?.max_agents_per_work ?? 20, "supervisor max_agents_per_work", 1_000),
577
- agent_concurrency: positive(input?.agent_concurrency ?? 4, "supervisor agent_concurrency", 100),
692
+ max_cycles: positive(input?.max_cycles ?? 50, "governor max_cycles", 1_000),
693
+ max_runtime_ms: positive(input?.max_runtime_ms ?? 4 * 60 * 60 * 1_000, "governor max_runtime_ms", 7 * 24 * 60 * 60 * 1_000),
694
+ max_parallel_work: positive(input?.max_parallel_work ?? 1, "governor max_parallel_work", 20),
695
+ max_total_attempts: positive(input?.max_total_attempts ?? 100, "governor max_total_attempts", 10_000),
696
+ max_agents_per_work: positive(input?.max_agents_per_work ?? 20, "governor max_agents_per_work", 1_000),
697
+ agent_concurrency: positive(input?.agent_concurrency ?? 4, "governor agent_concurrency", 100),
578
698
  };
579
699
  }
580
700
  function normalizeAutomation(input) {
@@ -637,8 +757,8 @@ function normalizeReviewPolicy(input, specialists, plannerSpecialist, limits) {
637
757
  if (!Array.isArray(input.reviewerSpecialists) || input.reviewerSpecialists.length < 1) {
638
758
  throw new Error("replanning review requires at least one reviewer specialist");
639
759
  }
640
- if (input.reviewerSpecialists.length > MAX_SUPERVISOR_PLAN_REVIEWERS) {
641
- throw new Error(`replanning review cannot exceed ${MAX_SUPERVISOR_PLAN_REVIEWERS} reviewer specialists`);
760
+ if (input.reviewerSpecialists.length > MAX_GOVERNOR_PLAN_REVIEWERS) {
761
+ throw new Error(`replanning review cannot exceed ${MAX_GOVERNOR_PLAN_REVIEWERS} reviewer specialists`);
642
762
  }
643
763
  const reviewerSpecialists = input.reviewerSpecialists.map((specialist, index) => bounded(specialist, `reviewer specialist[${index}]`, 100));
644
764
  if (new Set(reviewerSpecialists).size !== reviewerSpecialists.length) {
@@ -652,7 +772,7 @@ function normalizeReviewPolicy(input, specialists, plannerSpecialist, limits) {
652
772
  throw new Error("reviewer specialist cannot be the planner specialist");
653
773
  }
654
774
  }
655
- const maxRevisionRounds = nonNegative(input.maxRevisionRounds, "replanning review max_revision_rounds", MAX_SUPERVISOR_PLAN_REVISION_ROUNDS);
775
+ const maxRevisionRounds = nonNegative(input.maxRevisionRounds, "replanning review max_revision_rounds", MAX_GOVERNOR_PLAN_REVISION_ROUNDS);
656
776
  const worstCaseAgents = 1 + reviewerSpecialists.length * (maxRevisionRounds + 1) + maxRevisionRounds;
657
777
  if (worstCaseAgents > limits.max_agents_per_work) {
658
778
  throw new Error(`replanning review worst-case ${worstCaseAgents} agents exceeds max_agents_per_work ${limits.max_agents_per_work}`);
@@ -664,18 +784,18 @@ function normalizeReviewPolicy(input, specialists, plannerSpecialist, limits) {
664
784
  }
665
785
  function validateReplanning(policy, specialists, limits, goalId) {
666
786
  if (!specialists[policy.planner_specialist]) {
667
- throw new Error(`supervisor ${goalId} planner specialist is not in the frozen team`);
787
+ throw new Error(`governor ${goalId} planner specialist is not in the frozen team`);
668
788
  }
669
789
  boolean(policy.auto_apply, "replanning auto_apply");
670
790
  positive(policy.max_replans, "replanning max_replans", 100);
671
791
  positive(policy.max_work_items_per_plan, "replanning max_work_items_per_plan", 25);
672
792
  positive(policy.max_total_work_items, "replanning max_total_work_items", 100);
673
793
  if (policy.max_work_items_per_plan > policy.max_total_work_items) {
674
- throw new Error(`supervisor ${goalId} replanning work-item bounds are inconsistent`);
794
+ throw new Error(`governor ${goalId} replanning work-item bounds are inconsistent`);
675
795
  }
676
796
  const entries = Object.entries(policy.templates ?? {});
677
797
  if (entries.length < 1 || entries.length > MAX_TEMPLATES) {
678
- throw new Error(`supervisor ${goalId} has invalid replanning templates`);
798
+ throw new Error(`governor ${goalId} has invalid replanning templates`);
679
799
  }
680
800
  let rootCapable = false;
681
801
  for (const [id, template] of entries) {
@@ -686,45 +806,45 @@ function validateReplanning(policy, specialists, limits, goalId) {
686
806
  template.max_attempts < 1 ||
687
807
  template.max_attempts > 100 ||
688
808
  typeof template.root !== "boolean") {
689
- throw new Error(`supervisor ${goalId} replanning template ${id} is invalid`);
809
+ throw new Error(`governor ${goalId} replanning template ${id} is invalid`);
690
810
  }
691
811
  rootCapable ||= template.root;
692
812
  }
693
813
  if (!rootCapable)
694
- throw new Error(`supervisor ${goalId} has no root-capable replanning template`);
814
+ throw new Error(`governor ${goalId} has no root-capable replanning template`);
695
815
  if (policy.review !== undefined) {
696
816
  const review = policy.review;
697
817
  if (!Array.isArray(review.reviewer_specialists) ||
698
818
  review.reviewer_specialists.length < 1 ||
699
- review.reviewer_specialists.length > MAX_SUPERVISOR_PLAN_REVIEWERS ||
819
+ review.reviewer_specialists.length > MAX_GOVERNOR_PLAN_REVIEWERS ||
700
820
  !Number.isSafeInteger(review.max_revision_rounds) ||
701
821
  review.max_revision_rounds < 0 ||
702
- review.max_revision_rounds > MAX_SUPERVISOR_PLAN_REVISION_ROUNDS) {
703
- throw new Error(`supervisor ${goalId} replanning review policy is invalid`);
822
+ review.max_revision_rounds > MAX_GOVERNOR_PLAN_REVISION_ROUNDS) {
823
+ throw new Error(`governor ${goalId} replanning review policy is invalid`);
704
824
  }
705
825
  if (new Set(review.reviewer_specialists).size !== review.reviewer_specialists.length) {
706
- throw new Error(`supervisor ${goalId} replanning reviewers are not unique`);
826
+ throw new Error(`governor ${goalId} replanning reviewers are not unique`);
707
827
  }
708
828
  for (const specialist of review.reviewer_specialists) {
709
829
  if (!specialists[specialist]) {
710
- throw new Error(`supervisor ${goalId} reviewer specialist is not in the frozen team`);
830
+ throw new Error(`governor ${goalId} reviewer specialist is not in the frozen team`);
711
831
  }
712
832
  if (specialist === policy.planner_specialist) {
713
- throw new Error(`supervisor ${goalId} reviewer specialist cannot be planner`);
833
+ throw new Error(`governor ${goalId} reviewer specialist cannot be planner`);
714
834
  }
715
835
  }
716
836
  const worstCaseAgents = 1 +
717
837
  review.reviewer_specialists.length * (review.max_revision_rounds + 1) +
718
838
  review.max_revision_rounds;
719
839
  if (worstCaseAgents > limits.max_agents_per_work) {
720
- throw new Error(`supervisor ${goalId} review policy exceeds the agent budget`);
840
+ throw new Error(`governor ${goalId} review policy exceeds the agent budget`);
721
841
  }
722
842
  }
723
843
  }
724
844
  function collectGovernedWork(coordRoot, originalRootWorkId, plans, active) {
725
845
  const governed = new Map();
726
846
  if (workIntentExists(coordRoot, originalRootWorkId)) {
727
- for (const record of collectSupervisorWork(coordRoot, originalRootWorkId)) {
847
+ for (const record of collectGovernorWork(coordRoot, originalRootWorkId)) {
728
848
  governed.set(record.intent.id, record);
729
849
  }
730
850
  }
@@ -740,15 +860,15 @@ function workIntentExists(coordRoot, workId) {
740
860
  function missionRootId(goalId) {
741
861
  return `${goalId.slice(0, 87)}-mission-root`;
742
862
  }
743
- function supervisorDir(coordRoot, goalId) {
744
- assertSupervisorId(goalId);
745
- return join(resolve(coordRoot), ".harnery", "supervisors", goalId);
863
+ function governorDir(coordRoot, goalId) {
864
+ assertGovernorId(goalId);
865
+ return join(resolve(coordRoot), ".harnery", "governors", goalId);
746
866
  }
747
- function supervisorIntentPath(coordRoot, goalId) {
748
- return join(supervisorDir(coordRoot, goalId), "intent.json");
867
+ function governorIntentPath(coordRoot, goalId) {
868
+ return join(governorDir(coordRoot, goalId), "intent.json");
749
869
  }
750
- function supervisorLeaseIsLive(coordRoot, goalId) {
751
- const lease = readLease(join(supervisorDir(coordRoot, goalId), "lease.json"));
870
+ function governorLeaseIsLive(coordRoot, goalId) {
871
+ const lease = readLease(join(governorDir(coordRoot, goalId), "lease.json"));
752
872
  return lease ? leaseIsLive(lease) : false;
753
873
  }
754
874
  function readLease(path) {
@@ -787,7 +907,7 @@ function leaseIsLive(lease) {
787
907
  function writePrivateJson(path, value) {
788
908
  const body = `${JSON.stringify(value, null, 2)}\n`;
789
909
  if (Buffer.byteLength(body) > MAX_INTENT_BYTES) {
790
- throw new Error(`supervisor intent exceeds ${MAX_INTENT_BYTES} bytes`);
910
+ throw new Error(`governor intent exceeds ${MAX_INTENT_BYTES} bytes`);
791
911
  }
792
912
  writeFileSync(path, body, { encoding: "utf8", flag: "wx", mode: 0o600 });
793
913
  chmodSync(path, 0o600);
@@ -816,7 +936,7 @@ function nonNegative(value, field, max) {
816
936
  }
817
937
  function boolean(value, field) {
818
938
  if (typeof value !== "boolean")
819
- throw new Error(`supervisor ${field} must be boolean`);
939
+ throw new Error(`governor ${field} must be boolean`);
820
940
  return value;
821
941
  }
822
942
  function validTimestamp(value) {