@openrig/cli 0.5.17 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (430) hide show
  1. package/daemon/assets/guidance/openrig-start.md +7 -0
  2. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +7 -0
  3. package/daemon/context-packs/help/help.md +130 -0
  4. package/daemon/context-packs/help/manifest.yaml +9 -0
  5. package/daemon/context-packs/onboarding-width/manifest.yaml +1 -1
  6. package/daemon/context-packs/onboarding-width/public-what-you-can-do.md +3 -0
  7. package/daemon/context-packs/reference/getting-started.md +454 -0
  8. package/daemon/context-packs/reference/instance-layout.md +106 -0
  9. package/daemon/context-packs/reference/manifest.yaml +16 -0
  10. package/daemon/context-packs/reference/rig-spec.md +580 -0
  11. package/daemon/context-packs/skills/agent-operated-software/manifest.yaml +1 -1
  12. package/daemon/context-packs/skills/agent-operated-workflows/manifest.yaml +1 -1
  13. package/daemon/context-packs/skills/applying-a-permission-policy/manifest.yaml +1 -1
  14. package/daemon/context-packs/skills/claude-compaction-restore/manifest.yaml +1 -1
  15. package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
  16. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
  17. package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
  18. package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
  19. package/daemon/context-packs/skills/core/messaging-the-human/manifest.yaml +1 -1
  20. package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
  21. package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
  22. package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
  23. package/daemon/context-packs/skills/core/openrig-skills/SKILL.md +7 -0
  24. package/daemon/context-packs/skills/core/openrig-skills/manifest.yaml +1 -1
  25. package/daemon/context-packs/skills/core/openrig-software-factory/manifest.yaml +1 -1
  26. package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
  27. package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
  28. package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
  29. package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
  30. package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
  31. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
  32. package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
  33. package/daemon/context-packs/skills/delegating-work/manifest.yaml +1 -1
  34. package/daemon/context-packs/skills/forming-an-openrig-mental-model/manifest.yaml +1 -1
  35. package/daemon/context-packs/skills/loading-addressable-markdown/manifest.yaml +1 -1
  36. package/daemon/context-packs/skills/mission-slice-sop/manifest.yaml +1 -1
  37. package/daemon/context-packs/skills/openrig-operating-model/manifest.yaml +1 -1
  38. package/daemon/context-packs/skills/openrig-user/manifest.yaml +1 -1
  39. package/daemon/context-packs/skills/orienting-to-an-inherited-seat/manifest.yaml +1 -1
  40. package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
  41. package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
  42. package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
  43. package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
  44. package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
  45. package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +1 -1
  46. package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
  47. package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
  48. package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
  49. package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
  50. package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
  51. package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
  52. package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
  53. package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
  54. package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
  55. package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
  56. package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
  57. package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
  58. package/daemon/context-packs/skills/queue-handoff/manifest.yaml +1 -1
  59. package/daemon/context-packs/skills/refocusing/manifest.yaml +1 -1
  60. package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/manifest.yaml +1 -1
  61. package/daemon/context-packs/skills/seat-continuity-and-handover/manifest.yaml +1 -1
  62. package/daemon/context-packs/skills/session-compaction-and-restore/manifest.yaml +1 -1
  63. package/daemon/context-packs/skills/software-for-agents/manifest.yaml +1 -1
  64. package/daemon/context-packs/world-example/manifest.yaml +1 -1
  65. package/daemon/context-packs/world-public/manifest.yaml +1 -1
  66. package/daemon/dist/adapters/claude-code-adapter.d.ts +3 -0
  67. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  68. package/daemon/dist/adapters/claude-code-adapter.js +36 -14
  69. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  70. package/daemon/dist/adapters/claude-resume.d.ts +3 -1
  71. package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
  72. package/daemon/dist/adapters/claude-resume.js +20 -6
  73. package/daemon/dist/adapters/claude-resume.js.map +1 -1
  74. package/daemon/dist/adapters/codex-resume.d.ts +4 -1
  75. package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
  76. package/daemon/dist/adapters/codex-resume.js +8 -2
  77. package/daemon/dist/adapters/codex-resume.js.map +1 -1
  78. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +6 -0
  79. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  80. package/daemon/dist/adapters/codex-runtime-adapter.js +25 -4
  81. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  82. package/daemon/dist/adapters/pi-runner.d.ts +1 -0
  83. package/daemon/dist/adapters/pi-runner.d.ts.map +1 -1
  84. package/daemon/dist/adapters/pi-runner.js +7 -1
  85. package/daemon/dist/adapters/pi-runner.js.map +1 -1
  86. package/daemon/dist/adapters/tmux.d.ts +21 -1
  87. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  88. package/daemon/dist/adapters/tmux.js +141 -3
  89. package/daemon/dist/adapters/tmux.js.map +1 -1
  90. package/daemon/dist/adapters/yolo-mode.d.ts +3 -2
  91. package/daemon/dist/adapters/yolo-mode.d.ts.map +1 -1
  92. package/daemon/dist/adapters/yolo-mode.js +10 -2
  93. package/daemon/dist/adapters/yolo-mode.js.map +1 -1
  94. package/daemon/dist/build-info.js +3 -3
  95. package/daemon/dist/db/all-migrations.d.ts +1 -1
  96. package/daemon/dist/db/all-migrations.d.ts.map +1 -1
  97. package/daemon/dist/db/all-migrations.js +10 -2
  98. package/daemon/dist/db/all-migrations.js.map +1 -1
  99. package/daemon/dist/db/migrations/086_classification_fields_and_attempts.d.ts +26 -0
  100. package/daemon/dist/db/migrations/086_classification_fields_and_attempts.d.ts.map +1 -0
  101. package/daemon/dist/db/migrations/086_classification_fields_and_attempts.js +66 -0
  102. package/daemon/dist/db/migrations/086_classification_fields_and_attempts.js.map +1 -0
  103. package/daemon/dist/db/migrations/087_seat_delivery_guard.d.ts +3 -0
  104. package/daemon/dist/db/migrations/087_seat_delivery_guard.d.ts.map +1 -0
  105. package/daemon/dist/db/migrations/087_seat_delivery_guard.js +31 -0
  106. package/daemon/dist/db/migrations/087_seat_delivery_guard.js.map +1 -0
  107. package/daemon/dist/db/migrations/088_node_permission_selections.d.ts +3 -0
  108. package/daemon/dist/db/migrations/088_node_permission_selections.d.ts.map +1 -0
  109. package/daemon/dist/db/migrations/088_node_permission_selections.js +16 -0
  110. package/daemon/dist/db/migrations/088_node_permission_selections.js.map +1 -0
  111. package/daemon/dist/db/migrations/089_classification_identity_provenance.d.ts +3 -0
  112. package/daemon/dist/db/migrations/089_classification_identity_provenance.d.ts.map +1 -0
  113. package/daemon/dist/db/migrations/089_classification_identity_provenance.js +6 -0
  114. package/daemon/dist/db/migrations/089_classification_identity_provenance.js.map +1 -0
  115. package/daemon/dist/domain/applied-launch-observation-store.d.ts +1 -1
  116. package/daemon/dist/domain/applied-launch-observation-store.d.ts.map +1 -1
  117. package/daemon/dist/domain/applied-launch-observation-store.js +6 -4
  118. package/daemon/dist/domain/applied-launch-observation-store.js.map +1 -1
  119. package/daemon/dist/domain/capture-observer.d.ts +130 -0
  120. package/daemon/dist/domain/capture-observer.d.ts.map +1 -0
  121. package/daemon/dist/domain/capture-observer.js +113 -0
  122. package/daemon/dist/domain/capture-observer.js.map +1 -0
  123. package/daemon/dist/domain/claim-service.d.ts.map +1 -1
  124. package/daemon/dist/domain/claim-service.js +24 -3
  125. package/daemon/dist/domain/claim-service.js.map +1 -1
  126. package/daemon/dist/domain/classification-attempts.d.ts +143 -0
  127. package/daemon/dist/domain/classification-attempts.d.ts.map +1 -0
  128. package/daemon/dist/domain/classification-attempts.js +316 -0
  129. package/daemon/dist/domain/classification-attempts.js.map +1 -0
  130. package/daemon/dist/domain/classification-sources.d.ts +44 -0
  131. package/daemon/dist/domain/classification-sources.d.ts.map +1 -0
  132. package/daemon/dist/domain/classification-sources.js +102 -0
  133. package/daemon/dist/domain/classification-sources.js.map +1 -0
  134. package/daemon/dist/domain/classifier-lease-manager.d.ts +15 -4
  135. package/daemon/dist/domain/classifier-lease-manager.d.ts.map +1 -1
  136. package/daemon/dist/domain/classifier-lease-manager.js +63 -21
  137. package/daemon/dist/domain/classifier-lease-manager.js.map +1 -1
  138. package/daemon/dist/domain/claude-compaction-enforcer.d.ts +3 -1
  139. package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -1
  140. package/daemon/dist/domain/claude-compaction-enforcer.js +36 -7
  141. package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -1
  142. package/daemon/dist/domain/claude-managed-launch.d.ts +28 -0
  143. package/daemon/dist/domain/claude-managed-launch.d.ts.map +1 -0
  144. package/daemon/dist/domain/claude-managed-launch.js +111 -0
  145. package/daemon/dist/domain/claude-managed-launch.js.map +1 -0
  146. package/daemon/dist/domain/codex-daemon-support.d.ts +16 -0
  147. package/daemon/dist/domain/codex-daemon-support.d.ts.map +1 -0
  148. package/daemon/dist/domain/codex-daemon-support.js +52 -0
  149. package/daemon/dist/domain/codex-daemon-support.js.map +1 -0
  150. package/daemon/dist/domain/codex-git-add-dirs.d.ts +16 -0
  151. package/daemon/dist/domain/codex-git-add-dirs.d.ts.map +1 -0
  152. package/daemon/dist/domain/codex-git-add-dirs.js +43 -0
  153. package/daemon/dist/domain/codex-git-add-dirs.js.map +1 -0
  154. package/daemon/dist/domain/context-usage-store.d.ts +2 -2
  155. package/daemon/dist/domain/context-usage-store.d.ts.map +1 -1
  156. package/daemon/dist/domain/context-usage-store.js +4 -3
  157. package/daemon/dist/domain/context-usage-store.js.map +1 -1
  158. package/daemon/dist/domain/gateway/connections-projection.d.ts.map +1 -1
  159. package/daemon/dist/domain/gateway/connections-projection.js +6 -3
  160. package/daemon/dist/domain/gateway/connections-projection.js.map +1 -1
  161. package/daemon/dist/domain/gateway/slack/capabilities.d.ts +19 -0
  162. package/daemon/dist/domain/gateway/slack/capabilities.d.ts.map +1 -0
  163. package/daemon/dist/domain/gateway/slack/capabilities.js +24 -0
  164. package/daemon/dist/domain/gateway/slack/capabilities.js.map +1 -0
  165. package/daemon/dist/domain/gateway/slack/config.d.ts.map +1 -1
  166. package/daemon/dist/domain/gateway/slack/config.js +2 -1
  167. package/daemon/dist/domain/gateway/slack/config.js.map +1 -1
  168. package/daemon/dist/domain/gateway/slack/inbound.d.ts.map +1 -1
  169. package/daemon/dist/domain/gateway/slack/inbound.js +2 -1
  170. package/daemon/dist/domain/gateway/slack/inbound.js.map +1 -1
  171. package/daemon/dist/domain/gateway/slack/manifest.d.ts +54 -0
  172. package/daemon/dist/domain/gateway/slack/manifest.d.ts.map +1 -0
  173. package/daemon/dist/domain/gateway/slack/manifest.js +55 -0
  174. package/daemon/dist/domain/gateway/slack/manifest.js.map +1 -0
  175. package/daemon/dist/domain/model-divergence/current-generation-record.d.ts.map +1 -1
  176. package/daemon/dist/domain/model-divergence/current-generation-record.js +6 -3
  177. package/daemon/dist/domain/model-divergence/current-generation-record.js.map +1 -1
  178. package/daemon/dist/domain/model-divergence/model-divergence-monitor.d.ts +3 -2
  179. package/daemon/dist/domain/model-divergence/model-divergence-monitor.d.ts.map +1 -1
  180. package/daemon/dist/domain/model-divergence/model-divergence-monitor.js +9 -5
  181. package/daemon/dist/domain/model-divergence/model-divergence-monitor.js.map +1 -1
  182. package/daemon/dist/domain/native-permission-selection.d.ts +13 -0
  183. package/daemon/dist/domain/native-permission-selection.d.ts.map +1 -0
  184. package/daemon/dist/domain/native-permission-selection.js +30 -0
  185. package/daemon/dist/domain/native-permission-selection.js.map +1 -0
  186. package/daemon/dist/domain/native-permission-store.d.ts +17 -0
  187. package/daemon/dist/domain/native-permission-store.d.ts.map +1 -0
  188. package/daemon/dist/domain/native-permission-store.js +36 -0
  189. package/daemon/dist/domain/native-permission-store.js.map +1 -0
  190. package/daemon/dist/domain/native-resume-probe.d.ts +3 -1
  191. package/daemon/dist/domain/native-resume-probe.d.ts.map +1 -1
  192. package/daemon/dist/domain/native-resume-probe.js +22 -7
  193. package/daemon/dist/domain/native-resume-probe.js.map +1 -1
  194. package/daemon/dist/domain/node-inventory.d.ts +3 -0
  195. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  196. package/daemon/dist/domain/node-inventory.js +2 -0
  197. package/daemon/dist/domain/node-inventory.js.map +1 -1
  198. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  199. package/daemon/dist/domain/node-launcher.js +6 -0
  200. package/daemon/dist/domain/node-launcher.js.map +1 -1
  201. package/daemon/dist/domain/outbox-handler.d.ts +25 -2
  202. package/daemon/dist/domain/outbox-handler.d.ts.map +1 -1
  203. package/daemon/dist/domain/outbox-handler.js +70 -1
  204. package/daemon/dist/domain/outbox-handler.js.map +1 -1
  205. package/daemon/dist/domain/permission-drift-observer.d.ts +1 -0
  206. package/daemon/dist/domain/permission-drift-observer.d.ts.map +1 -1
  207. package/daemon/dist/domain/permission-drift-observer.js +1 -1
  208. package/daemon/dist/domain/permission-drift-observer.js.map +1 -1
  209. package/daemon/dist/domain/permission-drift.d.ts +10 -0
  210. package/daemon/dist/domain/permission-drift.d.ts.map +1 -1
  211. package/daemon/dist/domain/permission-drift.js +29 -18
  212. package/daemon/dist/domain/permission-drift.js.map +1 -1
  213. package/daemon/dist/domain/project-classifier.d.ts +43 -0
  214. package/daemon/dist/domain/project-classifier.d.ts.map +1 -1
  215. package/daemon/dist/domain/project-classifier.js +141 -25
  216. package/daemon/dist/domain/project-classifier.js.map +1 -1
  217. package/daemon/dist/domain/proof/judgments.d.ts +16 -0
  218. package/daemon/dist/domain/proof/judgments.d.ts.map +1 -1
  219. package/daemon/dist/domain/proof/judgments.js +17 -1
  220. package/daemon/dist/domain/proof/judgments.js.map +1 -1
  221. package/daemon/dist/domain/queue-repository.d.ts +8 -0
  222. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  223. package/daemon/dist/domain/queue-repository.js +41 -14
  224. package/daemon/dist/domain/queue-repository.js.map +1 -1
  225. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  226. package/daemon/dist/domain/restore-orchestrator.js +28 -1
  227. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  228. package/daemon/dist/domain/resume-metadata-refresher.d.ts.map +1 -1
  229. package/daemon/dist/domain/resume-metadata-refresher.js +3 -1
  230. package/daemon/dist/domain/resume-metadata-refresher.js.map +1 -1
  231. package/daemon/dist/domain/rig-lifecycle-service.d.ts.map +1 -1
  232. package/daemon/dist/domain/rig-lifecycle-service.js +7 -0
  233. package/daemon/dist/domain/rig-lifecycle-service.js.map +1 -1
  234. package/daemon/dist/domain/rig-teardown.d.ts.map +1 -1
  235. package/daemon/dist/domain/rig-teardown.js +4 -0
  236. package/daemon/dist/domain/rig-teardown.js.map +1 -1
  237. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  238. package/daemon/dist/domain/rigspec-instantiator.js +36 -22
  239. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  240. package/daemon/dist/domain/runtime-adapter.d.ts +6 -0
  241. package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
  242. package/daemon/dist/domain/runtime-adapter.js.map +1 -1
  243. package/daemon/dist/domain/seat-delivery-guard.d.ts +64 -0
  244. package/daemon/dist/domain/seat-delivery-guard.d.ts.map +1 -0
  245. package/daemon/dist/domain/seat-delivery-guard.js +224 -0
  246. package/daemon/dist/domain/seat-delivery-guard.js.map +1 -0
  247. package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
  248. package/daemon/dist/domain/seat-handover-service.js +19 -1
  249. package/daemon/dist/domain/seat-handover-service.js.map +1 -1
  250. package/daemon/dist/domain/seat-lifecycle-service.d.ts +16 -2
  251. package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -1
  252. package/daemon/dist/domain/seat-lifecycle-service.js +70 -0
  253. package/daemon/dist/domain/seat-lifecycle-service.js.map +1 -1
  254. package/daemon/dist/domain/seat-status-service.d.ts +10 -0
  255. package/daemon/dist/domain/seat-status-service.d.ts.map +1 -1
  256. package/daemon/dist/domain/seat-status-service.js +13 -0
  257. package/daemon/dist/domain/seat-status-service.js.map +1 -1
  258. package/daemon/dist/domain/session-transport.d.ts +19 -1
  259. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  260. package/daemon/dist/domain/session-transport.js +221 -23
  261. package/daemon/dist/domain/session-transport.js.map +1 -1
  262. package/daemon/dist/domain/shadow-capture.d.ts +97 -0
  263. package/daemon/dist/domain/shadow-capture.d.ts.map +1 -0
  264. package/daemon/dist/domain/shadow-capture.js +147 -0
  265. package/daemon/dist/domain/shadow-capture.js.map +1 -0
  266. package/daemon/dist/domain/sqlite-time.d.ts +5 -0
  267. package/daemon/dist/domain/sqlite-time.d.ts.map +1 -0
  268. package/daemon/dist/domain/sqlite-time.js +7 -0
  269. package/daemon/dist/domain/sqlite-time.js.map +1 -0
  270. package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  271. package/daemon/dist/domain/startup-orchestrator.js +11 -0
  272. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  273. package/daemon/dist/domain/stream-classification-worker.d.ts +106 -0
  274. package/daemon/dist/domain/stream-classification-worker.d.ts.map +1 -0
  275. package/daemon/dist/domain/stream-classification-worker.js +265 -0
  276. package/daemon/dist/domain/stream-classification-worker.js.map +1 -0
  277. package/daemon/dist/domain/successor-session-launcher.d.ts +1 -0
  278. package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  279. package/daemon/dist/domain/successor-session-launcher.js +4 -2
  280. package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  281. package/daemon/dist/domain/terminal/herdr-adapter.d.ts +7 -0
  282. package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -1
  283. package/daemon/dist/domain/terminal/herdr-adapter.js +119 -12
  284. package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -1
  285. package/daemon/dist/domain/terminal/terminal-provider.d.ts +5 -0
  286. package/daemon/dist/domain/terminal/terminal-provider.d.ts.map +1 -1
  287. package/daemon/dist/domain/terminal/terminal-service.js +6 -6
  288. package/daemon/dist/domain/terminal/terminal-service.js.map +1 -1
  289. package/daemon/dist/domain/terminal/view-composer.d.ts +6 -4
  290. package/daemon/dist/domain/terminal/view-composer.d.ts.map +1 -1
  291. package/daemon/dist/domain/terminal/view-composer.js +5 -5
  292. package/daemon/dist/domain/terminal/view-composer.js.map +1 -1
  293. package/daemon/dist/domain/types.d.ts +10 -0
  294. package/daemon/dist/domain/types.d.ts.map +1 -1
  295. package/daemon/dist/domain/types.js.map +1 -1
  296. package/daemon/dist/domain/watchdog-policy-engine.d.ts +3 -1
  297. package/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -1
  298. package/daemon/dist/domain/watchdog-policy-engine.js +5 -3
  299. package/daemon/dist/domain/watchdog-policy-engine.js.map +1 -1
  300. package/daemon/dist/gateway-slack-surface.d.ts +2 -0
  301. package/daemon/dist/gateway-slack-surface.d.ts.map +1 -1
  302. package/daemon/dist/gateway-slack-surface.js +2 -0
  303. package/daemon/dist/gateway-slack-surface.js.map +1 -1
  304. package/daemon/dist/routes/activity.d.ts.map +1 -1
  305. package/daemon/dist/routes/activity.js +28 -2
  306. package/daemon/dist/routes/activity.js.map +1 -1
  307. package/daemon/dist/routes/down.d.ts.map +1 -1
  308. package/daemon/dist/routes/down.js +3 -0
  309. package/daemon/dist/routes/down.js.map +1 -1
  310. package/daemon/dist/routes/gateway.d.ts.map +1 -1
  311. package/daemon/dist/routes/gateway.js +3 -0
  312. package/daemon/dist/routes/gateway.js.map +1 -1
  313. package/daemon/dist/routes/projects.d.ts.map +1 -1
  314. package/daemon/dist/routes/projects.js +205 -18
  315. package/daemon/dist/routes/projects.js.map +1 -1
  316. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  317. package/daemon/dist/routes/rigs.js +13 -5
  318. package/daemon/dist/routes/rigs.js.map +1 -1
  319. package/daemon/dist/routes/seat.d.ts.map +1 -1
  320. package/daemon/dist/routes/seat.js +78 -1
  321. package/daemon/dist/routes/seat.js.map +1 -1
  322. package/daemon/dist/routes/sessions.d.ts.map +1 -1
  323. package/daemon/dist/routes/sessions.js +6 -2
  324. package/daemon/dist/routes/sessions.js.map +1 -1
  325. package/daemon/dist/routes/transport.d.ts.map +1 -1
  326. package/daemon/dist/routes/transport.js +9 -1
  327. package/daemon/dist/routes/transport.js.map +1 -1
  328. package/daemon/dist/server.d.ts +5 -0
  329. package/daemon/dist/server.d.ts.map +1 -1
  330. package/daemon/dist/server.js +3 -0
  331. package/daemon/dist/server.js.map +1 -1
  332. package/daemon/dist/startup.d.ts.map +1 -1
  333. package/daemon/dist/startup.js +32 -8
  334. package/daemon/dist/startup.js.map +1 -1
  335. package/daemon/dist/stream-classifier-surface.d.ts +6 -0
  336. package/daemon/dist/stream-classifier-surface.d.ts.map +1 -0
  337. package/daemon/dist/stream-classifier-surface.js +6 -0
  338. package/daemon/dist/stream-classifier-surface.js.map +1 -0
  339. package/daemon/dist/terminal/TerminalSessionBroker.d.ts +1 -0
  340. package/daemon/dist/terminal/TerminalSessionBroker.d.ts.map +1 -1
  341. package/daemon/dist/terminal/TerminalSessionBroker.js +10 -6
  342. package/daemon/dist/terminal/TerminalSessionBroker.js.map +1 -1
  343. package/daemon/docs/reference/getting-started.md +63 -5
  344. package/daemon/docs/reference/help.md +130 -0
  345. package/daemon/docs/reference/rig-spec.md +6 -1
  346. package/daemon/docs/reference/slack-app-setup.md +90 -0
  347. package/daemon/docs/reference/stream-classifier-worker.md +244 -0
  348. package/daemon/policies/builtin/yolo.policy.md +5 -5
  349. package/daemon/specs/agents/apps/vault-specialist/skills/vault-user/SKILL.md +5 -0
  350. package/daemon/specs/agents/shared/skills/core/openrig-skills/SKILL.md +7 -0
  351. package/daemon/specs/rigs/launch/kernel/rig.yaml +4 -0
  352. package/dist/build-info.js +3 -3
  353. package/dist/commands/doctor.d.ts.map +1 -1
  354. package/dist/commands/doctor.js +9 -6
  355. package/dist/commands/doctor.js.map +1 -1
  356. package/dist/commands/policy.d.ts.map +1 -1
  357. package/dist/commands/policy.js +8 -1
  358. package/dist/commands/policy.js.map +1 -1
  359. package/dist/commands/preflight.d.ts.map +1 -1
  360. package/dist/commands/preflight.js +2 -0
  361. package/dist/commands/preflight.js.map +1 -1
  362. package/dist/commands/project-jev.d.ts +115 -0
  363. package/dist/commands/project-jev.d.ts.map +1 -0
  364. package/dist/commands/project-jev.js +239 -0
  365. package/dist/commands/project-jev.js.map +1 -0
  366. package/dist/commands/project-worker.d.ts +96 -0
  367. package/dist/commands/project-worker.d.ts.map +1 -0
  368. package/dist/commands/project-worker.js +125 -0
  369. package/dist/commands/project-worker.js.map +1 -0
  370. package/dist/commands/project.d.ts +5 -1
  371. package/dist/commands/project.d.ts.map +1 -1
  372. package/dist/commands/project.js +161 -0
  373. package/dist/commands/project.js.map +1 -1
  374. package/dist/commands/seat.d.ts.map +1 -1
  375. package/dist/commands/seat.js +79 -0
  376. package/dist/commands/seat.js.map +1 -1
  377. package/dist/commands/send.d.ts.map +1 -1
  378. package/dist/commands/send.js +18 -5
  379. package/dist/commands/send.js.map +1 -1
  380. package/dist/commands/slack.d.ts +4 -1
  381. package/dist/commands/slack.d.ts.map +1 -1
  382. package/dist/commands/slack.js +41 -2
  383. package/dist/commands/slack.js.map +1 -1
  384. package/dist/commands/terminal.d.ts.map +1 -1
  385. package/dist/commands/terminal.js +2 -0
  386. package/dist/commands/terminal.js.map +1 -1
  387. package/dist/commands/view.d.ts.map +1 -1
  388. package/dist/commands/view.js +3 -0
  389. package/dist/commands/view.js.map +1 -1
  390. package/dist/commands/walk.d.ts.map +1 -1
  391. package/dist/commands/walk.js +6 -0
  392. package/dist/commands/walk.js.map +1 -1
  393. package/dist/node-support.d.ts +12 -0
  394. package/dist/node-support.d.ts.map +1 -0
  395. package/dist/node-support.js +37 -0
  396. package/dist/node-support.js.map +1 -0
  397. package/dist/system-preflight.d.ts +2 -0
  398. package/dist/system-preflight.d.ts.map +1 -1
  399. package/dist/system-preflight.js +9 -10
  400. package/dist/system-preflight.js.map +1 -1
  401. package/package.json +3 -3
  402. package/scripts/check-abi.mjs +119 -65
  403. package/tui/dist/commands/registry.d.ts.map +1 -1
  404. package/tui/dist/commands/registry.js +3 -0
  405. package/tui/dist/commands/registry.js.map +1 -1
  406. package/tui/dist/connections/connections-model.d.ts +11 -1
  407. package/tui/dist/connections/connections-model.d.ts.map +1 -1
  408. package/tui/dist/connections/connections-model.js +28 -1
  409. package/tui/dist/connections/connections-model.js.map +1 -1
  410. package/tui/dist/daemon-client.d.ts +2 -0
  411. package/tui/dist/daemon-client.d.ts.map +1 -1
  412. package/tui/dist/daemon-client.js +1 -0
  413. package/tui/dist/daemon-client.js.map +1 -1
  414. package/tui/dist/hydrate.d.ts.map +1 -1
  415. package/tui/dist/hydrate.js +5 -0
  416. package/tui/dist/hydrate.js.map +1 -1
  417. package/tui/dist/main.js +16 -2
  418. package/tui/dist/main.js.map +1 -1
  419. package/tui/dist/print-for-copy.d.ts +36 -0
  420. package/tui/dist/print-for-copy.d.ts.map +1 -0
  421. package/tui/dist/print-for-copy.js +92 -0
  422. package/tui/dist/print-for-copy.js.map +1 -0
  423. package/tui/dist/render.d.ts.map +1 -1
  424. package/tui/dist/render.js +4 -1
  425. package/tui/dist/render.js.map +1 -1
  426. package/tui/dist/state.d.ts.map +1 -1
  427. package/tui/dist/state.js +2 -0
  428. package/tui/dist/state.js.map +1 -1
  429. package/tui/dist/types.d.ts +8 -0
  430. package/tui/dist/types.d.ts.map +1 -1
@@ -0,0 +1,143 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { ClassifierLeaseManager } from "./classifier-lease-manager.js";
3
+ /**
4
+ * Classification attempt ledger (0.6.0 S02 P1).
5
+ *
6
+ * Holds everything a classifier occupant must remember that does NOT belong in
7
+ * the immutable `project_classifications` row: in-flight work, abstentions and
8
+ * errors. It is a ledger, not a scheduler — the occupant is woken by the
9
+ * existing watchdog/wake cadence and asks `eligible()` what to do next.
10
+ *
11
+ * Identity: (stream_item_id, classifier_version, taxonomy_version, evidence_epoch).
12
+ * - abstained: terminal for that identity only. A new classifier/taxonomy
13
+ * version or an owner-authorized evidence epoch is a new identity.
14
+ * - error / abandoned in_flight: retried after a bounded, doubling delay until
15
+ * the retry budget is spent, then `exhausted` (terminal, visible).
16
+ * - written: set by ProjectClassifier in the same transaction as the row.
17
+ *
18
+ * Every state change validates the lease (active, same session, same lease id,
19
+ * not expired) inside its write transaction.
20
+ *
21
+ * Execution fence: each begin — first try, timeout reissue or error retry —
22
+ * mints a new executionId. abstain / fail / the classify attempt binding must
23
+ * present the CURRENT executionId; an older execution is refused
24
+ * (`attempt_superseded`) without touching the current one. A lease can be
25
+ * renewed indefinitely, so lease validity never proves an older execution is
26
+ * dead; only the fence does.
27
+ */
28
+ export declare const ATTEMPT_STATUSES: readonly ["in_flight", "abstained", "written", "error", "exhausted"];
29
+ export type AttemptStatus = (typeof ATTEMPT_STATUSES)[number];
30
+ /**
31
+ * Retry defaults, chosen against the existing cadence rather than a new
32
+ * scheduler:
33
+ * - budget 3 attempts per identity: one try plus two retries is enough to ride
34
+ * out a transient provider or daemon blip without looping on a poison item;
35
+ * - backoff 5 min, doubling, capped at 60 min: coarser than the occupant's own
36
+ * wake so a failing item never spins, and bounded so a recovered provider is
37
+ * retried within the hour;
38
+ * - in-flight timeout 15 min: after this long without a finish, the attempt
39
+ * may be reissued as a new execution (a crash is the common cause). This is
40
+ * NOT proof the older execution is dead — leases are renewable — which is why
41
+ * the reissue mints a new executionId and the old one can no longer finish.
42
+ * Reissues count against the budget.
43
+ * All are constructor options; tests inject time instead of sleeping.
44
+ */
45
+ export declare const DEFAULT_RETRY_BUDGET = 3;
46
+ export declare const DEFAULT_BASE_BACKOFF_MS: number;
47
+ export declare const DEFAULT_MAX_BACKOFF_MS: number;
48
+ export declare const DEFAULT_IN_FLIGHT_TIMEOUT_MS: number;
49
+ export declare const MAX_ELIGIBLE_PAGE = 100;
50
+ export interface AttemptIdentity {
51
+ streamItemId: string;
52
+ classifierVersion: string;
53
+ taxonomyVersion: string;
54
+ /** Owner-authorized retry epoch bound to changed evidence; "0" when unused. */
55
+ evidenceEpoch: string;
56
+ }
57
+ export interface ClassificationAttempt extends AttemptIdentity {
58
+ attemptId: string;
59
+ /** Current execution; only this value may finish the attempt. */
60
+ executionId: string;
61
+ status: AttemptStatus;
62
+ attemptCount: number;
63
+ leaseId: string;
64
+ classifierSession: string;
65
+ retryAfter: string | null;
66
+ reason: string | null;
67
+ createdAt: string;
68
+ updatedAt: string;
69
+ }
70
+ export interface EligibleItem {
71
+ streamItemId: string;
72
+ tsEmitted: string;
73
+ streamSortKey: string;
74
+ sourceSession: string;
75
+ }
76
+ export interface EligiblePage {
77
+ items: EligibleItem[];
78
+ /** Pass as `afterSortKey` to read the next page of THIS pass; null when done. */
79
+ nextAfterSortKey: string | null;
80
+ }
81
+ export declare class ClassificationAttemptError extends Error {
82
+ readonly code: string;
83
+ readonly meta: Record<string, unknown> | undefined;
84
+ constructor(code: string, message: string, meta?: Record<string, unknown>);
85
+ }
86
+ export interface ClassificationAttemptLedgerOptions {
87
+ now?: () => Date;
88
+ retryBudget?: number;
89
+ baseBackoffMs?: number;
90
+ maxBackoffMs?: number;
91
+ inFlightTimeoutMs?: number;
92
+ }
93
+ export declare class ClassificationAttemptLedger {
94
+ readonly db: Database.Database;
95
+ private readonly leaseManager;
96
+ private readonly now;
97
+ private readonly retryBudget;
98
+ private readonly baseBackoffMs;
99
+ private readonly maxBackoffMs;
100
+ private readonly inFlightTimeoutMs;
101
+ constructor(db: Database.Database, leaseManager: ClassifierLeaseManager, opts?: ClassificationAttemptLedgerOptions);
102
+ /**
103
+ * Start (or legitimately resume) an attempt for one identity under the
104
+ * caller's lease. Refuses terminal identities, fresh in-flight attempts and
105
+ * errors that are not yet due. An in-flight attempt older than the in-flight
106
+ * timeout, or owned by a replaced lease, counts as an abandoned crash.
107
+ */
108
+ begin(input: AttemptIdentity & {
109
+ leaseId: string;
110
+ classifierSession: string;
111
+ }): ClassificationAttempt;
112
+ /** Terminal abstention for this identity (below threshold / INDETERMINATE). */
113
+ abstain(input: FinishInput): ClassificationAttempt;
114
+ /** Transient failure: schedule a bounded retry, or exhaust the budget. */
115
+ fail(input: FinishInput): ClassificationAttempt;
116
+ /**
117
+ * One bounded page of items the occupant may attempt now for the given
118
+ * versions and epoch, in stream order. Derived by anti-join every call, so a
119
+ * later-due retry reappears on the next pass without any stored cursor
120
+ * skipping it. `afterSortKey` pages within a single pass only.
121
+ */
122
+ eligible(opts: {
123
+ classifierVersion: string;
124
+ taxonomyVersion: string;
125
+ evidenceEpoch: string;
126
+ limit?: number;
127
+ afterSortKey?: string;
128
+ }): EligiblePage;
129
+ getById(attemptId: string): ClassificationAttempt | null;
130
+ private finish;
131
+ private backoffMs;
132
+ private findRow;
133
+ private getByIdOrThrow;
134
+ }
135
+ export interface FinishInput {
136
+ attemptId: string;
137
+ /** The executionId returned by the begin() that started THIS execution. */
138
+ executionId: string;
139
+ leaseId: string;
140
+ classifierSession: string;
141
+ reason: string;
142
+ }
143
+ //# sourceMappingURL=classification-attempts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classification-attempts.d.ts","sourceRoot":"","sources":["../../src/domain/classification-attempts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,316 @@
1
+ import { ulid } from "ulid";
2
+ /**
3
+ * Classification attempt ledger (0.6.0 S02 P1).
4
+ *
5
+ * Holds everything a classifier occupant must remember that does NOT belong in
6
+ * the immutable `project_classifications` row: in-flight work, abstentions and
7
+ * errors. It is a ledger, not a scheduler — the occupant is woken by the
8
+ * existing watchdog/wake cadence and asks `eligible()` what to do next.
9
+ *
10
+ * Identity: (stream_item_id, classifier_version, taxonomy_version, evidence_epoch).
11
+ * - abstained: terminal for that identity only. A new classifier/taxonomy
12
+ * version or an owner-authorized evidence epoch is a new identity.
13
+ * - error / abandoned in_flight: retried after a bounded, doubling delay until
14
+ * the retry budget is spent, then `exhausted` (terminal, visible).
15
+ * - written: set by ProjectClassifier in the same transaction as the row.
16
+ *
17
+ * Every state change validates the lease (active, same session, same lease id,
18
+ * not expired) inside its write transaction.
19
+ *
20
+ * Execution fence: each begin — first try, timeout reissue or error retry —
21
+ * mints a new executionId. abstain / fail / the classify attempt binding must
22
+ * present the CURRENT executionId; an older execution is refused
23
+ * (`attempt_superseded`) without touching the current one. A lease can be
24
+ * renewed indefinitely, so lease validity never proves an older execution is
25
+ * dead; only the fence does.
26
+ */
27
+ export const ATTEMPT_STATUSES = ["in_flight", "abstained", "written", "error", "exhausted"];
28
+ const TERMINAL = ["abstained", "written", "exhausted"];
29
+ /**
30
+ * Retry defaults, chosen against the existing cadence rather than a new
31
+ * scheduler:
32
+ * - budget 3 attempts per identity: one try plus two retries is enough to ride
33
+ * out a transient provider or daemon blip without looping on a poison item;
34
+ * - backoff 5 min, doubling, capped at 60 min: coarser than the occupant's own
35
+ * wake so a failing item never spins, and bounded so a recovered provider is
36
+ * retried within the hour;
37
+ * - in-flight timeout 15 min: after this long without a finish, the attempt
38
+ * may be reissued as a new execution (a crash is the common cause). This is
39
+ * NOT proof the older execution is dead — leases are renewable — which is why
40
+ * the reissue mints a new executionId and the old one can no longer finish.
41
+ * Reissues count against the budget.
42
+ * All are constructor options; tests inject time instead of sleeping.
43
+ */
44
+ export const DEFAULT_RETRY_BUDGET = 3;
45
+ export const DEFAULT_BASE_BACKOFF_MS = 5 * 60 * 1000;
46
+ export const DEFAULT_MAX_BACKOFF_MS = 60 * 60 * 1000;
47
+ export const DEFAULT_IN_FLIGHT_TIMEOUT_MS = 15 * 60 * 1000;
48
+ export const MAX_ELIGIBLE_PAGE = 100;
49
+ export class ClassificationAttemptError extends Error {
50
+ code;
51
+ meta;
52
+ constructor(code, message, meta) {
53
+ super(message);
54
+ this.code = code;
55
+ this.meta = meta;
56
+ }
57
+ }
58
+ export class ClassificationAttemptLedger {
59
+ db;
60
+ leaseManager;
61
+ now;
62
+ retryBudget;
63
+ baseBackoffMs;
64
+ maxBackoffMs;
65
+ inFlightTimeoutMs;
66
+ constructor(db, leaseManager, opts) {
67
+ this.db = db;
68
+ this.leaseManager = leaseManager;
69
+ this.now = opts?.now ?? (() => new Date());
70
+ this.retryBudget = opts?.retryBudget ?? DEFAULT_RETRY_BUDGET;
71
+ this.baseBackoffMs = opts?.baseBackoffMs ?? DEFAULT_BASE_BACKOFF_MS;
72
+ this.maxBackoffMs = opts?.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
73
+ this.inFlightTimeoutMs = opts?.inFlightTimeoutMs ?? DEFAULT_IN_FLIGHT_TIMEOUT_MS;
74
+ }
75
+ /**
76
+ * Start (or legitimately resume) an attempt for one identity under the
77
+ * caller's lease. Refuses terminal identities, fresh in-flight attempts and
78
+ * errors that are not yet due. An in-flight attempt older than the in-flight
79
+ * timeout, or owned by a replaced lease, counts as an abandoned crash.
80
+ */
81
+ begin(input) {
82
+ requireIdentity(input);
83
+ requireStringFields(input, ["leaseId", "classifierSession"]);
84
+ const txn = this.db.transaction(() => {
85
+ this.leaseManager.requireActiveHolder(input.classifierSession, input.leaseId);
86
+ const stream = this.db
87
+ .prepare(`SELECT 1 FROM stream_items WHERE stream_item_id = ?`)
88
+ .get(input.streamItemId);
89
+ if (!stream) {
90
+ throw new ClassificationAttemptError("unknown_stream_item", `stream_item_id ${input.streamItemId} does not exist`, {
91
+ streamItemId: input.streamItemId,
92
+ });
93
+ }
94
+ const classified = this.db
95
+ .prepare(`SELECT project_id FROM project_classifications WHERE stream_item_id = ?`)
96
+ .get(input.streamItemId);
97
+ if (classified) {
98
+ throw new ClassificationAttemptError("already_classified", `stream_item_id ${input.streamItemId} is already classified`, {
99
+ existingProjectId: classified.project_id,
100
+ });
101
+ }
102
+ const nowIso = this.now().toISOString();
103
+ const existing = this.findRow(input);
104
+ if (!existing) {
105
+ const attemptId = ulid();
106
+ this.db
107
+ .prepare(`INSERT INTO classification_attempts (
108
+ attempt_id, stream_item_id, classifier_version, taxonomy_version, evidence_epoch,
109
+ status, attempt_count, execution_id, lease_id, classifier_session, retry_after, reason, created_at, updated_at
110
+ ) VALUES (?, ?, ?, ?, ?, 'in_flight', 1, ?, ?, ?, NULL, NULL, ?, ?)`)
111
+ .run(attemptId, input.streamItemId, input.classifierVersion, input.taxonomyVersion, input.evidenceEpoch, ulid(), input.leaseId, input.classifierSession, nowIso, nowIso);
112
+ return { attemptId, exhausted: false };
113
+ }
114
+ const status = existing.status;
115
+ if (TERMINAL.includes(status)) {
116
+ throw new ClassificationAttemptError("attempt_terminal", `attempt for this identity is ${status}`, {
117
+ attemptId: existing.attempt_id,
118
+ status,
119
+ });
120
+ }
121
+ if (status === "in_flight") {
122
+ const abandoned = existing.lease_id !== input.leaseId ||
123
+ Date.parse(existing.updated_at) + this.inFlightTimeoutMs <= this.now().getTime();
124
+ if (!abandoned) {
125
+ throw new ClassificationAttemptError("attempt_in_flight", "an attempt for this identity is already in flight", {
126
+ attemptId: existing.attempt_id,
127
+ });
128
+ }
129
+ }
130
+ if (status === "error" && existing.retry_after !== null && existing.retry_after > nowIso) {
131
+ throw new ClassificationAttemptError("attempt_not_due", `retry is not due until ${existing.retry_after}`, {
132
+ attemptId: existing.attempt_id,
133
+ retryAfter: existing.retry_after,
134
+ });
135
+ }
136
+ if (existing.attempt_count >= this.retryBudget) {
137
+ this.db
138
+ .prepare(`UPDATE classification_attempts
139
+ SET status = 'exhausted', retry_after = NULL, updated_at = ?,
140
+ reason = COALESCE(reason, 'retry budget spent')
141
+ WHERE attempt_id = ?`)
142
+ .run(nowIso, existing.attempt_id);
143
+ // Commit the terminal transition; the refusal is raised after commit.
144
+ return { attemptId: existing.attempt_id, exhausted: true };
145
+ }
146
+ this.db
147
+ .prepare(`UPDATE classification_attempts
148
+ SET status = 'in_flight', attempt_count = attempt_count + 1, execution_id = ?,
149
+ lease_id = ?, classifier_session = ?, retry_after = NULL, updated_at = ?
150
+ WHERE attempt_id = ?`)
151
+ .run(ulid(), input.leaseId, input.classifierSession, nowIso, existing.attempt_id);
152
+ return { attemptId: existing.attempt_id, exhausted: false };
153
+ });
154
+ const result = txn();
155
+ if (result.exhausted) {
156
+ throw new ClassificationAttemptError("attempt_exhausted", `retry budget of ${this.retryBudget} is spent`, {
157
+ attemptId: result.attemptId,
158
+ });
159
+ }
160
+ return this.getByIdOrThrow(result.attemptId);
161
+ }
162
+ /** Terminal abstention for this identity (below threshold / INDETERMINATE). */
163
+ abstain(input) {
164
+ return this.finish(input, (row, nowIso) => {
165
+ this.db
166
+ .prepare(`UPDATE classification_attempts SET status = 'abstained', reason = ?, retry_after = NULL, updated_at = ? WHERE attempt_id = ?`)
167
+ .run(input.reason, nowIso, row.attempt_id);
168
+ });
169
+ }
170
+ /** Transient failure: schedule a bounded retry, or exhaust the budget. */
171
+ fail(input) {
172
+ return this.finish(input, (row, nowIso) => {
173
+ if (row.attempt_count >= this.retryBudget) {
174
+ this.db
175
+ .prepare(`UPDATE classification_attempts SET status = 'exhausted', reason = ?, retry_after = NULL, updated_at = ? WHERE attempt_id = ?`)
176
+ .run(input.reason, nowIso, row.attempt_id);
177
+ return;
178
+ }
179
+ const retryAfter = new Date(this.now().getTime() + this.backoffMs(row.attempt_count)).toISOString();
180
+ this.db
181
+ .prepare(`UPDATE classification_attempts SET status = 'error', reason = ?, retry_after = ?, updated_at = ? WHERE attempt_id = ?`)
182
+ .run(input.reason, retryAfter, nowIso, row.attempt_id);
183
+ });
184
+ }
185
+ /**
186
+ * One bounded page of items the occupant may attempt now for the given
187
+ * versions and epoch, in stream order. Derived by anti-join every call, so a
188
+ * later-due retry reappears on the next pass without any stored cursor
189
+ * skipping it. `afterSortKey` pages within a single pass only.
190
+ */
191
+ eligible(opts) {
192
+ requireIdentity({ streamItemId: "-", ...opts });
193
+ const limit = Math.max(1, Math.min(opts.limit ?? MAX_ELIGIBLE_PAGE, MAX_ELIGIBLE_PAGE));
194
+ const nowIso = this.now().toISOString();
195
+ const inFlightCutoff = new Date(this.now().getTime() - this.inFlightTimeoutMs).toISOString();
196
+ const params = [
197
+ opts.classifierVersion, opts.taxonomyVersion, opts.evidenceEpoch, nowIso, inFlightCutoff,
198
+ ];
199
+ let cursorClause = "";
200
+ if (opts.afterSortKey) {
201
+ const cursor = this.db
202
+ .prepare(`SELECT ts_emitted, stream_sort_key FROM stream_items WHERE stream_sort_key = ?`)
203
+ .get(opts.afterSortKey);
204
+ if (!cursor) {
205
+ throw new ClassificationAttemptError("unknown_cursor", `afterSortKey ${opts.afterSortKey} is not a stream sort key`);
206
+ }
207
+ cursorClause = "AND (s.ts_emitted, s.stream_sort_key) > (?, ?)";
208
+ params.push(cursor.ts_emitted, cursor.stream_sort_key);
209
+ }
210
+ params.push(limit + 1);
211
+ const rows = this.db
212
+ .prepare(`SELECT s.stream_item_id, s.ts_emitted, s.stream_sort_key, s.source_session
213
+ FROM stream_items s
214
+ LEFT JOIN project_classifications p ON p.stream_item_id = s.stream_item_id
215
+ LEFT JOIN classification_attempts a
216
+ ON a.stream_item_id = s.stream_item_id
217
+ AND a.classifier_version = ? AND a.taxonomy_version = ? AND a.evidence_epoch = ?
218
+ WHERE s.archived_at IS NULL
219
+ AND p.stream_item_id IS NULL
220
+ AND (
221
+ a.attempt_id IS NULL
222
+ OR (a.status = 'error' AND (a.retry_after IS NULL OR a.retry_after <= ?))
223
+ OR (a.status = 'in_flight' AND a.updated_at <= ?)
224
+ )
225
+ ${cursorClause}
226
+ ORDER BY s.ts_emitted, s.stream_sort_key
227
+ LIMIT ?`)
228
+ .all(...params);
229
+ const more = rows.length > limit;
230
+ const page = rows.slice(0, limit).map((r) => ({
231
+ streamItemId: r.stream_item_id,
232
+ tsEmitted: r.ts_emitted,
233
+ streamSortKey: r.stream_sort_key,
234
+ sourceSession: r.source_session,
235
+ }));
236
+ return { items: page, nextAfterSortKey: more ? page[page.length - 1].streamSortKey : null };
237
+ }
238
+ getById(attemptId) {
239
+ const row = this.db.prepare(`SELECT * FROM classification_attempts WHERE attempt_id = ?`).get(attemptId);
240
+ return row ? rowToAttempt(row) : null;
241
+ }
242
+ finish(input, apply) {
243
+ requireStringFields(input, ["attemptId", "executionId", "leaseId", "classifierSession", "reason"]);
244
+ const txn = this.db.transaction(() => {
245
+ this.leaseManager.requireActiveHolder(input.classifierSession, input.leaseId);
246
+ const row = this.db.prepare(`SELECT * FROM classification_attempts WHERE attempt_id = ?`).get(input.attemptId);
247
+ if (!row)
248
+ throw new ClassificationAttemptError("attempt_not_found", `attempt ${input.attemptId} not found`);
249
+ if (row.execution_id !== input.executionId) {
250
+ throw new ClassificationAttemptError("attempt_superseded", "this execution was superseded by a newer execution of the attempt", {
251
+ attemptId: row.attempt_id,
252
+ });
253
+ }
254
+ if (row.status !== "in_flight" || row.lease_id !== input.leaseId) {
255
+ throw new ClassificationAttemptError("attempt_mismatch", "attempt is not in flight under this lease", {
256
+ attemptId: row.attempt_id,
257
+ status: row.status,
258
+ attemptLeaseId: row.lease_id,
259
+ });
260
+ }
261
+ apply(row, this.now().toISOString());
262
+ });
263
+ txn();
264
+ return this.getByIdOrThrow(input.attemptId);
265
+ }
266
+ backoffMs(attemptCount) {
267
+ return Math.min(this.baseBackoffMs * 2 ** Math.max(0, attemptCount - 1), this.maxBackoffMs);
268
+ }
269
+ findRow(id) {
270
+ return this.db
271
+ .prepare(`SELECT * FROM classification_attempts
272
+ WHERE stream_item_id = ? AND classifier_version = ? AND taxonomy_version = ? AND evidence_epoch = ?`)
273
+ .get(id.streamItemId, id.classifierVersion, id.taxonomyVersion, id.evidenceEpoch);
274
+ }
275
+ getByIdOrThrow(attemptId) {
276
+ const a = this.getById(attemptId);
277
+ if (!a)
278
+ throw new ClassificationAttemptError("attempt_not_found", `attempt ${attemptId} not found after write`);
279
+ return a;
280
+ }
281
+ }
282
+ /** Shape check for code-consumed string fields: present, a string, not blank. */
283
+ function requireStringFields(input, fields) {
284
+ for (const field of fields) {
285
+ const value = input[field];
286
+ if (typeof value !== "string" || value.trim() === "") {
287
+ throw new ClassificationAttemptError("invalid_field", `${field} must be a non-empty string`, { field });
288
+ }
289
+ }
290
+ }
291
+ function requireIdentity(id) {
292
+ for (const key of ["streamItemId", "classifierVersion", "taxonomyVersion", "evidenceEpoch"]) {
293
+ if (typeof id[key] !== "string" || id[key].trim() === "") {
294
+ throw new ClassificationAttemptError("invalid_attempt_identity", `${key} is required`, { field: key });
295
+ }
296
+ }
297
+ }
298
+ function rowToAttempt(row) {
299
+ return {
300
+ attemptId: row.attempt_id,
301
+ streamItemId: row.stream_item_id,
302
+ classifierVersion: row.classifier_version,
303
+ taxonomyVersion: row.taxonomy_version,
304
+ evidenceEpoch: row.evidence_epoch,
305
+ status: row.status,
306
+ attemptCount: row.attempt_count,
307
+ executionId: row.execution_id,
308
+ leaseId: row.lease_id,
309
+ classifierSession: row.classifier_session,
310
+ retryAfter: row.retry_after,
311
+ reason: row.reason,
312
+ createdAt: row.created_at,
313
+ updatedAt: row.updated_at,
314
+ };
315
+ }
316
+ //# sourceMappingURL=classification-attempts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classification-attempts.js","sourceRoot":"","sources":["../../src/domain/classification-attempts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type Database from "better-sqlite3";
2
+ import { type ProjectRead } from "./workspace/project-read.js";
3
+ import type { StreamStore } from "./stream-store.js";
4
+ export declare const sourceHash: (value: string) => string;
5
+ export interface ClassifierOccupant {
6
+ nodeId: string;
7
+ rigId: string;
8
+ session: string;
9
+ generation: string;
10
+ }
11
+ export declare function classifierOccupant(db: Database.Database, session: string): ClassifierOccupant | null;
12
+ export declare function classificationSources(db: Database.Database, project: ProjectRead, occupant: ClassifierOccupant, stream: StreamStore): {
13
+ occupant: ClassifierOccupant;
14
+ observedAt: string;
15
+ version: string;
16
+ sources: {
17
+ project: {
18
+ id: string;
19
+ root: string;
20
+ missionsRoot: string;
21
+ files: {
22
+ source: string;
23
+ hash: string;
24
+ }[];
25
+ };
26
+ scopes: {
27
+ id: string;
28
+ source: string;
29
+ hash: string;
30
+ }[];
31
+ rosterSource: string;
32
+ roster: ClassifierOccupant[];
33
+ recent: {
34
+ streamItemId: string;
35
+ body: string;
36
+ bodyTruncated: boolean;
37
+ sourceSession: string;
38
+ evidenceRef: string;
39
+ }[];
40
+ };
41
+ unavailable: string[];
42
+ duplicateCoverage: string;
43
+ };
44
+ //# sourceMappingURL=classification-sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classification-sources.d.ts","sourceRoot":"","sources":["../../src/domain/classification-sources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,WAAiE,CAAC;AAC1G,MAAM,WAAW,kBAAkB;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAG1G,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CASpG;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,WAAW;;;;;;;;;;wBAoBnG,MAAM;sBAAQ,MAAM;;;;gBAlB/B,MAAM;oBAAU,MAAM;kBAAQ,MAAM;;;;;;;;;;;;;;EAkDzD"}
@@ -0,0 +1,102 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { parse } from "yaml";
5
+ import { workSource, insideProject } from "./workspace/project-read.js";
6
+ import { isMissionDotId, isSliceDotId } from "./scope/dot-id.js";
7
+ export const sourceHash = (value) => `sha256:${createHash("sha256").update(value).digest("hex")}`;
8
+ // Same real running-session/tenure sources as startup liveness. No daemon pseudo-session.
9
+ export function classifierOccupant(db, session) {
10
+ const rows = db.prepare(`SELECT DISTINCT n.id AS nodeId, n.rig_id AS rigId, b.tmux_session AS session,
11
+ o.generation_uuid AS generation FROM nodes n JOIN bindings b ON b.node_id=n.id
12
+ JOIN sessions s ON s.node_id=n.id AND s.session_name=b.tmux_session AND s.status='running'
13
+ AND s.id=(SELECT id FROM sessions WHERE node_id=n.id ORDER BY id DESC LIMIT 1)
14
+ JOIN occupant_tenures o ON o.node_id=n.id
15
+ AND o.generation_ordinal=(SELECT MAX(generation_ordinal) FROM occupant_tenures WHERE node_id=n.id)
16
+ WHERE b.tmux_session=? LIMIT 2`).all(session);
17
+ return rows.length === 1 && rows[0].generation ? rows[0] : null;
18
+ }
19
+ export function classificationSources(db, project, occupant, stream) {
20
+ const unavailable = [];
21
+ const scopes = [];
22
+ const observedAt = new Date().toISOString();
23
+ let sourceBytes = 0;
24
+ const readScope = (dir, missionId) => {
25
+ if (scopes.length >= 1000)
26
+ throw Error("scope count exceeds 1000");
27
+ const source = insideProject(project.root, workSource(project.root, dir, false));
28
+ const size = fs.statSync(source).size;
29
+ if (size > 128 * 1024 || (sourceBytes += size) > 4 * 1024 * 1024)
30
+ throw Error("scope source byte limit");
31
+ const text = readBounded(source, Math.min(128 * 1024, 4 * 1024 * 1024 - sourceBytes + size));
32
+ const front = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
33
+ const id = front ? parse(front[1])?.id : undefined;
34
+ if (typeof id !== "string" || !(missionId ? isSliceDotId(id) && id.startsWith(missionId + ".") : isMissionDotId(id))) {
35
+ throw Error(`canonical ${missionId ? "slice" : "mission"} ID unavailable: ${source}`);
36
+ }
37
+ if (scopes.some(x => x.id === id))
38
+ throw Error(`ambiguous scope ID: ${id}`);
39
+ scopes.push({ id, source, hash: sourceHash(text) });
40
+ return id;
41
+ };
42
+ const projectSources = [];
43
+ try {
44
+ for (const source of [project.sourcePath, path.join(project.root, "project.yaml")]) {
45
+ if (!source || !fs.existsSync(source) || projectSources.some(x => x.source === source))
46
+ continue;
47
+ const actual = insideProject(project.root, source);
48
+ projectSources.push({ source: actual, hash: sourceHash(readBounded(actual, 128 * 1024)) });
49
+ }
50
+ if (!projectSources.length)
51
+ throw Error("project source unavailable");
52
+ insideProject(project.root, project.missionsRoot);
53
+ const missions = fs.readdirSync(project.missionsRoot, { withFileTypes: true }).filter(x => x.isDirectory() || x.isSymbolicLink()).sort((a, b) => a.name.localeCompare(b.name));
54
+ if (missions.length > 1000)
55
+ throw Error("mission count exceeds 1000");
56
+ for (const mission of missions) {
57
+ const dir = path.join(project.missionsRoot, mission.name);
58
+ const id = readScope(dir);
59
+ const slices = path.join(dir, "slices");
60
+ if (!fs.existsSync(slices))
61
+ continue;
62
+ insideProject(project.root, slices);
63
+ const children = fs.readdirSync(slices, { withFileTypes: true }).filter(x => x.isDirectory() || x.isSymbolicLink()).sort((a, b) => a.name.localeCompare(b.name));
64
+ if (children.length + scopes.length > 1000)
65
+ throw Error("scope count exceeds 1000");
66
+ for (const child of children)
67
+ readScope(path.join(slices, child.name), id);
68
+ }
69
+ }
70
+ catch (error) {
71
+ unavailable.push(error instanceof Error ? error.message : "scope sources unavailable");
72
+ }
73
+ const names = db.prepare(`SELECT DISTINCT b.tmux_session AS session FROM bindings b JOIN nodes n ON n.id=b.node_id WHERE n.rig_id=? ORDER BY session LIMIT 1001`).all(occupant.rigId);
74
+ const roster = names.flatMap(x => { const row = classifierOccupant(db, x.session); return row ? [row] : []; });
75
+ if (names.length > 1000)
76
+ unavailable.push("roster exceeds 1000");
77
+ const recent = stream.list({ limit: 100, direction: "latest" }).map(item => ({
78
+ streamItemId: item.streamItemId, body: item.body.slice(0, 2000), bodyTruncated: item.body.length > 2000, sourceSession: item.sourceSession,
79
+ evidenceRef: `stream:${item.streamItemId}:${sourceHash(item.body)}`,
80
+ }));
81
+ const sources = { project: { id: project.id, root: project.root, missionsRoot: project.missionsRoot, files: projectSources }, scopes, rosterSource: "bindings + running sessions + latest occupant_tenures in the classifier rig", roster: roster.slice(0, 1000), recent };
82
+ return { occupant, observedAt, version: sourceHash(JSON.stringify({ sources, unavailable })), sources, unavailable,
83
+ duplicateCoverage: "Most recent 100 nonarchived items; a retrieval miss is unknown, not no duplicate." };
84
+ }
85
+ function readBounded(file, limit) {
86
+ const fd = fs.openSync(file, "r");
87
+ try {
88
+ if (!fs.fstatSync(fd).isFile())
89
+ throw Error(`not a regular source file: ${file}`);
90
+ const bytes = Buffer.alloc(limit + 1);
91
+ let used = 0, count = 0;
92
+ while (used < bytes.length && (count = fs.readSync(fd, bytes, used, bytes.length - used, null)))
93
+ used += count;
94
+ if (used > limit)
95
+ throw Error(`source byte limit: ${file}`);
96
+ return bytes.subarray(0, used).toString("utf8");
97
+ }
98
+ finally {
99
+ fs.closeSync(fd);
100
+ }
101
+ }
102
+ //# sourceMappingURL=classification-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classification-sources.js","sourceRoot":"","sources":["../../src/domain/classification-sources.ts"],"names":[],"mappings":"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"}