harnery 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (501) hide show
  1. package/README.md +4 -4
  2. package/dist/commander.d.ts +8 -0
  3. package/dist/commander.d.ts.map +1 -1
  4. package/dist/commander.js +14 -13
  5. package/dist/commands/adapter.d.ts +12 -0
  6. package/dist/commands/adapter.d.ts.map +1 -0
  7. package/dist/commands/{harness.js → adapter.js} +35 -35
  8. package/dist/commands/agents.d.ts +3 -2
  9. package/dist/commands/agents.d.ts.map +1 -1
  10. package/dist/commands/agents.js +61 -60
  11. package/dist/commands/artifacts.d.ts +4 -0
  12. package/dist/commands/artifacts.d.ts.map +1 -0
  13. package/dist/commands/artifacts.js +143 -0
  14. package/dist/commands/backup.d.ts +1 -1
  15. package/dist/commands/backup.d.ts.map +1 -1
  16. package/dist/commands/backup.js +5 -2
  17. package/dist/commands/browse.d.ts.map +1 -1
  18. package/dist/commands/browse.js +310 -7
  19. package/dist/commands/checkpoint.d.ts +12 -0
  20. package/dist/commands/checkpoint.d.ts.map +1 -0
  21. package/dist/commands/checkpoint.js +162 -0
  22. package/dist/commands/context.d.ts +2 -2
  23. package/dist/commands/context.d.ts.map +1 -1
  24. package/dist/commands/context.js +3 -151
  25. package/dist/commands/decision.d.ts.map +1 -1
  26. package/dist/commands/decision.js +31 -7
  27. package/dist/commands/deinit.d.ts +2 -2
  28. package/dist/commands/deinit.js +15 -15
  29. package/dist/commands/doctor.js +23 -23
  30. package/dist/commands/governor.d.ts +4 -0
  31. package/dist/commands/governor.d.ts.map +1 -0
  32. package/dist/commands/{supervisor.js → governor.js} +133 -108
  33. package/dist/commands/init.d.ts +12 -12
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +44 -30
  36. package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
  37. package/dist/commands/journal.d.ts.map +1 -0
  38. package/dist/commands/{scratch.js → journal.js} +47 -47
  39. package/dist/commands/policy.js +1 -1
  40. package/dist/commands/presence.js +2 -2
  41. package/dist/commands/sync.d.ts +1 -1
  42. package/dist/commands/sync.js +3 -3
  43. package/dist/commands/tunnel.d.ts +16 -0
  44. package/dist/commands/tunnel.d.ts.map +1 -1
  45. package/dist/commands/tunnel.js +193 -23
  46. package/dist/commands/web-fetch.js +1 -1
  47. package/dist/commands/web.d.ts +19 -0
  48. package/dist/commands/web.d.ts.map +1 -1
  49. package/dist/commands/web.js +51 -0
  50. package/dist/commands/work.d.ts.map +1 -1
  51. package/dist/commands/work.js +38 -22
  52. package/dist/commands/workflow.d.ts.map +1 -1
  53. package/dist/commands/workflow.js +35 -28
  54. package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
  55. package/dist/core/adapters/attest-projection.d.ts.map +1 -0
  56. package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
  57. package/dist/core/adapters/attest.d.ts.map +1 -0
  58. package/dist/core/{harnesses → adapters}/attest.js +9 -9
  59. package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
  60. package/dist/core/adapters/attestation.d.ts.map +1 -0
  61. package/dist/core/{harnesses → adapters}/attestation.js +20 -20
  62. package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
  63. package/dist/core/adapters/bench.d.ts.map +1 -0
  64. package/dist/core/{harnesses → adapters}/bench.js +12 -12
  65. package/dist/core/adapters/index.d.ts +13 -0
  66. package/dist/core/adapters/index.d.ts.map +1 -0
  67. package/dist/core/adapters/index.js +6 -0
  68. package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
  69. package/dist/core/adapters/profiles.d.ts.map +1 -0
  70. package/dist/core/{harnesses → adapters}/profiles.js +11 -11
  71. package/dist/core/adapters/registry.d.ts +15 -0
  72. package/dist/core/adapters/registry.d.ts.map +1 -0
  73. package/dist/core/{harnesses → adapters}/registry.js +11 -11
  74. package/dist/core/{harnesses → adapters}/types.d.ts +23 -23
  75. package/dist/core/adapters/types.d.ts.map +1 -0
  76. package/dist/core/{harnesses → adapters}/types.js +1 -1
  77. package/dist/core/agents/canonical-emit.d.ts +4 -4
  78. package/dist/core/agents/canonical-emit.js +5 -5
  79. package/dist/core/agents/cli-emit.js +1 -1
  80. package/dist/core/agents/cli.js +30 -26
  81. package/dist/core/agents/codex-replay.d.ts +1 -1
  82. package/dist/core/agents/codex-replay.js +6 -6
  83. package/dist/core/agents/coord-client.d.ts +21 -2
  84. package/dist/core/agents/coord-client.d.ts.map +1 -1
  85. package/dist/core/agents/coord-client.js +122 -27
  86. package/dist/core/agents/events/consume.d.ts +1 -1
  87. package/dist/core/agents/events/emit.d.ts +5 -6
  88. package/dist/core/agents/events/emit.d.ts.map +1 -1
  89. package/dist/core/agents/events/emit.js +2 -2
  90. package/dist/core/agents/render/prompt-context.d.ts +21 -9
  91. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  92. package/dist/core/agents/render/prompt-context.js +82 -30
  93. package/dist/core/agents/render/session-context.d.ts +1 -1
  94. package/dist/core/agents/render/session-context.js +5 -5
  95. package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
  96. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  97. package/dist/core/agents/rules/claim-conflict.js +1 -1
  98. package/dist/core/agents/rules/commit-conflict.js +98 -22
  99. package/dist/core/agents/rules/stop-hook.d.ts +9 -9
  100. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  101. package/dist/core/agents/rules/stop-hook.js +23 -5
  102. package/dist/core/agents/rules/verdict.d.ts +14 -0
  103. package/dist/core/agents/rules/verdict.d.ts.map +1 -0
  104. package/dist/core/agents/rules/verdict.js +1 -0
  105. package/dist/core/agents/session-events.js +3 -3
  106. package/dist/core/agents/state/council.d.ts +1 -1
  107. package/dist/core/agents/state/council.js +1 -1
  108. package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
  109. package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
  110. package/dist/core/agents/state/heartbeat-projector.js +14 -10
  111. package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
  112. package/dist/core/agents/state/heartbeat-writer.js +12 -12
  113. package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
  114. package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
  115. package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
  116. package/dist/core/agents/state/pidmap.d.ts +28 -4
  117. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  118. package/dist/core/agents/state/pidmap.js +130 -15
  119. package/dist/core/agents/state/proc-start.d.ts +95 -0
  120. package/dist/core/agents/state/proc-start.d.ts.map +1 -0
  121. package/dist/core/agents/state/proc-start.js +199 -0
  122. package/dist/core/agents/state/shell-mutation.d.ts +1 -1
  123. package/dist/core/agents/state/shell-mutation.js +1 -1
  124. package/dist/core/agents/state/stale-sweep.js +7 -7
  125. package/dist/core/artifacts/index.d.ts +86 -0
  126. package/dist/core/artifacts/index.d.ts.map +1 -0
  127. package/dist/core/artifacts/index.js +421 -0
  128. package/dist/core/config.d.ts +9 -2
  129. package/dist/core/config.d.ts.map +1 -1
  130. package/dist/core/config.js +26 -2
  131. package/dist/core/context/index.d.ts +12 -12
  132. package/dist/core/context/index.js +10 -10
  133. package/dist/core/governor/adapter-spread.d.ts +52 -0
  134. package/dist/core/governor/adapter-spread.d.ts.map +1 -0
  135. package/dist/core/governor/adapter-spread.js +52 -0
  136. package/dist/core/governor/index.d.ts +7 -0
  137. package/dist/core/governor/index.d.ts.map +1 -0
  138. package/dist/core/governor/index.js +6 -0
  139. package/dist/core/governor/plan-api.d.ts +38 -0
  140. package/dist/core/governor/plan-api.d.ts.map +1 -0
  141. package/dist/core/governor/plan-api.js +83 -0
  142. package/dist/core/governor/plan-read.d.ts +5 -0
  143. package/dist/core/governor/plan-read.d.ts.map +1 -0
  144. package/dist/core/{supervisor → governor}/plan-read.js +66 -52
  145. package/dist/core/{supervisor → governor}/plan-types.d.ts +57 -56
  146. package/dist/core/governor/plan-types.d.ts.map +1 -0
  147. package/dist/core/{supervisor → governor}/plan-types.js +4 -4
  148. package/dist/core/governor/planning.d.ts +48 -0
  149. package/dist/core/governor/planning.d.ts.map +1 -0
  150. package/dist/core/{supervisor → governor}/planning.js +125 -94
  151. package/dist/core/governor/read.d.ts +6 -0
  152. package/dist/core/governor/read.d.ts.map +1 -0
  153. package/dist/core/governor/read.js +4 -0
  154. package/dist/core/governor/runner.d.ts +37 -0
  155. package/dist/core/governor/runner.d.ts.map +1 -0
  156. package/dist/core/{supervisor → governor}/runner.js +15 -15
  157. package/dist/core/governor/service-read.d.ts +6 -0
  158. package/dist/core/governor/service-read.d.ts.map +1 -0
  159. package/dist/core/{supervisor → governor}/service-read.js +12 -12
  160. package/dist/core/governor/service.d.ts +114 -0
  161. package/dist/core/governor/service.d.ts.map +1 -0
  162. package/dist/core/{supervisor → governor}/service.js +57 -57
  163. package/dist/core/governor/state.d.ts +116 -0
  164. package/dist/core/governor/state.d.ts.map +1 -0
  165. package/dist/core/{supervisor → governor}/state.js +228 -108
  166. package/dist/core/hooks/adapter/detect.d.ts +9 -0
  167. package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
  168. package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
  169. package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
  170. package/dist/core/hooks/adapter/events.d.ts.map +1 -0
  171. package/dist/core/hooks/{harness → adapter}/events.js +5 -5
  172. package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
  173. package/dist/core/hooks/adapter/output.d.ts.map +1 -0
  174. package/dist/core/hooks/{harness → adapter}/output.js +30 -22
  175. package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
  176. package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
  177. package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
  178. package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
  179. package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
  180. package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
  181. package/dist/core/hooks/cli.d.ts +3 -3
  182. package/dist/core/hooks/cli.js +175 -151
  183. package/dist/core/hooks/effects/image-capture.d.ts +5 -5
  184. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  185. package/dist/core/hooks/effects/image-capture.js +3 -3
  186. package/dist/core/hooks/effects/index.d.ts +12 -12
  187. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  188. package/dist/core/hooks/effects/index.js +17 -17
  189. package/dist/core/hooks/events/emit.d.ts +2 -2
  190. package/dist/core/hooks/events/emit.d.ts.map +1 -1
  191. package/dist/core/hooks/events/emit.js +1 -1
  192. package/dist/core/hooks/events/rotate.js +1 -1
  193. package/dist/core/hooks/events/schema.d.ts +13 -5
  194. package/dist/core/hooks/events/schema.d.ts.map +1 -1
  195. package/dist/core/hooks/guard-path.d.ts +2 -2
  196. package/dist/core/hooks/guard-path.js +2 -2
  197. package/dist/core/hooks/index.d.ts +1 -1
  198. package/dist/core/hooks/index.d.ts.map +1 -1
  199. package/dist/core/hooks/resolve/anchor.d.ts +14 -5
  200. package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
  201. package/dist/core/hooks/resolve/anchor.js +64 -7
  202. package/dist/core/hooks/resolve/coord-root.d.ts +3 -3
  203. package/dist/core/hooks/resolve/coord-root.js +4 -4
  204. package/dist/core/hooks/resolve/intent.js +1 -1
  205. package/dist/core/hooks/resolve/owner.d.ts +1 -1
  206. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  207. package/dist/core/hooks/resolve/owner.js +11 -5
  208. package/dist/core/{scratch → journal}/index.d.ts +25 -25
  209. package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
  210. package/dist/core/{scratch → journal}/index.js +38 -38
  211. package/dist/core/policy/evaluate.d.ts +1 -1
  212. package/dist/core/policy/evaluate.d.ts.map +1 -1
  213. package/dist/core/policy/evaluate.js +7 -7
  214. package/dist/core/policy/types.d.ts +3 -3
  215. package/dist/core/policy/types.d.ts.map +1 -1
  216. package/dist/core/work/state.d.ts +12 -4
  217. package/dist/core/work/state.d.ts.map +1 -1
  218. package/dist/core/work/state.js +50 -17
  219. package/dist/core/workflow/adapters.d.ts +17 -0
  220. package/dist/core/workflow/adapters.d.ts.map +1 -0
  221. package/dist/core/workflow/adapters.js +21 -0
  222. package/dist/core/workflow/approvals.js +6 -6
  223. package/dist/core/workflow/billing.d.ts +9 -9
  224. package/dist/core/workflow/billing.js +9 -9
  225. package/dist/core/workflow/child-env.d.ts +10 -2
  226. package/dist/core/workflow/child-env.d.ts.map +1 -1
  227. package/dist/core/workflow/child-env.js +12 -4
  228. package/dist/core/workflow/engine.d.ts +15 -5
  229. package/dist/core/workflow/engine.d.ts.map +1 -1
  230. package/dist/core/workflow/engine.js +138 -83
  231. package/dist/core/workflow/evidence-preflight.d.ts +24 -0
  232. package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
  233. package/dist/core/workflow/evidence-preflight.js +134 -0
  234. package/dist/core/workflow/index.d.ts +1 -1
  235. package/dist/core/workflow/index.d.ts.map +1 -1
  236. package/dist/core/workflow/proof.d.ts +11 -5
  237. package/dist/core/workflow/proof.d.ts.map +1 -1
  238. package/dist/core/workflow/proof.js +45 -36
  239. package/dist/core/workflow/run-state.d.ts +1 -1
  240. package/dist/core/workflow/run-state.js +7 -7
  241. package/dist/core/workflow/sandbox-projection.d.ts +6 -6
  242. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  243. package/dist/core/workflow/sandbox-projection.js +11 -11
  244. package/dist/core/workflow/spawn-claude.d.ts +3 -3
  245. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  246. package/dist/core/workflow/spawn-claude.js +9 -6
  247. package/dist/core/workflow/spawn-codex.d.ts +4 -4
  248. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  249. package/dist/core/workflow/spawn-codex.js +9 -6
  250. package/dist/core/workflow/spawn-cursor.d.ts +4 -4
  251. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  252. package/dist/core/workflow/spawn-cursor.js +9 -6
  253. package/dist/core/workflow/spawn-failure.d.ts +1 -1
  254. package/dist/core/workflow/spawn-failure.js +1 -1
  255. package/dist/core/workflow/specialists.js +2 -2
  256. package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
  257. package/dist/core/workflow/transcript.d.ts.map +1 -0
  258. package/dist/core/workflow/{journal.js → transcript.js} +14 -14
  259. package/dist/core/workflow/types.d.ts +98 -51
  260. package/dist/core/workflow/types.d.ts.map +1 -1
  261. package/dist/core/workflow/types.js +11 -1
  262. package/dist/core/workflow/validate.d.ts +1 -1
  263. package/dist/core/workflow/validate.js +1 -1
  264. package/dist/core/workflow/workspaces/cancellation.js +2 -2
  265. package/dist/core/workflow/workspaces/cleanup.js +2 -2
  266. package/dist/core/workflow/workspaces/execution.js +6 -6
  267. package/dist/core/workflow/workspaces/inspect.js +9 -9
  268. package/dist/core/workflow/workspaces/integration.js +14 -14
  269. package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
  270. package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
  271. package/dist/core/workflow/workspaces/lifecycle.js +9 -9
  272. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  273. package/dist/core/workflow/workspaces/local-git.js +39 -5
  274. package/dist/core/workflow/workspaces/recovery.js +3 -3
  275. package/dist/core/workflow/workspaces/state.d.ts +1 -1
  276. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  277. package/dist/core/workflow/workspaces/state.js +3 -3
  278. package/dist/core/workflow/workspaces/types.d.ts +1 -1
  279. package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
  280. package/dist/lib/browser/asserts.d.ts +28 -0
  281. package/dist/lib/browser/asserts.d.ts.map +1 -0
  282. package/dist/lib/browser/asserts.js +152 -0
  283. package/dist/lib/browser/client.d.ts +49 -0
  284. package/dist/lib/browser/client.d.ts.map +1 -1
  285. package/dist/lib/browser/client.js +155 -14
  286. package/dist/lib/browser/content-checks.d.ts +108 -0
  287. package/dist/lib/browser/content-checks.d.ts.map +1 -0
  288. package/dist/lib/browser/content-checks.js +474 -0
  289. package/dist/lib/browser/critique.d.ts +91 -0
  290. package/dist/lib/browser/critique.d.ts.map +1 -0
  291. package/dist/lib/browser/critique.js +167 -0
  292. package/dist/lib/browser/geometry.d.ts +32 -0
  293. package/dist/lib/browser/geometry.d.ts.map +1 -1
  294. package/dist/lib/browser/geometry.js +244 -1
  295. package/dist/lib/browser/index.d.ts +4 -1
  296. package/dist/lib/browser/index.d.ts.map +1 -1
  297. package/dist/lib/browser/index.js +2 -0
  298. package/dist/lib/claude-desktop.d.ts.map +1 -1
  299. package/dist/lib/claude-desktop.js +4 -1
  300. package/dist/lib/council/index.d.ts +6 -6
  301. package/dist/lib/council/index.d.ts.map +1 -1
  302. package/dist/lib/council/index.js +8 -8
  303. package/dist/lib/identities/assume.d.ts +2 -2
  304. package/dist/lib/identities/assume.js +7 -7
  305. package/dist/lib/instructions/apply.d.ts +3 -3
  306. package/dist/lib/instructions/apply.d.ts.map +1 -1
  307. package/dist/lib/instructions/apply.js +75 -27
  308. package/dist/lib/instructions/host-addendum.d.ts +54 -0
  309. package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
  310. package/dist/lib/instructions/host-addendum.js +107 -0
  311. package/dist/lib/instructions/templates.d.ts +10 -3
  312. package/dist/lib/instructions/templates.d.ts.map +1 -1
  313. package/dist/lib/instructions/templates.js +41 -12
  314. package/dist/lib/machine.d.ts +2 -2
  315. package/dist/lib/machine.js +2 -2
  316. package/package.json +26 -21
  317. package/schemas/config.schema.json +26 -1
  318. package/src/commander.ts +22 -13
  319. package/src/commands/{harness.ts → adapter.ts} +46 -46
  320. package/src/commands/agents.ts +71 -64
  321. package/src/commands/artifacts.ts +168 -0
  322. package/src/commands/backup.ts +47 -33
  323. package/src/commands/browse.ts +438 -2
  324. package/src/commands/checkpoint.ts +196 -0
  325. package/src/commands/context.ts +3 -176
  326. package/src/commands/decision.ts +41 -7
  327. package/src/commands/deinit.ts +16 -16
  328. package/src/commands/doctor.ts +28 -28
  329. package/src/commands/{supervisor.ts → governor.ts} +184 -154
  330. package/src/commands/init.ts +50 -34
  331. package/src/commands/{scratch.ts → journal.ts} +60 -60
  332. package/src/commands/policy.ts +1 -1
  333. package/src/commands/presence.ts +2 -2
  334. package/src/commands/sync.ts +3 -3
  335. package/src/commands/tunnel.ts +237 -34
  336. package/src/commands/web-fetch.ts +1 -1
  337. package/src/commands/web.ts +56 -1
  338. package/src/commands/work.ts +50 -35
  339. package/src/commands/workflow.ts +43 -34
  340. package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
  341. package/src/core/{harnesses → adapters}/attest.ts +27 -27
  342. package/src/core/{harnesses → adapters}/attestation.ts +41 -41
  343. package/src/core/{harnesses → adapters}/bench.ts +34 -43
  344. package/src/core/adapters/index.ts +56 -0
  345. package/src/core/{harnesses → adapters}/profiles.ts +16 -16
  346. package/src/core/{harnesses → adapters}/registry.ts +23 -23
  347. package/src/core/{harnesses → adapters}/types.ts +23 -23
  348. package/src/core/agents/canonical-emit.ts +6 -6
  349. package/src/core/agents/cli-emit.ts +1 -1
  350. package/src/core/agents/cli.ts +30 -28
  351. package/src/core/agents/codex-replay.ts +6 -6
  352. package/src/core/agents/coord-client.ts +119 -28
  353. package/src/core/agents/events/consume.ts +1 -1
  354. package/src/core/agents/events/emit.ts +7 -6
  355. package/src/core/agents/render/prompt-context.ts +107 -31
  356. package/src/core/agents/render/session-context.ts +6 -6
  357. package/src/core/agents/rules/claim-conflict.ts +4 -7
  358. package/src/core/agents/rules/commit-conflict.ts +103 -22
  359. package/src/core/agents/rules/stop-hook.ts +33 -17
  360. package/src/core/agents/rules/verdict.ts +13 -0
  361. package/src/core/agents/session-events.ts +4 -4
  362. package/src/core/agents/state/council.ts +1 -1
  363. package/src/core/agents/state/heartbeat-projector.ts +16 -12
  364. package/src/core/agents/state/heartbeat-writer.ts +12 -12
  365. package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
  366. package/src/core/agents/state/pidmap.ts +130 -15
  367. package/src/core/agents/state/proc-start.ts +208 -0
  368. package/src/core/agents/state/shell-mutation.ts +1 -1
  369. package/src/core/agents/state/stale-sweep.ts +7 -7
  370. package/src/core/artifacts/index.ts +557 -0
  371. package/src/core/config.ts +30 -2
  372. package/src/core/context/index.ts +15 -15
  373. package/src/core/governor/adapter-spread.ts +82 -0
  374. package/src/core/governor/index.ts +91 -0
  375. package/src/core/governor/plan-api.ts +115 -0
  376. package/src/core/{supervisor → governor}/plan-read.ts +112 -97
  377. package/src/core/{supervisor → governor}/plan-types.ts +59 -56
  378. package/src/core/{supervisor → governor}/planning.ts +223 -192
  379. package/src/core/governor/read.ts +59 -0
  380. package/src/core/{supervisor → governor}/runner.ts +39 -39
  381. package/src/core/{supervisor → governor}/service-read.ts +22 -22
  382. package/src/core/{supervisor → governor}/service.ts +117 -119
  383. package/src/core/{supervisor → governor}/state.ts +325 -167
  384. package/src/core/hooks/adapter/detect.ts +30 -0
  385. package/src/core/hooks/{harness → adapter}/events.ts +16 -14
  386. package/src/core/hooks/{harness → adapter}/output.ts +31 -23
  387. package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
  388. package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
  389. package/src/core/hooks/cli.ts +185 -162
  390. package/src/core/hooks/effects/image-capture.ts +6 -6
  391. package/src/core/hooks/effects/index.ts +17 -17
  392. package/src/core/hooks/events/emit.ts +3 -3
  393. package/src/core/hooks/events/rotate.ts +1 -1
  394. package/src/core/hooks/events/schema.ts +15 -7
  395. package/src/core/hooks/guard-path.ts +2 -2
  396. package/src/core/hooks/index.ts +1 -1
  397. package/src/core/hooks/resolve/anchor.ts +63 -8
  398. package/src/core/hooks/resolve/coord-root.ts +4 -4
  399. package/src/core/hooks/resolve/intent.ts +1 -1
  400. package/src/core/hooks/resolve/owner.ts +11 -5
  401. package/src/core/{scratch → journal}/index.ts +53 -53
  402. package/src/core/policy/evaluate.ts +8 -8
  403. package/src/core/policy/types.ts +3 -3
  404. package/src/core/work/state.ts +65 -23
  405. package/src/core/workflow/adapters.ts +33 -0
  406. package/src/core/workflow/approvals.ts +7 -7
  407. package/src/core/workflow/billing.ts +12 -12
  408. package/src/core/workflow/child-env.ts +13 -4
  409. package/src/core/workflow/engine.ts +155 -90
  410. package/src/core/workflow/evidence-preflight.ts +165 -0
  411. package/src/core/workflow/index.ts +3 -3
  412. package/src/core/workflow/proof.ts +60 -50
  413. package/src/core/workflow/run-state.ts +7 -7
  414. package/src/core/workflow/sandbox-projection.ts +16 -16
  415. package/src/core/workflow/spawn-claude.ts +13 -10
  416. package/src/core/workflow/spawn-codex.ts +13 -10
  417. package/src/core/workflow/spawn-cursor.ts +13 -10
  418. package/src/core/workflow/spawn-failure.ts +1 -1
  419. package/src/core/workflow/specialists.ts +2 -2
  420. package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
  421. package/src/core/workflow/types.ts +108 -51
  422. package/src/core/workflow/validate.ts +1 -1
  423. package/src/core/workflow/workspaces/cancellation.ts +2 -2
  424. package/src/core/workflow/workspaces/cleanup.ts +2 -2
  425. package/src/core/workflow/workspaces/execution.ts +6 -6
  426. package/src/core/workflow/workspaces/inspect.ts +14 -11
  427. package/src/core/workflow/workspaces/integration.ts +18 -14
  428. package/src/core/workflow/workspaces/lifecycle.ts +10 -10
  429. package/src/core/workflow/workspaces/local-git.ts +47 -5
  430. package/src/core/workflow/workspaces/recovery.ts +3 -3
  431. package/src/core/workflow/workspaces/state.ts +4 -3
  432. package/src/core/workflow/workspaces/types.ts +1 -1
  433. package/src/lib/browser/asserts.ts +177 -0
  434. package/src/lib/browser/client.ts +189 -14
  435. package/src/lib/browser/content-checks.ts +571 -0
  436. package/src/lib/browser/critique.ts +231 -0
  437. package/src/lib/browser/geometry.ts +297 -1
  438. package/src/lib/browser/index.ts +34 -0
  439. package/src/lib/claude-desktop.ts +4 -1
  440. package/src/lib/council/index.ts +9 -9
  441. package/src/lib/identities/assume.ts +7 -7
  442. package/src/lib/instructions/apply.ts +87 -25
  443. package/src/lib/instructions/host-addendum.ts +126 -0
  444. package/src/lib/instructions/templates.ts +44 -15
  445. package/src/lib/machine.ts +2 -2
  446. package/dist/commands/harness.d.ts +0 -12
  447. package/dist/commands/harness.d.ts.map +0 -1
  448. package/dist/commands/scratch.d.ts +0 -4
  449. package/dist/commands/scratch.d.ts.map +0 -1
  450. package/dist/commands/session.d.ts.map +0 -1
  451. package/dist/commands/session.js +0 -162
  452. package/dist/commands/supervisor.d.ts +0 -4
  453. package/dist/commands/supervisor.d.ts.map +0 -1
  454. package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
  455. package/dist/core/harnesses/attest.d.ts.map +0 -1
  456. package/dist/core/harnesses/attestation.d.ts.map +0 -1
  457. package/dist/core/harnesses/bench.d.ts.map +0 -1
  458. package/dist/core/harnesses/index.d.ts +0 -13
  459. package/dist/core/harnesses/index.d.ts.map +0 -1
  460. package/dist/core/harnesses/index.js +0 -6
  461. package/dist/core/harnesses/profiles.d.ts.map +0 -1
  462. package/dist/core/harnesses/registry.d.ts +0 -15
  463. package/dist/core/harnesses/registry.d.ts.map +0 -1
  464. package/dist/core/harnesses/types.d.ts.map +0 -1
  465. package/dist/core/hooks/harness/detect.d.ts +0 -9
  466. package/dist/core/hooks/harness/events.d.ts.map +0 -1
  467. package/dist/core/hooks/harness/output.d.ts.map +0 -1
  468. package/dist/core/supervisor/index.d.ts +0 -7
  469. package/dist/core/supervisor/index.d.ts.map +0 -1
  470. package/dist/core/supervisor/index.js +0 -6
  471. package/dist/core/supervisor/plan-api.d.ts +0 -23
  472. package/dist/core/supervisor/plan-api.d.ts.map +0 -1
  473. package/dist/core/supervisor/plan-api.js +0 -50
  474. package/dist/core/supervisor/plan-read.d.ts +0 -5
  475. package/dist/core/supervisor/plan-read.d.ts.map +0 -1
  476. package/dist/core/supervisor/plan-types.d.ts.map +0 -1
  477. package/dist/core/supervisor/planning.d.ts +0 -33
  478. package/dist/core/supervisor/planning.d.ts.map +0 -1
  479. package/dist/core/supervisor/read.d.ts +0 -6
  480. package/dist/core/supervisor/read.d.ts.map +0 -1
  481. package/dist/core/supervisor/read.js +0 -4
  482. package/dist/core/supervisor/runner.d.ts +0 -37
  483. package/dist/core/supervisor/runner.d.ts.map +0 -1
  484. package/dist/core/supervisor/service-read.d.ts +0 -6
  485. package/dist/core/supervisor/service-read.d.ts.map +0 -1
  486. package/dist/core/supervisor/service.d.ts +0 -114
  487. package/dist/core/supervisor/service.d.ts.map +0 -1
  488. package/dist/core/supervisor/state.d.ts +0 -95
  489. package/dist/core/supervisor/state.d.ts.map +0 -1
  490. package/dist/core/workflow/harnesses.d.ts +0 -17
  491. package/dist/core/workflow/harnesses.d.ts.map +0 -1
  492. package/dist/core/workflow/harnesses.js +0 -21
  493. package/dist/core/workflow/journal.d.ts.map +0 -1
  494. package/src/commands/session.ts +0 -187
  495. package/src/core/harnesses/index.ts +0 -56
  496. package/src/core/hooks/harness/detect.ts +0 -30
  497. package/src/core/supervisor/index.ts +0 -89
  498. package/src/core/supervisor/plan-api.ts +0 -73
  499. package/src/core/supervisor/read.ts +0 -59
  500. package/src/core/workflow/harnesses.ts +0 -33
  501. /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Council manifest helpers: file-based multi-agent coordination primitives.
3
3
  *
4
- * Lives under .harnery/councils/ alongside heartbeats + scratchpads. Council
4
+ * Lives under .harnery/councils/ alongside heartbeats + journals. Council
5
5
  * lifecycle commands serialize manifest mutations through a shared flock;
6
6
  * round contribution files are per-member and don't need shared locking.
7
7
  */
@@ -176,7 +176,7 @@ export function setCouncilSteward(councilId, steward) {
176
176
  * next-app's same-named constant. */
177
177
  const KNOWN_AGENT_STALE_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
178
178
  /**
179
- * Active heartbeats + recently-archived scratchpads, deduped by name.
179
+ * Active heartbeats + recently-archived journals, deduped by name.
180
180
  * Used by `agents council set-steward` to refuse arbitrary names;
181
181
  * pass `--allow-unknown` to bypass when bootstrapping a new agent.
182
182
  */
@@ -185,7 +185,7 @@ export function listKnownAgents() {
185
185
  if (!root)
186
186
  return [];
187
187
  const activeDir = resolve(root, ".harnery", "active");
188
- const archiveDir = resolve(root, ".harnery", "scratch", "archived");
188
+ const archiveDir = resolve(root, ".harnery", "journal", "archived");
189
189
  const byName = new Map();
190
190
  if (existsSync(activeDir)) {
191
191
  for (const f of readdirSync(activeDir)) {
@@ -220,7 +220,7 @@ export function listKnownAgents() {
220
220
  continue;
221
221
  try {
222
222
  const head = readFileSync(resolve(archiveDir, f), "utf8").slice(0, 200);
223
- const nameMatch = head.match(/^#\s+Scratchpad:\s+(agent-[A-Za-z][A-Za-z0-9_-]*)/m);
223
+ const nameMatch = head.match(/^#\s+Journal:\s+(agent-[A-Za-z][A-Za-z0-9_-]*)/m);
224
224
  if (!nameMatch)
225
225
  continue;
226
226
  const name = nameMatch[1];
@@ -504,7 +504,7 @@ export function writeContribution(councilId, round, memberName, body) {
504
504
  * Path to the round-N prompts directory: `.harnery/councils/<id>/round-N/prompts/`.
505
505
  * Sibling to the contribution files. Holds one `<member>.md` per non-self
506
506
  * council member, drafted by the steward, read by the operator (copy-paste
507
- * into each agent harness) and the web UI (per-member panel).
507
+ * into each agent adapter) and the web UI (per-member panel).
508
508
  */
509
509
  export function promptsDir(councilId, round) {
510
510
  const rd = roundDir(councilId, round);
@@ -549,9 +549,9 @@ const SUBMIT_FOOTER_MARKER = "<!-- council-submit-footer -->";
549
549
  * Build the submit footer appended to every steward-drafted prompt. This is the
550
550
  * load-bearing instruction that a contribution composed in chat is NOT recorded;
551
551
  * the agent must run the command below. It rides on the prompt (the one
552
- * artifact the operator always pastes) so it reaches every harness regardless of
552
+ * artifact the operator always pastes) so it reaches every adapter regardless of
553
553
  * whether the convene-time invitation was delivered or a `/council` skill is
554
- * available. Without it, agents (esp. non-Claude harnesses with no skill) write
554
+ * available. Without it, agents (esp. non-Claude adapters with no skill) write
555
555
  * their take as a reply and end the turn, leaving the council showing them as
556
556
  * still-pending. Visible markdown (not an HTML comment) so the agent reads it.
557
557
  */
@@ -567,7 +567,7 @@ export function buildSubmitFooter(councilId) {
567
567
  `# longer write-up? ${bin} agents council contribute ${councilId} --file <path>`,
568
568
  "```",
569
569
  "",
570
- '_(Or invoke the `council` skill in your harness: `/council contribute` in Claude Code, `$council` / "use the council skill" in Codex/Cursor, for the same flow with routing guards.)_',
570
+ '_(Or invoke the `council` skill in your adapter: `/council contribute` in Claude Code, `$council` / "use the council skill" in Codex/Cursor, for the same flow with routing guards.)_',
571
571
  ].join("\n");
572
572
  }
573
573
  /** Strip an appended submit footer from a prompt body, if present. */
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * Local collision policy: a fresh heartbeat alone is not enough to block.
10
10
  * If the namesake has no live pid-map process (crashed session, healed
11
- * zombie, or abandoned harness), reclaim that heartbeat and continue.
11
+ * zombie, or abandoned adapter), reclaim that heartbeat and continue.
12
12
  * Refuse only when another process is still alive, or when cached remote
13
13
  * presence reports the name.
14
14
  */
@@ -40,7 +40,7 @@ export interface IdentityAssumeResult {
40
40
  * presence. No network call occurs; absent presence degrades to local-only. */
41
41
  export declare function findIdentityConflict(coordRoot: string, instanceId: string, name: string, nowMs?: number): IdentityConflict | null;
42
42
  /**
43
- * Drop a local namesake whose harness process is gone. Fresh heartbeats can
43
+ * Drop a local namesake whose adapter process is gone. Fresh heartbeats can
44
44
  * linger after a crash (or after heartbeat heal without a live pid-map), and
45
45
  * `identity assume` is the supported takeover path — operators should not
46
46
  * need a separate kill/sweep step.
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * Local collision policy: a fresh heartbeat alone is not enough to block.
10
10
  * If the namesake has no live pid-map process (crashed session, healed
11
- * zombie, or abandoned harness), reclaim that heartbeat and continue.
11
+ * zombie, or abandoned adapter), reclaim that heartbeat and continue.
12
12
  * Refuse only when another process is still alive, or when cached remote
13
13
  * presence reports the name.
14
14
  */
@@ -78,7 +78,7 @@ export function findIdentityConflict(coordRoot, instanceId, name, nowMs = Date.n
78
78
  return null;
79
79
  }
80
80
  /**
81
- * Drop a local namesake whose harness process is gone. Fresh heartbeats can
81
+ * Drop a local namesake whose adapter process is gone. Fresh heartbeats can
82
82
  * linger after a crash (or after heartbeat heal without a live pid-map), and
83
83
  * `identity assume` is the supported takeover path — operators should not
84
84
  * need a separate kill/sweep step.
@@ -89,13 +89,13 @@ export function reclaimAbandonedLocalConflict(coordRoot, conflict) {
89
89
  if (instanceHasLivePid(coordRoot, conflict.instance_id))
90
90
  return false;
91
91
  const hbPath = join(coordRoot, ".harnery", "active", `${conflict.instance_id}.json`);
92
- let harness = "claude-code";
92
+ let adapter = "claude-code";
93
93
  let sessionId = conflict.instance_id;
94
94
  let ageSecs;
95
95
  if (existsSync(hbPath)) {
96
96
  try {
97
97
  const hb = JSON.parse(readFileSync(hbPath, "utf8"));
98
- harness = harnessOf(hb.platform);
98
+ adapter = adapterOf(hb.platform);
99
99
  sessionId = hb.session_id || conflict.instance_id;
100
100
  const ts = Date.parse(hb.last_heartbeat);
101
101
  if (Number.isFinite(ts))
@@ -117,7 +117,7 @@ export function reclaimAbandonedLocalConflict(coordRoot, conflict) {
117
117
  event_type: "health.heartbeat_swept",
118
118
  instance_id: conflict.instance_id,
119
119
  session_id: sessionId,
120
- harness,
120
+ adapter,
121
121
  source: "agent-coord",
122
122
  data: {
123
123
  reason: "stale",
@@ -186,7 +186,7 @@ function acquireLock(coordRoot) {
186
186
  }
187
187
  throw new IdentityAssumeError("identity_busy", "another identity assumption is in progress; retry in a moment");
188
188
  }
189
- function harnessOf(platform) {
189
+ function adapterOf(platform) {
190
190
  if (platform === "cursor")
191
191
  return "cursor";
192
192
  if (platform === "codex")
@@ -239,7 +239,7 @@ export function assumeIdentity(coordRoot, instanceId, target) {
239
239
  event_type: "identity.assumed",
240
240
  instance_id: instanceId,
241
241
  session_id: hb.session_id,
242
- harness: harnessOf(hb.platform),
242
+ adapter: adapterOf(hb.platform),
243
243
  data: {
244
244
  name: identity.name,
245
245
  agent_id: identity.agent_id,
@@ -21,7 +21,7 @@
21
21
  export declare function readSkillsExclude(projectRoot: string): Set<string>;
22
22
  interface ApplyOpts {
23
23
  binName: string;
24
- harness: string;
24
+ adapter: string;
25
25
  dryRun: boolean;
26
26
  }
27
27
  export interface ApplyResult {
@@ -35,7 +35,7 @@ export interface ApplyResult {
35
35
  */
36
36
  export declare function applyInstructions(projectRoot: string, opts: ApplyOpts): ApplyResult;
37
37
  interface RemoveOpts {
38
- harness: string;
38
+ adapter: string;
39
39
  dryRun: boolean;
40
40
  }
41
41
  /**
@@ -57,7 +57,7 @@ export interface CheckResult {
57
57
  */
58
58
  export declare function checkInstructions(projectRoot: string, opts: {
59
59
  binName: string;
60
- harness: string;
60
+ adapter: string;
61
61
  }): CheckResult;
62
62
  export {};
63
63
  //# sourceMappingURL=apply.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA4CH,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYlE;AAiBD,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CA4EnF;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAmErF;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CAqCb"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA8CH,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYlE;AAiBD,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CA8GnF;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAiFrF;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CAiDb"}
@@ -20,8 +20,9 @@
20
20
  import { existsSync, mkdirSync, readdirSync, readFileSync, rmdirSync, rmSync, writeFileSync, } from "node:fs";
21
21
  import { dirname, join } from "node:path";
22
22
  import { stripJsonComments } from "../../core/config.js";
23
+ import { readHostAddendum } from "./host-addendum.js";
23
24
  import { checkOwnedSkill, checkRegion, isOwnedFile, removeRegion, spliceRegion, } from "./splice.js";
24
- import { IMPORT_REGION, INSTRUCTIONS_REGION, renderInstructionsBlock, SKILLS, } from "./templates.js";
25
+ import { HOST_ADDENDUM_REGION, IMPORT_REGION, INSTRUCTIONS_REGION, renderInstructionsBlock, SKILLS, } from "./templates.js";
25
26
  const AGENTS_FILE = "AGENTS.md";
26
27
  const CLAUDE_FILE = "CLAUDE.md";
27
28
  const CLAUDE_SKILLS_DIR = join(".claude", "skills");
@@ -54,8 +55,8 @@ export function readSkillsExclude(projectRoot) {
54
55
  * codex get the block but no skill files, so both read false there. Kept in one
55
56
  * place so `applyInstructions` and `checkInstructions` render byte-identical blocks.
56
57
  */
57
- function blockSkills(projectRoot, harness) {
58
- const claudeCode = harness === "claude-code";
58
+ function blockSkills(projectRoot, adapter) {
59
+ const claudeCode = adapter === "claude-code";
59
60
  const exclude = readSkillsExclude(projectRoot);
60
61
  return {
61
62
  decide: claudeCode && !exclude.has("harn-decide"),
@@ -70,28 +71,57 @@ function blockSkills(projectRoot, harness) {
70
71
  export function applyInstructions(projectRoot, opts) {
71
72
  const actions = [];
72
73
  const warnings = [];
73
- const claudeCode = opts.harness === "claude-code";
74
+ const claudeCode = opts.adapter === "claude-code";
74
75
  // dry-run narrates the future ("would create"); a real run narrates the past.
75
76
  const verbed = (base, past) => (opts.dryRun ? `would ${base}` : past);
77
+ // Resolve the host addendum before touching a single file, so a bad path
78
+ // aborts the whole run instead of leaving AGENTS.md half-updated.
79
+ const addendum = readHostAddendum(projectRoot);
76
80
  // ── AGENTS.md orientation block ─────────────────────────────────────────
77
81
  const agentsPath = join(projectRoot, AGENTS_FILE);
78
82
  const agentsExisted = existsSync(agentsPath);
79
83
  const agentsBefore = agentsExisted ? readFileSync(agentsPath, "utf8") : "";
80
- const body = renderInstructionsBlock(opts.binName, blockSkills(projectRoot, opts.harness));
84
+ const body = renderInstructionsBlock(opts.binName, blockSkills(projectRoot, opts.adapter));
81
85
  const spliced = spliceRegion(agentsBefore, INSTRUCTIONS_REGION, body);
82
86
  if (!spliced.changed) {
83
87
  actions.push(`· ${AGENTS_FILE} instructions block already current`);
84
88
  }
89
+ else if (!agentsExisted) {
90
+ actions.push(`+ ${verbed("create", "created")} ${AGENTS_FILE} with the instructions block`);
91
+ }
92
+ else if (!spliced.had) {
93
+ actions.push(`+ ${verbed("inject", "injected")} the instructions block into ${AGENTS_FILE}`);
94
+ }
85
95
  else {
86
- if (!opts.dryRun)
87
- writeFileSync(agentsPath, spliced.text);
88
- if (!agentsExisted)
89
- actions.push(`+ ${verbed("create", "created")} ${AGENTS_FILE} with the instructions block`);
90
- else if (!spliced.had)
91
- actions.push(`+ ${verbed("inject", "injected")} the instructions block into ${AGENTS_FILE}`);
92
- else
93
- actions.push(`~ ${verbed("update", "updated")} the instructions block in ${AGENTS_FILE}`);
96
+ actions.push(`~ ${verbed("update", "updated")} the instructions block in ${AGENTS_FILE}`);
94
97
  }
98
+ // ── host addendum (a second region, content the host owns) ──────────────
99
+ // Harnery places and versions it; what it says is none of harnery's business.
100
+ // No configured source means any region left behind belongs to a config entry
101
+ // that has since been deleted, so init takes it back out.
102
+ let agentsAfter = spliced.text;
103
+ if (addendum.configured) {
104
+ const withAddendum = spliceRegion(agentsAfter, HOST_ADDENDUM_REGION, addendum.body);
105
+ agentsAfter = withAddendum.text;
106
+ if (!withAddendum.changed) {
107
+ actions.push(`· ${AGENTS_FILE} host addendum already current (${addendum.relPath})`);
108
+ }
109
+ else if (!withAddendum.had) {
110
+ actions.push(`+ ${verbed("splice", "spliced")} the host addendum into ${AGENTS_FILE} (${addendum.relPath})`);
111
+ }
112
+ else {
113
+ actions.push(`~ ${verbed("update", "updated")} the host addendum in ${AGENTS_FILE} (${addendum.relPath})`);
114
+ }
115
+ }
116
+ else {
117
+ const dropped = removeRegion(agentsAfter, HOST_ADDENDUM_REGION);
118
+ if (dropped.removed) {
119
+ agentsAfter = dropped.text;
120
+ actions.push(`+ ${verbed("remove", "removed")} the host addendum from ${AGENTS_FILE} (no longer configured)`);
121
+ }
122
+ }
123
+ if (!opts.dryRun && agentsAfter !== agentsBefore)
124
+ writeFileSync(agentsPath, agentsAfter);
95
125
  // ── CLAUDE.md import shim (claude-code only) ────────────────────────────
96
126
  if (claudeCode) {
97
127
  const claudePath = join(projectRoot, CLAUDE_FILE);
@@ -150,23 +180,32 @@ export function applyInstructions(projectRoot, opts) {
150
180
  export function removeInstructions(projectRoot, opts) {
151
181
  const actions = [];
152
182
  const warnings = [];
153
- const claudeCode = opts.harness === "claude-code";
154
- // ── AGENTS.md block ─────────────────────────────────────────────────────
183
+ const claudeCode = opts.adapter === "claude-code";
184
+ // ── AGENTS.md block + host addendum ─────────────────────────────────────
155
185
  const agentsPath = join(projectRoot, AGENTS_FILE);
156
186
  if (existsSync(agentsPath)) {
157
- const { text, removed } = removeRegion(readFileSync(agentsPath, "utf8"), INSTRUCTIONS_REGION);
158
- if (!removed) {
159
- actions.push(`· no instructions block in ${AGENTS_FILE}`);
187
+ // Both regions are harnery-placed, so deinit leaves neither behind. The
188
+ // addendum's *source file* is the host's and stays where it is.
189
+ const addendumGone = removeRegion(readFileSync(agentsPath, "utf8"), HOST_ADDENDUM_REGION);
190
+ if (addendumGone.removed) {
191
+ actions.push(`+ ${opts.dryRun ? "would remove" : "removed"} the host addendum from ${AGENTS_FILE}`);
160
192
  }
161
- else if (text === "") {
162
- if (!opts.dryRun)
163
- rmSync(agentsPath);
164
- actions.push(`+ ${opts.dryRun ? "would remove" : "removed"} ${AGENTS_FILE} (was block-only)`);
193
+ const { text, removed } = removeRegion(addendumGone.text, INSTRUCTIONS_REGION);
194
+ if (removed) {
195
+ actions.push(`+ ${opts.dryRun ? "would remove" : "removed"} the instructions block from ${AGENTS_FILE}`);
165
196
  }
166
- else {
167
- if (!opts.dryRun)
197
+ else if (!addendumGone.removed) {
198
+ actions.push(`· no instructions block in ${AGENTS_FILE}`);
199
+ }
200
+ if (removed || addendumGone.removed) {
201
+ if (text === "") {
202
+ if (!opts.dryRun)
203
+ rmSync(agentsPath);
204
+ actions.push(`+ ${opts.dryRun ? "would remove" : "removed"} ${AGENTS_FILE} (nothing left but ours)`);
205
+ }
206
+ else if (!opts.dryRun) {
168
207
  writeFileSync(agentsPath, text);
169
- actions.push(`+ ${opts.dryRun ? "would remove" : "removed"} the instructions block from ${AGENTS_FILE}`);
208
+ }
170
209
  }
171
210
  }
172
211
  // ── CLAUDE.md import shim (claude-code) ─────────────────────────────────
@@ -233,8 +272,17 @@ export function checkInstructions(projectRoot, opts) {
233
272
  try {
234
273
  const agentsPath = join(projectRoot, AGENTS_FILE);
235
274
  const content = existsSync(agentsPath) ? readFileSync(agentsPath, "utf8") : "";
236
- note(`${AGENTS_FILE} block`, checkRegion(content, INSTRUCTIONS_REGION, renderInstructionsBlock(opts.binName, blockSkills(projectRoot, opts.harness))));
237
- if (opts.harness === "claude-code") {
275
+ note(`${AGENTS_FILE} block`, checkRegion(content, INSTRUCTIONS_REGION, renderInstructionsBlock(opts.binName, blockSkills(projectRoot, opts.adapter))));
276
+ // A configured addendum is checked against its source; an unconfigured one
277
+ // still sitting in the file is drift too, since init would take it out.
278
+ const addendum = readHostAddendum(projectRoot);
279
+ if (addendum.configured) {
280
+ note(`${AGENTS_FILE} host addendum (${addendum.relPath})`, checkRegion(content, HOST_ADDENDUM_REGION, addendum.body));
281
+ }
282
+ else if (checkRegion(content, HOST_ADDENDUM_REGION, "") !== "missing") {
283
+ issues.push(`${AGENTS_FILE} host addendum: present but no longer configured (re-run init)`);
284
+ }
285
+ if (opts.adapter === "claude-code") {
238
286
  const exclude = readSkillsExclude(projectRoot);
239
287
  for (const skill of SKILLS) {
240
288
  if (exclude.has(skill.id))
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The host addendum: a second managed region whose *content* belongs to the
3
+ * consumer.
4
+ *
5
+ * Harnery's orientation block is deliberately generic, because it ships to
6
+ * every consumer (ADR 0007's portability split, ADR 0008's ~80-line budget). A
7
+ * project with real coordination policy of its own therefore had nowhere
8
+ * machine-managed to put it, and ended up hand-maintaining it next to the
9
+ * block, where nothing kept the two in step.
10
+ *
11
+ * The fix is declarative rather than programmatic. A consumer names a file:
12
+ *
13
+ * // .harnery/config.jsonc
14
+ * { "instructions": { "hostAddendumFile": ".agents/host-instructions.md" } }
15
+ *
16
+ * and harnery gives that file's contents the same lifecycle as its own block:
17
+ * spliced on `init`, refreshed when the file changes, reported by
18
+ * `init --check`, removed by `deinit` or by deleting the config entry. Harnery
19
+ * never parses, renders, or reasons about what the file says, which is what
20
+ * keeps the arrangement portable: the mechanism is generic even though every
21
+ * consumer's content is not.
22
+ *
23
+ * Exposing the splicer as a public primitive instead would have pushed the
24
+ * whole lifecycle onto each host, since `init` and `deinit` are registered
25
+ * inside harnery and every consumer would have had to wrap or replace them and
26
+ * reimplement apply, check, and remove. The config key keeps one implementation
27
+ * of all four.
28
+ *
29
+ * Every failure here is raised before the caller writes anything.
30
+ */
31
+ /** Dotted config key naming the addendum source, quoted in every error. */
32
+ export declare const HOST_ADDENDUM_KEY = "instructions.hostAddendumFile";
33
+ /** A host addendum that cannot be used. Callers abort before writing. */
34
+ export declare class HostAddendumError extends Error {
35
+ constructor(message: string);
36
+ }
37
+ export type HostAddendum = {
38
+ configured: false;
39
+ } | {
40
+ configured: true;
41
+ relPath: string;
42
+ body: string;
43
+ };
44
+ /**
45
+ * Resolve the configured addendum, or report that there is none.
46
+ *
47
+ * Absent config, absent key, and explicit `null` all mean "not configured",
48
+ * which is how a consumer turns the addendum off: delete the key and re-run
49
+ * `init`. Anything else that cannot become a readable file inside the project
50
+ * throws, because the alternative is an agent-facing instruction file that
51
+ * quietly lost a section the host believes is still there.
52
+ */
53
+ export declare function readHostAddendum(projectRoot: string): HostAddendum;
54
+ //# sourceMappingURL=host-addendum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-addendum.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/host-addendum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAMH,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,kCAAkC,CAAC;AAEjE,yEAAyE;AACzE,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,UAAU,EAAE,KAAK,CAAA;CAAE,GACrB;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAmDlE"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * The host addendum: a second managed region whose *content* belongs to the
3
+ * consumer.
4
+ *
5
+ * Harnery's orientation block is deliberately generic, because it ships to
6
+ * every consumer (ADR 0007's portability split, ADR 0008's ~80-line budget). A
7
+ * project with real coordination policy of its own therefore had nowhere
8
+ * machine-managed to put it, and ended up hand-maintaining it next to the
9
+ * block, where nothing kept the two in step.
10
+ *
11
+ * The fix is declarative rather than programmatic. A consumer names a file:
12
+ *
13
+ * // .harnery/config.jsonc
14
+ * { "instructions": { "hostAddendumFile": ".agents/host-instructions.md" } }
15
+ *
16
+ * and harnery gives that file's contents the same lifecycle as its own block:
17
+ * spliced on `init`, refreshed when the file changes, reported by
18
+ * `init --check`, removed by `deinit` or by deleting the config entry. Harnery
19
+ * never parses, renders, or reasons about what the file says, which is what
20
+ * keeps the arrangement portable: the mechanism is generic even though every
21
+ * consumer's content is not.
22
+ *
23
+ * Exposing the splicer as a public primitive instead would have pushed the
24
+ * whole lifecycle onto each host, since `init` and `deinit` are registered
25
+ * inside harnery and every consumer would have had to wrap or replace them and
26
+ * reimplement apply, check, and remove. The config key keeps one implementation
27
+ * of all four.
28
+ *
29
+ * Every failure here is raised before the caller writes anything.
30
+ */
31
+ import { readFileSync, statSync } from "node:fs";
32
+ import { isAbsolute, join, resolve, sep } from "node:path";
33
+ import { stripJsonComments } from "../../core/config.js";
34
+ /** Dotted config key naming the addendum source, quoted in every error. */
35
+ export const HOST_ADDENDUM_KEY = "instructions.hostAddendumFile";
36
+ /** A host addendum that cannot be used. Callers abort before writing. */
37
+ export class HostAddendumError extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = "HostAddendumError";
41
+ }
42
+ }
43
+ /**
44
+ * Resolve the configured addendum, or report that there is none.
45
+ *
46
+ * Absent config, absent key, and explicit `null` all mean "not configured",
47
+ * which is how a consumer turns the addendum off: delete the key and re-run
48
+ * `init`. Anything else that cannot become a readable file inside the project
49
+ * throws, because the alternative is an agent-facing instruction file that
50
+ * quietly lost a section the host believes is still there.
51
+ */
52
+ export function readHostAddendum(projectRoot) {
53
+ const configured = readConfiguredPath(projectRoot);
54
+ if (configured === null)
55
+ return { configured: false };
56
+ if (typeof configured !== "string" || configured.trim() === "") {
57
+ throw new HostAddendumError(`${HOST_ADDENDUM_KEY} must be a repo-relative path to a markdown file`);
58
+ }
59
+ const relPath = configured.trim();
60
+ // An absolute path would name one machine's checkout, and this repo is cloned
61
+ // to a different location on every one of them.
62
+ if (isAbsolute(relPath)) {
63
+ throw new HostAddendumError(`${HOST_ADDENDUM_KEY} must be repo-relative, not absolute (got "${relPath}")`);
64
+ }
65
+ const root = resolve(projectRoot);
66
+ const target = resolve(root, relPath);
67
+ if (target !== root && !target.startsWith(root + sep)) {
68
+ throw new HostAddendumError(`${HOST_ADDENDUM_KEY} resolves outside the project ("${relPath}"); ` +
69
+ `the addendum must be a committed file in this repo`);
70
+ }
71
+ let body;
72
+ try {
73
+ if (statSync(target).isDirectory()) {
74
+ throw new HostAddendumError(`${HOST_ADDENDUM_KEY} points at a directory ("${relPath}")`);
75
+ }
76
+ body = readFileSync(target, "utf8");
77
+ }
78
+ catch (err) {
79
+ if (err instanceof HostAddendumError)
80
+ throw err;
81
+ throw new HostAddendumError(`${HOST_ADDENDUM_KEY} not found or unreadable ("${relPath}"): ${err.message}`);
82
+ }
83
+ // Splicing an empty region is never what anyone meant by configuring one, and
84
+ // it fails silently: the file looks fine and the policy simply is not there.
85
+ if (body.trim() === "") {
86
+ throw new HostAddendumError(`${HOST_ADDENDUM_KEY} is empty ("${relPath}")`);
87
+ }
88
+ // Trimmed because the splicer supplies the newlines around a region body;
89
+ // otherwise a trailing newline in the file shows up as a blank line that
90
+ // makes every re-render look like a change.
91
+ return { configured: true, relPath, body: body.trim() };
92
+ }
93
+ /** The raw config value, or null when the file, the section, or the key is absent. */
94
+ function readConfiguredPath(projectRoot) {
95
+ const configPath = join(projectRoot, ".harnery", "config.jsonc");
96
+ let parsed;
97
+ try {
98
+ parsed = JSON.parse(stripJsonComments(readFileSync(configPath, "utf8")));
99
+ }
100
+ catch {
101
+ // No config, or one harnery cannot parse. The rest of init already tolerates
102
+ // that, so the addendum does too rather than blocking an unrelated run.
103
+ return null;
104
+ }
105
+ const value = parsed?.instructions?.hostAddendumFile;
106
+ return value === undefined || value === null ? null : value;
107
+ }
@@ -14,6 +14,13 @@
14
14
  export declare const INSTRUCTIONS_REGION = "instructions";
15
15
  /** Managed-region name for the CLAUDE.md `@AGENTS.md` import shim. */
16
16
  export declare const IMPORT_REGION = "import";
17
+ /**
18
+ * Managed-region name for the consumer's own coordination policy, spliced from
19
+ * the file named by `instructions.hostAddendumFile`. Harnery places and
20
+ * versions the region; the content is the host's and is never rendered here.
21
+ * See `host-addendum.ts`.
22
+ */
23
+ export declare const HOST_ADDENDUM_REGION = "host-addendum";
17
24
  /** Which shipped skills exist in the project the block is rendered for. */
18
25
  export interface BlockSkills {
19
26
  /** the `harn-decide` skill file is present (claude-code, not excluded) */
@@ -29,15 +36,15 @@ export interface BlockSkills {
29
36
  * `harn-council`) even for a renamed bin; only command strings track `binName`.
30
37
  *
31
38
  * The block only points at a skill that actually exists here: a host that
32
- * excludes one via `skills.exclude`, or a harness with no skill primitive
39
+ * excludes one via `skills.exclude`, or a adapter with no skill primitive
33
40
  * (cursor/codex get the block but no skill files), gets a `--help` pointer
34
41
  * instead of a dangling reference to a skill it doesn't have.
35
42
  */
36
43
  export declare function renderInstructionsBlock(binName: string, skills?: BlockSkills): string;
37
- /** A shipped skill: its harness-relative file path + a bin-name-aware renderer. */
44
+ /** A shipped skill: its adapter-relative file path + a bin-name-aware renderer. */
38
45
  export interface SkillTemplate {
39
46
  id: string;
40
- /** path under the harness skill dir, e.g. `harn-decide/SKILL.md` */
47
+ /** path under the adapter skill dir, e.g. `harn-decide/SKILL.md` */
41
48
  relPath: string;
42
49
  render: (binName: string) => string;
43
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAClD,sEAAsE;AACtE,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;IAChB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,WAA6C,GACpD,MAAM,CA4DR;AAID,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAsKD,eAAO,MAAM,MAAM,EAAE,aAAa,EA4BjC,CAAC"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAClD,sEAAsE;AACtE,eAAO,MAAM,aAAa,WAAW,CAAC;AACtC;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;IAChB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,WAA6C,GACpD,MAAM,CAkFR;AAID,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAsKD,eAAO,MAAM,MAAM,EAAE,aAAa,EA4BjC,CAAC"}
@@ -10,12 +10,19 @@
10
10
  * files), so they compile into `dist/` and resolve identically under Bun and
11
11
  * Node — no `files`-field copy or package-path guesswork.
12
12
  */
13
- import { SCRATCH_CATEGORIES } from "../../core/scratch/index.js";
13
+ import { JOURNAL_CATEGORIES } from "../../core/journal/index.js";
14
14
  import { buildOwnedSkill } from "./splice.js";
15
15
  /** Managed-region name for the AGENTS.md orientation block. */
16
16
  export const INSTRUCTIONS_REGION = "instructions";
17
17
  /** Managed-region name for the CLAUDE.md `@AGENTS.md` import shim. */
18
18
  export const IMPORT_REGION = "import";
19
+ /**
20
+ * Managed-region name for the consumer's own coordination policy, spliced from
21
+ * the file named by `instructions.hostAddendumFile`. Harnery places and
22
+ * versions the region; the content is the host's and is never rendered here.
23
+ * See `host-addendum.ts`.
24
+ */
25
+ export const HOST_ADDENDUM_REGION = "host-addendum";
19
26
  /**
20
27
  * The always-on orientation spliced into `AGENTS.md`. Target ≤ 80 rendered
21
28
  * lines: it costs every agent context on every turn, so it states that each
@@ -24,7 +31,7 @@ export const IMPORT_REGION = "import";
24
31
  * `harn-council`) even for a renamed bin; only command strings track `binName`.
25
32
  *
26
33
  * The block only points at a skill that actually exists here: a host that
27
- * excludes one via `skills.exclude`, or a harness with no skill primitive
34
+ * excludes one via `skills.exclude`, or a adapter with no skill primitive
28
35
  * (cursor/codex get the block but no skill files), gets a `--help` pointer
29
36
  * instead of a dangling reference to a skill it doesn't have.
30
37
  */
@@ -33,24 +40,25 @@ export function renderInstructionsBlock(binName, skills = { decide: true, counci
33
40
  const named = [skills.decide && "`harn-decide`", skills.council && "`harn-council`"].filter(Boolean);
34
41
  const deeper = named.length > 0
35
42
  ? `Procedures for the deeper flows live in the ${named.join(" and ")} skill${named.length > 1 ? "s" : ""}.`
36
- : `See \`${b} decision --help\` and \`${b} council --help\` for the deeper procedures.`;
43
+ : `See \`${b} decision --help\` and \`${b} agents council --help\` for the deeper procedures.`;
37
44
  const decidePointer = skills.decide
38
45
  ? "The `harn-decide` skill has the file / claim / resolve-with-evidence procedure."
39
46
  : `See \`${b} decision --help\` for the file / claim / resolve-with-evidence procedure.`;
40
47
  const councilPointer = skills.council
41
48
  ? "The `harn-council` skill has the steward and member flow."
42
- : `See \`${b} council --help\` for the steward and member flow.`;
43
- // Render the scratch categories from the canonical enum so this prose can
44
- // never drift from what `scratch add` actually accepts (the "note, plan…" list
49
+ : `See \`${b} agents council --help\` for the steward and member flow.`;
50
+ // Render the journal categories from the canonical enum so this prose can
51
+ // never drift from what `journal add` actually accepts (the "note, plan…" list
45
52
  // silently lagged the tool by two categories before this).
46
- const scratchCats = SCRATCH_CATEGORIES.length > 1
47
- ? `${SCRATCH_CATEGORIES.slice(0, -1).join(", ")}, or ${SCRATCH_CATEGORIES.at(-1)}`
48
- : SCRATCH_CATEGORIES[0];
53
+ const journalCats = JOURNAL_CATEGORIES.length > 1
54
+ ? `${JOURNAL_CATEGORIES.slice(0, -1).join(", ")}, or ${JOURNAL_CATEGORIES.at(-1)}`
55
+ : JOURNAL_CATEGORIES[0];
49
56
  return `## harnery coordination
50
57
 
51
58
  This project runs [harnery](https://harnery.com) for multi-agent coordination.
52
59
  You share this checkout with other agents; the surfaces below keep you oriented
53
- and out of each other's way. Run \`${b} <command> --help\` for any command's full
60
+ and out of each other's way, and let you dispatch a team of your own when a job
61
+ is bigger than one session. Run \`${b} <command> --help\` for any command's full
54
62
  surface. ${deeper}
55
63
 
56
64
  **Identity + peers.** You are one of several agents in this repo.
@@ -59,6 +67,20 @@ active peers and the files they've claimed; \`${b} agents set-task "<focus>"\`
59
67
  declares your current focus so peers can see it. Check for peers before editing
60
68
  widely-shared files.
61
69
 
70
+ **Dispatching a team.** Everything else here coordinates the agents already
71
+ present. These three start new ones, and they differ by how long the objective
72
+ outlives a single execution. \`${b} run <script>\` is one bounded pass:
73
+ plain JS stages fan out to headless subagents that are born
74
+ coordination-registered, with deterministic code deciding the routing between
75
+ stages. \`${b} work create <title> <workflow>\` wraps an objective that has to
76
+ survive many such passes, holding it across retries, failures, and review.
77
+ \`${b} governor create\` drives a whole graph of work toward a goal, choosing
78
+ what runs next and how much it may settle without asking a human. Reach for the
79
+ first when one pass will do, the second when the objective must outlive the
80
+ attempt, and the third when a human would otherwise have to babysit the loop. A
81
+ run that needs authorization parks durably instead of failing, so check
82
+ \`${b} approval list\` when one appears to be waiting rather than stuck.
83
+
62
84
  **Durable role handoff.** When you are replacing a prior session in the same
63
85
  named role, run \`${b} agents identity assume <name>\` before declaring your task.
64
86
  It reclaims an abandoned namesake (no live process) and refuses only when another
@@ -70,11 +92,18 @@ coordination ledger. Lead a shell command with a \`# intent: <why>\` comment (or
70
92
  the tool's description) so the recorded event carries a reason instead of
71
93
  \`(no intent)\`.
72
94
 
73
- **Scratch journal.** \`${b} scratch add <category> "<text>"\` (category = ${scratchCats})
95
+ **Journal.** \`${b} journal add <category> "<text>"\` (category = ${journalCats})
74
96
  leaves breadcrumbs that survive context compaction;
75
- \`${b} scratch read\` reads yours, \`${b} scratch read --name <peer>\` reads a peer's.
97
+ \`${b} journal read\` reads yours, \`${b} journal read --name <peer>\` reads a peer's.
76
98
  Use it for anything future-you or a peer will need to pick up your thread.
77
99
 
100
+ **Working artifacts.** For screenshots, exports, audit dumps, rollback inputs,
101
+ and other untracked files that must survive a session, create a managed workspace
102
+ with \`${b} artifacts create <slug> --purpose "<why>"\`. Write files under the
103
+ returned path, then run \`${b} artifacts release <id>\` when active work is done.
104
+ Do not create a repo-root temp directory; \`${b} artifacts clean\` previews
105
+ expired cleanup and requires \`--yes\` to delete anything.
106
+
78
107
  **Decision docket.** When you would otherwise stop to ask a human a decision you
79
108
  can't resolve from the repo, file it instead. \`${b} decision file "<question>"\`
80
109
  records it and lets you proceed on a stated default; \`${b} decision search "<terms>"\`