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
@@ -182,13 +182,13 @@ async function emitClaimRelease(
182
182
  const { emit } = await import("./events/emit.ts");
183
183
  const canonical = path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
184
184
  const platform = hb.platform;
185
- const harness =
185
+ const adapter =
186
186
  platform === "cursor" ? "cursor" : platform === "codex" ? "codex" : "claude-code";
187
187
  emit(root, {
188
188
  event_type: "claim.release",
189
189
  instance_id: owner,
190
190
  session_id: hb.session_id ?? owner,
191
- harness,
191
+ adapter,
192
192
  source: "agent-coord",
193
193
  data: { path: canonical, reason },
194
194
  });
@@ -291,16 +291,16 @@ async function handleStateAction(root: string, action: string, rest: string[]):
291
291
  return 0;
292
292
  }
293
293
  case "heal-heartbeat": {
294
- // harness arrives as a `--harness=<h>` flag (not positional) so the live
294
+ // adapter arrives as a `--adapter=<h>` flag (not positional) so the live
295
295
  // tool.pre_use heal and the manual `harn agents heal` path (which pass
296
296
  // different positional counts) can both supply it without arg-order
297
297
  // fragility. Positionals (sessionId, model) stay as-is once flags are
298
298
  // filtered out.
299
- const harness = args.find((a) => a.startsWith("--harness="))?.slice("--harness=".length);
299
+ const adapter = args.find((a) => a.startsWith("--adapter="))?.slice("--adapter=".length);
300
300
  const positional = args.filter((a) => !a.startsWith("--"));
301
301
  const sessionId = positional[0];
302
302
  const model = positional[1];
303
- const hb = writer.healHeartbeat(root, owner, sessionId, model, harness);
303
+ const hb = writer.healHeartbeat(root, owner, sessionId, model, adapter);
304
304
  process.stdout.write(`${JSON.stringify({ instance_id: owner, recreated: !!hb })}\n`);
305
305
  return hb ? 0 : 1;
306
306
  }
@@ -324,19 +324,19 @@ async function handleStateAction(root: string, action: string, rest: string[]):
324
324
  }
325
325
  }
326
326
 
327
- async function handleScratchAction(root: string, action: string, rest: string[]): Promise<number> {
328
- const scratch = await import("./state/scratch.ts");
327
+ async function handleJournalAction(root: string, action: string, rest: string[]): Promise<number> {
328
+ const journal = await import("./state/journal.ts");
329
329
 
330
- if (action === "append-scratch") {
330
+ if (action === "append-journal") {
331
331
  const [owner, category, ...bodyParts] = rest;
332
332
  const body = bodyParts.join(" ");
333
333
  if (!owner || !category || !body) {
334
- process.stderr.write("agent-coord append-scratch <instance_id> <category> <body>\n");
334
+ process.stderr.write("agent-coord append-journal <instance_id> <category> <body>\n");
335
335
  return 2;
336
336
  }
337
- const result = scratch.appendScratch(root, owner, category, body);
337
+ const result = journal.appendJournal(root, owner, category, body);
338
338
  if (!result.ok) {
339
- process.stderr.write(`agent-coord append-scratch: ${result.reason}\n`);
339
+ process.stderr.write(`agent-coord append-journal: ${result.reason}\n`);
340
340
  return 1;
341
341
  }
342
342
  process.stdout.write(
@@ -345,24 +345,22 @@ async function handleScratchAction(root: string, action: string, rest: string[])
345
345
  return 0;
346
346
  }
347
347
 
348
- if (action === "edit-scratchpad") {
348
+ if (action === "edit-journal") {
349
349
  const [owner, newBodyFile, ...summaryParts] = rest;
350
350
  const summary = summaryParts.join(" ");
351
351
  if (!owner || !newBodyFile) {
352
- process.stderr.write(
353
- "agent-coord edit-scratchpad <instance_id> <new-body-file> [<summary>]\n",
354
- );
352
+ process.stderr.write("agent-coord edit-journal <instance_id> <new-body-file> [<summary>]\n");
355
353
  return 2;
356
354
  }
357
355
  if (!existsSync(newBodyFile)) {
358
- process.stderr.write(`agent-coord edit-scratchpad: file not found: ${newBodyFile}\n`);
356
+ process.stderr.write(`agent-coord edit-journal: file not found: ${newBodyFile}\n`);
359
357
  return 2;
360
358
  }
361
359
  const { readFileSync } = await import("node:fs");
362
360
  const newBody = readFileSync(newBodyFile, "utf8");
363
- const result = scratch.editScratchpad(root, owner, newBody, summary);
361
+ const result = journal.editJournal(root, owner, newBody, summary);
364
362
  if (!result.ok) {
365
- process.stderr.write(`agent-coord edit-scratchpad: ${result.reason}\n`);
363
+ process.stderr.write(`agent-coord edit-journal: ${result.reason}\n`);
366
364
  return 1;
367
365
  }
368
366
  process.stdout.write(
@@ -371,7 +369,7 @@ async function handleScratchAction(root: string, action: string, rest: string[])
371
369
  return 0;
372
370
  }
373
371
 
374
- process.stderr.write(`agent-coord: unknown scratch action ${action}\n`);
372
+ process.stderr.write(`agent-coord: unknown journal action ${action}\n`);
375
373
  return 2;
376
374
  }
377
375
 
@@ -566,7 +564,7 @@ async function handleShellMutationClaimLog(root: string, rest: string[]): Promis
566
564
  // in a log file; now a canonical decision.warn so the
567
565
  // signal survives in events.ndjson. (The blocking claim-conflict path is
568
566
  // separate: claim.conflict / verdict, and unaffected.)
569
- const harness = platform === "cursor" ? "cursor" : platform === "codex" ? "codex" : "claude-code";
567
+ const adapter = platform === "cursor" ? "cursor" : platform === "codex" ? "codex" : "claude-code";
570
568
  const hb = owner ? readHeartbeat(root, owner) : null;
571
569
  for (const p of paths) {
572
570
  try {
@@ -574,7 +572,7 @@ async function handleShellMutationClaimLog(root: string, rest: string[]): Promis
574
572
  event_type: "decision.warn",
575
573
  instance_id: owner ?? "unknown",
576
574
  session_id: hb?.session_id ?? owner ?? "unknown",
577
- harness,
575
+ adapter,
578
576
  data: {
579
577
  rule: "shell_mutation_candidate",
580
578
  reason: `path=${p} cmd=${truncated} platform=${platform}`,
@@ -612,10 +610,12 @@ async function handlePromptContext(root: string, rest: string[]): Promise<number
612
610
  const instanceId = args.instance;
613
611
  const sessionId = args.session ?? instanceId;
614
612
  const agentName = args.name;
613
+ const sessionNameNudge = args["session-name-nudge"] === "true";
615
614
  const taskNudge = args["task-nudge"] === "true";
615
+ const statusFooterNudge = args["status-footer-nudge"] === "true";
616
616
  if (!instanceId) {
617
617
  process.stderr.write(
618
- "agent-coord prompt-context --instance <id> [--session <id>] [--name <agent-name>] [--task-nudge]\n",
618
+ "agent-coord prompt-context --instance <id> [--session <id>] [--name <agent-name>] [--session-name-nudge] [--task-nudge] [--status-footer-nudge]\n",
619
619
  );
620
620
  return 2;
621
621
  }
@@ -625,7 +625,9 @@ async function handlePromptContext(root: string, rest: string[]): Promise<number
625
625
  instanceId,
626
626
  sessionId: sessionId!,
627
627
  agentName,
628
+ sessionNameNudge,
628
629
  taskNudge,
630
+ statusFooterNudge,
629
631
  });
630
632
  process.stdout.write(text);
631
633
  return 0;
@@ -743,12 +745,12 @@ async function handleEmitEvent(root: string, rest: string[]): Promise<number> {
743
745
  const eventType = args.type;
744
746
  const instanceId = args.owner;
745
747
  const sessionId = args.session;
746
- const harness = args.harness as "claude-code" | "cursor" | "codex" | undefined;
748
+ const adapter = args.adapter as "claude-code" | "cursor" | "codex" | undefined;
747
749
  const dataJson = args["data-json"] ?? "{}";
748
750
 
749
- if (!eventType || !instanceId || !sessionId || !harness) {
751
+ if (!eventType || !instanceId || !sessionId || !adapter) {
750
752
  process.stderr.write(
751
- "agent-coord emit-event --type <T> --owner <id> --session <id> --harness <h> [--data-json '<json>']\n",
753
+ "agent-coord emit-event --type <T> --owner <id> --session <id> --adapter <h> [--data-json '<json>']\n",
752
754
  );
753
755
  return 2;
754
756
  }
@@ -774,7 +776,7 @@ async function handleEmitEvent(root: string, rest: string[]): Promise<number> {
774
776
  event_type: eventType,
775
777
  instance_id: instanceId,
776
778
  session_id: sessionId,
777
- harness,
779
+ adapter,
778
780
  turn_id: args["turn-id"],
779
781
  parent_session_id: args["parent-session-id"],
780
782
  parent_turn_id: args["parent-turn-id"],
@@ -822,8 +824,8 @@ async function main(): Promise<number> {
822
824
  return handleStateAction(root, subcommand, rest);
823
825
  }
824
826
 
825
- if (subcommand === "append-scratch" || subcommand === "edit-scratchpad") {
826
- return handleScratchAction(root, subcommand, rest);
827
+ if (subcommand === "append-journal" || subcommand === "edit-journal") {
828
+ return handleJournalAction(root, subcommand, rest);
827
829
  }
828
830
 
829
831
  if (
@@ -4,7 +4,7 @@
4
4
  * Production codex sessions emit canonical events from each `harn` invocation
5
5
  * via the in-process session-tee middleware (which calls `agent-coord
6
6
  * emit-event` for state.task_set / state.status_checked). But the codex
7
- * harness itself doesn't wire agent-hook on preToolUse, so user_prompt.submit
7
+ * adapter itself doesn't wire agent-hook on preToolUse, so user_prompt.submit
8
8
  * + tool.pre_use + turn.stop aren't emitted live.
9
9
  *
10
10
  * This module parses the Codex JSONL transcript at stop time and emits the
@@ -71,7 +71,7 @@ export function replayCodexJsonl(opts: CodexReplayOpts): { emitted: number } {
71
71
  event_type: "user_prompt.submit",
72
72
  instance_id: instanceId,
73
73
  session_id: sessionId,
74
- harness: "codex",
74
+ adapter: "codex",
75
75
  ts,
76
76
  data: {
77
77
  prompt_text: clamp(entry.payload.message ?? "", 4000),
@@ -97,7 +97,7 @@ export function replayCodexJsonl(opts: CodexReplayOpts): { emitted: number } {
97
97
  event_type: "tool.pre_use",
98
98
  instance_id: instanceId,
99
99
  session_id: sessionId,
100
- harness: "codex",
100
+ adapter: "codex",
101
101
  ts,
102
102
  data: {
103
103
  tool_name: name === "exec_command" ? "Bash" : name,
@@ -117,7 +117,7 @@ export function replayCodexJsonl(opts: CodexReplayOpts): { emitted: number } {
117
117
  event_type: "state.status_checked",
118
118
  instance_id: instanceId,
119
119
  session_id: sessionId,
120
- harness: "codex",
120
+ adapter: "codex",
121
121
  ts,
122
122
  data: { source: "codex-replay" },
123
123
  });
@@ -128,7 +128,7 @@ export function replayCodexJsonl(opts: CodexReplayOpts): { emitted: number } {
128
128
  event_type: "state.task_set",
129
129
  instance_id: instanceId,
130
130
  session_id: sessionId,
131
- harness: "codex",
131
+ adapter: "codex",
132
132
  ts,
133
133
  data: { source: "codex-replay" },
134
134
  });
@@ -145,7 +145,7 @@ export function replayCodexJsonl(opts: CodexReplayOpts): { emitted: number } {
145
145
  event_type: "turn.stop",
146
146
  instance_id: instanceId,
147
147
  session_id: sessionId,
148
- harness: "codex",
148
+ adapter: "codex",
149
149
  data: {
150
150
  status_box_present: boxPresent,
151
151
  tool_call_count: -1,
@@ -73,7 +73,7 @@ export interface Heartbeat {
73
73
  last_tool_target?: string;
74
74
  /** Free-form task/intent string set via `harn agents set-task`. Phase 2. */
75
75
  task?: string;
76
- /** UTC ISO-8601 timestamp when task was last set/cleared. Used by harnesses without Stop enforcement to compute staleness. 2026-05-24. */
76
+ /** UTC ISO-8601 timestamp when task was last set/cleared. Used by adapters without Stop enforcement to compute staleness. 2026-05-24. */
77
77
  task_updated_at?: string | null;
78
78
  /** Auto-generated per-turn summary written by the Stop hook via Haiku. 2026-05-23. */
79
79
  turn_summary?: string | null;
@@ -146,9 +146,93 @@ export function parsePidmapRowOwner(row: string): string {
146
146
 
147
147
  /** Parse platform from a pid-map row; legacy rows default to `claude_code`. */
148
148
  export function parsePidmapRowPlatform(row: string): string {
149
- const trimmed = row.trim();
150
- const tab = trimmed.indexOf("\t");
151
- return tab >= 0 ? trimmed.slice(tab + 1).trim() : "claude_code";
149
+ const platform = row.trim().split("\t")[1]?.trim();
150
+ return platform || "claude_code";
151
+ }
152
+
153
+ /** Parse the start token from a pid-map row; rows written before it carry none. */
154
+ export function parsePidmapRowStartToken(row: string): string | undefined {
155
+ return row.trim().split("\t")[2]?.trim() || undefined;
156
+ }
157
+
158
+ /**
159
+ * Is the process now holding `pid` the one this row was written for?
160
+ *
161
+ * A pid is a number the OS re-issues, and quickly: a `pid_max` of 99999 against
162
+ * ~100 new processes a second recycles the whole space about every quarter
163
+ * hour. Believing a row past that point resolves this session to whichever
164
+ * agent last held the number — which is what made `whoami` report a stranger's
165
+ * name and files. The start token settles it, since two processes may share a
166
+ * pid but never a pid and a start instant.
167
+ *
168
+ * Deliberately inlined rather than imported from `state/proc-start.ts`: this
169
+ * file is vendored verbatim into a downstream consumer and stays on node
170
+ * builtins only. The token is a wire format shared with that module and with
171
+ * the host's commit guard, so the copies must agree byte for byte; exported so
172
+ * a test can hold this one against `processStartToken` and fail on drift.
173
+ */
174
+ export function pidStartToken(pid: number): string | null {
175
+ const forced = process.env.HARNERY_PID_PROBE;
176
+ const useProcfs = forced === "procfs" || (forced !== "ps" && existsSync("/proc/self/stat"));
177
+ // One machine, one probe. Falling back to the other on a read failure would
178
+ // answer in the wrong dialect and read as a recycled pid.
179
+ if (useProcfs) {
180
+ try {
181
+ const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
182
+ const afterComm = stat.slice(stat.lastIndexOf(") ") + 2);
183
+ // Fields after comm, 0-based: 0 is state (field 3), starttime (22) is 19.
184
+ const ticks = afterComm.split(" ")[19];
185
+ if (!ticks || !/^\d+$/.test(ticks)) return null;
186
+ // Ticks count from boot, so they repeat across reboots; the boot id scopes
187
+ // them. Rows written before it carry ticks alone and still compare.
188
+ let boot = "";
189
+ try {
190
+ const raw = readFileSync("/proc/sys/kernel/random/boot_id", "utf8")
191
+ .trim()
192
+ .replace(/-/g, "");
193
+ if (/^[0-9a-f]{8,}$/.test(raw)) boot = `${raw.slice(0, 8)}.`;
194
+ } catch {
195
+ /* unnamed boot: fall back to the tick-only shape */
196
+ }
197
+ return `l${boot}${ticks}`;
198
+ } catch {
199
+ return null;
200
+ }
201
+ }
202
+ try {
203
+ // TZ and locale are pinned because `ps` renders the date through them, and
204
+ // two callers with different environments must not disagree about one
205
+ // process.
206
+ const out = spawnSync("ps", ["-o", "lstart=", "-p", String(pid)], {
207
+ encoding: "utf8",
208
+ timeout: 2000,
209
+ env: { ...process.env, TZ: "UTC", LC_ALL: "C" },
210
+ });
211
+ if (out.status !== 0) return null;
212
+ const lstart = (out.stdout ?? "").split("\n")[0]?.trim().replace(/\s+/g, " ");
213
+ return lstart ? `p${lstart}` : null;
214
+ } catch {
215
+ return null;
216
+ }
217
+ }
218
+
219
+ function pidWasRecycled(pid: number, row: string): boolean {
220
+ const recorded = parsePidmapRowStartToken(row);
221
+ if (!recorded) return false; // pre-token row: unverifiable, behave as before
222
+ const current = pidStartToken(pid);
223
+ if (!current) return false;
224
+ if (current === recorded) return false;
225
+ // A row predating the boot segment recorded ticks alone; compare it on what
226
+ // it recorded rather than pruning every live row on the first upgraded run.
227
+ if (
228
+ recorded[0] === "l" &&
229
+ current[0] === "l" &&
230
+ recorded.includes(".") !== current.includes(".")
231
+ ) {
232
+ const ticks = (t: string) => (t.includes(".") ? t.slice(t.indexOf(".") + 1) : t.slice(1));
233
+ return ticks(recorded) !== ticks(current);
234
+ }
235
+ return true;
152
236
  }
153
237
 
154
238
  function readPidmapRow(pidmapDir: string, pid: number): string | null {
@@ -197,9 +281,14 @@ export function resolveOwnerWithSource(): {
197
281
  const root = monorepoRoot();
198
282
  if (!root) return { owner: null, source: "none" };
199
283
 
200
- // Cursor's Glass/Agents UI can run several chats under one long-lived node
201
- // process, so the pid-map row for that shared ancestor is last-writer-wins.
202
- // Prefer the per-chat session id when Cursor exposes one in the tool env.
284
+ // Every supported adapter exports its session id into the env of the
285
+ // subprocess it spawns for a tool call, and each heartbeat records the
286
+ // session id it was minted under. Matching the two names us outright, even
287
+ // with many live agents, so it goes ahead of the ppid walk rather than
288
+ // catching what the walk drops. Cursor needed this first because its
289
+ // Glass/Agents UI runs several chats under one node ancestor, making that row
290
+ // last-writer-wins; pid recycling generalises the same hazard to every
291
+ // adapter.
203
292
  if (shouldPreferSessionEnv()) {
204
293
  const bySession = resolveOwnerBySessionEnv(root);
205
294
  if (bySession) {
@@ -217,7 +306,7 @@ export function resolveOwnerWithSource(): {
217
306
  for (let hop = 0; hop < 20; hop++) {
218
307
  if (pid === null) break;
219
308
  const row = readPidmapRow(pidmapDir, pid);
220
- if (row) {
309
+ if (row && !pidWasRecycled(pid, row)) {
221
310
  const rowOwner = parsePidmapRowOwner(row);
222
311
  const rowPlat = parsePidmapRowPlatform(row);
223
312
  if (rowPlat === prefer) {
@@ -231,18 +320,6 @@ export function resolveOwnerWithSource(): {
231
320
  return { owner: fallbackOwner, source: "pidmap_fallback" };
232
321
  }
233
322
 
234
- // The ppid walk found nothing (e.g. a Bash-tool subshell whose process tree
235
- // doesn't climb back to the harness anchor). Before guessing, try the
236
- // harness-provided session id from the environment: every supported harness
237
- // exports its session id into the tool subprocess env, and each heartbeat
238
- // records the `session_id` it was minted under. Matching the two resolves us
239
- // unambiguously even with multiple live agents, which is the case the
240
- // singleton fallback below cannot handle.
241
- const bySession = resolveOwnerBySessionEnv(root);
242
- if (bySession) {
243
- return { owner: bySession, source: "session_env" };
244
- }
245
-
246
323
  // Last resort: if exactly one agent is live in this coord root, it's
247
324
  // unambiguously us — resolve to it. This is what lets the bare `agents
248
325
  // status` / `set-task` the stop hook recommends work without a `--session-id`
@@ -257,8 +334,8 @@ export function resolveOwnerWithSource(): {
257
334
  }
258
335
 
259
336
  /**
260
- * Harness-exported session-id environment variables, in precedence order. Each
261
- * supported harness propagates its session id into the env of the subprocess it
337
+ * Adapter-exported session-id environment variables, in precedence order. Each
338
+ * supported adapter propagates its session id into the env of the subprocess it
262
339
  * spawns for a tool call (Claude Code's Bash tool, Cursor's terminal, Codex's
263
340
  * shell). A coord CLI invoked as such a tool can therefore recover its own
264
341
  * identity from the env even when the ppid walk misses.
@@ -274,7 +351,7 @@ const SESSION_ID_ENV_VARS = [
274
351
  "CODEX_SESSION_ID",
275
352
  ] as const;
276
353
 
277
- /** Read normalized candidates from the first non-empty harness session-id env var. */
354
+ /** Read normalized candidates from the first non-empty adapter session-id env var. */
278
355
  function sessionIdsFromEnv(): string[] {
279
356
  for (const key of SESSION_ID_ENV_VARS) {
280
357
  const v = process.env[key]?.trim();
@@ -287,19 +364,33 @@ function sessionIdsFromEnv(): string[] {
287
364
  return [];
288
365
  }
289
366
 
290
- /** Read the first non-empty harness session-id env var, or null. */
367
+ /** Read the first non-empty adapter session-id env var, or null. */
291
368
  function sessionIdFromEnv(): string | null {
292
369
  return sessionIdsFromEnv()[0] ?? null;
293
370
  }
294
371
 
372
+ /**
373
+ * Should the adapter-exported session id be consulted before the ppid walk?
374
+ *
375
+ * Yes, whenever one is exported. The env var is the adapter stating its own
376
+ * identity; the walk is a guess over a namespace the OS recycles. On a box with
377
+ * `pid_max` of 99999 and ~100 pids allocated per second the whole pid space
378
+ * turns over about every quarter hour, so a row written before that can name a
379
+ * pid some unrelated process now holds. Pruning cannot save the walk here:
380
+ * it removes rows whose pid is dead, and a recycled pid is alive. Letting a
381
+ * guess outrank a statement of fact is what made `agents whoami` report another
382
+ * agent's name and file list.
383
+ *
384
+ * This only reorders the two. Session-env resolution still requires a live
385
+ * heartbeat carrying that session id, so when it does not match, the walk runs
386
+ * exactly as before.
387
+ */
295
388
  function shouldPreferSessionEnv(): boolean {
296
- if (!sessionIdFromEnv()) return false;
297
- const platform = process.env.HARNERY_AGENT_COORD_PLATFORM?.trim();
298
- return process.env.CURSOR_AGENT === "1" || platform === "cursor";
389
+ return sessionIdFromEnv() !== null;
299
390
  }
300
391
 
301
392
  /**
302
- * Resolve the owner by matching the harness session-id env var against the
393
+ * Resolve the owner by matching the adapter session-id env var against the
303
394
  * `session_id` of a live heartbeat in this coord root. Returns the matching
304
395
  * `instance_id`, or null if there's no session-id env var or no live heartbeat
305
396
  * carries it. "Live" reuses the same 10-minute freshness window the singleton
@@ -56,7 +56,7 @@ export interface CanonicalEvent {
56
56
  parent_session_id?: string;
57
57
  turn_id?: string;
58
58
  parent_turn_id?: string;
59
- harness: string;
59
+ adapter: string;
60
60
  source: string;
61
61
  data: Record<string, unknown>;
62
62
  }
@@ -5,7 +5,7 @@
5
5
  * event/schema types).
6
6
  *
7
7
  * Phase 4: agent-coord uses this from CLI handlers (state.task_set,
8
- * state.status_checked, state.scratch_append, council.*, decision.*,
8
+ * state.status_checked, state.journal_append, council.*, decision.*,
9
9
  * presence.*).
10
10
  */
11
11
 
@@ -19,8 +19,9 @@ const STREAM_FILE = ".harnery/events.ndjson";
19
19
  const LOCK_FILE = ".harnery/events.ndjson.lock";
20
20
  const MAX_LINE_BYTES = 64 * 1024;
21
21
 
22
- export type Harness = "claude-code" | "cursor" | "codex";
23
- export type Source = "agent-hooks" | "agent-coord" | "user" | "system";
22
+ export type { Adapter, Source } from "../../hooks/events/schema.ts";
23
+
24
+ import type { Adapter, Source } from "../../hooks/events/schema.ts";
24
25
 
25
26
  export interface Envelope {
26
27
  schema_version: typeof SCHEMA_VERSION;
@@ -32,7 +33,7 @@ export interface Envelope {
32
33
  parent_session_id?: string;
33
34
  turn_id?: string;
34
35
  parent_turn_id?: string;
35
- harness: Harness;
36
+ adapter: Adapter;
36
37
  source: Source;
37
38
  data: Record<string, unknown>;
38
39
  }
@@ -41,7 +42,7 @@ export interface EmitInput {
41
42
  event_type: string;
42
43
  instance_id: string;
43
44
  session_id: string;
44
- harness: Harness;
45
+ adapter: Adapter;
45
46
  source?: Source;
46
47
  parent_session_id?: string;
47
48
  turn_id?: string;
@@ -61,7 +62,7 @@ export function buildEnvelope(input: EmitInput): Envelope {
61
62
  parent_session_id: input.parent_session_id,
62
63
  turn_id: input.turn_id,
63
64
  parent_turn_id: input.parent_turn_id,
64
- harness: input.harness,
65
+ adapter: input.adapter,
65
66
  source: input.source ?? "agent-coord",
66
67
  data: input.data,
67
68
  };