@kya-os/cli 1.8.1 → 1.8.3

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 (385) hide show
  1. package/dist/commands/agent.d.ts +35 -0
  2. package/dist/commands/agent.d.ts.map +1 -0
  3. package/dist/commands/agent.js +321 -0
  4. package/dist/commands/agent.js.map +1 -0
  5. package/dist/commands/build.js +2 -2
  6. package/dist/commands/build.js.map +1 -1
  7. package/dist/commands/check.js +3 -3
  8. package/dist/commands/check.js.map +1 -1
  9. package/dist/commands/checkpoint-init.d.ts +1 -1
  10. package/dist/commands/checkpoint-init.d.ts.map +1 -1
  11. package/dist/commands/checkpoint-init.js +8 -41
  12. package/dist/commands/checkpoint-init.js.map +1 -1
  13. package/dist/commands/claim.js +2 -2
  14. package/dist/commands/claim.js.map +1 -1
  15. package/dist/commands/dco.d.ts +59 -0
  16. package/dist/commands/dco.d.ts.map +1 -1
  17. package/dist/commands/dco.js +280 -5
  18. package/dist/commands/dco.js.map +1 -1
  19. package/dist/commands/dev.js +1 -1
  20. package/dist/commands/dev.js.map +1 -1
  21. package/dist/commands/doctor.d.ts.map +1 -1
  22. package/dist/commands/doctor.js +18 -24
  23. package/dist/commands/doctor.js.map +1 -1
  24. package/dist/commands/env.js +6 -6
  25. package/dist/commands/env.js.map +1 -1
  26. package/dist/commands/identity.js +3 -3
  27. package/dist/commands/identity.js.map +1 -1
  28. package/dist/commands/init-stages.d.ts +141 -0
  29. package/dist/commands/init-stages.d.ts.map +1 -0
  30. package/dist/commands/init-stages.js +684 -0
  31. package/dist/commands/init-stages.js.map +1 -0
  32. package/dist/commands/init.d.ts +46 -16
  33. package/dist/commands/init.d.ts.map +1 -1
  34. package/dist/commands/init.js +229 -279
  35. package/dist/commands/init.js.map +1 -1
  36. package/dist/commands/orchestrator.d.ts +18 -0
  37. package/dist/commands/orchestrator.d.ts.map +1 -0
  38. package/dist/commands/orchestrator.js +251 -0
  39. package/dist/commands/orchestrator.js.map +1 -0
  40. package/dist/commands/register.d.ts +1 -1
  41. package/dist/commands/register.d.ts.map +1 -1
  42. package/dist/commands/register.js +35 -7
  43. package/dist/commands/register.js.map +1 -1
  44. package/dist/commands/review.d.ts +48 -0
  45. package/dist/commands/review.d.ts.map +1 -0
  46. package/dist/commands/review.js +220 -0
  47. package/dist/commands/review.js.map +1 -0
  48. package/dist/commands/rotate.js +4 -4
  49. package/dist/commands/rotate.js.map +1 -1
  50. package/dist/commands/score.d.ts +15 -0
  51. package/dist/commands/score.d.ts.map +1 -0
  52. package/dist/commands/score.js +471 -0
  53. package/dist/commands/score.js.map +1 -0
  54. package/dist/commands/start.js +3 -3
  55. package/dist/commands/start.js.map +1 -1
  56. package/dist/commands/status.js +1 -1
  57. package/dist/commands/status.js.map +1 -1
  58. package/dist/commands/verify.js +6 -6
  59. package/dist/commands/verify.js.map +1 -1
  60. package/dist/dco.d.ts +4 -0
  61. package/dist/dco.d.ts.map +1 -0
  62. package/dist/dco.js +23 -0
  63. package/dist/dco.js.map +1 -0
  64. package/dist/index.js +52 -9
  65. package/dist/orchestrator/daemon.d.ts +137 -0
  66. package/dist/orchestrator/daemon.d.ts.map +1 -0
  67. package/dist/orchestrator/daemon.js +242 -0
  68. package/dist/orchestrator/daemon.js.map +1 -0
  69. package/dist/orchestrator/db/dispatches.d.ts +108 -0
  70. package/dist/orchestrator/db/dispatches.d.ts.map +1 -0
  71. package/dist/orchestrator/db/dispatches.js +122 -0
  72. package/dist/orchestrator/db/dispatches.js.map +1 -0
  73. package/dist/orchestrator/db/index.d.ts +50 -0
  74. package/dist/orchestrator/db/index.d.ts.map +1 -0
  75. package/dist/orchestrator/db/index.js +116 -0
  76. package/dist/orchestrator/db/index.js.map +1 -0
  77. package/dist/orchestrator/db/journal.d.ts +93 -0
  78. package/dist/orchestrator/db/journal.d.ts.map +1 -0
  79. package/dist/orchestrator/db/journal.js +91 -0
  80. package/dist/orchestrator/db/journal.js.map +1 -0
  81. package/dist/orchestrator/db/liveness.d.ts +97 -0
  82. package/dist/orchestrator/db/liveness.d.ts.map +1 -0
  83. package/dist/orchestrator/db/liveness.js +105 -0
  84. package/dist/orchestrator/db/liveness.js.map +1 -0
  85. package/dist/orchestrator/db/mission.d.ts +78 -0
  86. package/dist/orchestrator/db/mission.d.ts.map +1 -0
  87. package/dist/orchestrator/db/mission.js +99 -0
  88. package/dist/orchestrator/db/mission.js.map +1 -0
  89. package/dist/orchestrator/db/schema.d.ts +14 -0
  90. package/dist/orchestrator/db/schema.d.ts.map +1 -0
  91. package/dist/orchestrator/db/schema.js +169 -0
  92. package/dist/orchestrator/db/schema.js.map +1 -0
  93. package/dist/orchestrator/db/tickets.d.ts +147 -0
  94. package/dist/orchestrator/db/tickets.d.ts.map +1 -0
  95. package/dist/orchestrator/db/tickets.js +238 -0
  96. package/dist/orchestrator/db/tickets.js.map +1 -0
  97. package/dist/orchestrator/db/verdicts.d.ts +187 -0
  98. package/dist/orchestrator/db/verdicts.d.ts.map +1 -0
  99. package/dist/orchestrator/db/verdicts.js +197 -0
  100. package/dist/orchestrator/db/verdicts.js.map +1 -0
  101. package/dist/orchestrator/events.d.ts +69 -0
  102. package/dist/orchestrator/events.d.ts.map +1 -0
  103. package/dist/orchestrator/events.js +20 -0
  104. package/dist/orchestrator/events.js.map +1 -0
  105. package/dist/orchestrator/github-credential-anchor-sender.d.ts +159 -0
  106. package/dist/orchestrator/github-credential-anchor-sender.d.ts.map +1 -0
  107. package/dist/orchestrator/github-credential-anchor-sender.js +313 -0
  108. package/dist/orchestrator/github-credential-anchor-sender.js.map +1 -0
  109. package/dist/orchestrator/hub-dispatch.d.ts +120 -0
  110. package/dist/orchestrator/hub-dispatch.d.ts.map +1 -0
  111. package/dist/orchestrator/hub-dispatch.js +257 -0
  112. package/dist/orchestrator/hub-dispatch.js.map +1 -0
  113. package/dist/orchestrator/hub-observer.d.ts +201 -0
  114. package/dist/orchestrator/hub-observer.d.ts.map +1 -0
  115. package/dist/orchestrator/hub-observer.js +474 -0
  116. package/dist/orchestrator/hub-observer.js.map +1 -0
  117. package/dist/orchestrator/journal-writer.d.ts +80 -0
  118. package/dist/orchestrator/journal-writer.d.ts.map +1 -0
  119. package/dist/orchestrator/journal-writer.js +113 -0
  120. package/dist/orchestrator/journal-writer.js.map +1 -0
  121. package/dist/orchestrator/mcp/server.d.ts +136 -0
  122. package/dist/orchestrator/mcp/server.d.ts.map +1 -0
  123. package/dist/orchestrator/mcp/server.js +582 -0
  124. package/dist/orchestrator/mcp/server.js.map +1 -0
  125. package/dist/orchestrator/mcp/stdio.d.ts +22 -0
  126. package/dist/orchestrator/mcp/stdio.d.ts.map +1 -0
  127. package/dist/orchestrator/mcp/stdio.js +51 -0
  128. package/dist/orchestrator/mcp/stdio.js.map +1 -0
  129. package/dist/orchestrator/review.d.ts +131 -0
  130. package/dist/orchestrator/review.d.ts.map +1 -0
  131. package/dist/orchestrator/review.js +322 -0
  132. package/dist/orchestrator/review.js.map +1 -0
  133. package/dist/tui/app.d.ts +33 -0
  134. package/dist/tui/app.d.ts.map +1 -0
  135. package/dist/tui/app.js +71 -0
  136. package/dist/tui/app.js.map +1 -0
  137. package/dist/tui/components.d.ts +110 -0
  138. package/dist/tui/components.d.ts.map +1 -0
  139. package/dist/tui/components.js +118 -0
  140. package/dist/tui/components.js.map +1 -0
  141. package/dist/tui/index.d.ts +30 -0
  142. package/dist/tui/index.d.ts.map +1 -0
  143. package/dist/tui/index.js +95 -0
  144. package/dist/tui/index.js.map +1 -0
  145. package/dist/tui/keymap.d.ts +33 -0
  146. package/dist/tui/keymap.d.ts.map +1 -0
  147. package/dist/tui/keymap.js +49 -0
  148. package/dist/tui/keymap.js.map +1 -0
  149. package/dist/tui/nav.d.ts +29 -0
  150. package/dist/tui/nav.d.ts.map +1 -0
  151. package/dist/tui/nav.js +39 -0
  152. package/dist/tui/nav.js.map +1 -0
  153. package/dist/tui/sanitize.d.ts +25 -0
  154. package/dist/tui/sanitize.d.ts.map +1 -0
  155. package/dist/tui/sanitize.js +36 -0
  156. package/dist/tui/sanitize.js.map +1 -0
  157. package/dist/tui/theme.d.ts +32 -0
  158. package/dist/tui/theme.d.ts.map +1 -0
  159. package/dist/tui/theme.js +63 -0
  160. package/dist/tui/theme.js.map +1 -0
  161. package/dist/tui/views/agents.d.ts +67 -0
  162. package/dist/tui/views/agents.d.ts.map +1 -0
  163. package/dist/tui/views/agents.js +231 -0
  164. package/dist/tui/views/agents.js.map +1 -0
  165. package/dist/tui/views/index.d.ts +93 -0
  166. package/dist/tui/views/index.d.ts.map +1 -0
  167. package/dist/tui/views/index.js +150 -0
  168. package/dist/tui/views/index.js.map +1 -0
  169. package/dist/tui/views/registry.d.ts +22 -0
  170. package/dist/tui/views/registry.d.ts.map +1 -0
  171. package/dist/tui/views/registry.js +110 -0
  172. package/dist/tui/views/registry.js.map +1 -0
  173. package/dist/utils/agent/backoff.d.ts +31 -0
  174. package/dist/utils/agent/backoff.d.ts.map +1 -0
  175. package/dist/utils/agent/backoff.js +51 -0
  176. package/dist/utils/agent/backoff.js.map +1 -0
  177. package/dist/utils/agent/markers.d.ts +87 -0
  178. package/dist/utils/agent/markers.d.ts.map +1 -0
  179. package/dist/utils/agent/markers.js +147 -0
  180. package/dist/utils/agent/markers.js.map +1 -0
  181. package/dist/utils/agent/review.d.ts +67 -0
  182. package/dist/utils/agent/review.d.ts.map +1 -0
  183. package/dist/utils/agent/review.js +305 -0
  184. package/dist/utils/agent/review.js.map +1 -0
  185. package/dist/utils/agent/spawn-agent.d.ts +117 -0
  186. package/dist/utils/agent/spawn-agent.d.ts.map +1 -0
  187. package/dist/utils/agent/spawn-agent.js +177 -0
  188. package/dist/utils/agent/spawn-agent.js.map +1 -0
  189. package/dist/utils/agent/task.d.ts +101 -0
  190. package/dist/utils/agent/task.d.ts.map +1 -0
  191. package/dist/utils/agent/task.js +357 -0
  192. package/dist/utils/agent/task.js.map +1 -0
  193. package/dist/utils/agent/verify.d.ts +47 -0
  194. package/dist/utils/agent/verify.d.ts.map +1 -0
  195. package/dist/utils/agent/verify.js +144 -0
  196. package/dist/utils/agent/verify.js.map +1 -0
  197. package/dist/utils/agent-detector.d.ts +48 -0
  198. package/dist/utils/agent-detector.d.ts.map +1 -0
  199. package/dist/utils/agent-detector.js +74 -0
  200. package/dist/utils/agent-detector.js.map +1 -0
  201. package/dist/utils/agent-profile-stage.d.ts +70 -0
  202. package/dist/utils/agent-profile-stage.d.ts.map +1 -0
  203. package/dist/utils/agent-profile-stage.js +153 -0
  204. package/dist/utils/agent-profile-stage.js.map +1 -0
  205. package/dist/utils/agent-profiles.d.ts +27 -0
  206. package/dist/utils/agent-profiles.d.ts.map +1 -0
  207. package/dist/utils/agent-profiles.js +61 -0
  208. package/dist/utils/agent-profiles.js.map +1 -0
  209. package/dist/utils/checkpoint-api.d.ts +1 -1
  210. package/dist/utils/checkpoint-api.js +1 -1
  211. package/dist/utils/checkpoint-env.d.ts +1 -1
  212. package/dist/utils/checkpoint-env.js +2 -2
  213. package/dist/utils/checkpoint-env.js.map +1 -1
  214. package/dist/utils/checkpoint-scaffold.d.ts +1 -1
  215. package/dist/utils/checkpoint-scaffold.js +1 -1
  216. package/dist/utils/cli-kit/browser.d.ts +24 -0
  217. package/dist/utils/cli-kit/browser.d.ts.map +1 -0
  218. package/dist/utils/cli-kit/browser.js +58 -0
  219. package/dist/utils/cli-kit/browser.js.map +1 -0
  220. package/dist/utils/cli-kit/claim-polling.d.ts +18 -0
  221. package/dist/utils/cli-kit/claim-polling.d.ts.map +1 -0
  222. package/dist/utils/{claim-polling.js → cli-kit/claim-polling.js} +19 -26
  223. package/dist/utils/cli-kit/claim-polling.js.map +1 -0
  224. package/dist/utils/cli-kit/diagnostics.d.ts +9 -0
  225. package/dist/utils/cli-kit/diagnostics.d.ts.map +1 -0
  226. package/dist/utils/cli-kit/diagnostics.js +11 -0
  227. package/dist/utils/cli-kit/diagnostics.js.map +1 -0
  228. package/dist/utils/cli-kit/fs-safe.d.ts +14 -0
  229. package/dist/utils/cli-kit/fs-safe.d.ts.map +1 -0
  230. package/dist/utils/cli-kit/fs-safe.js +20 -0
  231. package/dist/utils/cli-kit/fs-safe.js.map +1 -0
  232. package/dist/utils/cli-kit/index.d.ts +15 -0
  233. package/dist/utils/cli-kit/index.d.ts.map +1 -0
  234. package/dist/utils/cli-kit/index.js +10 -0
  235. package/dist/utils/cli-kit/index.js.map +1 -0
  236. package/dist/utils/cli-kit/json-file.d.ts +21 -0
  237. package/dist/utils/cli-kit/json-file.d.ts.map +1 -0
  238. package/dist/utils/cli-kit/json-file.js +51 -0
  239. package/dist/utils/cli-kit/json-file.js.map +1 -0
  240. package/dist/utils/cli-kit/marker-block.d.ts +26 -0
  241. package/dist/utils/cli-kit/marker-block.d.ts.map +1 -0
  242. package/dist/utils/cli-kit/marker-block.js +61 -0
  243. package/dist/utils/cli-kit/marker-block.js.map +1 -0
  244. package/dist/utils/cli-kit/paths.d.ts +15 -0
  245. package/dist/utils/cli-kit/paths.d.ts.map +1 -0
  246. package/dist/utils/cli-kit/paths.js +21 -0
  247. package/dist/utils/cli-kit/paths.js.map +1 -0
  248. package/dist/utils/cli-kit/secure-storage.d.ts +14 -0
  249. package/dist/utils/cli-kit/secure-storage.d.ts.map +1 -0
  250. package/dist/utils/cli-kit/secure-storage.js +20 -0
  251. package/dist/utils/cli-kit/secure-storage.js.map +1 -0
  252. package/dist/utils/cli-kit/step-report.d.ts +16 -0
  253. package/dist/utils/cli-kit/step-report.d.ts.map +1 -0
  254. package/dist/utils/cli-kit/step-report.js +36 -0
  255. package/dist/utils/cli-kit/step-report.js.map +1 -0
  256. package/dist/utils/dco/agent-metadata.d.ts +1 -1
  257. package/dist/utils/dco/agent-metadata.js +1 -1
  258. package/dist/utils/dco/agent-metadata.js.map +1 -1
  259. package/dist/utils/dco/claude-config.d.ts +18 -14
  260. package/dist/utils/dco/claude-config.d.ts.map +1 -1
  261. package/dist/utils/dco/claude-config.js +31 -97
  262. package/dist/utils/dco/claude-config.js.map +1 -1
  263. package/dist/utils/dco/dispatch.d.ts +134 -0
  264. package/dist/utils/dco/dispatch.d.ts.map +1 -0
  265. package/dist/utils/dco/dispatch.js +399 -0
  266. package/dist/utils/dco/dispatch.js.map +1 -0
  267. package/dist/utils/dco/fix.d.ts +122 -0
  268. package/dist/utils/dco/fix.d.ts.map +1 -0
  269. package/dist/utils/dco/fix.js +560 -0
  270. package/dist/utils/dco/fix.js.map +1 -0
  271. package/dist/utils/dco/git-config.d.ts.map +1 -1
  272. package/dist/utils/dco/git-config.js +5 -3
  273. package/dist/utils/dco/git-config.js.map +1 -1
  274. package/dist/utils/dco/github.d.ts +101 -0
  275. package/dist/utils/dco/github.d.ts.map +1 -1
  276. package/dist/utils/dco/github.js +133 -0
  277. package/dist/utils/dco/github.js.map +1 -1
  278. package/dist/utils/dco/paths.d.ts +1 -8
  279. package/dist/utils/dco/paths.d.ts.map +1 -1
  280. package/dist/utils/dco/paths.js +3 -12
  281. package/dist/utils/dco/paths.js.map +1 -1
  282. package/dist/utils/dco/render.d.ts +1 -1
  283. package/dist/utils/dco/render.d.ts.map +1 -1
  284. package/dist/utils/dco/render.js +4 -21
  285. package/dist/utils/dco/render.js.map +1 -1
  286. package/dist/utils/dco/resolve-agent.d.ts +54 -0
  287. package/dist/utils/dco/resolve-agent.d.ts.map +1 -0
  288. package/dist/utils/dco/resolve-agent.js +164 -0
  289. package/dist/utils/dco/resolve-agent.js.map +1 -0
  290. package/dist/utils/dco/setup.d.ts +10 -7
  291. package/dist/utils/dco/setup.d.ts.map +1 -1
  292. package/dist/utils/dco/setup.js +264 -200
  293. package/dist/utils/dco/setup.js.map +1 -1
  294. package/dist/utils/dco/signing-key-writer.d.ts +40 -0
  295. package/dist/utils/dco/signing-key-writer.d.ts.map +1 -0
  296. package/dist/utils/dco/signing-key-writer.js +76 -0
  297. package/dist/utils/dco/signing-key-writer.js.map +1 -0
  298. package/dist/utils/dco/ssh-key.d.ts +50 -0
  299. package/dist/utils/dco/ssh-key.d.ts.map +1 -1
  300. package/dist/utils/dco/ssh-key.js +129 -8
  301. package/dist/utils/dco/ssh-key.js.map +1 -1
  302. package/dist/utils/dco/status.d.ts +1 -1
  303. package/dist/utils/dco/status.d.ts.map +1 -1
  304. package/dist/utils/dco/status.js +3 -3
  305. package/dist/utils/dco/status.js.map +1 -1
  306. package/dist/utils/dco/verify.d.ts +170 -0
  307. package/dist/utils/dco/verify.d.ts.map +1 -0
  308. package/dist/utils/dco/verify.js +550 -0
  309. package/dist/utils/dco/verify.js.map +1 -0
  310. package/dist/utils/dependency-installer.d.ts +37 -0
  311. package/dist/utils/dependency-installer.d.ts.map +1 -0
  312. package/dist/utils/dependency-installer.js +32 -0
  313. package/dist/utils/dependency-installer.js.map +1 -0
  314. package/dist/utils/github-credential-stage.d.ts +87 -0
  315. package/dist/utils/github-credential-stage.d.ts.map +1 -0
  316. package/dist/utils/github-credential-stage.js +168 -0
  317. package/dist/utils/github-credential-stage.js.map +1 -0
  318. package/dist/utils/github-credential.d.ts +160 -0
  319. package/dist/utils/github-credential.d.ts.map +1 -0
  320. package/dist/utils/github-credential.js +308 -0
  321. package/dist/utils/github-credential.js.map +1 -0
  322. package/dist/utils/gitignore.d.ts +17 -0
  323. package/dist/utils/gitignore.d.ts.map +1 -0
  324. package/dist/utils/gitignore.js +40 -0
  325. package/dist/utils/gitignore.js.map +1 -0
  326. package/dist/utils/hub-config.d.ts +21 -0
  327. package/dist/utils/hub-config.d.ts.map +1 -0
  328. package/dist/utils/hub-config.js +28 -0
  329. package/dist/utils/hub-config.js.map +1 -0
  330. package/dist/utils/identity-heal.d.ts +16 -0
  331. package/dist/utils/identity-heal.d.ts.map +1 -0
  332. package/dist/utils/identity-heal.js +37 -0
  333. package/dist/utils/identity-heal.js.map +1 -0
  334. package/dist/utils/init/pipeline.d.ts +74 -0
  335. package/dist/utils/init/pipeline.d.ts.map +1 -0
  336. package/dist/utils/init/pipeline.js +96 -0
  337. package/dist/utils/init/pipeline.js.map +1 -0
  338. package/dist/utils/poll.d.ts +15 -1
  339. package/dist/utils/poll.d.ts.map +1 -1
  340. package/dist/utils/poll.js +6 -3
  341. package/dist/utils/poll.js.map +1 -1
  342. package/dist/utils/register-agent-identity.d.ts +67 -0
  343. package/dist/utils/register-agent-identity.d.ts.map +1 -0
  344. package/dist/utils/register-agent-identity.js +34 -0
  345. package/dist/utils/register-agent-identity.js.map +1 -0
  346. package/dist/utils/review/did-web-key.d.ts +34 -0
  347. package/dist/utils/review/did-web-key.d.ts.map +1 -0
  348. package/dist/utils/review/did-web-key.js +104 -0
  349. package/dist/utils/review/did-web-key.js.map +1 -0
  350. package/dist/utils/review/load-registry.d.ts +33 -0
  351. package/dist/utils/review/load-registry.d.ts.map +1 -0
  352. package/dist/utils/review/load-registry.js +62 -0
  353. package/dist/utils/review/load-registry.js.map +1 -0
  354. package/dist/utils/review/verdict-verify.d.ts +43 -0
  355. package/dist/utils/review/verdict-verify.d.ts.map +1 -0
  356. package/dist/utils/review/verdict-verify.js +53 -0
  357. package/dist/utils/review/verdict-verify.js.map +1 -0
  358. package/dist/utils/review-registry-writer.d.ts +52 -0
  359. package/dist/utils/review-registry-writer.d.ts.map +1 -0
  360. package/dist/utils/review-registry-writer.js +79 -0
  361. package/dist/utils/review-registry-writer.js.map +1 -0
  362. package/dist/utils/should-install-dependency.d.ts +17 -0
  363. package/dist/utils/should-install-dependency.d.ts.map +1 -0
  364. package/dist/utils/should-install-dependency.js +25 -0
  365. package/dist/utils/should-install-dependency.js.map +1 -0
  366. package/dist/utils/tool-readiness.d.ts +57 -0
  367. package/dist/utils/tool-readiness.d.ts.map +1 -0
  368. package/dist/utils/tool-readiness.js +114 -0
  369. package/dist/utils/tool-readiness.js.map +1 -0
  370. package/dist/utils/which.d.ts +2 -0
  371. package/dist/utils/which.d.ts.map +1 -0
  372. package/dist/utils/which.js +22 -0
  373. package/dist/utils/which.js.map +1 -0
  374. package/dist/version.d.ts +15 -0
  375. package/dist/version.d.ts.map +1 -0
  376. package/dist/version.js +29 -0
  377. package/dist/version.js.map +1 -0
  378. package/package.json +19 -6
  379. package/dist/utils/claim-polling.d.ts +0 -21
  380. package/dist/utils/claim-polling.d.ts.map +0 -1
  381. package/dist/utils/claim-polling.js.map +0 -1
  382. package/dist/utils/dco/fs-safe.d.ts +0 -14
  383. package/dist/utils/dco/fs-safe.d.ts.map +0 -1
  384. package/dist/utils/dco/fs-safe.js +0 -20
  385. package/dist/utils/dco/fs-safe.js.map +0 -1
@@ -0,0 +1,474 @@
1
+ /**
2
+ * A coordination hub, observed from outside its process.
3
+ *
4
+ * This is what makes the daemon host pluggable. `OrchestratorDaemon` takes a
5
+ * structural `EventSource` -- `onEvent` plus `getRecentEvents` -- rather than the
6
+ * concrete hub, so anything that can supply those two methods can drive it. In
7
+ * process, the hub itself supplies them. Here they come over a WebSocket, which
8
+ * lets the daemon run wherever the operator already runs things and attach to
9
+ * whichever hub they already point their agents at.
10
+ *
11
+ * The CLI deliberately does not depend on @kya-os/compute: compute is PID 1 in a
12
+ * Fly worker, this is a published CLI. So the observer protocol is spoken
13
+ * directly, against the wire format in @kya-os/contracts/handshake rather than
14
+ * a copy of it. (Not `/proof`: both a `proof.ts` and a `proof/index.ts` exist
15
+ * there, and Node and tsc disagree about which one that subpath means.)
16
+ *
17
+ * ## Why connect() waits for the snapshot
18
+ *
19
+ * `getRecentEvents` is synchronous, because in-process it reads an array. Over a
20
+ * socket the history arrives in a frame, so `connect()` does not resolve until
21
+ * that frame lands. A daemon started before it arrives would reconcile against
22
+ * an empty window and silently skip the recovery a restart exists to perform --
23
+ * the failure mode is a quiet no-op, which is the kind that survives review.
24
+ *
25
+ * @module cli/orchestrator/hub-observer
26
+ */
27
+ import { readFileSync } from "node:fs";
28
+ import { createPublicKey } from "node:crypto";
29
+ import { SignJWT } from "jose";
30
+ import WebSocket from "ws";
31
+ import { DIDCOMM_POP_TYP, DIDCOMM_POP_ALG, ObserverHelloSchema, DIDCommChallengeSchema, DIDCommProofSchema, } from "@kya-os/contracts/handshake";
32
+ import { ed25519PrivateKeyFromSeed } from "../utils/dco/ssh-key.js";
33
+ import { HubEventLikeSchema } from "./events.js";
34
+ /**
35
+ * Read an identity file, returning undefined rather than throwing.
36
+ *
37
+ * A missing or malformed identity is a normal state -- the operator may not have
38
+ * run `dco setup` -- and it only matters if the hub demands authentication. The
39
+ * hub's rejection message says far more about what is wrong than a parse error
40
+ * raised here would.
41
+ */
42
+ export function readObserverIdentity(path) {
43
+ try {
44
+ const raw = JSON.parse(readFileSync(path, "utf8"));
45
+ if (typeof raw !== "object" || raw === null)
46
+ return undefined;
47
+ const rec = raw;
48
+ const did = rec["did"];
49
+ const privateKey = rec["privateKey"];
50
+ if (typeof did !== "string" || did.length === 0)
51
+ return undefined;
52
+ if (typeof privateKey !== "string" || privateKey.length === 0)
53
+ return undefined;
54
+ // Check the seed HERE, not later inside a socket handler. A corrupted
55
+ // identity is a configuration problem, and surfacing it as "no usable
56
+ // identity" beats an exception thrown from an open handler where nothing is
57
+ // waiting to catch it.
58
+ if (Buffer.from(privateKey, "base64").length !== 32)
59
+ return undefined;
60
+ return { did, privateKey };
61
+ }
62
+ catch {
63
+ return undefined;
64
+ }
65
+ }
66
+ /** The public JWK the hub needs to bind a did:key to the presented key. */
67
+ export function publicJwkFor(identity) {
68
+ const key = ed25519PrivateKeyFromSeed(Buffer.from(identity.privateKey, "base64"));
69
+ return JSON.stringify(createPublicKey(key).export({ format: "jwk" }));
70
+ }
71
+ /**
72
+ * The `observe` hello frame for an optional identity -- shared by every
73
+ * observer-wire client (this file's long-lived `HubObserver` and
74
+ * `hub-dispatch.ts`'s short-lived one-shot client), so the two cannot
75
+ * silently drift on what an anonymous vs. authenticated hello looks like.
76
+ */
77
+ export function buildObserverHello(identity) {
78
+ return ObserverHelloSchema.parse({
79
+ type: "observe",
80
+ ...(identity ? { did: identity.did, publicKey: publicJwkFor(identity) } : {}),
81
+ });
82
+ }
83
+ /** Sign the hub's challenge, per the wire format in contracts. */
84
+ export async function signChallenge(identity, nonce) {
85
+ const key = ed25519PrivateKeyFromSeed(Buffer.from(identity.privateKey, "base64"));
86
+ return new SignJWT({ nonce })
87
+ .setProtectedHeader({
88
+ alg: DIDCOMM_POP_ALG,
89
+ kid: `${identity.did}#key-1`,
90
+ typ: DIDCOMM_POP_TYP,
91
+ })
92
+ .setSubject(identity.did)
93
+ .sign(key);
94
+ }
95
+ /**
96
+ * Validate a raw `challenge` frame and, if well-formed, answer it: sign its
97
+ * nonce and build the wire `proof` frame to send back. Returns `undefined`
98
+ * for a frame that fails `DIDCommChallengeSchema` (not this caller's to
99
+ * handle -- the same "ignore, don't fail" choice both callers already made
100
+ * before this was factored out). Every caller of the observer
101
+ * `observe`/`challenge`/`proof` handshake shares this exact step -- {@link
102
+ * HubObserver}'s long-lived `connect()` and the one-shot
103
+ * `github-credential-anchor-sender.ts` -- so it lives here once rather than
104
+ * being reimplemented per caller.
105
+ */
106
+ export async function respondToObserverChallenge(identity, rawChallenge) {
107
+ const challenge = DIDCommChallengeSchema.safeParse(rawChallenge);
108
+ if (!challenge.success)
109
+ return undefined;
110
+ const jws = await signChallenge(identity, challenge.data.nonce);
111
+ return JSON.stringify(DIDCommProofSchema.parse({ type: "proof", jws }));
112
+ }
113
+ /**
114
+ * Hosts that need no transport encryption because nothing off this machine
115
+ * can reach them. Both `::1` and `[::1]` are listed because `URL#hostname`
116
+ * keeps an IPv6 literal's brackets rather than stripping them.
117
+ */
118
+ export const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
119
+ /**
120
+ * Is this an unencrypted `ws://` endpoint pointed somewhere other than this
121
+ * machine?
122
+ *
123
+ * A loopback hub genuinely does not need TLS -- nothing but this machine can
124
+ * see the socket. Anything else sends the DID, the public key, and the signed
125
+ * proof of possession over a transport anyone on the path can read; `wss://`
126
+ * is the production default for exactly this reason, and a plain `ws://` to a
127
+ * remote host is far more likely a dev config that escaped dev than a
128
+ * deliberate choice. An endpoint this cannot even parse is left alone: it
129
+ * fails at `connect()`, with a clearer error than anything said here.
130
+ */
131
+ export function isPlaintextNonLoopback(endpoint) {
132
+ let url;
133
+ try {
134
+ url = new URL(endpoint);
135
+ }
136
+ catch {
137
+ return false;
138
+ }
139
+ return url.protocol === "ws:" && !LOOPBACK_HOSTS.has(url.hostname.toLowerCase());
140
+ }
141
+ /**
142
+ * How many live events to retain between snapshots.
143
+ *
144
+ * The hub bounds its own ring; a client that did not would grow forever on a
145
+ * connection that never drops. Sized generously relative to the reconcile window
146
+ * the daemon actually reads.
147
+ */
148
+ const MAX_LIVE_HISTORY = 1000;
149
+ /** Is this object actually shaped like a {@link HubEventLike}? */
150
+ function isHubEventLike(value) {
151
+ return HubEventLikeSchema.safeParse(value).success;
152
+ }
153
+ /** How many times to retry a replayed event whose write failed, and the gap between attempts. */
154
+ const REPLAY_RETRY_ATTEMPTS = 3;
155
+ const REPLAY_RETRY_DELAY_MS = 200;
156
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
157
+ export class HubObserver {
158
+ constructor(config) {
159
+ this.handlers = [];
160
+ this.history = [];
161
+ this.closedByUs = false;
162
+ this.backoffMs = 500;
163
+ /**
164
+ * Has a handshake ever completed?
165
+ *
166
+ * Reconnecting is only right after a connection that WORKED. Retrying a first
167
+ * failure means a misconfigured or unauthorised hub is retried forever in the
168
+ * background while the caller has already been told it failed -- a daemon that
169
+ * looks alive and records nothing, which is the outcome connect() rejects to
170
+ * avoid.
171
+ */
172
+ this.hasConnected = false;
173
+ /**
174
+ * Serializes `handleFrame` across messages.
175
+ *
176
+ * `ws.on("message")` fires and forgets (`void this.handleFrame(...)`), which
177
+ * was harmless while every frame finished synchronously within one tick.
178
+ * Retrying a replay's failed write does not: it `await`s a `setTimeout`, and
179
+ * without this queue a live frame arriving during that wait ran a SECOND,
180
+ * concurrent `handleFrame` -- pushing onto `this.history` right before the
181
+ * still-in-flight snapshot handler clobbered it with `this.history = window`,
182
+ * and dispatching that live event ahead of the gap it was meant to follow
183
+ * (review finding on #686). Chaining onto this instead makes every frame
184
+ * fully finish before the next one starts, socket-wide.
185
+ */
186
+ this.frameQueue = Promise.resolve();
187
+ this.config = config;
188
+ }
189
+ /** Queue a frame behind whatever is still being processed for this socket. */
190
+ enqueueFrame(text, fail, ready) {
191
+ this.frameQueue = this.frameQueue
192
+ // One frame's rejection must not wedge every frame queued behind it: a
193
+ // `.then` chained onto an already-rejected promise never runs its
194
+ // callback, so without this, `handleFrame` would silently stop being
195
+ // called for every later frame too.
196
+ .catch(() => { })
197
+ .then(() => this.handleFrame(text, fail, ready));
198
+ }
199
+ /**
200
+ * Connect, authenticate if asked to, and resolve once the snapshot has landed.
201
+ *
202
+ * Rejects rather than retrying: a first connection that cannot authenticate is
203
+ * a configuration problem, and retrying it forever would leave a daemon that
204
+ * looks alive and records nothing. Reconnection after a WORKING connection is
205
+ * a different case and is handled silently below.
206
+ */
207
+ connect() {
208
+ return new Promise((resolve, reject) => {
209
+ const ws = new WebSocket(this.config.endpoint);
210
+ this.ws = ws;
211
+ let settled = false;
212
+ const finish = (err) => {
213
+ if (settled)
214
+ return;
215
+ settled = true;
216
+ clearTimeout(timer);
217
+ if (err)
218
+ reject(err);
219
+ else
220
+ resolve();
221
+ };
222
+ /**
223
+ * This attempt failed: report it AND drop the socket, always.
224
+ *
225
+ * These were two steps written at each call site, and one site forgot --
226
+ * a throw while answering the challenge rejected connect() and left the
227
+ * socket open. Reconnect is only scheduled from the close handler, so the
228
+ * observer then sat on a live socket with the handshake timer already
229
+ * cleared: no timeout, no retry, attached and recording nothing until the
230
+ * hub happened to hang up. Folding the close in makes the pair structural
231
+ * instead of something every future failure path has to remember.
232
+ *
233
+ * The close is NOT conditional on `settled`, because the stall is worst
234
+ * exactly when it is: a frame that fails after the handshake completed
235
+ * would otherwise leave the socket with nobody watching it at all.
236
+ */
237
+ const fail = (err) => {
238
+ finish(err);
239
+ ws.close();
240
+ };
241
+ const timer = setTimeout(() => {
242
+ fail(new Error(`hub at ${this.config.endpoint} did not complete the observer handshake in time`));
243
+ }, this.config.handshakeTimeoutMs ?? 10000);
244
+ ws.on("open", () => {
245
+ // publicJwkFor can throw on a malformed seed, and so, now, can a hello
246
+ // that fails ObserverHelloSchema. Both are unhandled-inside-an-event-
247
+ // handler otherwise: an uncaught exception, with connect() left to hang
248
+ // to its timeout and report the wrong cause.
249
+ try {
250
+ ws.send(JSON.stringify(buildObserverHello(this.config.identity)));
251
+ }
252
+ catch (err) {
253
+ fail(err instanceof Error ? err : new Error(String(err)));
254
+ }
255
+ });
256
+ ws.on("message", (raw) => {
257
+ this.enqueueFrame(raw.toString(), fail, finish);
258
+ });
259
+ ws.on("error", (err) => fail(err instanceof Error ? err : new Error(String(err))));
260
+ ws.on("close", (code, reason) => {
261
+ // Before the handshake completes, a close IS the failure: the hub rejects
262
+ // an unauthenticated or unprovable observer by closing.
263
+ finish(new Error(`hub closed the observer connection (${code}${reason.length ? `: ${reason.toString()}` : ""})`));
264
+ // Only if we had a working connection to lose.
265
+ if (this.hasConnected)
266
+ this.scheduleReconnect();
267
+ });
268
+ });
269
+ }
270
+ async handleFrame(text, fail, ready) {
271
+ let msg;
272
+ try {
273
+ const parsed = JSON.parse(text);
274
+ if (typeof parsed !== "object" || parsed === null)
275
+ return;
276
+ msg = parsed;
277
+ }
278
+ catch {
279
+ return; // a frame we cannot parse is not a frame we can act on
280
+ }
281
+ const type = msg["type"];
282
+ if (type === "challenge") {
283
+ if (!this.config.identity)
284
+ return;
285
+ try {
286
+ const frame = await respondToObserverChallenge(this.config.identity, msg);
287
+ if (frame)
288
+ this.ws?.send(frame);
289
+ }
290
+ catch (err) {
291
+ fail(err instanceof Error ? err : new Error(String(err)));
292
+ }
293
+ return;
294
+ }
295
+ if (type === "snapshot") {
296
+ const events = msg["events"];
297
+ // A hub without the event-history addition sends agents only. Treat that as
298
+ // an empty window rather than an error: the daemon still works, it simply
299
+ // cannot recover what it slept through, which is strictly better than
300
+ // refusing to start. An entry that does not match HubEventLikeSchema is
301
+ // dropped rather than cast through: "verified protocol events" ought to
302
+ // mean the shape was actually checked, not merely asserted at the type
303
+ // level over a socket nothing on the wire guarantees conforms.
304
+ const window = Array.isArray(events) ? events.filter(isHubEventLike) : [];
305
+ if (Array.isArray(events) && window.length !== events.length) {
306
+ console.error(`[orchestrator] dropped ${events.length - window.length} malformed event(s) from the hub's snapshot`);
307
+ }
308
+ // REPLACE, on a reconnect as much as a first connect. The snapshot IS the
309
+ // hub's recent ring, and in-process `getRecentEvents` returns that same
310
+ // ring -- so mirroring it is what keeps this implementation faithful to the
311
+ // one it substitutes for. Appending instead duplicated every event the ring
312
+ // still held, drifted this view away from the hub's, and grew without the
313
+ // hub's size bound on a long-lived daemon.
314
+ //
315
+ // Events the client saw live that have since aged out of the ring are
316
+ // dropped, which is correct: they have aged out of the answer the question
317
+ // is asking.
318
+ if (this.hasConnected) {
319
+ // A RECONNECT. The daemon reconciles only at boot, so events from the
320
+ // gap would otherwise sit in history and never reach the ledger. Replay
321
+ // them through the handlers exactly as if they had arrived live.
322
+ //
323
+ // Safe to replay events already seen: journal ids are content-derived
324
+ // and verdicts are keyed on (repo, pr, sha, reviewer), so a duplicate
325
+ // collapses instead of double-counting. That idempotency is precisely
326
+ // what makes recovery a replay rather than a diff.
327
+ // Dispatch BEFORE replacing, so a handler that reads getRecentEvents
328
+ // sees the window it is being told about rather than the previous one.
329
+ //
330
+ // Retried, unlike a live dispatch below: a live event that a handler
331
+ // fails to write will still sit in the hub's ring and reach this same
332
+ // replay path at the NEXT reconnect, but reconcile only runs at boot,
333
+ // so a replay failure has no later chance -- without a retry here, the
334
+ // one recovery a reconnect exists to perform becomes a logged no-op.
335
+ for (const event of window)
336
+ await this.dispatchReplayed(event);
337
+ }
338
+ this.history = window;
339
+ this.hasConnected = true;
340
+ this.backoffMs = 500; // a completed handshake resets the backoff
341
+ ready();
342
+ return;
343
+ }
344
+ // Anything else with a `type` is meant to be a hub event.
345
+ if (typeof type === "string") {
346
+ if (!isHubEventLike(msg)) {
347
+ console.error(`[orchestrator] dropped a malformed "${type}" frame from the hub`);
348
+ return;
349
+ }
350
+ this.history.push(msg);
351
+ if (this.history.length > MAX_LIVE_HISTORY) {
352
+ this.history = this.history.slice(-MAX_LIVE_HISTORY);
353
+ }
354
+ this.dispatch(msg);
355
+ }
356
+ }
357
+ /**
358
+ * Hand one event to every handler, once.
359
+ *
360
+ * Shared by live delivery and reconnect replay (through {@link
361
+ * dispatchReplayed}) so the two cannot diverge -- a replay that skipped a
362
+ * handler would recover the journal and not the ticket status, which reads
363
+ * as the reactor having run and disagreed. Returns whether every handler
364
+ * succeeded, so a caller that can retry (replay) knows whether it needs to.
365
+ *
366
+ * This is now the ONLY place a handler's failure is caught. The handlers
367
+ * themselves (`registerJournalWriter`, `registerReviewReactor`) deliberately
368
+ * do not swallow their own write errors -- a handler that always reports
369
+ * success by catching internally makes `allOk` a lie, which is what made
370
+ * `dispatchReplayed`'s retry dead code against the real handlers even though
371
+ * it worked against a mock that threw directly.
372
+ */
373
+ dispatch(event) {
374
+ let allOk = true;
375
+ for (const h of [...this.handlers]) {
376
+ try {
377
+ h(event);
378
+ }
379
+ catch (err) {
380
+ allOk = false;
381
+ // One bad handler must not cost the others their event, nor the socket.
382
+ console.error(`[orchestrator] observer handler failed on ${event.type}: ${err instanceof Error ? err.message : String(err)}`);
383
+ }
384
+ }
385
+ return allOk;
386
+ }
387
+ /**
388
+ * Dispatch one event from a reconnect's gap replay, retrying instead of
389
+ * letting a write failure disappear it.
390
+ *
391
+ * All handlers together, every attempt, not just the ones that failed: safe
392
+ * because journal ids are content-derived and verdicts are keyed on their
393
+ * subject, so re-dispatching an event a handler already wrote collapses
394
+ * rather than double-applying. SQLite's own `busy_timeout` already absorbs a
395
+ * same-instant lock collision between two writers; this covers whatever
396
+ * survives that -- a slower disk, any other transient failure -- during the
397
+ * one window where a dropped write has no later chance to be recovered.
398
+ */
399
+ async dispatchReplayed(event) {
400
+ for (let attempt = 1; attempt <= REPLAY_RETRY_ATTEMPTS; attempt++) {
401
+ if (this.dispatch(event))
402
+ return;
403
+ if (attempt < REPLAY_RETRY_ATTEMPTS) {
404
+ await sleep(REPLAY_RETRY_DELAY_MS * attempt);
405
+ }
406
+ }
407
+ console.error(`[orchestrator] gave up recovering a replayed "${event.type}" event after ` +
408
+ `${REPLAY_RETRY_ATTEMPTS} attempts`);
409
+ }
410
+ /**
411
+ * Schedule the next attempt.
412
+ *
413
+ * The timer is deliberately NOT unref'd, and that is the whole point. While
414
+ * reconnecting there is no socket, and in `kya-os orchestrator daemon` the
415
+ * socket is the only handle keeping the process alive -- the liveness beat is
416
+ * unref'd and the command holds no stdin. An unref'd timer here therefore let
417
+ * the process exit during the exact window it was supposed to be recovering
418
+ * in: a hub restart quietly killed the daemon, with no error and no exit
419
+ * message. This timer stands in for the socket, so it has to hold the loop
420
+ * exactly as the socket does.
421
+ *
422
+ * The rule the two now share: the observer owns the daemon's liveness while
423
+ * it is attached or trying to be, and everything else (the beat, the signal
424
+ * handlers) is incidental and stays unref'd.
425
+ */
426
+ scheduleReconnect() {
427
+ if (this.closedByUs || this.reconnectTimer)
428
+ return;
429
+ const delay = this.backoffMs;
430
+ this.backoffMs = Math.min(delay * 2, this.config.maxBackoffMs ?? 30000);
431
+ this.reconnectTimer = setTimeout(() => {
432
+ this.reconnectTimer = undefined;
433
+ if (this.closedByUs)
434
+ return;
435
+ // Reconnect failures are logged, not thrown: nothing is awaiting this, and
436
+ // an unhandled rejection would take the daemon down over a hub restart.
437
+ this.connect().catch((err) => {
438
+ console.error(`[orchestrator] hub reconnect failed: ${err instanceof Error ? err.message : String(err)}`);
439
+ });
440
+ }, delay);
441
+ }
442
+ /**
443
+ * Is a reconnect scheduled -- i.e. is this observer still holding the process
444
+ * open on purpose? Distinguishes a cancelled timer from a merely neutered one,
445
+ * which is invisible from the outside and is the difference between a stopped
446
+ * daemon exiting and hanging.
447
+ */
448
+ hasPendingReconnect() {
449
+ return this.reconnectTimer !== undefined;
450
+ }
451
+ onEvent(handler) {
452
+ this.handlers.push(handler);
453
+ return () => {
454
+ this.handlers = this.handlers.filter((h) => h !== handler);
455
+ };
456
+ }
457
+ getRecentEvents(limit) {
458
+ return limit === undefined ? [...this.history] : this.history.slice(-limit);
459
+ }
460
+ /** Stop observing. Idempotent, and suppresses the reconnect. */
461
+ close() {
462
+ this.closedByUs = true;
463
+ // CANCEL the pending reconnect, do not just make its callback do nothing.
464
+ // Now that the timer holds the event loop open on purpose, a neutered one
465
+ // still keeps a stopped daemon (and any test suite) running to its deadline.
466
+ if (this.reconnectTimer) {
467
+ clearTimeout(this.reconnectTimer);
468
+ this.reconnectTimer = undefined;
469
+ }
470
+ this.ws?.close();
471
+ this.ws = undefined;
472
+ }
473
+ }
474
+ //# sourceMappingURL=hub-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-observer.js","sourceRoot":"","sources":["../../src/orchestrator/hub-observer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Journal writer (ORC-W1 PR-2).
3
+ *
4
+ * Turns hub events into ledger rows. This is the piece that makes the journal
5
+ * evidence rather than narration: rows land because a verified protocol event
6
+ * arrived, not because a model chose to record one.
7
+ *
8
+ * @module orchestrator/journal-writer
9
+ */
10
+ import type { Ledger } from "./db/index.js";
11
+ import type { EventSource, HubEventLike } from "./events.js";
12
+ /**
13
+ * Pull a task id out of an event's untyped `data` bag.
14
+ *
15
+ * `data` is `Record<string, unknown>` on the wire, so this narrows rather than
16
+ * casting. Anything that is not a non-empty string is treated as absent, which
17
+ * is the honest reading: a malformed taskId must not be used to look up a
18
+ * ticket and silently attach an observation to the wrong one.
19
+ */
20
+ export declare function taskIdOf(event: HubEventLike): string | null;
21
+ /**
22
+ * Persist one event.
23
+ *
24
+ * Correlates to a ticket through `dispatches` when the event names a task this
25
+ * orchestrator dispatched. When it does not, the row is still written with a
26
+ * null ticket, because an uncorrelated observation is worth more than no
27
+ * observation and guessing at a ticket would be worse than either.
28
+ *
29
+ * Returns true when the row was new (false means it was a replay).
30
+ */
31
+ export declare function writeEvent(db: Ledger, event: HubEventLike): boolean;
32
+ /** The PR a review event is about, or null if it does not name one completely. */
33
+ export interface ReviewSubject {
34
+ repo: string;
35
+ prNumber: number;
36
+ headSha: string;
37
+ }
38
+ /**
39
+ * Read a review event's subject out of its untyped `data` bag.
40
+ *
41
+ * All three fields or nothing. A verdict missing part of its subject cannot be
42
+ * attributed, and attributing it to the wrong ticket is worse than leaving the
43
+ * row uncorrelated.
44
+ */
45
+ export declare function reviewSubjectOf(event: HubEventLike): ReviewSubject | null;
46
+ /**
47
+ * Resolve the ticket an event concerns: task id first, pull request second.
48
+ *
49
+ * Task id is exact where present. PR correlation is the fallback and the ONLY
50
+ * option for `pr_quorum_reached`, which carries no task id -- so before this
51
+ * existed every quorum event journalled with a null ticket, and the Review lens
52
+ * could show that something reached quorum but never which ticket it was for.
53
+ */
54
+ export declare function ticketIdForEvent(db: Ledger, event: HubEventLike): string | null;
55
+ /**
56
+ * Subscribe to the hub and journal everything it emits.
57
+ *
58
+ * Returns the unsubscribe, matching the hub's own `onEvent` contract, so the
59
+ * daemon can detach cleanly on shutdown instead of leaking a handler that
60
+ * writes to a closed database.
61
+ *
62
+ * Deliberately does NOT catch a write failure here. Every real dispatcher
63
+ * this attaches to -- the hub's own emit loop, `HubObserver.dispatch()` --
64
+ * already isolates one handler's failure from its siblings and from itself,
65
+ * so catching AGAIN in here just hides the failure from that dispatcher: a
66
+ * reconnect's replay retries a write only if it can tell the write failed,
67
+ * and a handler that always reports success by swallowing its own errors
68
+ * makes that retry permanently dead code (review finding on #686).
69
+ */
70
+ export declare function registerJournalWriter(db: Ledger, hub: EventSource): () => void;
71
+ /**
72
+ * Replay the hub's recent-event window into the journal.
73
+ *
74
+ * Called once on boot so a daemon restart recovers what it slept through.
75
+ * Idempotent by construction: journal ids are derived from event content, so
76
+ * an event already recorded live is ignored rather than duplicated. Returns
77
+ * how many rows were genuinely new.
78
+ */
79
+ export declare function reconcileRecentEvents(db: Ledger, hub: EventSource, limit?: number): number;
80
+ //# sourceMappingURL=journal-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal-writer.d.ts","sourceRoot":"","sources":["../../src/orchestrator/journal-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAG3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAEnE;AAED,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,GAAG,IAAI,CAWzE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAQ/E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,MAAM,IAAI,CAI9E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,SAAK,GAAG,MAAM,CAMtF"}