harnery 0.29.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/README.md +4 -4
  2. package/dist/commander.d.ts +8 -0
  3. package/dist/commander.d.ts.map +1 -1
  4. package/dist/commander.js +14 -13
  5. package/dist/commands/adapter.d.ts +12 -0
  6. package/dist/commands/adapter.d.ts.map +1 -0
  7. package/dist/commands/{harness.js → adapter.js} +35 -35
  8. package/dist/commands/agents.d.ts +3 -2
  9. package/dist/commands/agents.d.ts.map +1 -1
  10. package/dist/commands/agents.js +61 -60
  11. package/dist/commands/artifacts.d.ts +4 -0
  12. package/dist/commands/artifacts.d.ts.map +1 -0
  13. package/dist/commands/artifacts.js +143 -0
  14. package/dist/commands/backup.d.ts +1 -1
  15. package/dist/commands/backup.d.ts.map +1 -1
  16. package/dist/commands/backup.js +5 -2
  17. package/dist/commands/browse.d.ts.map +1 -1
  18. package/dist/commands/browse.js +310 -7
  19. package/dist/commands/checkpoint.d.ts +12 -0
  20. package/dist/commands/checkpoint.d.ts.map +1 -0
  21. package/dist/commands/checkpoint.js +162 -0
  22. package/dist/commands/context.d.ts +2 -2
  23. package/dist/commands/context.d.ts.map +1 -1
  24. package/dist/commands/context.js +3 -151
  25. package/dist/commands/decision.d.ts.map +1 -1
  26. package/dist/commands/decision.js +31 -7
  27. package/dist/commands/deinit.d.ts +2 -2
  28. package/dist/commands/deinit.js +15 -15
  29. package/dist/commands/doctor.js +23 -23
  30. package/dist/commands/governor.d.ts +4 -0
  31. package/dist/commands/governor.d.ts.map +1 -0
  32. package/dist/commands/{supervisor.js → governor.js} +133 -108
  33. package/dist/commands/init.d.ts +12 -12
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +44 -30
  36. package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
  37. package/dist/commands/journal.d.ts.map +1 -0
  38. package/dist/commands/{scratch.js → journal.js} +47 -47
  39. package/dist/commands/policy.js +1 -1
  40. package/dist/commands/presence.js +2 -2
  41. package/dist/commands/sync.d.ts +1 -1
  42. package/dist/commands/sync.js +3 -3
  43. package/dist/commands/tunnel.d.ts +16 -0
  44. package/dist/commands/tunnel.d.ts.map +1 -1
  45. package/dist/commands/tunnel.js +193 -23
  46. package/dist/commands/web-fetch.js +1 -1
  47. package/dist/commands/web.d.ts +19 -0
  48. package/dist/commands/web.d.ts.map +1 -1
  49. package/dist/commands/web.js +51 -0
  50. package/dist/commands/work.d.ts +2 -1
  51. package/dist/commands/work.d.ts.map +1 -1
  52. package/dist/commands/work.js +55 -25
  53. package/dist/commands/workflow.d.ts.map +1 -1
  54. package/dist/commands/workflow.js +35 -28
  55. package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
  56. package/dist/core/adapters/attest-projection.d.ts.map +1 -0
  57. package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
  58. package/dist/core/adapters/attest.d.ts.map +1 -0
  59. package/dist/core/{harnesses → adapters}/attest.js +9 -9
  60. package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
  61. package/dist/core/adapters/attestation.d.ts.map +1 -0
  62. package/dist/core/{harnesses → adapters}/attestation.js +20 -20
  63. package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
  64. package/dist/core/adapters/bench.d.ts.map +1 -0
  65. package/dist/core/{harnesses → adapters}/bench.js +12 -12
  66. package/dist/core/adapters/index.d.ts +13 -0
  67. package/dist/core/adapters/index.d.ts.map +1 -0
  68. package/dist/core/adapters/index.js +6 -0
  69. package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
  70. package/dist/core/adapters/profiles.d.ts.map +1 -0
  71. package/dist/core/{harnesses → adapters}/profiles.js +11 -11
  72. package/dist/core/adapters/registry.d.ts +15 -0
  73. package/dist/core/adapters/registry.d.ts.map +1 -0
  74. package/dist/core/{harnesses → adapters}/registry.js +11 -11
  75. package/dist/core/{harnesses → adapters}/types.d.ts +28 -23
  76. package/dist/core/adapters/types.d.ts.map +1 -0
  77. package/dist/core/{harnesses → adapters}/types.js +1 -1
  78. package/dist/core/agents/canonical-emit.d.ts +4 -4
  79. package/dist/core/agents/canonical-emit.js +5 -5
  80. package/dist/core/agents/cli-emit.js +1 -1
  81. package/dist/core/agents/cli.js +30 -26
  82. package/dist/core/agents/codex-replay.d.ts +1 -1
  83. package/dist/core/agents/codex-replay.js +6 -6
  84. package/dist/core/agents/coord-client.d.ts +21 -2
  85. package/dist/core/agents/coord-client.d.ts.map +1 -1
  86. package/dist/core/agents/coord-client.js +122 -27
  87. package/dist/core/agents/events/consume.d.ts +1 -1
  88. package/dist/core/agents/events/emit.d.ts +5 -6
  89. package/dist/core/agents/events/emit.d.ts.map +1 -1
  90. package/dist/core/agents/events/emit.js +2 -2
  91. package/dist/core/agents/render/prompt-context.d.ts +21 -9
  92. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  93. package/dist/core/agents/render/prompt-context.js +82 -30
  94. package/dist/core/agents/render/session-context.d.ts +1 -1
  95. package/dist/core/agents/render/session-context.js +5 -5
  96. package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
  97. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  98. package/dist/core/agents/rules/claim-conflict.js +1 -1
  99. package/dist/core/agents/rules/commit-conflict.js +98 -22
  100. package/dist/core/agents/rules/stop-hook.d.ts +9 -9
  101. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  102. package/dist/core/agents/rules/stop-hook.js +23 -5
  103. package/dist/core/agents/rules/verdict.d.ts +14 -0
  104. package/dist/core/agents/rules/verdict.d.ts.map +1 -0
  105. package/dist/core/agents/rules/verdict.js +1 -0
  106. package/dist/core/agents/session-events.js +3 -3
  107. package/dist/core/agents/state/council.d.ts +1 -1
  108. package/dist/core/agents/state/council.js +1 -1
  109. package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
  110. package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
  111. package/dist/core/agents/state/heartbeat-projector.js +14 -10
  112. package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
  113. package/dist/core/agents/state/heartbeat-writer.js +12 -12
  114. package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
  115. package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
  116. package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
  117. package/dist/core/agents/state/pidmap.d.ts +28 -4
  118. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  119. package/dist/core/agents/state/pidmap.js +130 -15
  120. package/dist/core/agents/state/proc-start.d.ts +95 -0
  121. package/dist/core/agents/state/proc-start.d.ts.map +1 -0
  122. package/dist/core/agents/state/proc-start.js +199 -0
  123. package/dist/core/agents/state/shell-mutation.d.ts +1 -1
  124. package/dist/core/agents/state/shell-mutation.js +1 -1
  125. package/dist/core/agents/state/stale-sweep.js +7 -7
  126. package/dist/core/artifacts/index.d.ts +86 -0
  127. package/dist/core/artifacts/index.d.ts.map +1 -0
  128. package/dist/core/artifacts/index.js +421 -0
  129. package/dist/core/config.d.ts +9 -2
  130. package/dist/core/config.d.ts.map +1 -1
  131. package/dist/core/config.js +26 -2
  132. package/dist/core/context/index.d.ts +12 -12
  133. package/dist/core/context/index.js +10 -10
  134. package/dist/core/governor/adapter-spread.d.ts +52 -0
  135. package/dist/core/governor/adapter-spread.d.ts.map +1 -0
  136. package/dist/core/governor/adapter-spread.js +52 -0
  137. package/dist/core/governor/index.d.ts +7 -0
  138. package/dist/core/governor/index.d.ts.map +1 -0
  139. package/dist/core/governor/index.js +6 -0
  140. package/dist/core/governor/plan-api.d.ts +38 -0
  141. package/dist/core/governor/plan-api.d.ts.map +1 -0
  142. package/dist/core/governor/plan-api.js +83 -0
  143. package/dist/core/governor/plan-read.d.ts +5 -0
  144. package/dist/core/governor/plan-read.d.ts.map +1 -0
  145. package/dist/core/{supervisor → governor}/plan-read.js +71 -51
  146. package/dist/core/governor/plan-types.d.ts +181 -0
  147. package/dist/core/governor/plan-types.d.ts.map +1 -0
  148. package/dist/core/{supervisor → governor}/plan-types.js +4 -4
  149. package/dist/core/governor/planning.d.ts +48 -0
  150. package/dist/core/governor/planning.d.ts.map +1 -0
  151. package/dist/core/{supervisor → governor}/planning.js +143 -94
  152. package/dist/core/governor/read.d.ts +6 -0
  153. package/dist/core/governor/read.d.ts.map +1 -0
  154. package/dist/core/governor/read.js +4 -0
  155. package/dist/core/governor/runner.d.ts +37 -0
  156. package/dist/core/governor/runner.d.ts.map +1 -0
  157. package/dist/core/{supervisor → governor}/runner.js +15 -15
  158. package/dist/core/governor/service-read.d.ts +6 -0
  159. package/dist/core/governor/service-read.d.ts.map +1 -0
  160. package/dist/core/{supervisor → governor}/service-read.js +12 -12
  161. package/dist/core/governor/service.d.ts +114 -0
  162. package/dist/core/governor/service.d.ts.map +1 -0
  163. package/dist/core/{supervisor → governor}/service.js +57 -57
  164. package/dist/core/governor/state.d.ts +116 -0
  165. package/dist/core/governor/state.d.ts.map +1 -0
  166. package/dist/core/{supervisor → governor}/state.js +290 -116
  167. package/dist/core/hooks/adapter/detect.d.ts +9 -0
  168. package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
  169. package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
  170. package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
  171. package/dist/core/hooks/adapter/events.d.ts.map +1 -0
  172. package/dist/core/hooks/{harness → adapter}/events.js +5 -5
  173. package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
  174. package/dist/core/hooks/adapter/output.d.ts.map +1 -0
  175. package/dist/core/hooks/{harness → adapter}/output.js +30 -22
  176. package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
  177. package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
  178. package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
  179. package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
  180. package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
  181. package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
  182. package/dist/core/hooks/cli.d.ts +3 -3
  183. package/dist/core/hooks/cli.js +175 -151
  184. package/dist/core/hooks/effects/image-capture.d.ts +5 -5
  185. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  186. package/dist/core/hooks/effects/image-capture.js +3 -3
  187. package/dist/core/hooks/effects/index.d.ts +12 -12
  188. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  189. package/dist/core/hooks/effects/index.js +17 -17
  190. package/dist/core/hooks/events/emit.d.ts +2 -2
  191. package/dist/core/hooks/events/emit.d.ts.map +1 -1
  192. package/dist/core/hooks/events/emit.js +1 -1
  193. package/dist/core/hooks/events/rotate.js +1 -1
  194. package/dist/core/hooks/events/schema.d.ts +13 -5
  195. package/dist/core/hooks/events/schema.d.ts.map +1 -1
  196. package/dist/core/hooks/guard-path.d.ts +2 -2
  197. package/dist/core/hooks/guard-path.js +2 -2
  198. package/dist/core/hooks/index.d.ts +1 -1
  199. package/dist/core/hooks/index.d.ts.map +1 -1
  200. package/dist/core/hooks/resolve/anchor.d.ts +14 -5
  201. package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
  202. package/dist/core/hooks/resolve/anchor.js +64 -7
  203. package/dist/core/hooks/resolve/coord-root.d.ts +3 -3
  204. package/dist/core/hooks/resolve/coord-root.js +4 -4
  205. package/dist/core/hooks/resolve/intent.js +1 -1
  206. package/dist/core/hooks/resolve/owner.d.ts +1 -1
  207. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  208. package/dist/core/hooks/resolve/owner.js +11 -5
  209. package/dist/core/{scratch → journal}/index.d.ts +25 -25
  210. package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
  211. package/dist/core/{scratch → journal}/index.js +38 -38
  212. package/dist/core/policy/evaluate.d.ts +1 -1
  213. package/dist/core/policy/evaluate.d.ts.map +1 -1
  214. package/dist/core/policy/evaluate.js +7 -7
  215. package/dist/core/policy/types.d.ts +3 -3
  216. package/dist/core/policy/types.d.ts.map +1 -1
  217. package/dist/core/work/runner.d.ts.map +1 -1
  218. package/dist/core/work/runner.js +11 -2
  219. package/dist/core/work/state.d.ts +28 -3
  220. package/dist/core/work/state.d.ts.map +1 -1
  221. package/dist/core/work/state.js +148 -16
  222. package/dist/core/workflow/adapters.d.ts +17 -0
  223. package/dist/core/workflow/adapters.d.ts.map +1 -0
  224. package/dist/core/workflow/adapters.js +21 -0
  225. package/dist/core/workflow/approvals.js +6 -6
  226. package/dist/core/workflow/billing.d.ts +9 -9
  227. package/dist/core/workflow/billing.js +9 -9
  228. package/dist/core/workflow/child-env.d.ts +10 -2
  229. package/dist/core/workflow/child-env.d.ts.map +1 -1
  230. package/dist/core/workflow/child-env.js +12 -4
  231. package/dist/core/workflow/engine.d.ts +15 -5
  232. package/dist/core/workflow/engine.d.ts.map +1 -1
  233. package/dist/core/workflow/engine.js +151 -83
  234. package/dist/core/workflow/evidence-preflight.d.ts +24 -0
  235. package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
  236. package/dist/core/workflow/evidence-preflight.js +134 -0
  237. package/dist/core/workflow/index.d.ts +3 -2
  238. package/dist/core/workflow/index.d.ts.map +1 -1
  239. package/dist/core/workflow/index.js +2 -1
  240. package/dist/core/workflow/proof.d.ts +28 -5
  241. package/dist/core/workflow/proof.d.ts.map +1 -1
  242. package/dist/core/workflow/proof.js +77 -34
  243. package/dist/core/workflow/run-state.d.ts +1 -1
  244. package/dist/core/workflow/run-state.js +7 -7
  245. package/dist/core/workflow/sandbox-projection.d.ts +6 -6
  246. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  247. package/dist/core/workflow/sandbox-projection.js +11 -11
  248. package/dist/core/workflow/spawn-claude.d.ts +3 -3
  249. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  250. package/dist/core/workflow/spawn-claude.js +28 -8
  251. package/dist/core/workflow/spawn-codex.d.ts +4 -4
  252. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  253. package/dist/core/workflow/spawn-codex.js +26 -8
  254. package/dist/core/workflow/spawn-cursor.d.ts +4 -4
  255. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  256. package/dist/core/workflow/spawn-cursor.js +27 -8
  257. package/dist/core/workflow/spawn-failure.d.ts +15 -1
  258. package/dist/core/workflow/spawn-failure.d.ts.map +1 -1
  259. package/dist/core/workflow/spawn-failure.js +35 -1
  260. package/dist/core/workflow/specialists.js +2 -2
  261. package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
  262. package/dist/core/workflow/transcript.d.ts.map +1 -0
  263. package/dist/core/workflow/{journal.js → transcript.js} +14 -14
  264. package/dist/core/workflow/types.d.ts +119 -46
  265. package/dist/core/workflow/types.d.ts.map +1 -1
  266. package/dist/core/workflow/types.js +11 -1
  267. package/dist/core/workflow/validate.d.ts +1 -1
  268. package/dist/core/workflow/validate.js +1 -1
  269. package/dist/core/workflow/workspaces/cancellation.js +2 -2
  270. package/dist/core/workflow/workspaces/cleanup.js +2 -2
  271. package/dist/core/workflow/workspaces/execution.js +6 -6
  272. package/dist/core/workflow/workspaces/inspect.js +9 -9
  273. package/dist/core/workflow/workspaces/integration.js +14 -14
  274. package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
  275. package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
  276. package/dist/core/workflow/workspaces/lifecycle.js +9 -9
  277. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  278. package/dist/core/workflow/workspaces/local-git.js +39 -5
  279. package/dist/core/workflow/workspaces/recovery.js +3 -3
  280. package/dist/core/workflow/workspaces/state.d.ts +1 -1
  281. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  282. package/dist/core/workflow/workspaces/state.js +3 -3
  283. package/dist/core/workflow/workspaces/types.d.ts +1 -1
  284. package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
  285. package/dist/lib/browser/asserts.d.ts +28 -0
  286. package/dist/lib/browser/asserts.d.ts.map +1 -0
  287. package/dist/lib/browser/asserts.js +152 -0
  288. package/dist/lib/browser/client.d.ts +49 -0
  289. package/dist/lib/browser/client.d.ts.map +1 -1
  290. package/dist/lib/browser/client.js +155 -14
  291. package/dist/lib/browser/content-checks.d.ts +108 -0
  292. package/dist/lib/browser/content-checks.d.ts.map +1 -0
  293. package/dist/lib/browser/content-checks.js +474 -0
  294. package/dist/lib/browser/critique.d.ts +91 -0
  295. package/dist/lib/browser/critique.d.ts.map +1 -0
  296. package/dist/lib/browser/critique.js +167 -0
  297. package/dist/lib/browser/geometry.d.ts +32 -0
  298. package/dist/lib/browser/geometry.d.ts.map +1 -1
  299. package/dist/lib/browser/geometry.js +244 -1
  300. package/dist/lib/browser/index.d.ts +4 -1
  301. package/dist/lib/browser/index.d.ts.map +1 -1
  302. package/dist/lib/browser/index.js +2 -0
  303. package/dist/lib/claude-desktop.d.ts.map +1 -1
  304. package/dist/lib/claude-desktop.js +4 -1
  305. package/dist/lib/council/index.d.ts +6 -6
  306. package/dist/lib/council/index.d.ts.map +1 -1
  307. package/dist/lib/council/index.js +8 -8
  308. package/dist/lib/exec.d.ts +7 -0
  309. package/dist/lib/exec.d.ts.map +1 -1
  310. package/dist/lib/exec.js +6 -3
  311. package/dist/lib/identities/assume.d.ts +2 -2
  312. package/dist/lib/identities/assume.js +7 -7
  313. package/dist/lib/instructions/apply.d.ts +3 -3
  314. package/dist/lib/instructions/apply.d.ts.map +1 -1
  315. package/dist/lib/instructions/apply.js +75 -27
  316. package/dist/lib/instructions/host-addendum.d.ts +54 -0
  317. package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
  318. package/dist/lib/instructions/host-addendum.js +107 -0
  319. package/dist/lib/instructions/templates.d.ts +10 -3
  320. package/dist/lib/instructions/templates.d.ts.map +1 -1
  321. package/dist/lib/instructions/templates.js +41 -12
  322. package/dist/lib/machine.d.ts +2 -2
  323. package/dist/lib/machine.js +2 -2
  324. package/package.json +26 -21
  325. package/schemas/config.schema.json +26 -1
  326. package/src/commander.ts +22 -13
  327. package/src/commands/{harness.ts → adapter.ts} +46 -46
  328. package/src/commands/agents.ts +71 -64
  329. package/src/commands/artifacts.ts +168 -0
  330. package/src/commands/backup.ts +47 -33
  331. package/src/commands/browse.ts +438 -2
  332. package/src/commands/checkpoint.ts +196 -0
  333. package/src/commands/context.ts +3 -176
  334. package/src/commands/decision.ts +41 -7
  335. package/src/commands/deinit.ts +16 -16
  336. package/src/commands/doctor.ts +28 -28
  337. package/src/commands/{supervisor.ts → governor.ts} +184 -154
  338. package/src/commands/init.ts +50 -34
  339. package/src/commands/{scratch.ts → journal.ts} +60 -60
  340. package/src/commands/policy.ts +1 -1
  341. package/src/commands/presence.ts +2 -2
  342. package/src/commands/sync.ts +3 -3
  343. package/src/commands/tunnel.ts +237 -34
  344. package/src/commands/web-fetch.ts +1 -1
  345. package/src/commands/web.ts +56 -1
  346. package/src/commands/work.ts +72 -38
  347. package/src/commands/workflow.ts +43 -34
  348. package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
  349. package/src/core/{harnesses → adapters}/attest.ts +27 -27
  350. package/src/core/{harnesses → adapters}/attestation.ts +41 -41
  351. package/src/core/{harnesses → adapters}/bench.ts +34 -43
  352. package/src/core/adapters/index.ts +56 -0
  353. package/src/core/{harnesses → adapters}/profiles.ts +16 -16
  354. package/src/core/{harnesses → adapters}/registry.ts +23 -23
  355. package/src/core/{harnesses → adapters}/types.ts +28 -23
  356. package/src/core/agents/canonical-emit.ts +6 -6
  357. package/src/core/agents/cli-emit.ts +1 -1
  358. package/src/core/agents/cli.ts +30 -28
  359. package/src/core/agents/codex-replay.ts +6 -6
  360. package/src/core/agents/coord-client.ts +119 -28
  361. package/src/core/agents/events/consume.ts +1 -1
  362. package/src/core/agents/events/emit.ts +7 -6
  363. package/src/core/agents/render/prompt-context.ts +107 -31
  364. package/src/core/agents/render/session-context.ts +6 -6
  365. package/src/core/agents/rules/claim-conflict.ts +4 -7
  366. package/src/core/agents/rules/commit-conflict.ts +103 -22
  367. package/src/core/agents/rules/stop-hook.ts +33 -17
  368. package/src/core/agents/rules/verdict.ts +13 -0
  369. package/src/core/agents/session-events.ts +4 -4
  370. package/src/core/agents/state/council.ts +1 -1
  371. package/src/core/agents/state/heartbeat-projector.ts +16 -12
  372. package/src/core/agents/state/heartbeat-writer.ts +12 -12
  373. package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
  374. package/src/core/agents/state/pidmap.ts +130 -15
  375. package/src/core/agents/state/proc-start.ts +208 -0
  376. package/src/core/agents/state/shell-mutation.ts +1 -1
  377. package/src/core/agents/state/stale-sweep.ts +7 -7
  378. package/src/core/artifacts/index.ts +557 -0
  379. package/src/core/config.ts +30 -2
  380. package/src/core/context/index.ts +15 -15
  381. package/src/core/governor/adapter-spread.ts +82 -0
  382. package/src/core/governor/index.ts +91 -0
  383. package/src/core/governor/plan-api.ts +115 -0
  384. package/src/core/{supervisor → governor}/plan-read.ts +120 -96
  385. package/src/core/{supervisor → governor}/plan-types.ts +64 -50
  386. package/src/core/{supervisor → governor}/planning.ts +240 -188
  387. package/src/core/governor/read.ts +59 -0
  388. package/src/core/{supervisor → governor}/runner.ts +39 -39
  389. package/src/core/{supervisor → governor}/service-read.ts +22 -22
  390. package/src/core/{supervisor → governor}/service.ts +117 -119
  391. package/src/core/{supervisor → governor}/state.ts +389 -174
  392. package/src/core/hooks/adapter/detect.ts +30 -0
  393. package/src/core/hooks/{harness → adapter}/events.ts +16 -14
  394. package/src/core/hooks/{harness → adapter}/output.ts +31 -23
  395. package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
  396. package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
  397. package/src/core/hooks/cli.ts +185 -162
  398. package/src/core/hooks/effects/image-capture.ts +6 -6
  399. package/src/core/hooks/effects/index.ts +17 -17
  400. package/src/core/hooks/events/emit.ts +3 -3
  401. package/src/core/hooks/events/rotate.ts +1 -1
  402. package/src/core/hooks/events/schema.ts +15 -7
  403. package/src/core/hooks/guard-path.ts +2 -2
  404. package/src/core/hooks/index.ts +1 -1
  405. package/src/core/hooks/resolve/anchor.ts +63 -8
  406. package/src/core/hooks/resolve/coord-root.ts +4 -4
  407. package/src/core/hooks/resolve/intent.ts +1 -1
  408. package/src/core/hooks/resolve/owner.ts +11 -5
  409. package/src/core/{scratch → journal}/index.ts +53 -53
  410. package/src/core/policy/evaluate.ts +8 -8
  411. package/src/core/policy/types.ts +3 -3
  412. package/src/core/work/runner.ts +11 -2
  413. package/src/core/work/state.ts +185 -21
  414. package/src/core/workflow/adapters.ts +33 -0
  415. package/src/core/workflow/approvals.ts +7 -7
  416. package/src/core/workflow/billing.ts +12 -12
  417. package/src/core/workflow/child-env.ts +13 -4
  418. package/src/core/workflow/engine.ts +166 -90
  419. package/src/core/workflow/evidence-preflight.ts +165 -0
  420. package/src/core/workflow/index.ts +6 -3
  421. package/src/core/workflow/proof.ts +94 -48
  422. package/src/core/workflow/run-state.ts +7 -7
  423. package/src/core/workflow/sandbox-projection.ts +16 -16
  424. package/src/core/workflow/spawn-claude.ts +34 -12
  425. package/src/core/workflow/spawn-codex.ts +30 -12
  426. package/src/core/workflow/spawn-cursor.ts +31 -12
  427. package/src/core/workflow/spawn-failure.ts +41 -1
  428. package/src/core/workflow/specialists.ts +2 -2
  429. package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
  430. package/src/core/workflow/types.ts +130 -46
  431. package/src/core/workflow/validate.ts +1 -1
  432. package/src/core/workflow/workspaces/cancellation.ts +2 -2
  433. package/src/core/workflow/workspaces/cleanup.ts +2 -2
  434. package/src/core/workflow/workspaces/execution.ts +6 -6
  435. package/src/core/workflow/workspaces/inspect.ts +14 -11
  436. package/src/core/workflow/workspaces/integration.ts +18 -14
  437. package/src/core/workflow/workspaces/lifecycle.ts +10 -10
  438. package/src/core/workflow/workspaces/local-git.ts +47 -5
  439. package/src/core/workflow/workspaces/recovery.ts +3 -3
  440. package/src/core/workflow/workspaces/state.ts +4 -3
  441. package/src/core/workflow/workspaces/types.ts +1 -1
  442. package/src/lib/browser/asserts.ts +177 -0
  443. package/src/lib/browser/client.ts +189 -14
  444. package/src/lib/browser/content-checks.ts +571 -0
  445. package/src/lib/browser/critique.ts +231 -0
  446. package/src/lib/browser/geometry.ts +297 -1
  447. package/src/lib/browser/index.ts +34 -0
  448. package/src/lib/claude-desktop.ts +4 -1
  449. package/src/lib/council/index.ts +9 -9
  450. package/src/lib/exec.ts +13 -3
  451. package/src/lib/identities/assume.ts +7 -7
  452. package/src/lib/instructions/apply.ts +87 -25
  453. package/src/lib/instructions/host-addendum.ts +126 -0
  454. package/src/lib/instructions/templates.ts +44 -15
  455. package/src/lib/machine.ts +2 -2
  456. package/dist/commands/harness.d.ts +0 -12
  457. package/dist/commands/harness.d.ts.map +0 -1
  458. package/dist/commands/scratch.d.ts +0 -4
  459. package/dist/commands/scratch.d.ts.map +0 -1
  460. package/dist/commands/session.d.ts.map +0 -1
  461. package/dist/commands/session.js +0 -162
  462. package/dist/commands/supervisor.d.ts +0 -4
  463. package/dist/commands/supervisor.d.ts.map +0 -1
  464. package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
  465. package/dist/core/harnesses/attest.d.ts.map +0 -1
  466. package/dist/core/harnesses/attestation.d.ts.map +0 -1
  467. package/dist/core/harnesses/bench.d.ts.map +0 -1
  468. package/dist/core/harnesses/index.d.ts +0 -13
  469. package/dist/core/harnesses/index.d.ts.map +0 -1
  470. package/dist/core/harnesses/index.js +0 -6
  471. package/dist/core/harnesses/profiles.d.ts.map +0 -1
  472. package/dist/core/harnesses/registry.d.ts +0 -15
  473. package/dist/core/harnesses/registry.d.ts.map +0 -1
  474. package/dist/core/harnesses/types.d.ts.map +0 -1
  475. package/dist/core/hooks/harness/detect.d.ts +0 -9
  476. package/dist/core/hooks/harness/events.d.ts.map +0 -1
  477. package/dist/core/hooks/harness/output.d.ts.map +0 -1
  478. package/dist/core/supervisor/index.d.ts +0 -7
  479. package/dist/core/supervisor/index.d.ts.map +0 -1
  480. package/dist/core/supervisor/index.js +0 -6
  481. package/dist/core/supervisor/plan-api.d.ts +0 -23
  482. package/dist/core/supervisor/plan-api.d.ts.map +0 -1
  483. package/dist/core/supervisor/plan-api.js +0 -50
  484. package/dist/core/supervisor/plan-read.d.ts +0 -5
  485. package/dist/core/supervisor/plan-read.d.ts.map +0 -1
  486. package/dist/core/supervisor/plan-types.d.ts +0 -170
  487. package/dist/core/supervisor/plan-types.d.ts.map +0 -1
  488. package/dist/core/supervisor/planning.d.ts +0 -33
  489. package/dist/core/supervisor/planning.d.ts.map +0 -1
  490. package/dist/core/supervisor/read.d.ts +0 -6
  491. package/dist/core/supervisor/read.d.ts.map +0 -1
  492. package/dist/core/supervisor/read.js +0 -4
  493. package/dist/core/supervisor/runner.d.ts +0 -37
  494. package/dist/core/supervisor/runner.d.ts.map +0 -1
  495. package/dist/core/supervisor/service-read.d.ts +0 -6
  496. package/dist/core/supervisor/service-read.d.ts.map +0 -1
  497. package/dist/core/supervisor/service.d.ts +0 -114
  498. package/dist/core/supervisor/service.d.ts.map +0 -1
  499. package/dist/core/supervisor/state.d.ts +0 -95
  500. package/dist/core/supervisor/state.d.ts.map +0 -1
  501. package/dist/core/workflow/harnesses.d.ts +0 -17
  502. package/dist/core/workflow/harnesses.d.ts.map +0 -1
  503. package/dist/core/workflow/harnesses.js +0 -21
  504. package/dist/core/workflow/journal.d.ts.map +0 -1
  505. package/src/commands/session.ts +0 -187
  506. package/src/core/harnesses/index.ts +0 -56
  507. package/src/core/hooks/harness/detect.ts +0 -30
  508. package/src/core/supervisor/index.ts +0 -89
  509. package/src/core/supervisor/plan-api.ts +0 -73
  510. package/src/core/supervisor/read.ts +0 -59
  511. package/src/core/workflow/harnesses.ts +0 -33
  512. /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
@@ -3,8 +3,8 @@
3
3
  * alongside the legacy stream.
4
4
  *
5
5
  * Flow:
6
- * 1. Parse argv → event-name + harness.
7
- * 2. Read stdin → harness payload (JSON or empty).
6
+ * 1. Parse argv → event-name + adapter.
7
+ * 2. Read stdin → adapter payload (JSON or empty).
8
8
  * 3. Find coord root (walk up for .harnery/).
9
9
  * 4. Resolve instance_id (env → payload → pid-map walk).
10
10
  * 5. Map event-name → canonical event_type.
@@ -15,7 +15,7 @@
15
15
  * Phase 2 ship criterion: confirms parser correctness across thousands of
16
16
  * real events without affecting behavior. Always exits 0. Failures land in
17
17
  * `.harnery/debug/agent-hook.errors.ndjson` for audit but never break the
18
- * harness flow.
18
+ * adapter flow.
19
19
  */
20
20
 
21
21
  import { spawnSync } from "node:child_process";
@@ -26,6 +26,7 @@ import { replayCodexJsonl } from "../agents/codex-replay.ts";
26
26
  import { consumeSince, writeCursor } from "../agents/events/consume.ts";
27
27
  import { evaluateStopHook } from "../agents/rules/stop-hook.ts";
28
28
  import { projectHeartbeats } from "../agents/state/heartbeat-projector.ts";
29
+ import { writePidmapRow } from "../agents/state/pidmap.ts";
29
30
  import { shellMutationPaths } from "../agents/state/shell-mutation.ts";
30
31
  import {
31
32
  checkpointContext,
@@ -38,32 +39,32 @@ import {
38
39
  recordContextSample,
39
40
  } from "../context/index.ts";
40
41
  import { ensureRelayDaemon, fetchPresence, publishPresence } from "../presence/index.ts";
42
+ import { detectAdapter } from "./adapter/detect.ts";
43
+ import {
44
+ extractBashCommand,
45
+ extractToolDescription,
46
+ type NormalizedEventType,
47
+ normalizeEventName,
48
+ type ParsedPayload,
49
+ parsePayload,
50
+ } from "./adapter/parse.ts";
41
51
  import {
42
52
  captureImages,
43
53
  detectPresence,
44
54
  imageJanitor,
55
+ journalArchive,
56
+ journalJanitor,
57
+ journalRecoveryCue,
45
58
  playSound,
46
59
  resetSoundCounters,
47
60
  runSessionSyncExtension,
48
61
  runTurnSummary,
49
- scratchArchive,
50
- scratchJanitor,
51
- scratchRecoveryCue,
52
62
  soundForEvent,
53
63
  } from "./effects/index.ts";
54
64
  import { emit } from "./events/emit.ts";
55
- import type { Harness } from "./events/schema.ts";
65
+ import type { Adapter } from "./events/schema.ts";
56
66
  import { canonicalize } from "./guard-path.ts";
57
- import { detectHarness } from "./harness/detect.ts";
58
- import {
59
- extractBashCommand,
60
- extractToolDescription,
61
- type NormalizedEventType,
62
- normalizeEventName,
63
- type ParsedPayload,
64
- parsePayload,
65
- } from "./harness/parse.ts";
66
- import { parsePsChainLine, selectAnchorPid } from "./resolve/anchor.ts";
67
+ import { adapterPidFromEnv, parsePsChainLine, selectAnchorPid } from "./resolve/anchor.ts";
67
68
  import { findCoordRoot } from "./resolve/coord-root.ts";
68
69
  import { extractIntentComment, resolveIntent } from "./resolve/intent.ts";
69
70
  import { resolveOwner } from "./resolve/owner.ts";
@@ -78,11 +79,11 @@ function parseArgv(argv: string[]): Argv {
78
79
  const out: Argv = { eventName: null, extra: [] };
79
80
  for (let i = 0; i < argv.length; i++) {
80
81
  const arg = argv[i]!;
81
- if (arg === "--harness") {
82
- i++; // detectHarness will re-parse; just consume the value here.
82
+ if (arg === "--adapter") {
83
+ i++; // detectAdapter will re-parse; just consume the value here.
83
84
  continue;
84
85
  }
85
- if (arg.startsWith("--harness=")) continue;
86
+ if (arg.startsWith("--adapter=")) continue;
86
87
  if (!out.eventName && !arg.startsWith("--")) {
87
88
  out.eventName = arg;
88
89
  } else {
@@ -108,7 +109,7 @@ async function readStdin(): Promise<string> {
108
109
  /**
109
110
  * Env for child agent-coord spawns, with the coord root pinned. The hook
110
111
  * process may be running with the session shell's cwd (inside a submodule or
111
- * scratch dir), and agent-coord resolves its root from cwd unless overridden —
112
+ * journal dir), and agent-coord resolves its root from cwd unless overridden —
112
113
  * without the pin a child could write state to a different .harnery than the
113
114
  * one this hook resolved.
114
115
  */
@@ -149,7 +150,7 @@ function logError(coordRoot: string | null, err: unknown, context: Record<string
149
150
  /**
150
151
  * Spawn `agent-coord assign-name <owner> <kind>` to mint or recover the
151
152
  * hurricane-style name for this owner. Returns null on any failure so
152
- * session.start emission never breaks the harness flow.
153
+ * session.start emission never breaks the adapter flow.
153
154
  *
154
155
  * Lives at agent-hooks side (not agent-coord) to keep emitter/consumer
155
156
  * separation: we spawn rather than import.
@@ -182,9 +183,15 @@ function assignNameViaAgentCoord(
182
183
  }
183
184
 
184
185
  /**
185
- * Direct (in-process) pidmap write, avoids the spawn overhead of going via
186
- * the agent-coord CLI for every session.start / subagent.start. Pid-map
187
- * rows are essential for `harn agents whoami` ppid resolution.
186
+ * Direct (in-process) pidmap write, avoiding the spawn overhead of going via
187
+ * the agent-coord CLI for every session.start / subagent.start. Pid-map rows
188
+ * are essential for `harn agents whoami` ppid resolution.
189
+ *
190
+ * This used to inline its own copy of the write to keep this module's
191
+ * dependencies narrow, which quietly mattered: the shared writer is where row
192
+ * hygiene lives, so the duplicate meant the only hot write path in the system
193
+ * never swept dead rows, and the map grew unbounded. It calls the shared writer
194
+ * now, and this module already imports from that directory anyway.
188
195
  */
189
196
  function writePidmapViaAgentCoord(
190
197
  coordRoot: string,
@@ -193,26 +200,9 @@ function writePidmapViaAgentCoord(
193
200
  platform: string,
194
201
  ): void {
195
202
  try {
196
- // Inline write: same atomic temp+rename pattern as
197
- // agent-coord/src/state/pidmap.ts but skips importing across module
198
- // boundaries to keep agent-hooks's deps explicit.
199
- const dir = join(coordRoot, ".harnery", "pid-map");
200
- const path = join(dir, String(pid));
201
- const row = `${instanceId}\t${platform}`;
202
- if (existsSync(path)) {
203
- try {
204
- const current = require("node:fs").readFileSync(path, "utf8");
205
- if (current === row) return;
206
- } catch {
207
- /* fall through */
208
- }
209
- }
210
- mkdirSync(dir, { recursive: true });
211
- const tmp = `${path}.tmp.${process.pid}`;
212
- require("node:fs").writeFileSync(tmp, row, "utf8");
213
- require("node:fs").renameSync(tmp, path);
203
+ writePidmapRow(coordRoot, pid, instanceId, platform);
214
204
  } catch {
215
- /* never break the harness flow */
205
+ /* never break the adapter flow */
216
206
  }
217
207
  }
218
208
 
@@ -234,7 +224,7 @@ interface BuildContext {
234
224
  coordRoot: string;
235
225
  payload: ParsedPayload | null;
236
226
  raw: string;
237
- harness: Harness;
227
+ adapter: Adapter;
238
228
  instanceId: string;
239
229
  }
240
230
 
@@ -245,24 +235,24 @@ function buildEventData(
245
235
  const p = ctx.payload;
246
236
  switch (eventType) {
247
237
  case "session.start": {
248
- const harnessPlatform =
249
- ctx.harness === "claude-code"
238
+ const adapterPlatform =
239
+ ctx.adapter === "claude-code"
250
240
  ? "claude_code"
251
- : ctx.harness === "cursor"
241
+ : ctx.adapter === "cursor"
252
242
  ? "cursor"
253
243
  : "codex";
254
244
  // Assign (or recover) name + kind via agent-coord. Idempotent: resume
255
245
  // returns the original name; new owner consumes a counter slot.
256
246
  const assigned = assignNameViaAgentCoord(ctx.coordRoot, ctx.instanceId, "session");
257
- // Write the harness pid-map row so `harn agents whoami` ppid-walks find
247
+ // Write the adapter pid-map row so `harn agents whoami` ppid-walks find
258
248
  // this owner. Prefer the payload pid (the actual claude binary), then the
259
249
  // anchor walk (the `node` ancestor for Cursor, which has no payload pid),
260
250
  // then our own process.ppid. Without the anchor, Cursor anchored on the
261
251
  // ephemeral hook bash parent, a PID that dies before the agent's next
262
252
  // shell tool call, so the ppid walk found nothing (no_pidmap_entry).
263
- const harnessPid = p?.pid ?? findHarnessAnchorPid(ctx.harness) ?? process.ppid;
264
- if (harnessPid) {
265
- writePidmapViaAgentCoord(ctx.coordRoot, harnessPid, ctx.instanceId, harnessPlatform);
253
+ const adapterPid = p?.pid ?? findAdapterAnchorPid(ctx.adapter) ?? process.ppid;
254
+ if (adapterPid) {
255
+ writePidmapViaAgentCoord(ctx.coordRoot, adapterPid, ctx.instanceId, adapterPlatform);
266
256
  }
267
257
  return {
268
258
  started_at: new Date().toISOString(),
@@ -271,17 +261,25 @@ function buildEventData(
271
261
  // supply it). Fall back to the transcript, populated on `resume`, and
272
262
  // backfilled later by `turn.stop` for a fresh `startup` session.
273
263
  model: p?.model ?? scanTranscriptModel(p?.transcript_path),
274
- pid: harnessPid,
264
+ pid: adapterPid,
275
265
  source: p?.source,
276
- platform: harnessPlatform,
266
+ platform: adapterPlatform,
277
267
  name: assigned?.name,
278
268
  kind: "session",
279
269
  agent_id: ctx.instanceId,
280
270
  // Workflow-child linkage: `workflow run` children carry the run id in
281
271
  // env (spawn adapters set it via buildChildEnv), so their sessions and
282
- // heartbeats join back to the run journal + /workflows web view.
272
+ // heartbeats join back to the run transcript + /workflows web view.
283
273
  ...(coordEnv("WORKFLOW_CHILD") === "1" && coordEnv("WORKFLOW_RUN_ID")
284
- ? { workflow_run_id: coordEnv("WORKFLOW_RUN_ID") }
274
+ ? {
275
+ workflow_run_id: coordEnv("WORKFLOW_RUN_ID"),
276
+ // Which agent row of that run this session is. The orchestrator
277
+ // stamps it on the way in, because the adapter does not report a
278
+ // session id until the agent has already finished.
279
+ ...(coordEnv("WORKFLOW_AGENT_ID")
280
+ ? { workflow_agent_id: coordEnv("WORKFLOW_AGENT_ID") }
281
+ : {}),
282
+ }
285
283
  : {}),
286
284
  };
287
285
  }
@@ -300,7 +298,7 @@ function buildEventData(
300
298
 
301
299
  case "turn.stop": {
302
300
  return {
303
- // Backfill the model for harnesses that omit it at session.start
301
+ // Backfill the model for adapters that omit it at session.start
304
302
  // (Claude Code). The transcript is populated with assistant turns by
305
303
  // Stop-hook time, so this resolves even for fresh `startup` sessions.
306
304
  model: p?.model ?? scanTranscriptModel(p?.transcript_path),
@@ -442,14 +440,14 @@ function numberField(value: unknown): number | undefined {
442
440
 
443
441
  async function main(): Promise<number> {
444
442
  const { eventName, extra } = parseArgv(process.argv.slice(2));
445
- const harness = detectHarness(process.argv.slice(2));
443
+ const adapter = detectAdapter(process.argv.slice(2));
446
444
  const raw = await readStdin();
447
445
 
448
446
  // Kill-switch-INDEPENDENT effects: notification sounds fire BEFORE the
449
447
  // HARNERY_AGENT_COORD_OFF gate so audible feedback survives incident-triage
450
448
  // bypass: sound playback happens before the kill-switch bailout.
451
449
  // Claude-Code-only; stop-failure → error, sub-agent-start → subagent-start.
452
- if (harness === "claude-code" && eventName) {
450
+ if (adapter === "claude-code" && eventName) {
453
451
  const s = soundForEvent(eventName);
454
452
  if (s) {
455
453
  const repoRoot = findCoordRoot(process.cwd());
@@ -481,7 +479,7 @@ async function main(): Promise<number> {
481
479
  const debugBase = {
482
480
  ts: new Date().toISOString(),
483
481
  event_name: eventName,
484
- harness,
482
+ adapter,
485
483
  extra_argv: extra,
486
484
  payload_bytes: raw.length,
487
485
  cwd: process.cwd(),
@@ -489,8 +487,8 @@ async function main(): Promise<number> {
489
487
  ppid: process.ppid,
490
488
  };
491
489
 
492
- if (!eventName || !harness) {
493
- appendDebug(coordRoot, { ...debugBase, skipped: "missing-event-or-harness" });
490
+ if (!eventName || !adapter) {
491
+ appendDebug(coordRoot, { ...debugBase, skipped: "missing-event-or-adapter" });
494
492
  return 0;
495
493
  }
496
494
 
@@ -500,7 +498,7 @@ async function main(): Promise<number> {
500
498
  return 0;
501
499
  }
502
500
 
503
- const payload = parsePayload(raw, harness);
501
+ const payload = parsePayload(raw, adapter);
504
502
  const owner = resolveOwner({ payload: payload?.raw ?? null, coordRoot });
505
503
  if (!owner) {
506
504
  appendDebug(coordRoot, {
@@ -517,7 +515,7 @@ async function main(): Promise<number> {
517
515
  coordRoot,
518
516
  payload,
519
517
  raw,
520
- harness,
518
+ adapter,
521
519
  instanceId: owner.instance_id,
522
520
  });
523
521
 
@@ -528,7 +526,7 @@ async function main(): Promise<number> {
528
526
  parent_session_id: payload?.parent_session_id,
529
527
  turn_id: payload?.turn_id,
530
528
  parent_turn_id: payload?.parent_turn_id,
531
- harness,
529
+ adapter,
532
530
  data,
533
531
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
534
532
  } as Parameters<typeof emit>[1]);
@@ -541,13 +539,13 @@ async function main(): Promise<number> {
541
539
  });
542
540
 
543
541
  // Context telemetry is opportunistic and truthful: only persist a sample
544
- // when the harness payload actually exposes usage/window data. Identical
542
+ // when the adapter payload actually exposes usage/window data. Identical
545
543
  // measurements are de-duplicated before they reach the canonical stream.
546
544
  if (payload?.raw) {
547
545
  try {
548
546
  const sample = extractContextSample(payload.raw, {
549
547
  sessionId,
550
- harness,
548
+ adapter,
551
549
  model: payload.model,
552
550
  source: "hook",
553
551
  confidence: "reported",
@@ -559,7 +557,7 @@ async function main(): Promise<number> {
559
557
  event_type: "context.sampled",
560
558
  instance_id: owner.instance_id,
561
559
  session_id: sessionId,
562
- harness,
560
+ adapter,
563
561
  data: {
564
562
  model: sample.model,
565
563
  used_tokens: sample.used_tokens,
@@ -578,13 +576,13 @@ async function main(): Promise<number> {
578
576
 
579
577
  // A native pre-compaction signal is the safest available point to capture
580
578
  // external work state. The operation is idempotent until recovery, so a
581
- // harness retry cannot create a storm of near-identical capsules.
579
+ // adapter retry cannot create a storm of near-identical capsules.
582
580
  if (norm.event_type === "context.compaction.started") {
583
581
  try {
584
582
  const checkpoint = checkpointContext(coordRoot, {
585
583
  sessionId,
586
584
  instanceId: owner.instance_id,
587
- harness,
585
+ adapter,
588
586
  cwd: payload?.cwd ?? process.cwd(),
589
587
  reason: "pre_compact",
590
588
  model: payload?.model,
@@ -593,7 +591,7 @@ async function main(): Promise<number> {
593
591
  event_type: "context.checkpoint.created",
594
592
  instance_id: owner.instance_id,
595
593
  session_id: sessionId,
596
- harness,
594
+ adapter,
597
595
  data: {
598
596
  capsule_id: checkpoint.capsule.capsule_id,
599
597
  generation: checkpoint.capsule.generation,
@@ -619,17 +617,17 @@ async function main(): Promise<number> {
619
617
  }
620
618
 
621
619
  // Phase 8: SessionStart post-emit: project the event so the heartbeat
622
- // lands synchronously, run stale-sweep, and emit the harness-shaped
620
+ // lands synchronously, run stale-sweep, and emit the adapter-shaped
623
621
  // systemMessage JSON (peer table + wiring check + council invites).
624
- // Harness-agnostic since v0.5.0; replaces the previous bash UX layer
625
- // and the equivalent per-harness bash session_start handlers.
622
+ // Adapter-agnostic since v0.5.0; replaces the previous bash UX layer
623
+ // and the equivalent per-adapter bash session_start handlers.
626
624
  if (norm.event_type === "session.start") {
627
- // Effect (claude-code): prune stale scratch archives + sweep orphans.
625
+ // Effect (claude-code): prune stale journal archives + sweep orphans.
628
626
  // The recovery-cue is merged into the
629
627
  // session-start additionalContext inside emitSessionStartSystemMessage.
630
- if (harness === "claude-code") scratchJanitor(coordRoot);
631
- // Image-feed retention sweep (size + age cap on .harnery/images/). Harness-
632
- // agnostic, cheap (one readdir), fail-soft. Paired with scratchJanitor as a
628
+ if (adapter === "claude-code") journalJanitor(coordRoot);
629
+ // Image-feed retention sweep (size + age cap on .harnery/images/). Adapter-
630
+ // agnostic, cheap (one readdir), fail-soft. Paired with journalJanitor as a
633
631
  // session-start "tidy the coord layer" step.
634
632
  try {
635
633
  imageJanitor(coordRoot);
@@ -643,7 +641,7 @@ async function main(): Promise<number> {
643
641
  event_type: "context.compaction.completed",
644
642
  instance_id: owner.instance_id,
645
643
  session_id: sessionId,
646
- harness,
644
+ adapter,
647
645
  data: { trigger: "auto" },
648
646
  });
649
647
  markContextCompactionCompleted(coordRoot, {
@@ -665,7 +663,7 @@ async function main(): Promise<number> {
665
663
  owner.instance_id,
666
664
  sessionId,
667
665
  data,
668
- harness,
666
+ adapter,
669
667
  recovery?.briefing ?? "",
670
668
  );
671
669
  if (injected && recovery) {
@@ -673,7 +671,7 @@ async function main(): Promise<number> {
673
671
  coordRoot,
674
672
  owner.instance_id,
675
673
  sessionId,
676
- harness,
674
+ adapter,
677
675
  recovery,
678
676
  "SessionStart",
679
677
  );
@@ -693,7 +691,7 @@ async function main(): Promise<number> {
693
691
  }
694
692
  }
695
693
 
696
- // Phase 8: SessionEnd cleanup: delete heartbeat + pid-map rows. Harness-
694
+ // Phase 8: SessionEnd cleanup: delete heartbeat + pid-map rows. Adapter-
697
695
  // agnostic since v0.5.0.
698
696
  if (norm.event_type === "session.end") {
699
697
  try {
@@ -701,10 +699,10 @@ async function main(): Promise<number> {
701
699
  } catch (err) {
702
700
  logError(coordRoot, err, { phase: "session-end-cleanup" });
703
701
  }
704
- // Effects (claude-code): archive the ending agent's scratchpad + force a
702
+ // Effects (claude-code): archive the ending agent's journal + force a
705
703
  // session-telemetry sync (via HARNERY_CLAUDE_SESSIONS_FORCE=1).
706
- if (harness === "claude-code") {
707
- scratchArchive(coordRoot, owner.instance_id);
704
+ if (adapter === "claude-code") {
705
+ journalArchive(coordRoot, owner.instance_id);
708
706
  runSessionSyncExtension(coordRoot, true);
709
707
  }
710
708
  // Presence: publish the post-cleanup state so peers see this session gone
@@ -732,14 +730,14 @@ async function main(): Promise<number> {
732
730
  agentCoordBin,
733
731
  [
734
732
  "log",
735
- `SUBAGENT_START agent_type=${(data.agent_type as string) ?? "unknown"} agent_id=${owner.instance_id.slice(0, 8)} platform=${harnessPlatform(harness)}`,
733
+ `SUBAGENT_START agent_type=${(data.agent_type as string) ?? "unknown"} agent_id=${owner.instance_id.slice(0, 8)} platform=${adapterPlatform(adapter)}`,
736
734
  "--instance",
737
735
  owner.instance_id,
738
736
  ],
739
737
  { encoding: "utf8", timeout: 2000, env: childEnv(coordRoot) },
740
738
  );
741
739
  }
742
- emitSubagentStartContext(coordRoot, owner.instance_id, sessionId, data, harness);
740
+ emitSubagentStartContext(coordRoot, owner.instance_id, sessionId, data, adapter);
743
741
  } catch (err) {
744
742
  logError(coordRoot, err, { phase: "subagent-start-project" });
745
743
  }
@@ -755,7 +753,7 @@ async function main(): Promise<number> {
755
753
  agentCoordBin,
756
754
  [
757
755
  "log",
758
- `SUBAGENT_STOP agent_id=${owner.instance_id.slice(0, 8)} platform=${harnessPlatform(harness)}`,
756
+ `SUBAGENT_STOP agent_id=${owner.instance_id.slice(0, 8)} platform=${adapterPlatform(adapter)}`,
759
757
  "--instance",
760
758
  owner.instance_id,
761
759
  ],
@@ -768,11 +766,11 @@ async function main(): Promise<number> {
768
766
  }
769
767
 
770
768
  // Phase 8: UserPromptSubmit: render dedup'd peer table + council pending
771
- // and emit the harness-shaped systemMessage JSON. Harness-agnostic since v0.5.0.
769
+ // and emit the adapter-shaped systemMessage JSON. Adapter-agnostic since v0.5.0.
772
770
  if (norm.event_type === "user_prompt.submit") {
773
771
  // Effects (claude-code): reset per-turn sound rate-limit counters + run
774
772
  // presence detection on the prompt.
775
- if (harness === "claude-code") {
773
+ if (adapter === "claude-code") {
776
774
  resetSoundCounters(sessionId);
777
775
  const prompt = (payload?.raw?.prompt as string | undefined) ?? "";
778
776
  if (prompt) detectPresence(prompt);
@@ -805,7 +803,7 @@ async function main(): Promise<number> {
805
803
  coordRoot,
806
804
  owner.instance_id,
807
805
  sessionId,
808
- harness,
806
+ adapter,
809
807
  recovery?.briefing ?? "",
810
808
  );
811
809
  if (injected && recovery) {
@@ -813,7 +811,7 @@ async function main(): Promise<number> {
813
811
  coordRoot,
814
812
  owner.instance_id,
815
813
  sessionId,
816
- harness,
814
+ adapter,
817
815
  recovery,
818
816
  "UserPromptSubmit",
819
817
  );
@@ -824,7 +822,7 @@ async function main(): Promise<number> {
824
822
  }
825
823
 
826
824
  // turn.stop: telemetry + turn-summary effects, then the stop verdict. The
827
- // verdict + codex-replay previously lived in the per-harness shell adapters;
825
+ // verdict + codex-replay previously lived in the per-adapter shell adapters;
828
826
  // agent-hook owns them now. Runs on the normal "stop" event only;
829
827
  // "stop-failure" (API error) gets no gate, matching the previous
830
828
  // stop vs stop-failure split.
@@ -833,7 +831,7 @@ async function main(): Promise<number> {
833
831
  // the status_checked / task_set / status_box_present evidence (codex
834
832
  // doesn't emit those live; this re-emits turn.stop after agent-hook's own,
835
833
  // so the verdict reads the replay's box signal as the latest).
836
- if (harness === "codex" && payload?.transcript_path && existsSync(payload.transcript_path)) {
834
+ if (adapter === "codex" && payload?.transcript_path && existsSync(payload.transcript_path)) {
837
835
  try {
838
836
  replayCodexJsonl({
839
837
  coordRoot,
@@ -849,7 +847,7 @@ async function main(): Promise<number> {
849
847
 
850
848
  // CC effects: rate-limited session-telemetry sync + turn-summary Haiku
851
849
  // auto-summary.
852
- if (harness === "claude-code") {
850
+ if (adapter === "claude-code") {
853
851
  runSessionSyncExtension(coordRoot, false);
854
852
  runTurnSummary(coordRoot, owner.instance_id, sessionId, payload?.transcript_path);
855
853
  }
@@ -857,7 +855,7 @@ async function main(): Promise<number> {
857
855
  // Master-state heartbeat projection. Drains events.ndjson since the last
858
856
  // cursor → per-owner heartbeats. Was a SECOND binary (`agent-coord project`)
859
857
  // pinned to Claude Code Stop only; folded in here so it (a) is one
860
- // entry per event like everything else and (b) fires on EVERY harness's stop,
858
+ // entry per event like everything else and (b) fires on EVERY adapter's stop,
861
859
  // not just CC. Runs unconditionally before the verdict's possible exit-2 return
862
860
  // (the events are real regardless of whether the agent gets nagged), and after
863
861
  // codex-replay above so codex's replayed events are included in the drain.
@@ -888,22 +886,22 @@ async function main(): Promise<number> {
888
886
  rule: "stop-hook",
889
887
  instance_id: owner.instance_id,
890
888
  session_id: sessionId,
891
- harness,
889
+ adapter,
892
890
  bypass: coordEnv("AGENT_COORD_BYPASS_STOP") === "1",
893
891
  workflow_child: coordEnv("WORKFLOW_CHILD") === "1",
894
892
  });
895
893
  if (!verdict.allow) {
896
- // Harness-aware enforcement channel: Claude Code / Codex honor exit-2 +
894
+ // Adapter-aware enforcement channel: Claude Code / Codex honor exit-2 +
897
895
  // stderr as a turn block; Cursor ignores exit codes (fail-open) and
898
896
  // re-prompts only via a `followup_message` it auto-submits. emitStopBlock
899
897
  // writes the right shape and returns the exit code to use.
900
- const { emitStopBlock } = await import("./harness/output.ts");
901
- return emitStopBlock(harness, verdict);
898
+ const { emitStopBlock } = await import("./adapter/output.ts");
899
+ return emitStopBlock(adapter, verdict);
902
900
  }
903
901
  }
904
902
 
905
903
  // Phase 7: PreToolUse: heartbeat + pid-map self-heal on every tool call.
906
- // Harness-agnostic: both writes have the same shape regardless of who fired.
904
+ // Adapter-agnostic: both writes have the same shape regardless of who fired.
907
905
  // Cursor/Codex bash dispatchers still fire their own G-guard logic, but the
908
906
  // heals here keep the agent-coord layer's view of liveness fresh.
909
907
  //
@@ -913,8 +911,8 @@ async function main(): Promise<number> {
913
911
  // call was restored here afterward.
914
912
  if (norm.event_type === "tool.pre_use") {
915
913
  try {
916
- healHeartbeatViaCli(coordRoot, owner.instance_id, sessionId, harness);
917
- refreshPidmap(coordRoot, owner.instance_id, harness, payload?.pid);
914
+ healHeartbeatViaCli(coordRoot, owner.instance_id, sessionId, adapter);
915
+ refreshPidmap(coordRoot, owner.instance_id, adapter, payload?.pid);
918
916
  } catch (err) {
919
917
  logError(coordRoot, err, { phase: "pre-tool-use-heal" });
920
918
  }
@@ -928,29 +926,29 @@ async function main(): Promise<number> {
928
926
  payload,
929
927
  instanceId: owner.instance_id,
930
928
  sessionId,
931
- harness,
929
+ adapter,
932
930
  });
933
931
  } catch (err) {
934
932
  logError(coordRoot, err, { phase: "pre-tool-use-image-capture" });
935
933
  }
936
934
 
937
- // G-guard for ALL harnesses. Claude Code previously ran this via a
935
+ // G-guard for ALL adapters. Claude Code previously ran this via a
938
936
  // pre-tool-use bash adapter (which called `agent-coord verdict --rule=claim`);
939
- // that adapter is now deleted, so agent-hook owns the deny for every harness.
940
- // emitDeny() inside emits the harness-shaped permission JSON (claude-code +
937
+ // that adapter is now deleted, so agent-hook owns the deny for every adapter.
938
+ // emitDeny() inside emits the adapter-shaped permission JSON (claude-code +
941
939
  // codex use hookSpecificOutput.permissionDecision; cursor uses .permission).
942
940
  // apply_patch (codex) parses paths from the patch body and runs verdict
943
941
  // per-path; Edit/Write/NotebookEdit resolve a single target. Non-write tools
944
942
  // (incl. Agent) yield no targets and pass through with no deny.
945
943
  try {
946
- await runPreToolUseGuard(coordRoot, owner.instance_id, sessionId, data, harness);
944
+ await runPreToolUseGuard(coordRoot, owner.instance_id, sessionId, data, adapter);
947
945
  } catch (err) {
948
946
  logError(coordRoot, err, { phase: "pre-tool-use-guard" });
949
947
  }
950
948
 
951
949
  // Shell-mutation warn (warn-only, never blocks). Was the cursor
952
950
  // beforeShellExecution + codex preToolUse-Bash shell-mutation-claim-log in
953
- // the per-harness shell adapters. Cursor sends the command at payload.command;
951
+ // the per-adapter shell adapters. Cursor sends the command at payload.command;
954
952
  // codex Bash at tool_input.command. Emits a decision.warn per candidate-mutated
955
953
  // path so a peer sees the write in events.ndjson. (CC never did this,
956
954
  // preserved; it emits with its own hooks-side emitter per the
@@ -958,7 +956,7 @@ async function main(): Promise<number> {
958
956
  const shellCmd =
959
957
  eventName === "before-shell-execution"
960
958
  ? ((payload?.raw.command as string | undefined) ?? "")
961
- : harness === "codex" && data.tool_name === "Bash"
959
+ : adapter === "codex" && data.tool_name === "Bash"
962
960
  ? (((payload?.raw.tool_input as Record<string, unknown> | undefined)?.command as
963
961
  | string
964
962
  | undefined) ?? "")
@@ -967,13 +965,13 @@ async function main(): Promise<number> {
967
965
  try {
968
966
  const paths = shellMutationPaths(shellCmd, coordRoot);
969
967
  const truncated = shellCmd.length > 80 ? shellCmd.slice(0, 80) : shellCmd;
970
- const platform = harnessPlatform(harness);
968
+ const platform = adapterPlatform(adapter);
971
969
  for (const p of paths) {
972
970
  emit(coordRoot, {
973
971
  event_type: "decision.warn",
974
972
  instance_id: owner.instance_id,
975
973
  session_id: sessionId,
976
- harness,
974
+ adapter,
977
975
  data: {
978
976
  rule: "shell_mutation_candidate",
979
977
  reason: `path=${p} cmd=${truncated} platform=${platform}`,
@@ -988,7 +986,7 @@ async function main(): Promise<number> {
988
986
  }
989
987
 
990
988
  // Phase 7: PostToolUse: stamp last_tool + last_tool_target on heartbeat.
991
- // Harness-agnostic for the same reason as tool.pre_use above.
989
+ // Adapter-agnostic for the same reason as tool.pre_use above.
992
990
  if (norm.event_type === "tool.post_use") {
993
991
  try {
994
992
  stampToolActivity(coordRoot, owner.instance_id, data);
@@ -1006,7 +1004,7 @@ async function main(): Promise<number> {
1006
1004
  payload,
1007
1005
  instanceId: owner.instance_id,
1008
1006
  sessionId,
1009
- harness,
1007
+ adapter,
1010
1008
  });
1011
1009
  } catch (err) {
1012
1010
  logError(coordRoot, err, { phase: "post-tool-use-image-capture" });
@@ -1014,7 +1012,7 @@ async function main(): Promise<number> {
1014
1012
  }
1015
1013
 
1016
1014
  // Phase 7: PostToolUseFailure: release claim on failed Edit (the file
1017
- // never landed; the claim is stale). Harness-agnostic.
1015
+ // never landed; the claim is stale). Adapter-agnostic.
1018
1016
  if (norm.event_type === "tool.post_use_failure") {
1019
1017
  try {
1020
1018
  releaseClaimOnFailure(coordRoot, owner.instance_id, data, payload?.raw);
@@ -1031,7 +1029,7 @@ async function runPreToolUseGuard(
1031
1029
  instanceId: string,
1032
1030
  sessionId: string,
1033
1031
  data: Record<string, unknown>,
1034
- harness: Harness,
1032
+ adapter: Adapter,
1035
1033
  ): Promise<void> {
1036
1034
  const toolName = (data.tool_name as string | undefined) ?? "";
1037
1035
  const targets = collectGuardTargets(toolName, data)
@@ -1075,8 +1073,8 @@ async function runPreToolUseGuard(
1075
1073
  reason += ` The patch also touched: ${siblings}: pick a different file or wait.`;
1076
1074
  }
1077
1075
  }
1078
- const { emitDeny } = await import("./harness/output.ts");
1079
- emitDeny(harness, reason);
1076
+ const { emitDeny } = await import("./adapter/output.ts");
1077
+ emitDeny(adapter, reason);
1080
1078
  return;
1081
1079
  }
1082
1080
  }
@@ -1142,15 +1140,15 @@ function healHeartbeatViaCli(
1142
1140
  coordRoot: string,
1143
1141
  instanceId: string,
1144
1142
  sessionId: string,
1145
- harness: string,
1143
+ adapter: string,
1146
1144
  ): void {
1147
1145
  const agentCoordBin = join(coordRoot, "harnery", "bin", "agent-coord");
1148
1146
  if (!existsSync(agentCoordBin)) return;
1149
- // Pass the detected harness so a pruned Cursor/Codex heartbeat is recreated
1147
+ // Pass the detected adapter so a pruned Cursor/Codex heartbeat is recreated
1150
1148
  // with the correct platform; without it, healHeartbeat defaults to
1151
1149
  // claude_code and the dashboard mislabels the agent. See
1152
1150
  // heartbeat-writer.healHeartbeat.
1153
- spawnSync(agentCoordBin, ["heal-heartbeat", instanceId, sessionId, `--harness=${harness}`], {
1151
+ spawnSync(agentCoordBin, ["heal-heartbeat", instanceId, sessionId, `--adapter=${adapter}`], {
1154
1152
  encoding: "utf8",
1155
1153
  timeout: 2000,
1156
1154
  env: childEnv(coordRoot),
@@ -1158,38 +1156,59 @@ function healHeartbeatViaCli(
1158
1156
  }
1159
1157
 
1160
1158
  /**
1161
- * Walk up the ppid chain on Linux/WSL looking for the harness anchor PID,
1159
+ * Walk up the ppid chain on Linux/WSL looking for the adapter anchor PID,
1162
1160
  * the PID of the claude / cursor / codex binary. Finds the agent PID. Used by
1163
- * `tool.pre_use`'s pid-map self-heal so a re-parented harness binary (the
1161
+ * `tool.pre_use`'s pid-map self-heal so a re-parented adapter binary (the
1164
1162
  * VS Code 2.1.x sibling-claude spawn case) gets its pid-map row rewritten on
1165
1163
  * the next tool call rather than going invisible until SessionStart fires
1166
1164
  * again, which it may never do.
1167
1165
  *
1168
1166
  * Returns undefined only when no anchor is found; callers fall back to
1169
- * `process.ppid` (the bash wrapper's parent, which is usually the harness binary
1167
+ * `process.ppid` (the bash wrapper's parent, which is usually the adapter binary
1170
1168
  * itself). `HARNERY_AGENT_COORD_TEST_ANCHOR_PID` overrides everything so the
1171
1169
  * test sandbox can pin a deterministic PID.
1172
1170
  */
1173
- function findHarnessAnchorPid(harness?: Harness): number | undefined {
1171
+ function findAdapterAnchorPid(adapter?: Adapter): number | undefined {
1174
1172
  const override = coordEnv("AGENT_COORD_TEST_ANCHOR_PID");
1175
1173
  if (override) {
1176
1174
  const n = Number(override);
1177
1175
  if (Number.isFinite(n) && n > 0) return n;
1178
1176
  }
1177
+ // A adapter that states its own pid ends the search. Nothing inferred from the
1178
+ // process tree beats the adapter naming itself, and the inference is the part
1179
+ // that has been failing: comm matching wants a binary called after its
1180
+ // adapter, and one Claude Code build ships its CLI under a version-numbered
1181
+ // filename, so the walk found nothing and the caller fell back to the hook's
1182
+ // own shell. That row was dead within seconds, leaving every session in this
1183
+ // environment unattributed.
1184
+ const fromEnv = adapterPidFromEnv();
1185
+ if (fromEnv) return fromEnv;
1179
1186
  // Build the ppid chain (nearest → root, up to 20 hops), then hand it to the
1180
1187
  // pure selector. Linux/WSL reads /proc; macOS/BSD (no /proc) falls back to
1181
1188
  // `ps -o ppid=,comm=` parsed by the unit-tested `parsePsChainLine`. Splitting
1182
- // the walk (untestable off a live box) from the comm-matching keeps the
1183
- // cursor `node`-fallback logic verifiable.
1184
- const chain: Array<{ pid: number; comm: string }> = [];
1189
+ // the walk (untestable off a live box) from the matching keeps the selector
1190
+ // logic verifiable.
1191
+ //
1192
+ // Only the /proc branch carries an executable path for the selector's
1193
+ // path-based pass. Asking `ps` for one means either a second spawn per hop or
1194
+ // splitting `comm` from `args` on a line where comm may itself contain spaces,
1195
+ // and the adapter that needs the path pass states its pid in the env anyway.
1196
+ const chain: Array<{ pid: number; comm: string; exe?: string }> = [];
1185
1197
  let pid = process.pid;
1186
1198
  for (let hops = 0; hops < 20; hops++) {
1187
- let hop: { comm: string; ppid: number } | null = null;
1199
+ let hop: { comm: string; ppid: number; exe?: string } | null = null;
1188
1200
  try {
1189
1201
  const comm = readFileSync(`/proc/${pid}/comm`, "utf8").trim();
1190
1202
  const status = readFileSync(`/proc/${pid}/status`, "utf8");
1191
1203
  const m = status.match(/^PPid:\s+(\d+)/m);
1192
- hop = { comm, ppid: m ? Number(m[1]) : 0 };
1204
+ // argv[0], for the path-based second pass. cmdline is NUL-separated.
1205
+ let exe: string | undefined;
1206
+ try {
1207
+ exe = readFileSync(`/proc/${pid}/cmdline`, "utf8").split("\0")[0] || undefined;
1208
+ } catch {
1209
+ /* exe is optional */
1210
+ }
1211
+ hop = { comm, ppid: m ? Number(m[1]) : 0, exe };
1193
1212
  } catch {
1194
1213
  // no /proc (macOS/BSD) — fall through to ps
1195
1214
  }
@@ -1198,11 +1217,11 @@ function findHarnessAnchorPid(harness?: Harness): number | undefined {
1198
1217
  if (out.status === 0) hop = parsePsChainLine(out.stdout);
1199
1218
  }
1200
1219
  if (!hop) break;
1201
- chain.push({ pid, comm: hop.comm });
1220
+ chain.push({ pid, comm: hop.comm, exe: hop.exe });
1202
1221
  if (!Number.isFinite(hop.ppid) || hop.ppid === 0 || hop.ppid === 1) break;
1203
1222
  pid = hop.ppid;
1204
1223
  }
1205
- return selectAnchorPid(chain, harness);
1224
+ return selectAnchorPid(chain, adapter);
1206
1225
  }
1207
1226
 
1208
1227
  /**
@@ -1212,7 +1231,7 @@ function findHarnessAnchorPid(harness?: Harness): number | undefined {
1212
1231
  *
1213
1232
  * The pid argument prefers the payload's `pid` (CC populates it on
1214
1233
  * SessionStart and may also send it on PreToolUse), then
1215
- * `findHarnessAnchorPid`, then `process.ppid`. Writes go through the same
1234
+ * `findAdapterAnchorPid`, then `process.ppid`. Writes go through the same
1216
1235
  * idempotent `writePidmapViaAgentCoord` helper that SessionStart uses: no
1217
1236
  * disk I/O on no-op heals (when the row already points at us).
1218
1237
  *
@@ -1223,12 +1242,12 @@ function findHarnessAnchorPid(harness?: Harness): number | undefined {
1223
1242
  function refreshPidmap(
1224
1243
  coordRoot: string,
1225
1244
  instanceId: string,
1226
- harness: Harness,
1245
+ adapter: Adapter,
1227
1246
  payloadPid?: number,
1228
1247
  ): void {
1229
- const pid = payloadPid ?? findHarnessAnchorPid(harness) ?? process.ppid;
1248
+ const pid = payloadPid ?? findAdapterAnchorPid(adapter) ?? process.ppid;
1230
1249
  if (!Number.isFinite(pid) || pid <= 0) return;
1231
- writePidmapViaAgentCoord(coordRoot, pid, instanceId, harnessPlatform(harness));
1250
+ writePidmapViaAgentCoord(coordRoot, pid, instanceId, adapterPlatform(adapter));
1232
1251
  }
1233
1252
 
1234
1253
  function stampToolActivity(
@@ -1363,7 +1382,7 @@ async function emitUserPromptSubmitSystemMessage(
1363
1382
  coordRoot: string,
1364
1383
  instanceId: string,
1365
1384
  sessionId: string,
1366
- harness: Harness,
1385
+ adapter: Adapter,
1367
1386
  recoveryBriefing = "",
1368
1387
  ): Promise<boolean> {
1369
1388
  const agentCoordBin = join(coordRoot, "harnery", "bin", "agent-coord");
@@ -1385,10 +1404,14 @@ async function emitUserPromptSubmitSystemMessage(
1385
1404
 
1386
1405
  const args = ["prompt-context", "--instance", instanceId, "--session", sessionId];
1387
1406
  if (agentName) args.push("--name", agentName);
1388
- // Cursor + Codex sessions get the set-task staleness nudge. CC enforces it
1389
- // via the Stop-hook transcript scan; the nudge replaces that for harnesses
1390
- // that don't reliably expose a transcript_path during stop.
1391
- if (harness === "cursor" || harness === "codex") args.push("--task-nudge");
1407
+ // Every human-facing adapter gets the first-session naming reminder from
1408
+ // the shared hook path. Cursor + Codex additionally get ongoing set-task
1409
+ // staleness nudges; Claude Code enforces those via its Stop transcript.
1410
+ // Codex gets a fresh status-footer reminder on every prompt. Its Stop hook
1411
+ // stays observe-only, so missing the footer never replaces the answer.
1412
+ args.push("--session-name-nudge");
1413
+ if (adapter === "cursor" || adapter === "codex") args.push("--task-nudge");
1414
+ if (adapter === "codex") args.push("--status-footer-nudge");
1392
1415
  const result = spawnSync(agentCoordBin, args, { encoding: "utf8", timeout: 3000 });
1393
1416
  if (result.status === 0 && result.stdout) additionalContext = result.stdout.trim();
1394
1417
  }
@@ -1397,8 +1420,8 @@ async function emitUserPromptSubmitSystemMessage(
1397
1420
  }
1398
1421
  if (!additionalContext) return false;
1399
1422
 
1400
- const { emitContext } = await import("./harness/output.ts");
1401
- emitContext(harness, "UserPromptSubmit", additionalContext);
1423
+ const { emitContext } = await import("./adapter/output.ts");
1424
+ emitContext(adapter, "UserPromptSubmit", additionalContext);
1402
1425
  return true;
1403
1426
  }
1404
1427
 
@@ -1407,14 +1430,14 @@ function emitSubagentStartContext(
1407
1430
  instanceId: string,
1408
1431
  sessionId: string,
1409
1432
  data: Record<string, unknown>,
1410
- harness: Harness,
1433
+ adapter: Adapter,
1411
1434
  ): void {
1412
1435
  // Look up the subagent's assigned name (just-written by agent-coord assignName
1413
1436
  // in session.start data) + the parent's short id for the "you are a subagent
1414
1437
  // of X" framing.
1415
1438
  const subagentName = (data.name as string | undefined) ?? "";
1416
1439
  if (!subagentName) return;
1417
- const platformLabel = harnessPlatform(harness);
1440
+ const platformLabel = adapterPlatform(adapter);
1418
1441
  const parentShort =
1419
1442
  sessionId && sessionId !== instanceId ? `agent-${sessionId.slice(0, 8)}` : "the parent session";
1420
1443
  const message = `You are agent-${subagentName} (${platformLabel} subagent). You're a subagent of ${parentShort}.`;
@@ -1436,14 +1459,14 @@ function emitSubagentStartContext(
1436
1459
 
1437
1460
  // Use SubagentStart event-name in CC's hookSpecificOutput shape; cursor's
1438
1461
  // flat `additional_context` works the same way.
1439
- void import("./harness/output.ts").then(({ emitContext }) => {
1440
- emitContext(harness, "SubagentStart", combined);
1462
+ void import("./adapter/output.ts").then(({ emitContext }) => {
1463
+ emitContext(adapter, "SubagentStart", combined);
1441
1464
  });
1442
1465
  }
1443
1466
 
1444
- function harnessPlatform(harness: Harness): string {
1445
- if (harness === "claude-code") return "claude_code";
1446
- return harness;
1467
+ function adapterPlatform(adapter: Adapter): string {
1468
+ if (adapter === "claude-code") return "claude_code";
1469
+ return adapter;
1447
1470
  }
1448
1471
 
1449
1472
  async function emitSessionStartSystemMessage(
@@ -1451,7 +1474,7 @@ async function emitSessionStartSystemMessage(
1451
1474
  instanceId: string,
1452
1475
  sessionId: string,
1453
1476
  emittedData: Record<string, unknown>,
1454
- harness: Harness,
1477
+ adapter: Adapter,
1455
1478
  recoveryBriefing = "",
1456
1479
  ): Promise<boolean> {
1457
1480
  const agentCoordBin = join(coordRoot, "harnery", "bin", "agent-coord");
@@ -1463,10 +1486,10 @@ async function emitSessionStartSystemMessage(
1463
1486
  // Stale-sweep dead peers before rendering peer table.
1464
1487
  spawnSync(agentCoordBin, ["stale-sweep"], { encoding: "utf8", timeout: 3000 });
1465
1488
 
1466
- // SESSION_START activity log line, fired across all harnesses.
1489
+ // SESSION_START activity log line, fired across all adapters.
1467
1490
  const model = (emittedData.model as string | undefined) ?? "unknown";
1468
1491
  const source = (emittedData.source as string | undefined) ?? "startup";
1469
- const platform = harnessPlatform(harness);
1492
+ const platform = adapterPlatform(adapter);
1470
1493
  spawnSync(
1471
1494
  agentCoordBin,
1472
1495
  [
@@ -1485,19 +1508,19 @@ async function emitSessionStartSystemMessage(
1485
1508
  // The "You are agent-X." prefix in session-context renders unqualified by
1486
1509
  // default (claude-code-style). For cursor/codex the bash dispatchers add
1487
1510
  // a "(Cursor)" / "(Codex)" suffix; pass it through as --platform-label.
1488
- if (harness !== "claude-code") {
1511
+ if (adapter !== "claude-code") {
1489
1512
  args.push("--platform-label", platform === "cursor" ? "Cursor" : "Codex");
1490
1513
  }
1491
1514
  const result = spawnSync(agentCoordBin, args, { encoding: "utf8", timeout: 3000 });
1492
1515
  if (result.status === 0 && result.stdout) additionalContext = result.stdout.trim();
1493
1516
  }
1494
1517
 
1495
- // Effect (claude-code): merge the scratch recovery cue into the session-start
1518
+ // Effect (claude-code): merge the journal recovery cue into the session-start
1496
1519
  // context. Was a standalone additionalContext emission from the previous
1497
- // scratch-on-start adapter; now that agent-hook is the single SessionStart
1520
+ // journal-on-start adapter; now that agent-hook is the single SessionStart
1498
1521
  // entry, it folds in here.
1499
- if (harness === "claude-code") {
1500
- const cue = scratchRecoveryCue(coordRoot);
1522
+ if (adapter === "claude-code") {
1523
+ const cue = journalRecoveryCue(coordRoot);
1501
1524
  if (cue) additionalContext = [additionalContext, cue].filter(Boolean).join("\n\n");
1502
1525
  }
1503
1526
  if (recoveryBriefing) {
@@ -1505,8 +1528,8 @@ async function emitSessionStartSystemMessage(
1505
1528
  }
1506
1529
  if (!additionalContext) return false;
1507
1530
 
1508
- const { emitContext } = await import("./harness/output.ts");
1509
- emitContext(harness, "SessionStart", additionalContext);
1531
+ const { emitContext } = await import("./adapter/output.ts");
1532
+ emitContext(adapter, "SessionStart", additionalContext);
1510
1533
  return true;
1511
1534
  }
1512
1535
 
@@ -1514,7 +1537,7 @@ function completeRecoveryInjection(
1514
1537
  coordRoot: string,
1515
1538
  instanceId: string,
1516
1539
  sessionId: string,
1517
- harness: Harness,
1540
+ adapter: Adapter,
1518
1541
  recovery: PreparedContextRecovery,
1519
1542
  injectionEvent: "SessionStart" | "UserPromptSubmit",
1520
1543
  ): void {
@@ -1523,7 +1546,7 @@ function completeRecoveryInjection(
1523
1546
  event_type: "context.recovery.injected",
1524
1547
  instance_id: instanceId,
1525
1548
  session_id: sessionId,
1526
- harness,
1549
+ adapter,
1527
1550
  data: {
1528
1551
  capsule_id: recovery.capsule.capsule_id,
1529
1552
  generation: recovery.capsule.generation,