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
@@ -27,13 +27,14 @@ import {
27
27
  import { homedir, tmpdir } from "node:os";
28
28
  import { basename, join, resolve } from "node:path";
29
29
  import type { Command } from "commander";
30
- import type { EmitContext } from "../commander.ts";
30
+ import type { EmitContext, HarneryProgramContext } from "../commander.ts";
31
+ import { coordBinPath } from "../core/agents/coord-bin.ts";
31
32
  import { readStreamTailBounded } from "../core/agents/events/consume.ts";
32
33
  import {
33
34
  emitCanonical,
34
35
  type Heartbeat,
35
36
  monorepoRoot,
36
- normalizeHarness,
37
+ normalizeAdapter,
37
38
  readHeartbeat,
38
39
  resolveOwner,
39
40
  resolveOwnerBySessionEnv,
@@ -41,6 +42,7 @@ import {
41
42
  } from "../core/agents/index.ts";
42
43
  import { coordFreshnessSeconds, resolveBinName } from "../core/config.ts";
43
44
  import { type RemoteMachine, readRemoteMachines } from "../core/presence/index.ts";
45
+ import { registerContextCommand } from "./context.ts";
44
46
 
45
47
  /** Cap for CLI scans of the unbounded event ledger (`trace` / `health`). Well
46
48
  * under V8's ~512MB max string length so a `readFileSync` of the whole file can
@@ -48,7 +50,7 @@ import { type RemoteMachine, readRemoteMachines } from "../core/presence/index.t
48
50
  const STREAM_SCAN_CAP_BYTES = 128 * 1024 * 1024; // 128 MiB
49
51
 
50
52
  import { parsePsChainLine } from "../core/hooks/resolve/anchor.ts";
51
- import { appendEntry, resolveOwnerByName } from "../core/scratch/index.ts";
53
+ import { appendEntry, resolveOwnerByName } from "../core/journal/index.ts";
52
54
  import {
53
55
  buildCouncilId,
54
56
  buildInviteMarkdown,
@@ -115,6 +117,44 @@ export function coordHelperOpts(root: string): { cwd: string; env: NodeJS.Proces
115
117
  return { cwd: root, env: { ...process.env, HARNERY_COORD_ROOT_OVERRIDE: root } };
116
118
  }
117
119
 
120
+ /**
121
+ * Resolve the bundled `agent-coord` helper, or exit with an error that names the
122
+ * problem. Every heartbeat mutation goes through that binary, so a caller who
123
+ * cannot find it has nothing useful to do — but it has to SAY so, because the
124
+ * alternative was spawning a path that did not exist and then crashing on the
125
+ * result (see `spawnFailureMessage`).
126
+ */
127
+ function agentCoordOrExit(root: string): string {
128
+ const binary = coordBinPath("agent-coord", root);
129
+ if (!binary) {
130
+ emit.error({
131
+ code: "coord_helper_missing",
132
+ message: `agent-coord helper not found for coord root ${root}; reinstall or rebuild harnery`,
133
+ });
134
+ process.exit(1);
135
+ }
136
+ return binary;
137
+ }
138
+
139
+ /**
140
+ * Describe a failed `spawnSync` without assuming it ran.
141
+ *
142
+ * When the binary cannot be executed at all (ENOENT, EACCES) node reports
143
+ * `status: null` AND `stderr: null`, so the obvious `result.stderr.trim()`
144
+ * threw "null is not an object" — replacing a legible "helper not found" with a
145
+ * crash that pointed at the wrong layer entirely. `error` carries the real
146
+ * cause on that path, so prefer it.
147
+ */
148
+ function spawnFailureMessage(
149
+ result: { status: number | null; stderr: string | null; error?: Error },
150
+ what: string,
151
+ ): string {
152
+ if (result.error) return `${what}: ${result.error.message}`;
153
+ const stderr = result.stderr?.trim();
154
+ if (stderr) return stderr;
155
+ return result.status === null ? `${what}: did not run` : `${what} exited ${result.status}`;
156
+ }
157
+
118
158
  function formatPlatformLabel(platform?: string | null): string {
119
159
  if (platform === "cursor") return "Cursor";
120
160
  if (platform === "codex") return "Codex";
@@ -145,11 +185,19 @@ interface Row {
145
185
 
146
186
  let emit: EmitContext;
147
187
 
148
- export function registerAgentsCommand(program: Command, emitParam: EmitContext): void {
188
+ export function registerAgentsCommand(
189
+ program: Command,
190
+ emitParam: EmitContext,
191
+ programContext?: HarneryProgramContext,
192
+ ): void {
149
193
  emit = emitParam;
150
194
  const cmd = program
151
195
  .command("agents")
152
- .description("Query the multi-agent coordination layer (whoami / list / status / health)");
196
+ .description(
197
+ "The live agent sessions in this project: who is running now, what they hold, and their coordination state (whoami / list / status / health).",
198
+ );
199
+
200
+ registerContextCommand(cmd, emitParam, programContext);
153
201
 
154
202
  cmd
155
203
  .command("whoami")
@@ -187,7 +235,7 @@ export function registerAgentsCommand(program: Command, emitParam: EmitContext):
187
235
  .command("suggest-name [description...]")
188
236
  .description(
189
237
  'Reprint a session name ("Agent <you> - <description>") for the operator to set as their ' +
190
- "harness tab title. With no arg, derives it from your current task. The primary naming path " +
238
+ "adapter tab title. With no arg, derives it from your current task. The primary naming path " +
191
239
  "is set-task (it suggests a name on the first focus declaration); reach for this to reprint " +
192
240
  "or re-suggest after a topic pivot. Read-only.",
193
241
  )
@@ -273,7 +321,7 @@ export function registerAgentsCommand(program: Command, emitParam: EmitContext):
273
321
  cmd
274
322
  .command("ping <name> <message...>")
275
323
  .description(
276
- "Append a 'handoff' entry to a peer agent's scratchpad. Body prefixed with " +
324
+ "Append a 'handoff' entry to a peer agent's journal. Body prefixed with " +
277
325
  "`from agent-<me>:`. Use to leave actionable coordination notes for peers " +
278
326
  "currently holding files you need.",
279
327
  )
@@ -344,9 +392,9 @@ export function registerAgentsCommand(program: Command, emitParam: EmitContext):
344
392
  });
345
393
 
346
394
  cmd
347
- .command("harness-probe <id>")
395
+ .command("adapter-probe <id>")
348
396
  .description(
349
- "Harness wiring probe: ppid chain, comm names, pid-map anchor, sample payload paths. " +
397
+ "Adapter wiring probe: ppid chain, comm names, pid-map anchor, sample payload paths. " +
350
398
  "With --replay-samples, also replays every checked-in sample payload against the live " +
351
399
  "adapter in an isolated sandbox to catch adapter / payload-shape drift. " +
352
400
  "Complements heal-events (drift telemetry). Id: claude_code | cursor.",
@@ -354,7 +402,7 @@ export function registerAgentsCommand(program: Command, emitParam: EmitContext):
354
402
  .option("--json", "JSON envelope output")
355
403
  .option(
356
404
  "--replay-samples",
357
- "Replay docs/api/<harness>-hooks/samples/*.json against the live adapter in an isolated sandbox. " +
405
+ "Replay docs/api/<adapter>-hooks/samples/*.json against the live adapter in an isolated sandbox. " +
358
406
  "Exits non-zero if any sample crashes the adapter.",
359
407
  )
360
408
  .option(
@@ -362,7 +410,7 @@ export function registerAgentsCommand(program: Command, emitParam: EmitContext):
362
410
  "Replay only the named sample file (basename match). Implies --replay-samples.",
363
411
  )
364
412
  .action((id: string, opts: { json?: boolean; replaySamples?: boolean; sample?: string }) => {
365
- runHarnessProbe(id, opts);
413
+ runAdapterProbe(id, opts);
366
414
  });
367
415
 
368
416
  cmd
@@ -395,8 +443,6 @@ export function registerAgentsCommand(program: Command, emitParam: EmitContext):
395
443
  runHeal(opts);
396
444
  },
397
445
  );
398
-
399
- registerCouncilCommands(cmd);
400
446
  registerIdentityCommands(cmd);
401
447
  }
402
448
 
@@ -551,7 +597,7 @@ function runIdentityAssume(target: string, opts: { json?: boolean; sessionId?: s
551
597
  }
552
598
  }
553
599
 
554
- function registerCouncilCommands(parent: Command): void {
600
+ export function registerCouncilCommands(parent: Command): void {
555
601
  const council = parent
556
602
  .command("council")
557
603
  .description(
@@ -685,7 +731,7 @@ function registerCouncilCommands(parent: Command): void {
685
731
  "(or omit [steward]) to drop the field and revert to the default " +
686
732
  "(the convener). Refuses to mutate archived councils. By default, " +
687
733
  "rejects names not in the known-agents list (active heartbeats + " +
688
- "scratchpads archived in the last 30 days); pass --allow-unknown " +
734
+ "journals archived in the last 30 days); pass --allow-unknown " +
689
735
  "to bypass when bootstrapping.",
690
736
  )
691
737
  .option("--clear", "Clear the steward field, reverting to created_by default")
@@ -711,7 +757,7 @@ function registerCouncilCommands(parent: Command): void {
711
757
  "Pass either --message <inline> or --file <path>. Writes to " +
712
758
  ".harnery/councils/<id>/round-<N>/<agent-Name>.md. Pass --as <member> " +
713
759
  "to contribute under a council seat name that differs from the running " +
714
- "agent's heartbeat name (useful for cross-harness councils where each " +
760
+ "agent's heartbeat name (useful for cross-adapter councils where each " +
715
761
  "reviewer has a different auto-generated session name).",
716
762
  )
717
763
  .option("--message <text>", "Inline contribution text (caps at 4KB)")
@@ -813,7 +859,7 @@ function runWhoami(opts: { json?: boolean }): void {
813
859
  if (!hb) {
814
860
  emit.error({
815
861
  code: "no_heartbeat",
816
- message: `pid-map resolved owner=${myOwner.slice(0, 8)} but no heartbeat exists`,
862
+ message: noHeartbeatMessage(myOwner),
817
863
  });
818
864
  process.exit(1);
819
865
  }
@@ -1013,6 +1059,41 @@ function normalizeKind(kind: string | undefined | null): string {
1013
1059
  return kind;
1014
1060
  }
1015
1061
 
1062
+ /**
1063
+ * The `no_heartbeat` diagnostic, quoting the owner id in FULL.
1064
+ *
1065
+ * This id is actionable: the reader's next move is `agents heal --kind
1066
+ * heartbeat --owner <id>`, and heartbeats are keyed by the whole
1067
+ * `instance_id` (`.harnery/active/<instance_id>.json`). An abbreviated id
1068
+ * here reads as complete, so it gets copy-pasted into `--owner` and mints a
1069
+ * heartbeat at a filename no reader resolves — an orphan that leaves the
1070
+ * session looking unhealable. Abbreviate ids for display elsewhere, never in
1071
+ * a message whose whole purpose is to hand the reader an id to pass back.
1072
+ */
1073
+ function noHeartbeatMessage(owner: string): string {
1074
+ return `resolved owner=${owner} but no heartbeat exists at .harnery/active/${owner}.json`;
1075
+ }
1076
+
1077
+ /**
1078
+ * The instance_id of a live heartbeat that `prefix` strictly prefixes, or null.
1079
+ *
1080
+ * Used to recognize an abbreviated id handed back by a reader when the caller
1081
+ * supplied no canonical id of their own. Ambiguity is treated as "no answer":
1082
+ * two live sessions sharing the prefix means we cannot name the one intended,
1083
+ * and refusing with the wrong id in the message would be worse than the orphan.
1084
+ */
1085
+ function liveIdWithPrefix(root: string, prefix: string): string | null {
1086
+ const activeDir = resolve(root, ".harnery", "active");
1087
+ if (!existsSync(activeDir)) return null;
1088
+ const matches = new Set<string>();
1089
+ for (const file of readdirSync(activeDir)) {
1090
+ if (!file.endsWith(".json")) continue;
1091
+ const id = file.slice(0, -".json".length);
1092
+ if (id !== prefix && id.startsWith(prefix)) matches.add(id);
1093
+ }
1094
+ return matches.size === 1 ? (matches.values().next().value as string) : null;
1095
+ }
1096
+
1016
1097
  async function runWatch(pollMs: number): Promise<void> {
1017
1098
  const root = monorepoRoot();
1018
1099
  if (!root) {
@@ -1326,8 +1407,8 @@ function ensureCursorSession(root: string): void {
1326
1407
 
1327
1408
  const sessionId = cursorEnvSessionId();
1328
1409
  if (!sessionId) return;
1329
- const agentHook = resolve(root, "harnery", "bin", "agent-hook");
1330
- if (!existsSync(agentHook)) return;
1410
+ const agentHook = coordBinPath("agent-hook", root);
1411
+ if (!agentHook) return;
1331
1412
 
1332
1413
  const payload = JSON.stringify({
1333
1414
  conversation_id: sessionId,
@@ -1339,7 +1420,7 @@ function ensureCursorSession(root: string): void {
1339
1420
  is_background_agent: false,
1340
1421
  });
1341
1422
 
1342
- spawnSync("bash", [agentHook, "session-start", "--harness", "cursor"], {
1423
+ spawnSync("bash", [agentHook, "session-start", "--adapter", "cursor"], {
1343
1424
  input: payload,
1344
1425
  cwd: root,
1345
1426
  encoding: "utf8",
@@ -1376,7 +1457,7 @@ function runReleaseClaim(path: string): void {
1376
1457
  let canonical = path;
1377
1458
  if (path.startsWith(`${root}/`)) canonical = path.slice(root.length + 1);
1378
1459
 
1379
- const helper = resolve(root, "harnery", "bin", "agent-coord");
1460
+ const helper = agentCoordOrExit(root);
1380
1461
  const result = spawnSync(helper, ["release-claim", myOwner, canonical], {
1381
1462
  encoding: "utf8",
1382
1463
  ...coordHelperOpts(root),
@@ -1384,7 +1465,7 @@ function runReleaseClaim(path: string): void {
1384
1465
  if (result.status !== 0) {
1385
1466
  emit.error({
1386
1467
  code: "release_claim_failed",
1387
- message: result.stderr.trim() || `agent-coord exited ${result.status}`,
1468
+ message: spawnFailureMessage(result, "agent-coord"),
1388
1469
  });
1389
1470
  process.exit(1);
1390
1471
  }
@@ -1425,7 +1506,7 @@ function runSetTask(task: string, opts?: { sessionId?: string }): void {
1425
1506
  const firstOfSession = !priorHb?.task_updated_at;
1426
1507
 
1427
1508
  // Heartbeat mutation goes through agent-coord (atomic temp+rename).
1428
- const helper = resolve(root, "harnery", "bin", "agent-coord");
1509
+ const helper = agentCoordOrExit(root);
1429
1510
  const result = spawnSync(helper, ["set-task", myOwner, task], {
1430
1511
  encoding: "utf8",
1431
1512
  ...coordHelperOpts(root),
@@ -1433,7 +1514,7 @@ function runSetTask(task: string, opts?: { sessionId?: string }): void {
1433
1514
  if (result.status !== 0) {
1434
1515
  emit.error({
1435
1516
  code: "set_task_failed",
1436
- message: result.stderr.trim() || `agent-coord exited ${result.status}`,
1517
+ message: spawnFailureMessage(result, "agent-coord"),
1437
1518
  });
1438
1519
  process.exit(1);
1439
1520
  }
@@ -1443,12 +1524,12 @@ function runSetTask(task: string, opts?: { sessionId?: string }): void {
1443
1524
  type: "state.task_set",
1444
1525
  owner: myOwner,
1445
1526
  session: hb?.session_id ?? myOwner,
1446
- harness: normalizeHarness(hb?.platform),
1527
+ adapter: normalizeAdapter(hb?.platform),
1447
1528
  data: { task, cleared: !task || task.length === 0 },
1448
1529
  });
1449
1530
 
1450
1531
  // On the first focus declaration of a session, surface a suggested session
1451
- // name for the operator to set as their harness tab title. Read the result
1532
+ // name for the operator to set as their adapter tab title. Read the result
1452
1533
  // (`suggested_session_name`) and reproduce it in a fenced code block so the
1453
1534
  // UI's Copy button hands over the exact string. null on every later call.
1454
1535
  const built =
@@ -1570,7 +1651,7 @@ function runStatus(opts: { json?: boolean; sessionId?: string }): void {
1570
1651
  if (!hb) {
1571
1652
  emit.error({
1572
1653
  code: "no_heartbeat",
1573
- message: `pid-map resolved owner=${myOwner.slice(0, 8)} but no heartbeat exists`,
1654
+ message: noHeartbeatMessage(myOwner),
1574
1655
  });
1575
1656
  process.exit(1);
1576
1657
  }
@@ -1580,7 +1661,7 @@ function runStatus(opts: { json?: boolean; sessionId?: string }): void {
1580
1661
  // populated for back-compat with consumers reading v1 directly. The stamp
1581
1662
  // goes through agent-coord (atomic write).
1582
1663
  try {
1583
- const helper = resolve(root, "harnery", "bin", "agent-coord");
1664
+ const helper = agentCoordOrExit(root);
1584
1665
  spawnSync(helper, ["stamp-status-call", myOwner], {
1585
1666
  encoding: "utf8",
1586
1667
  timeout: 2000,
@@ -1593,7 +1674,7 @@ function runStatus(opts: { json?: boolean; sessionId?: string }): void {
1593
1674
  type: "state.status_checked",
1594
1675
  owner: myOwner,
1595
1676
  session: hb.session_id ?? myOwner,
1596
- harness: normalizeHarness(hb.platform),
1677
+ adapter: normalizeAdapter(hb.platform),
1597
1678
  data: {
1598
1679
  format: opts.json ? "json" : "box",
1599
1680
  agent_count: 0, // computed below, not yet available here; Phase 5 verdict reads owner-scope only
@@ -2039,7 +2120,7 @@ interface CanonicalEvent {
2039
2120
  event_type: string;
2040
2121
  ts: string;
2041
2122
  instance_id?: string;
2042
- harness?: string;
2123
+ adapter?: string;
2043
2124
  data?: Record<string, unknown>;
2044
2125
  }
2045
2126
 
@@ -2073,12 +2154,12 @@ function readCanonicalEventsInWindow(root: string, cutoffMs: number): CanonicalE
2073
2154
  return out;
2074
2155
  }
2075
2156
 
2076
- /** harness ("claude-code") → legacy platform label ("claude_code") so the
2157
+ /** adapter ("claude-code") → legacy platform label ("claude_code") so the
2077
2158
  * existing formatPlatformLabel rendering keeps working unchanged. */
2078
- function harnessToPlatform(harness: string | undefined): string {
2079
- if (harness === "claude-code") return "claude_code";
2080
- if (harness === "cursor") return "cursor";
2081
- if (harness === "codex") return "codex";
2159
+ function adapterToPlatform(adapter: string | undefined): string {
2160
+ if (adapter === "claude-code") return "claude_code";
2161
+ if (adapter === "cursor") return "cursor";
2162
+ if (adapter === "codex") return "codex";
2082
2163
  return "claude_code";
2083
2164
  }
2084
2165
 
@@ -2100,7 +2181,7 @@ function canonicalToHealEvent(ev: CanonicalEvent, nameById: Map<string, string>)
2100
2181
  agent,
2101
2182
  kind,
2102
2183
  reason,
2103
- platform: harnessToPlatform(ev.harness),
2184
+ platform: adapterToPlatform(ev.adapter),
2104
2185
  };
2105
2186
  if (kind === "pidmap" && data.pid !== undefined && data.pid !== null) {
2106
2187
  out.pid = String(data.pid);
@@ -2982,17 +3063,17 @@ interface SampleReplayResult {
2982
3063
  message?: string;
2983
3064
  }
2984
3065
 
2985
- function runHarnessProbe(
3066
+ function runAdapterProbe(
2986
3067
  id: string,
2987
3068
  opts: { json?: boolean; replaySamples?: boolean; sample?: string },
2988
3069
  ): void {
2989
3070
  if (opts.json) emit.config({ format: "json" });
2990
3071
 
2991
- const harness = id.trim();
2992
- if (harness !== "claude_code" && harness !== "cursor") {
3072
+ const adapter = id.trim();
3073
+ if (adapter !== "claude_code" && adapter !== "cursor") {
2993
3074
  emit.error({
2994
- code: "bad_harness",
2995
- message: "harness id must be claude_code or cursor",
3075
+ code: "bad_adapter",
3076
+ message: "adapter id must be claude_code or cursor",
2996
3077
  });
2997
3078
  process.exit(1);
2998
3079
  }
@@ -3007,16 +3088,16 @@ function runHarnessProbe(
3007
3088
  }
3008
3089
 
3009
3090
  const subagentDir =
3010
- harness === "cursor" ? ".harnery/.cursor-subagent-map" : `.harnery/.subagent-map/${harness}`;
3091
+ adapter === "cursor" ? ".harnery/.cursor-subagent-map" : `.harnery/.subagent-map/${adapter}`;
3011
3092
  const sampleDir =
3012
- harness === "cursor" ? "docs/api/cursor-hooks/samples" : "docs/api/claude-code-hooks/samples";
3093
+ adapter === "cursor" ? "docs/api/cursor-hooks/samples" : "docs/api/claude-code-hooks/samples";
3013
3094
  const dispatchEntry =
3014
- harness === "cursor"
3015
- ? "harnery/bin/agent-hook session-start --harness cursor"
3016
- : "harnery/bin/agent-hook session-start --harness claude-code";
3095
+ adapter === "cursor"
3096
+ ? "harnery/bin/agent-hook session-start --adapter cursor"
3097
+ : "harnery/bin/agent-hook session-start --adapter claude-code";
3017
3098
 
3018
3099
  // TS-native probe. The owner + anchor-pid resolution it reports lives in
3019
- // `findHarnessAnchorPid` (core/hooks/cli.ts, the /proc walk mirrored below)
3100
+ // `findAdapterAnchorPid` (core/hooks/cli.ts, the /proc walk mirrored below)
3020
3101
  // and `resolveOwner` here, so the probe reports exactly what the live hot
3021
3102
  // path resolves.
3022
3103
  const anchorTokens = new Set(["claude", "claude-code", "cursor", "codex"]);
@@ -3054,7 +3135,7 @@ function runHarnessProbe(
3054
3135
  }
3055
3136
 
3056
3137
  const data: Record<string, unknown> = {
3057
- harness,
3138
+ adapter,
3058
3139
  anchor_pid: anchorPid,
3059
3140
  hook_pid: String(process.pid),
3060
3141
  resolved_owner: resolveOwner() ?? "",
@@ -3062,14 +3143,14 @@ function runHarnessProbe(
3062
3143
  subagent_map_dir: subagentDir,
3063
3144
  sample_ref: sampleDir,
3064
3145
  dispatch_entry: dispatchEntry,
3065
- note: "heal-events counts drift; harness-probe answers wiring",
3146
+ note: "heal-events counts drift; adapter-probe answers wiring",
3066
3147
  };
3067
3148
 
3068
3149
  const wantReplay = opts.replaySamples || !!opts.sample;
3069
3150
  let samples: SampleReplayResult[] = [];
3070
3151
  let replayExitCode = 0;
3071
3152
  if (wantReplay) {
3072
- const result = replayHarnessSamples(harness, root, sampleDir, opts.sample);
3153
+ const result = replayAdapterSamples(adapter, root, sampleDir, opts.sample);
3073
3154
  samples = result.samples;
3074
3155
  replayExitCode = result.exitCode;
3075
3156
  data.samples = samples;
@@ -3079,7 +3160,7 @@ function runHarnessProbe(
3079
3160
  emit.data(data);
3080
3161
  if (process.stdout.isTTY && !opts.json) {
3081
3162
  const lines = [
3082
- `Harness probe: ${harness}`,
3163
+ `Adapter probe: ${adapter}`,
3083
3164
  ` anchor_pid: ${String(data.anchor_pid) || "(empty, expected in sandbox/non-IDE)"}`,
3084
3165
  ` hook_pid: ${String(data.hook_pid)}`,
3085
3166
  ` resolved_owner: ${String(data.resolved_owner) || "(none)"}`,
@@ -3125,11 +3206,11 @@ function runHarnessProbe(
3125
3206
  }
3126
3207
 
3127
3208
  /**
3128
- * Replay every JSON fixture in <root>/<sampleDir> against the live harness
3209
+ * Replay every JSON fixture in <root>/<sampleDir> against the live adapter
3129
3210
  * dispatcher in an isolated sandbox.
3130
3211
  *
3131
3212
  * Sandbox isolation strategy:
3132
- * - mkdtempSync(tmpdir(), "harn-harness-probe-") creates a non-git tmp dir.
3213
+ * - mkdtempSync(tmpdir(), "harn-adapter-probe-") creates a non-git tmp dir.
3133
3214
  * - The dispatcher's coord-root resolution falls back to
3134
3215
  * `HARNERY_COORD_ROOT_OVERRIDE` when git rev-parse fails. We set it to the sandbox.
3135
3216
  * - We rewrite the payload's `cwd` field (Cursor cds to it) to the sandbox,
@@ -3141,8 +3222,8 @@ function runHarnessProbe(
3141
3222
  * payload with `.hook_event_name`. Event name resolution falls back to the
3142
3223
  * filename (without `.json`) when neither field exists.
3143
3224
  */
3144
- function replayHarnessSamples(
3145
- harness: string,
3225
+ function replayAdapterSamples(
3226
+ adapter: string,
3146
3227
  root: string,
3147
3228
  relativeSampleDir: string,
3148
3229
  filter?: string,
@@ -3174,7 +3255,7 @@ function replayHarnessSamples(
3174
3255
  }
3175
3256
 
3176
3257
  // agent-hook is the single entry point. Replay sample payloads against it,
3177
- // mapping the harness-native hook_event_name to the agent-hook CLI subcommand.
3258
+ // mapping the adapter-native hook_event_name to the agent-hook CLI subcommand.
3178
3259
  const agentHook = resolve(root, "harnery/bin/agent-hook");
3179
3260
  if (!existsSync(agentHook)) {
3180
3261
  return {
@@ -3212,9 +3293,9 @@ function replayHarnessSamples(
3212
3293
  stopFailure: "stop-failure",
3213
3294
  StopFailure: "stop-failure",
3214
3295
  };
3215
- const harnessFlag = harness === "claude_code" ? "claude-code" : harness;
3296
+ const adapterFlag = adapter === "claude_code" ? "claude-code" : adapter;
3216
3297
 
3217
- const sandbox = mkdtempSync(join(tmpdir(), "harn-harness-probe-"));
3298
+ const sandbox = mkdtempSync(join(tmpdir(), "harn-adapter-probe-"));
3218
3299
  const results: SampleReplayResult[] = [];
3219
3300
 
3220
3301
  try {
@@ -3255,7 +3336,7 @@ function replayHarnessSamples(
3255
3336
  }
3256
3337
 
3257
3338
  const subcommand = EVENT_SUBCOMMAND[event] ?? event;
3258
- const dispatch = spawnSync("bash", [agentHook, subcommand, "--harness", harnessFlag], {
3339
+ const dispatch = spawnSync("bash", [agentHook, subcommand, "--adapter", adapterFlag], {
3259
3340
  cwd: sandbox,
3260
3341
  encoding: "utf8",
3261
3342
  input: JSON.stringify(payloadObj),
@@ -3263,8 +3344,8 @@ function replayHarnessSamples(
3263
3344
  env: {
3264
3345
  ...process.env,
3265
3346
  HARNERY_COORD_ROOT_OVERRIDE: sandbox,
3266
- HARNERY_AGENT_COORD_HARNESS: harness,
3267
- HARNERY_AGENT_COORD_PLATFORM: harness,
3347
+ HARNERY_AGENT_COORD_ADAPTER: adapter,
3348
+ HARNERY_AGENT_COORD_PLATFORM: adapter,
3268
3349
  HARNERY_AGENT_COORD_OFF: "0",
3269
3350
  },
3270
3351
  });
@@ -3405,8 +3486,8 @@ function runPing(name: string, message: string, opts: { json?: boolean }): void
3405
3486
  peer_instance_id: peerOwner,
3406
3487
  from: fromName,
3407
3488
  body,
3408
- scratch_path: doc.path,
3409
- scratch_bytes: doc.bytes,
3489
+ journal_path: doc.path,
3490
+ journal_bytes: doc.bytes,
3410
3491
  };
3411
3492
 
3412
3493
  if (opts.json) {
@@ -3571,6 +3652,44 @@ function runHeal(opts: {
3571
3652
  const action =
3572
3653
  kind === "pidmap" ? "heal-pidmap" : kind === "heartbeat" ? "heal-heartbeat" : "kill-heartbeat";
3573
3654
 
3655
+ // Refuse to mint a heartbeat at a TRUNCATED owner id.
3656
+ //
3657
+ // Heartbeats are keyed by the whole instance_id, so healing at an
3658
+ // abbreviated id writes `.harnery/active/<prefix>.json` while every reader
3659
+ // (`status`, `set-task`, `whoami`) resolves `<instance_id>.json`. The heal
3660
+ // reports success, the session stays broken, and an orphan file is left
3661
+ // behind that the singleton fallback can then mis-resolve other callers to.
3662
+ //
3663
+ // A distinct instance_id (subagent, workflow child) is never a prefix of its
3664
+ // own session_id, so a strict prefix is unambiguously an abbreviated id
3665
+ // rather than a legitimately different owner. Only guard the create path: an
3666
+ // existing heartbeat at `owner` means the id is real, whatever its shape.
3667
+ //
3668
+ // Two sources for the canonical id, because the reported failure arrives
3669
+ // without `--session-id`: someone copies a truncated id out of a diagnostic
3670
+ // and passes it as `--owner` alone. Comparing against `--session-id` alone
3671
+ // therefore misses the exact path that produced the orphan; a live heartbeat
3672
+ // whose instance_id this id is a prefix of settles it just as well, and is
3673
+ // present in precisely the case that matters (the session the reader was
3674
+ // trying to heal is registered, just not under the abbreviated name).
3675
+ if (kind === "heartbeat" && !readHeartbeat(owner)) {
3676
+ const canonical =
3677
+ opts.sessionId && opts.sessionId.trim() !== owner && opts.sessionId.trim().startsWith(owner)
3678
+ ? opts.sessionId.trim()
3679
+ : liveIdWithPrefix(root, owner);
3680
+ if (canonical) {
3681
+ const source = opts.sessionId?.trim() === canonical ? "--session-id" : "a live heartbeat";
3682
+ emit.error({
3683
+ code: "truncated_owner",
3684
+ message:
3685
+ `--owner ${owner} is a prefix of ${canonical} (${source}), and no heartbeat exists ` +
3686
+ `at .harnery/active/${owner}.json. Healing here would create a heartbeat no reader ` +
3687
+ `resolves. Re-run with --owner ${canonical}.`,
3688
+ });
3689
+ process.exit(1);
3690
+ }
3691
+ }
3692
+
3574
3693
  // Build positional args. agent-coord's arg layout:
3575
3694
  // heal-pidmap <instance_id> [<pid>]
3576
3695
  // heal-heartbeat <instance_id> [<session_id>]
@@ -3580,8 +3699,8 @@ function runHeal(opts: {
3580
3699
  if (kind === "heartbeat" && opts.sessionId) helperArgs.push(opts.sessionId);
3581
3700
 
3582
3701
  // heal-pidmap / heal-heartbeat / kill-heartbeat are handled by the
3583
- // agent-coord binary at harnery/bin/agent-coord.
3584
- const helper = `${root}/harnery/bin/agent-coord`;
3702
+ // bundled agent-coord binary.
3703
+ const helper = agentCoordOrExit(root);
3585
3704
  const proc = spawnSync(helper, helperArgs, {
3586
3705
  encoding: "utf8",
3587
3706
  ...coordHelperOpts(root),
@@ -3590,7 +3709,7 @@ function runHeal(opts: {
3590
3709
  if (proc.status !== 0) {
3591
3710
  emit.error({
3592
3711
  code: "heal_failed",
3593
- message: proc.stderr?.trim() || `agent-coord ${action} exited non-zero`,
3712
+ message: spawnFailureMessage(proc, `agent-coord ${action}`),
3594
3713
  });
3595
3714
  process.exit(1);
3596
3715
  }
@@ -3628,7 +3747,10 @@ function runHeal(opts: {
3628
3747
  ],
3629
3748
  meta: {
3630
3749
  kind,
3631
- helper: "harnery/bin/agent-coord",
3750
+ // The path actually spawned, not a guess at the layout: the helper is
3751
+ // resolved from harnery's own package location, which differs between a
3752
+ // submodule, an installed dependency, and a standalone checkout.
3753
+ helper,
3632
3754
  },
3633
3755
  });
3634
3756
  if (!opts.json) {
@@ -3663,7 +3785,7 @@ function emitCouncilStateEvent(
3663
3785
  type,
3664
3786
  owner: myOwner,
3665
3787
  session: hb?.session_id ?? myOwner,
3666
- harness: normalizeHarness(hb?.platform),
3788
+ adapter: normalizeAdapter(hb?.platform),
3667
3789
  data: { council_id: manifest.council_id, ...extraData },
3668
3790
  });
3669
3791
  }
@@ -3787,7 +3909,7 @@ function runCouncilCreate(
3787
3909
  type: "council.open",
3788
3910
  owner: myOwner,
3789
3911
  session: myHbForEmit?.session_id ?? myOwner,
3790
- harness: normalizeHarness(myHbForEmit?.platform),
3912
+ adapter: normalizeAdapter(myHbForEmit?.platform),
3791
3913
  data: {
3792
3914
  council_id: councilId,
3793
3915
  topic: trimmedObjective,
@@ -3797,7 +3919,7 @@ function runCouncilCreate(
3797
3919
  });
3798
3920
  }
3799
3921
 
3800
- // Best-effort: ping each currently-active member's scratchpad with a
3922
+ // Best-effort: ping each currently-active member's journal with a
3801
3923
  // handoff entry pointing them at the council. Members not currently active
3802
3924
  // get nothing here; the Phase 2 SessionStart adapter will surface the
3803
3925
  // invite on their next session.
@@ -4269,7 +4391,7 @@ function runCouncilSetSteward(
4269
4391
  const known_names = known.map((a) => a.name).join(", ") || "(none)";
4270
4392
  emit.error({
4271
4393
  code: "steward_not_known",
4272
- message: `'${steward}' is not a known agent (active heartbeats + scratchpads archived in the last 30 days). Pass --allow-unknown to bootstrap. Known: ${known_names}`,
4394
+ message: `'${steward}' is not a known agent (active heartbeats + journals archived in the last 30 days). Pass --allow-unknown to bootstrap. Known: ${known_names}`,
4273
4395
  });
4274
4396
  process.exit(1);
4275
4397
  }
@@ -4304,7 +4426,7 @@ function runCouncilSetSteward(
4304
4426
  }
4305
4427
  }
4306
4428
 
4307
- /** Build a markdown transcript of every round's contributions on disk. */
4429
+ /** Build a markdown journal of every round's contributions on disk. */
4308
4430
  function buildTranscript(manifest: CouncilManifest): {
4309
4431
  markdown: string;
4310
4432
  rounds: Array<{ round: number; contributions: number }>;
@@ -4382,7 +4504,7 @@ function runCouncilContribute(
4382
4504
 
4383
4505
  // Resolve the contributor name. Two paths:
4384
4506
  // 1. --as <member> override: caller explicitly names the council seat. Used
4385
- // for cross-harness councils where each reviewer agent has a different
4507
+ // for cross-adapter councils where each reviewer agent has a different
4386
4508
  // auto-generated session name from a different name pool; they can
4387
4509
  // contribute under a fixed seat name without renaming the session.
4388
4510
  // 2. Heartbeat-derived (default): resolve owner via ppid walk + read the
@@ -4423,7 +4545,7 @@ function runCouncilContribute(
4423
4545
  if (!myHb?.name) {
4424
4546
  emit.error({
4425
4547
  code: "no_self_name",
4426
- message: `resolved owner ${myOwner.slice(0, 8)} has no name on heartbeat (pass --as <member> to override)`,
4548
+ message: `resolved owner ${myOwner} has no name on heartbeat (pass --as <member> to override)`,
4427
4549
  });
4428
4550
  process.exit(1);
4429
4551
  }
@@ -4576,7 +4698,7 @@ function runCouncilPrompt(
4576
4698
  }
4577
4699
 
4578
4700
  // Resolve caller identity (steward authority check). Same --as override
4579
- // shape as `contribute` for cross-harness scripting.
4701
+ // shape as `contribute` for cross-adapter scripting.
4580
4702
  let callerName: string;
4581
4703
  let actualName: string | null = null;
4582
4704
  if (opts.as) {
@@ -4798,7 +4920,7 @@ function runCouncilAdvance(id: string, opts: { force?: boolean; json?: boolean }
4798
4920
  * Shared advance helper used by both `advance` and auto-advance from
4799
4921
  * `contribute`. Increments current_round, flips round_status back to open,
4800
4922
  * creates the new round directory, writes the manifest, and pings each
4801
- * member's scratchpad with the advance notification.
4923
+ * member's journal with the advance notification.
4802
4924
  */
4803
4925
  function advanceCouncil(manifest: CouncilManifest, force: boolean): CouncilManifest {
4804
4926
  const nextRound = manifest.current_round + 1;
@@ -4812,7 +4934,7 @@ function advanceCouncil(manifest: CouncilManifest, force: boolean): CouncilManif
4812
4934
  if (rd && !existsSync(rd)) mkdirSync(rd, { recursive: true });
4813
4935
  writeManifest(next);
4814
4936
 
4815
- // Ping each member's scratchpad with the advance notification.
4937
+ // Ping each member's journal with the advance notification.
4816
4938
  // (Convener already knows; we skip pinging them if they convened it from
4817
4939
  // their own session.)
4818
4940
  const myOwner = resolveOwner();
@@ -4829,7 +4951,7 @@ function advanceCouncil(manifest: CouncilManifest, force: boolean): CouncilManif
4829
4951
  `from council advance (${manifest.council_id}): round ${nextRound} is now open${force ? " (advanced with --force; some round-N members dropped)" : ""}. Run 'harn agents council show ${manifest.council_id}' to read prior round + 'harn agents council contribute ${manifest.council_id}' to weigh in.`,
4830
4952
  );
4831
4953
  } catch {
4832
- /* best-effort; member scratchpad may not exist yet */
4954
+ /* best-effort; member journal may not exist yet */
4833
4955
  }
4834
4956
  }
4835
4957
  return next;