@quickchatai/quickreview 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1443) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +385 -2
  3. package/THIRD-PARTY-NOTICES.md +134 -0
  4. package/agents/pass-abstraction.md +64 -0
  5. package/agents/pass-ask-human.md +134 -0
  6. package/agents/pass-backcompat.md +67 -0
  7. package/agents/pass-baseline.md +61 -0
  8. package/agents/pass-behaviour-delta.md +64 -0
  9. package/agents/pass-bounds.md +36 -0
  10. package/agents/pass-claims.md +31 -0
  11. package/agents/pass-concurrency.md +168 -0
  12. package/agents/pass-consistency.md +57 -0
  13. package/agents/pass-contracts.md +30 -0
  14. package/agents/pass-data-safety.md +54 -0
  15. package/agents/pass-deferred.md +35 -0
  16. package/agents/pass-delivery.md +37 -0
  17. package/agents/pass-duplication.md +60 -0
  18. package/agents/pass-intent.md +63 -0
  19. package/agents/pass-lint-conformance.md +46 -0
  20. package/agents/pass-maintainability.md +67 -0
  21. package/agents/pass-placement.md +68 -0
  22. package/agents/pass-prod-risk.md +24 -0
  23. package/agents/pass-rollout.md +32 -0
  24. package/agents/pass-roundtrip.md +46 -0
  25. package/agents/pass-security.md +31 -0
  26. package/agents/pass-simplicity.md +68 -0
  27. package/agents/pass-statelessness.md +27 -0
  28. package/agents/pass-style.md +37 -0
  29. package/agents/pass-sweep.md +57 -0
  30. package/agents/pass-tests.md +58 -0
  31. package/agents/pass-ui.md +23 -0
  32. package/agents/pass-validate.md +50 -0
  33. package/agents/pass-widened.md +46 -0
  34. package/agents/scan/pass-scan.md +86 -0
  35. package/bin/qcr.js +11 -0
  36. package/config.example.toml +1067 -0
  37. package/deploy/ansible/README.md +356 -0
  38. package/deploy/ansible/group_vars/all.yml +212 -0
  39. package/deploy/ansible/inventory.example.ini +25 -0
  40. package/deploy/ansible/playbook.yml +360 -0
  41. package/deploy/collect-secrets.sh +289 -0
  42. package/deploy/collect-slack-secrets.mjs +1190 -0
  43. package/deploy/github-app-manifest.json +31 -0
  44. package/deploy/manifest.schema.json +75 -0
  45. package/deploy/qcr-update.sh +803 -0
  46. package/deploy/reviewer/AGENTS.override.md +12 -0
  47. package/dist/extensions/cli/bash-guard-ambient.js +42 -0
  48. package/dist/extensions/cli/bash-guard-ambient.js.map +1 -0
  49. package/dist/extensions/cli/bash-guard.js +5 -0
  50. package/dist/extensions/cli/bash-guard.js.map +1 -0
  51. package/dist/extensions/cli/companion-guard.js +5 -0
  52. package/dist/extensions/cli/companion-guard.js.map +1 -0
  53. package/dist/extensions/cli/debug-round.js +8 -0
  54. package/dist/extensions/cli/debug-round.js.map +1 -0
  55. package/dist/extensions/cli/inject-bridge.js +5 -0
  56. package/dist/extensions/cli/inject-bridge.js.map +1 -0
  57. package/dist/extensions/cli/ledger-pin.js +5 -0
  58. package/dist/extensions/cli/ledger-pin.js.map +1 -0
  59. package/dist/extensions/cli/lens.js +13 -0
  60. package/dist/extensions/cli/lens.js.map +1 -0
  61. package/dist/extensions/cli/muted-theme.js +5 -0
  62. package/dist/extensions/cli/muted-theme.js.map +1 -0
  63. package/dist/extensions/cli/onboarding.js +5 -0
  64. package/dist/extensions/cli/onboarding.js.map +1 -0
  65. package/dist/extensions/cli/setup.js +5 -0
  66. package/dist/extensions/cli/setup.js.map +1 -0
  67. package/dist/extensions/cli/tui-view.js +5 -0
  68. package/dist/extensions/cli/tui-view.js.map +1 -0
  69. package/dist/extensions/companion-guard.js +361 -0
  70. package/dist/extensions/companion-guard.js.map +1 -0
  71. package/dist/extensions/debug-round.js +204 -0
  72. package/dist/extensions/debug-round.js.map +1 -0
  73. package/dist/extensions/inject-bridge.js +603 -0
  74. package/dist/extensions/inject-bridge.js.map +1 -0
  75. package/dist/extensions/muted-theme.js +12 -0
  76. package/dist/extensions/muted-theme.js.map +1 -0
  77. package/dist/extensions/onboarding.js +175 -0
  78. package/dist/extensions/onboarding.js.map +1 -0
  79. package/dist/extensions/setup-replay.js +269 -0
  80. package/dist/extensions/setup-replay.js.map +1 -0
  81. package/dist/extensions/setup-scan.js +998 -0
  82. package/dist/extensions/setup-scan.js.map +1 -0
  83. package/dist/extensions/setup-triage.js +175 -0
  84. package/dist/extensions/setup-triage.js.map +1 -0
  85. package/dist/extensions/setup.js +1160 -0
  86. package/dist/extensions/setup.js.map +1 -0
  87. package/dist/extensions/tui-view.js +389 -0
  88. package/dist/extensions/tui-view.js.map +1 -0
  89. package/dist/extensions/vendor/openviking-pi/client.js +376 -0
  90. package/dist/extensions/vendor/openviking-pi/client.js.map +1 -0
  91. package/dist/extensions/vendor/openviking-pi/config.js +189 -0
  92. package/dist/extensions/vendor/openviking-pi/config.js.map +1 -0
  93. package/dist/extensions/vendor/openviking-pi/index.js +421 -0
  94. package/dist/extensions/vendor/openviking-pi/index.js.map +1 -0
  95. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +86 -0
  96. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs.map +1 -0
  97. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs +408 -0
  98. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs.map +1 -0
  99. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +41 -0
  100. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs.map +1 -0
  101. package/dist/extensions/vendor/openviking-pi/qcr-hint.js +290 -0
  102. package/dist/extensions/vendor/openviking-pi/qcr-hint.js.map +1 -0
  103. package/dist/extensions/vendor/openviking-pi/qcr-honest.js +148 -0
  104. package/dist/extensions/vendor/openviking-pi/qcr-honest.js.map +1 -0
  105. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js +68 -0
  106. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js.map +1 -0
  107. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js +77 -0
  108. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js.map +1 -0
  109. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js +216 -0
  110. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js.map +1 -0
  111. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js +154 -0
  112. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js.map +1 -0
  113. package/dist/extensions/vendor/openviking-pi/qcr-recall.js +254 -0
  114. package/dist/extensions/vendor/openviking-pi/qcr-recall.js.map +1 -0
  115. package/dist/extensions/vendor/openviking-pi/qcr-shim.js +94 -0
  116. package/dist/extensions/vendor/openviking-pi/qcr-shim.js.map +1 -0
  117. package/dist/extensions/vendor/openviking-pi/qcr-write.js +333 -0
  118. package/dist/extensions/vendor/openviking-pi/qcr-write.js.map +1 -0
  119. package/dist/extensions/vendor/openviking-pi/recall.js +108 -0
  120. package/dist/extensions/vendor/openviking-pi/recall.js.map +1 -0
  121. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs +529 -0
  122. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs.map +1 -0
  123. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs +205 -0
  124. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs.map +1 -0
  125. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs +442 -0
  126. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs.map +1 -0
  127. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs +286 -0
  128. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs.map +1 -0
  129. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +189 -0
  130. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs.map +1 -0
  131. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs +580 -0
  132. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs.map +1 -0
  133. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs +11 -0
  134. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs.map +1 -0
  135. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs +63 -0
  136. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs.map +1 -0
  137. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs +58 -0
  138. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs.map +1 -0
  139. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  140. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs.map +1 -0
  141. package/dist/extensions/vendor/openviking-pi/sync.js +127 -0
  142. package/dist/extensions/vendor/openviking-pi/sync.js.map +1 -0
  143. package/dist/extensions/vendor/openviking-pi/takeover.js +25 -0
  144. package/dist/extensions/vendor/openviking-pi/takeover.js.map +1 -0
  145. package/dist/extensions/vendor/openviking-pi/tools.js +417 -0
  146. package/dist/extensions/vendor/openviking-pi/tools.js.map +1 -0
  147. package/dist/src/anomalies.js +483 -0
  148. package/dist/src/anomalies.js.map +1 -0
  149. package/dist/src/answerworker.js +180 -0
  150. package/dist/src/answerworker.js.map +1 -0
  151. package/dist/src/appstamp.js +68 -0
  152. package/dist/src/appstamp.js.map +1 -0
  153. package/dist/src/archive/admission.js +3 -0
  154. package/dist/src/archive/admission.js.map +1 -0
  155. package/dist/src/archive/archivedb.js +474 -0
  156. package/dist/src/archive/archivedb.js.map +1 -0
  157. package/dist/src/archive/archiver.js +1770 -0
  158. package/dist/src/archive/archiver.js.map +1 -0
  159. package/dist/src/archive/archivewrite.js +198 -0
  160. package/dist/src/archive/archivewrite.js.map +1 -0
  161. package/dist/src/archive/bundle.js +266 -0
  162. package/dist/src/archive/bundle.js.map +1 -0
  163. package/dist/src/archive/dbmove.js +638 -0
  164. package/dist/src/archive/dbmove.js.map +1 -0
  165. package/dist/src/archive/duplicatecounts.js +80 -0
  166. package/dist/src/archive/duplicatecounts.js.map +1 -0
  167. package/dist/src/archive/eligibility.js +113 -0
  168. package/dist/src/archive/eligibility.js.map +1 -0
  169. package/dist/src/archive/extract.js +288 -0
  170. package/dist/src/archive/extract.js.map +1 -0
  171. package/dist/src/archive/fsutil.js +330 -0
  172. package/dist/src/archive/fsutil.js.map +1 -0
  173. package/dist/src/archive/gzfile.js +277 -0
  174. package/dist/src/archive/gzfile.js.map +1 -0
  175. package/dist/src/archive/kinds.js +22 -0
  176. package/dist/src/archive/kinds.js.map +1 -0
  177. package/dist/src/archive/livecheckpoint.js +178 -0
  178. package/dist/src/archive/livecheckpoint.js.map +1 -0
  179. package/dist/src/archive/liveretention.js +145 -0
  180. package/dist/src/archive/liveretention.js.map +1 -0
  181. package/dist/src/archive/manifest.js +284 -0
  182. package/dist/src/archive/manifest.js.map +1 -0
  183. package/dist/src/archive/overseer.js +283 -0
  184. package/dist/src/archive/overseer.js.map +1 -0
  185. package/dist/src/archive/piglobal.js +129 -0
  186. package/dist/src/archive/piglobal.js.map +1 -0
  187. package/dist/src/archive/plan.js +398 -0
  188. package/dist/src/archive/plan.js.map +1 -0
  189. package/dist/src/archive/prarchive.js +831 -0
  190. package/dist/src/archive/prarchive.js.map +1 -0
  191. package/dist/src/archive/prfiles.js +303 -0
  192. package/dist/src/archive/prfiles.js.map +1 -0
  193. package/dist/src/archive/report.js +169 -0
  194. package/dist/src/archive/report.js.map +1 -0
  195. package/dist/src/archive/restore.js +276 -0
  196. package/dist/src/archive/restore.js.map +1 -0
  197. package/dist/src/archive/rows.js +106 -0
  198. package/dist/src/archive/rows.js.map +1 -0
  199. package/dist/src/archive/seal.js +480 -0
  200. package/dist/src/archive/seal.js.map +1 -0
  201. package/dist/src/archive/status.js +528 -0
  202. package/dist/src/archive/status.js.map +1 -0
  203. package/dist/src/archive/storepass.js +409 -0
  204. package/dist/src/archive/storepass.js.map +1 -0
  205. package/dist/src/backfill.js +217 -0
  206. package/dist/src/backfill.js.map +1 -0
  207. package/dist/src/bench/cost.js +87 -0
  208. package/dist/src/bench/exec.js +76 -0
  209. package/dist/src/bench/values.js +14 -0
  210. package/dist/src/botcontrol.js +127 -0
  211. package/dist/src/botcontrol.js.map +1 -0
  212. package/dist/src/botworker.js +805 -0
  213. package/dist/src/botworker.js.map +1 -0
  214. package/dist/src/capture.js +234 -0
  215. package/dist/src/capture.js.map +1 -0
  216. package/dist/src/cases.js +1491 -0
  217. package/dist/src/cases.js.map +1 -0
  218. package/dist/src/channelfs.js +27 -0
  219. package/dist/src/channelfs.js.map +1 -0
  220. package/dist/src/checklist.js +312 -0
  221. package/dist/src/checklist.js.map +1 -0
  222. package/dist/src/ciretry.js +91 -0
  223. package/dist/src/ciretry.js.map +1 -0
  224. package/dist/src/cli.js +1916 -0
  225. package/dist/src/cli.js.map +1 -0
  226. package/dist/src/cliops.js +333 -0
  227. package/dist/src/cliops.js.map +1 -0
  228. package/dist/src/clonedir.js +15 -0
  229. package/dist/src/clonedir.js.map +1 -0
  230. package/dist/src/commandeffects.js +43 -0
  231. package/dist/src/commandeffects.js.map +1 -0
  232. package/dist/src/commands.js +1312 -0
  233. package/dist/src/commands.js.map +1 -0
  234. package/dist/src/companioninbox.js +203 -0
  235. package/dist/src/companioninbox.js.map +1 -0
  236. package/dist/src/compare.js +673 -0
  237. package/dist/src/compare.js.map +1 -0
  238. package/dist/src/config.js +1027 -0
  239. package/dist/src/config.js.map +1 -0
  240. package/dist/src/configcheck.js +111 -0
  241. package/dist/src/configcheck.js.map +1 -0
  242. package/dist/src/coreext.js +43 -0
  243. package/dist/src/coreext.js.map +1 -0
  244. package/dist/src/daemon.js +929 -0
  245. package/dist/src/daemon.js.map +1 -0
  246. package/dist/src/debuground.js +731 -0
  247. package/dist/src/debuground.js.map +1 -0
  248. package/dist/src/debugroundpi.js +219 -0
  249. package/dist/src/debugroundpi.js.map +1 -0
  250. package/dist/src/diagnostics.js +14 -0
  251. package/dist/src/diagnostics.js.map +1 -0
  252. package/dist/src/digest.js +139 -0
  253. package/dist/src/digest.js.map +1 -0
  254. package/dist/src/dispatch.js +1726 -0
  255. package/dist/src/dispatch.js.map +1 -0
  256. package/dist/src/engine/answerguard.js +18 -0
  257. package/dist/src/engine/answerguard.js.map +1 -0
  258. package/dist/src/engine/botsdk.js +262 -0
  259. package/dist/src/engine/botsdk.js.map +1 -0
  260. package/dist/src/engine/caserunner-sdk.js +332 -0
  261. package/dist/src/engine/caserunner-sdk.js.map +1 -0
  262. package/dist/src/engine/debugpi.js +194 -0
  263. package/dist/src/engine/debugpi.js.map +1 -0
  264. package/dist/src/eod.js +473 -0
  265. package/dist/src/eod.js.map +1 -0
  266. package/dist/src/eodpinwatch.js +391 -0
  267. package/dist/src/eodpinwatch.js.map +1 -0
  268. package/dist/src/escalation.js +1009 -0
  269. package/dist/src/escalation.js.map +1 -0
  270. package/dist/src/eventloop.js +779 -0
  271. package/dist/src/eventloop.js.map +1 -0
  272. package/dist/src/execboundary.js +430 -0
  273. package/dist/src/execboundary.js.map +1 -0
  274. package/dist/src/feedback.js +915 -0
  275. package/dist/src/feedback.js.map +1 -0
  276. package/dist/src/findingscheck.js +200 -0
  277. package/dist/src/findingscheck.js.map +1 -0
  278. package/dist/src/fsdenied.js +26 -0
  279. package/dist/src/fsdenied.js.map +1 -0
  280. package/dist/src/ghread.js +181 -0
  281. package/dist/src/ghread.js.map +1 -0
  282. package/dist/src/github.js +1063 -0
  283. package/dist/src/github.js.map +1 -0
  284. package/dist/src/homes.js +103 -0
  285. package/dist/src/homes.js.map +1 -0
  286. package/dist/src/hostroute.js +24 -0
  287. package/dist/src/hostroute.js.map +1 -0
  288. package/dist/src/improvements.js +625 -0
  289. package/dist/src/improvements.js.map +1 -0
  290. package/dist/src/install.js +946 -0
  291. package/dist/src/install.js.map +1 -0
  292. package/dist/src/installkind.js +40 -0
  293. package/dist/src/installkind.js.map +1 -0
  294. package/dist/src/ipc/capability.js +286 -0
  295. package/dist/src/ipc/capability.js.map +1 -0
  296. package/dist/src/ipc/client.js +226 -0
  297. package/dist/src/ipc/client.js.map +1 -0
  298. package/dist/src/ipc/control.js +70 -0
  299. package/dist/src/ipc/control.js.map +1 -0
  300. package/dist/src/ipc/ghreadshim.js +77 -0
  301. package/dist/src/ipc/ghreadshim.js.map +1 -0
  302. package/dist/src/ipc/launcher.js +65 -0
  303. package/dist/src/ipc/launcher.js.map +1 -0
  304. package/dist/src/ipc/permits.js +293 -0
  305. package/dist/src/ipc/permits.js.map +1 -0
  306. package/dist/src/ipc/postshim.js +137 -0
  307. package/dist/src/ipc/postshim.js.map +1 -0
  308. package/dist/src/ipc/protocol.js +239 -0
  309. package/dist/src/ipc/protocol.js.map +1 -0
  310. package/dist/src/ipc/server.js +312 -0
  311. package/dist/src/ipc/server.js.map +1 -0
  312. package/dist/src/ipc/workerspec.js +148 -0
  313. package/dist/src/ipc/workerspec.js.map +1 -0
  314. package/dist/src/learner/learner.js +1272 -0
  315. package/dist/src/learner/learner.js.map +1 -0
  316. package/dist/src/learner/miner.js +948 -0
  317. package/dist/src/learner/miner.js.map +1 -0
  318. package/dist/src/learner/packet.js +216 -0
  319. package/dist/src/learner/packet.js.map +1 -0
  320. package/dist/src/learner/receipt.js +135 -0
  321. package/dist/src/learner/receipt.js.map +1 -0
  322. package/dist/src/learner/status.js +38 -0
  323. package/dist/src/learner/status.js.map +1 -0
  324. package/dist/src/ledgercheck.js +120 -0
  325. package/dist/src/ledgercheck.js.map +1 -0
  326. package/dist/src/lessonledger.js +451 -0
  327. package/dist/src/lessonledger.js.map +1 -0
  328. package/dist/src/lessonselect.js +639 -0
  329. package/dist/src/lessonselect.js.map +1 -0
  330. package/dist/src/lessonshadow.js +540 -0
  331. package/dist/src/lessonshadow.js.map +1 -0
  332. package/dist/src/levers.js +302 -0
  333. package/dist/src/levers.js.map +1 -0
  334. package/dist/src/live/projection.js +450 -0
  335. package/dist/src/live/projection.js.map +1 -0
  336. package/dist/src/live/publish.js +83 -0
  337. package/dist/src/live/publish.js.map +1 -0
  338. package/dist/src/live/read.js +60 -0
  339. package/dist/src/live/read.js.map +1 -0
  340. package/dist/src/livecli.js +288 -0
  341. package/dist/src/livecli.js.map +1 -0
  342. package/dist/src/loginhint.js +42 -0
  343. package/dist/src/loginhint.js.map +1 -0
  344. package/dist/src/loginrefresh/atomic.js +66 -0
  345. package/dist/src/loginrefresh/atomic.js.map +1 -0
  346. package/dist/src/loginrefresh/lock.js +93 -0
  347. package/dist/src/loginrefresh/lock.js.map +1 -0
  348. package/dist/src/loginrefresh/main.js +58 -0
  349. package/dist/src/loginrefresh/main.js.map +1 -0
  350. package/dist/src/loginrefresh/pirefresh.js +49 -0
  351. package/dist/src/loginrefresh/pirefresh.js.map +1 -0
  352. package/dist/src/loginrefresh/refresher.js +286 -0
  353. package/dist/src/loginrefresh/refresher.js.map +1 -0
  354. package/dist/src/loginrefresh/supervisor.js +253 -0
  355. package/dist/src/loginrefresh/supervisor.js.map +1 -0
  356. package/dist/src/loginrefresh/types.js +4 -0
  357. package/dist/src/loginrefresh/types.js.map +1 -0
  358. package/dist/src/memory/context.js +251 -0
  359. package/dist/src/memory/context.js.map +1 -0
  360. package/dist/src/memory/datafence.js +5 -0
  361. package/dist/src/memory/datafence.js.map +1 -0
  362. package/dist/src/memory/delivery.js +131 -0
  363. package/dist/src/memory/delivery.js.map +1 -0
  364. package/dist/src/memory/eventtags.js +81 -0
  365. package/dist/src/memory/eventtags.js.map +1 -0
  366. package/dist/src/memory/health.js +713 -0
  367. package/dist/src/memory/health.js.map +1 -0
  368. package/dist/src/memory/import.js +504 -0
  369. package/dist/src/memory/import.js.map +1 -0
  370. package/dist/src/memory/layout.js +252 -0
  371. package/dist/src/memory/layout.js.map +1 -0
  372. package/dist/src/memory/legacy-file.js +100 -0
  373. package/dist/src/memory/legacy-file.js.map +1 -0
  374. package/dist/src/memory/lessons.js +370 -0
  375. package/dist/src/memory/lessons.js.map +1 -0
  376. package/dist/src/memory/ovsession.js +449 -0
  377. package/dist/src/memory/ovsession.js.map +1 -0
  378. package/dist/src/memory/relayout.js +259 -0
  379. package/dist/src/memory/relayout.js.map +1 -0
  380. package/dist/src/memory/roundactivity.js +180 -0
  381. package/dist/src/memory/roundactivity.js.map +1 -0
  382. package/dist/src/memory/selection.js +690 -0
  383. package/dist/src/memory/selection.js.map +1 -0
  384. package/dist/src/memory/shadowstatus.js +69 -0
  385. package/dist/src/memory/shadowstatus.js.map +1 -0
  386. package/dist/src/memory/store.js +83 -0
  387. package/dist/src/memory/store.js.map +1 -0
  388. package/dist/src/memory/textidentity.js +8 -0
  389. package/dist/src/memory/textidentity.js.map +1 -0
  390. package/dist/src/metrics.js +773 -0
  391. package/dist/src/metrics.js.map +1 -0
  392. package/dist/src/missingconfig.js +8 -0
  393. package/dist/src/missingconfig.js.map +1 -0
  394. package/dist/src/npmverbs.js +226 -0
  395. package/dist/src/npmverbs.js.map +1 -0
  396. package/dist/src/onboard/choices.js +191 -0
  397. package/dist/src/onboard/choices.js.map +1 -0
  398. package/dist/src/onboard/engine.js +344 -0
  399. package/dist/src/onboard/engine.js.map +1 -0
  400. package/dist/src/onboard/launch.js +83 -0
  401. package/dist/src/onboard/launch.js.map +1 -0
  402. package/dist/src/onboard/steps/appslug.js +211 -0
  403. package/dist/src/onboard/steps/appslug.js.map +1 -0
  404. package/dist/src/onboard/steps/bringup.js +408 -0
  405. package/dist/src/onboard/steps/bringup.js.map +1 -0
  406. package/dist/src/onboard/steps/compose.js +343 -0
  407. package/dist/src/onboard/steps/compose.js.map +1 -0
  408. package/dist/src/onboard/steps/configdelivery.js +50 -0
  409. package/dist/src/onboard/steps/configdelivery.js.map +1 -0
  410. package/dist/src/onboard/steps/configfill.js +1148 -0
  411. package/dist/src/onboard/steps/configfill.js.map +1 -0
  412. package/dist/src/onboard/steps/deploysh.js +80 -0
  413. package/dist/src/onboard/steps/deploysh.js.map +1 -0
  414. package/dist/src/onboard/steps/embeddings.js +472 -0
  415. package/dist/src/onboard/steps/embeddings.js.map +1 -0
  416. package/dist/src/onboard/steps/escalation.js +571 -0
  417. package/dist/src/onboard/steps/escalation.js.map +1 -0
  418. package/dist/src/onboard/steps/githubapp.js +1092 -0
  419. package/dist/src/onboard/steps/githubapp.js.map +1 -0
  420. package/dist/src/onboard/steps/golive.js +506 -0
  421. package/dist/src/onboard/steps/golive.js.map +1 -0
  422. package/dist/src/onboard/steps/index.js +67 -0
  423. package/dist/src/onboard/steps/index.js.map +1 -0
  424. package/dist/src/onboard/steps/ingress.js +762 -0
  425. package/dist/src/onboard/steps/ingress.js.map +1 -0
  426. package/dist/src/onboard/steps/inventory.js +420 -0
  427. package/dist/src/onboard/steps/inventory.js.map +1 -0
  428. package/dist/src/onboard/steps/llmauth.js +893 -0
  429. package/dist/src/onboard/steps/llmauth.js.map +1 -0
  430. package/dist/src/onboard/steps/memory.js +1060 -0
  431. package/dist/src/onboard/steps/memory.js.map +1 -0
  432. package/dist/src/onboard/steps/memorykeys.js +43 -0
  433. package/dist/src/onboard/steps/memorykeys.js.map +1 -0
  434. package/dist/src/onboard/steps/preflight.js +172 -0
  435. package/dist/src/onboard/steps/preflight.js.map +1 -0
  436. package/dist/src/onboard/steps/proof.js +502 -0
  437. package/dist/src/onboard/steps/proof.js.map +1 -0
  438. package/dist/src/onboard/steps/ssh.js +300 -0
  439. package/dist/src/onboard/steps/ssh.js.map +1 -0
  440. package/dist/src/onboard/steps/topology.js +291 -0
  441. package/dist/src/onboard/steps/topology.js.map +1 -0
  442. package/dist/src/onboard/steps/transport.js +511 -0
  443. package/dist/src/onboard/steps/transport.js.map +1 -0
  444. package/dist/src/onboard/steps/verifyup.js +362 -0
  445. package/dist/src/onboard/steps/verifyup.js.map +1 -0
  446. package/dist/src/onboard/steps/vmdeploy.js +368 -0
  447. package/dist/src/onboard/steps/vmdeploy.js.map +1 -0
  448. package/dist/src/onboard/toml.js +53 -0
  449. package/dist/src/onboard/toml.js.map +1 -0
  450. package/dist/src/opencli.js +508 -0
  451. package/dist/src/opencli.js.map +1 -0
  452. package/dist/src/openpr.js +457 -0
  453. package/dist/src/openpr.js.map +1 -0
  454. package/dist/src/openviking/client.js +821 -0
  455. package/dist/src/openviking/client.js.map +1 -0
  456. package/dist/src/openviking/context.js +218 -0
  457. package/dist/src/openviking/context.js.map +1 -0
  458. package/dist/src/openviking/embedder.js +457 -0
  459. package/dist/src/openviking/embedder.js.map +1 -0
  460. package/dist/src/openviking/gapsink.js +38 -0
  461. package/dist/src/openviking/gapsink.js.map +1 -0
  462. package/dist/src/openviking/health.js +69 -0
  463. package/dist/src/openviking/health.js.map +1 -0
  464. package/dist/src/openviking/index.js +24 -0
  465. package/dist/src/openviking/index.js.map +1 -0
  466. package/dist/src/openviking/lessonfind.js +54 -0
  467. package/dist/src/openviking/lessonfind.js.map +1 -0
  468. package/dist/src/openviking/probe.js +89 -0
  469. package/dist/src/openviking/probe.js.map +1 -0
  470. package/dist/src/openviking/proc.js +95 -0
  471. package/dist/src/openviking/proc.js.map +1 -0
  472. package/dist/src/openviking/provisionreport.js +144 -0
  473. package/dist/src/openviking/provisionreport.js.map +1 -0
  474. package/dist/src/openviking/reembed.js +317 -0
  475. package/dist/src/openviking/reembed.js.map +1 -0
  476. package/dist/src/openviking/relayout.js +153 -0
  477. package/dist/src/openviking/relayout.js.map +1 -0
  478. package/dist/src/openviking/sidecar-main.js +39 -0
  479. package/dist/src/openviking/sidecar-main.js.map +1 -0
  480. package/dist/src/openviking/sidecar.js +79 -0
  481. package/dist/src/openviking/sidecar.js.map +1 -0
  482. package/dist/src/openviking/store.js +1758 -0
  483. package/dist/src/openviking/store.js.map +1 -0
  484. package/dist/src/openviking/supervisor.js +422 -0
  485. package/dist/src/openviking/supervisor.js.map +1 -0
  486. package/dist/src/openviking/types.js +5 -0
  487. package/dist/src/openviking/types.js.map +1 -0
  488. package/dist/src/operator-recovery.js +172 -0
  489. package/dist/src/operator-recovery.js.map +1 -0
  490. package/dist/src/operatormessage.js +44 -0
  491. package/dist/src/operatormessage.js.map +1 -0
  492. package/dist/src/outcomes.js +1361 -0
  493. package/dist/src/outcomes.js.map +1 -0
  494. package/dist/src/piauthcopy.js +5 -0
  495. package/dist/src/piauthcopy.js.map +1 -0
  496. package/dist/src/picli.js +45 -0
  497. package/dist/src/picli.js.map +1 -0
  498. package/dist/src/picwd.js +25 -0
  499. package/dist/src/picwd.js.map +1 -0
  500. package/dist/src/pilogin.js +35 -0
  501. package/dist/src/pilogin.js.map +1 -0
  502. package/dist/src/pingpong.js +1028 -0
  503. package/dist/src/pingpong.js.map +1 -0
  504. package/dist/src/posting-journal.js +441 -0
  505. package/dist/src/posting-journal.js.map +1 -0
  506. package/dist/src/posting-outbox.js +662 -0
  507. package/dist/src/posting-outbox.js.map +1 -0
  508. package/dist/src/posting-receipt.js +203 -0
  509. package/dist/src/posting-receipt.js.map +1 -0
  510. package/dist/src/posting.js +348 -0
  511. package/dist/src/posting.js.map +1 -0
  512. package/dist/src/postops.js +637 -0
  513. package/dist/src/postops.js.map +1 -0
  514. package/dist/src/pr-activity.js +11 -0
  515. package/dist/src/pr-activity.js.map +1 -0
  516. package/dist/src/pr-author.js +5 -0
  517. package/dist/src/pr-author.js.map +1 -0
  518. package/dist/src/pr-conversation.js +355 -0
  519. package/dist/src/pr-conversation.js.map +1 -0
  520. package/dist/src/pr-session-lifecycle.js +542 -0
  521. package/dist/src/pr-session-lifecycle.js.map +1 -0
  522. package/dist/src/preflight.js +341 -0
  523. package/dist/src/preflight.js.map +1 -0
  524. package/dist/src/priorresolve.js +275 -0
  525. package/dist/src/priorresolve.js.map +1 -0
  526. package/dist/src/qcrbin.js +180 -0
  527. package/dist/src/qcrbin.js.map +1 -0
  528. package/dist/src/recheck.js +1398 -0
  529. package/dist/src/recheck.js.map +1 -0
  530. package/dist/src/reconcile.js +820 -0
  531. package/dist/src/reconcile.js.map +1 -0
  532. package/dist/src/recordedfindings.js +15 -0
  533. package/dist/src/recordedfindings.js.map +1 -0
  534. package/dist/src/regression.js +546 -0
  535. package/dist/src/regression.js.map +1 -0
  536. package/dist/src/replay.js +598 -0
  537. package/dist/src/replay.js.map +1 -0
  538. package/dist/src/requiredpasses.js +113 -0
  539. package/dist/src/requiredpasses.js.map +1 -0
  540. package/dist/src/resumecheck.js +168 -0
  541. package/dist/src/resumecheck.js.map +1 -0
  542. package/dist/src/reviewcli.js +671 -0
  543. package/dist/src/reviewcli.js.map +1 -0
  544. package/dist/src/reviewcontext.js +22 -0
  545. package/dist/src/reviewcontext.js.map +1 -0
  546. package/dist/src/reviewdetach.js +574 -0
  547. package/dist/src/reviewdetach.js.map +1 -0
  548. package/dist/src/reviewhistory.js +284 -0
  549. package/dist/src/reviewhistory.js.map +1 -0
  550. package/dist/src/reviewhome.js +26 -0
  551. package/dist/src/reviewhome.js.map +1 -0
  552. package/dist/src/reviewmemory.js +110 -0
  553. package/dist/src/reviewmemory.js.map +1 -0
  554. package/dist/src/reviewrendercli.js +104 -0
  555. package/dist/src/reviewrendercli.js.map +1 -0
  556. package/dist/src/round-work.js +20 -0
  557. package/dist/src/round-work.js.map +1 -0
  558. package/dist/src/runhost.js +72 -0
  559. package/dist/src/runhost.js.map +1 -0
  560. package/dist/src/scanauth.js +25 -0
  561. package/dist/src/scanauth.js.map +1 -0
  562. package/dist/src/scanbox.js +846 -0
  563. package/dist/src/scanbox.js.map +1 -0
  564. package/dist/src/scancli.js +1074 -0
  565. package/dist/src/scancli.js.map +1 -0
  566. package/dist/src/scandriverlog.js +30 -0
  567. package/dist/src/scandriverlog.js.map +1 -0
  568. package/dist/src/session-bridge.js +75 -0
  569. package/dist/src/session-bridge.js.map +1 -0
  570. package/dist/src/session-command-payload.js +29 -0
  571. package/dist/src/session-command-payload.js.map +1 -0
  572. package/dist/src/session-command-supervisor.js +939 -0
  573. package/dist/src/session-command-supervisor.js.map +1 -0
  574. package/dist/src/sessionjsonl.js +85 -0
  575. package/dist/src/sessionjsonl.js.map +1 -0
  576. package/dist/src/sessions.js +541 -0
  577. package/dist/src/sessions.js.map +1 -0
  578. package/dist/src/setup/adapters.js +330 -0
  579. package/dist/src/setup/adapters.js.map +1 -0
  580. package/dist/src/setup/baselines.js +64 -0
  581. package/dist/src/setup/baselines.js.map +1 -0
  582. package/dist/src/setup/caserunner.js +554 -0
  583. package/dist/src/setup/caserunner.js.map +1 -0
  584. package/dist/src/setup/configcommit.js +358 -0
  585. package/dist/src/setup/configcommit.js.map +1 -0
  586. package/dist/src/setup/engine.js +672 -0
  587. package/dist/src/setup/engine.js.map +1 -0
  588. package/dist/src/setup/facts.js +593 -0
  589. package/dist/src/setup/facts.js.map +1 -0
  590. package/dist/src/setup/findings.js +948 -0
  591. package/dist/src/setup/findings.js.map +1 -0
  592. package/dist/src/setup/history.js +338 -0
  593. package/dist/src/setup/history.js.map +1 -0
  594. package/dist/src/setup/interview.js +185 -0
  595. package/dist/src/setup/interview.js.map +1 -0
  596. package/dist/src/setup/ledger.js +207 -0
  597. package/dist/src/setup/ledger.js.map +1 -0
  598. package/dist/src/setup/pins.js +43 -0
  599. package/dist/src/setup/pins.js.map +1 -0
  600. package/dist/src/setup/portrait.js +432 -0
  601. package/dist/src/setup/portrait.js.map +1 -0
  602. package/dist/src/setup/presentation.js +9 -0
  603. package/dist/src/setup/presentation.js.map +1 -0
  604. package/dist/src/setup/profile.js +417 -0
  605. package/dist/src/setup/profile.js.map +1 -0
  606. package/dist/src/setup/replay.js +240 -0
  607. package/dist/src/setup/replay.js.map +1 -0
  608. package/dist/src/setup/replaybuild.js +311 -0
  609. package/dist/src/setup/replaybuild.js.map +1 -0
  610. package/dist/src/setup/replayrun.js +806 -0
  611. package/dist/src/setup/replayrun.js.map +1 -0
  612. package/dist/src/setup/replaysource.js +169 -0
  613. package/dist/src/setup/replaysource.js.map +1 -0
  614. package/dist/src/setup/retune.js +333 -0
  615. package/dist/src/setup/retune.js.map +1 -0
  616. package/dist/src/setup/retunelog.js +51 -0
  617. package/dist/src/setup/retunelog.js.map +1 -0
  618. package/dist/src/setup/scan.js +725 -0
  619. package/dist/src/setup/scan.js.map +1 -0
  620. package/dist/src/setup/scanbuild.js +133 -0
  621. package/dist/src/setup/scanbuild.js.map +1 -0
  622. package/dist/src/setup/scanfacts.js +96 -0
  623. package/dist/src/setup/scanfacts.js.map +1 -0
  624. package/dist/src/setup/scanlease.js +251 -0
  625. package/dist/src/setup/scanlease.js.map +1 -0
  626. package/dist/src/setup/scanreport.js +289 -0
  627. package/dist/src/setup/scanreport.js.map +1 -0
  628. package/dist/src/setup/scanrun.js +1733 -0
  629. package/dist/src/setup/scanrun.js.map +1 -0
  630. package/dist/src/setup/scantree.js +257 -0
  631. package/dist/src/setup/scantree.js.map +1 -0
  632. package/dist/src/setup/stage2.js +617 -0
  633. package/dist/src/setup/stage2.js.map +1 -0
  634. package/dist/src/setup/stage2request.js +259 -0
  635. package/dist/src/setup/stage2request.js.map +1 -0
  636. package/dist/src/setup/survey.js +307 -0
  637. package/dist/src/setup/survey.js.map +1 -0
  638. package/dist/src/setup/surveyrun.js +549 -0
  639. package/dist/src/setup/surveyrun.js.map +1 -0
  640. package/dist/src/setup/textsniff.js +89 -0
  641. package/dist/src/setup/textsniff.js.map +1 -0
  642. package/dist/src/setup/trackersink.js +395 -0
  643. package/dist/src/setup/trackersink.js.map +1 -0
  644. package/dist/src/setup/triage.js +636 -0
  645. package/dist/src/setup/triage.js.map +1 -0
  646. package/dist/src/setup/tuning.js +585 -0
  647. package/dist/src/setup/tuning.js.map +1 -0
  648. package/dist/src/setup/unitcut.js +437 -0
  649. package/dist/src/setup/unitcut.js.map +1 -0
  650. package/dist/src/singleflight.js +72 -0
  651. package/dist/src/singleflight.js.map +1 -0
  652. package/dist/src/slack/announce.js +725 -0
  653. package/dist/src/slack/announce.js.map +1 -0
  654. package/dist/src/slack/api.js +227 -0
  655. package/dist/src/slack/api.js.map +1 -0
  656. package/dist/src/slack/messages.js +158 -0
  657. package/dist/src/slack/messages.js.map +1 -0
  658. package/dist/src/slack/origin.js +550 -0
  659. package/dist/src/slack/origin.js.map +1 -0
  660. package/dist/src/slack/policy.js +225 -0
  661. package/dist/src/slack/policy.js.map +1 -0
  662. package/dist/src/slack/reply.js +153 -0
  663. package/dist/src/slack/reply.js.map +1 -0
  664. package/dist/src/slack/router.js +189 -0
  665. package/dist/src/slack/router.js.map +1 -0
  666. package/dist/src/slack/socket.js +323 -0
  667. package/dist/src/slack/socket.js.map +1 -0
  668. package/dist/src/slack/types.js +11 -0
  669. package/dist/src/slack/types.js.map +1 -0
  670. package/dist/src/sqlitehint.js +30 -0
  671. package/dist/src/sqlitehint.js.map +1 -0
  672. package/dist/src/ssh-observation.js +25 -0
  673. package/dist/src/ssh-observation.js.map +1 -0
  674. package/dist/src/state.js +5869 -0
  675. package/dist/src/state.js.map +1 -0
  676. package/dist/src/statemachine.js +220 -0
  677. package/dist/src/statemachine.js.map +1 -0
  678. package/dist/src/stubs.js +52 -0
  679. package/dist/src/stubs.js.map +1 -0
  680. package/dist/src/takeover.js +506 -0
  681. package/dist/src/takeover.js.map +1 -0
  682. package/dist/src/takeoverpi.js +249 -0
  683. package/dist/src/takeoverpi.js.map +1 -0
  684. package/dist/src/terminal-failure.js +26 -0
  685. package/dist/src/terminal-failure.js.map +1 -0
  686. package/dist/src/thread-resolution-refusal.js +4 -0
  687. package/dist/src/thread-resolution-refusal.js.map +1 -0
  688. package/dist/src/tmux.js +126 -0
  689. package/dist/src/tmux.js.map +1 -0
  690. package/dist/src/trackerid.js +43 -0
  691. package/dist/src/trackerid.js.map +1 -0
  692. package/dist/src/transcriptindex.js +512 -0
  693. package/dist/src/transcriptindex.js.map +1 -0
  694. package/dist/src/tui/actions.js +404 -0
  695. package/dist/src/tui/actions.js.map +1 -0
  696. package/dist/src/tui/alerts.js +523 -0
  697. package/dist/src/tui/alerts.js.map +1 -0
  698. package/dist/src/tui/app.js +1835 -0
  699. package/dist/src/tui/app.js.map +1 -0
  700. package/dist/src/tui/archiveops.js +164 -0
  701. package/dist/src/tui/archiveops.js.map +1 -0
  702. package/dist/src/tui/autofile.js +191 -0
  703. package/dist/src/tui/autofile.js.map +1 -0
  704. package/dist/src/tui/board.js +1143 -0
  705. package/dist/src/tui/board.js.map +1 -0
  706. package/dist/src/tui/candidates.js +699 -0
  707. package/dist/src/tui/candidates.js.map +1 -0
  708. package/dist/src/tui/cellwidth.js +151 -0
  709. package/dist/src/tui/cellwidth.js.map +1 -0
  710. package/dist/src/tui/changelog-store.js +404 -0
  711. package/dist/src/tui/changelog-store.js.map +1 -0
  712. package/dist/src/tui/chord.js +26 -0
  713. package/dist/src/tui/chord.js.map +1 -0
  714. package/dist/src/tui/clipboard.js +81 -0
  715. package/dist/src/tui/clipboard.js.map +1 -0
  716. package/dist/src/tui/cmdbar.js +253 -0
  717. package/dist/src/tui/cmdbar.js.map +1 -0
  718. package/dist/src/tui/companion.js +1275 -0
  719. package/dist/src/tui/companion.js.map +1 -0
  720. package/dist/src/tui/companionplan.js +200 -0
  721. package/dist/src/tui/companionplan.js.map +1 -0
  722. package/dist/src/tui/companiontab.js +61 -0
  723. package/dist/src/tui/companiontab.js.map +1 -0
  724. package/dist/src/tui/confighome.js +105 -0
  725. package/dist/src/tui/confighome.js.map +1 -0
  726. package/dist/src/tui/connect.js +44 -0
  727. package/dist/src/tui/connect.js.map +1 -0
  728. package/dist/src/tui/deploy-ceremony.js +75 -0
  729. package/dist/src/tui/deploy-ceremony.js.map +1 -0
  730. package/dist/src/tui/deploy-drain.js +93 -0
  731. package/dist/src/tui/deploy-drain.js.map +1 -0
  732. package/dist/src/tui/deploy-process.js +234 -0
  733. package/dist/src/tui/deploy-process.js.map +1 -0
  734. package/dist/src/tui/deploytab.js +1263 -0
  735. package/dist/src/tui/deploytab.js.map +1 -0
  736. package/dist/src/tui/design.js +111 -0
  737. package/dist/src/tui/design.js.map +1 -0
  738. package/dist/src/tui/digesttab.js +148 -0
  739. package/dist/src/tui/digesttab.js.map +1 -0
  740. package/dist/src/tui/emptystate.js +32 -0
  741. package/dist/src/tui/emptystate.js.map +1 -0
  742. package/dist/src/tui/evidence.js +790 -0
  743. package/dist/src/tui/evidence.js.map +1 -0
  744. package/dist/src/tui/feed.js +415 -0
  745. package/dist/src/tui/feed.js.map +1 -0
  746. package/dist/src/tui/feedbacktab.js +907 -0
  747. package/dist/src/tui/feedbacktab.js.map +1 -0
  748. package/dist/src/tui/filters.js +72 -0
  749. package/dist/src/tui/filters.js.map +1 -0
  750. package/dist/src/tui/ghread.js +272 -0
  751. package/dist/src/tui/ghread.js.map +1 -0
  752. package/dist/src/tui/historypull.js +61 -0
  753. package/dist/src/tui/historypull.js.map +1 -0
  754. package/dist/src/tui/inboxpull.js +197 -0
  755. package/dist/src/tui/inboxpull.js.map +1 -0
  756. package/dist/src/tui/index.js +1425 -0
  757. package/dist/src/tui/index.js.map +1 -0
  758. package/dist/src/tui/issuesink.js +206 -0
  759. package/dist/src/tui/issuesink.js.map +1 -0
  760. package/dist/src/tui/jsonfile.js +32 -0
  761. package/dist/src/tui/jsonfile.js.map +1 -0
  762. package/dist/src/tui/keys.js +97 -0
  763. package/dist/src/tui/keys.js.map +1 -0
  764. package/dist/src/tui/layout.js +70 -0
  765. package/dist/src/tui/layout.js.map +1 -0
  766. package/dist/src/tui/learning.js +469 -0
  767. package/dist/src/tui/learning.js.map +1 -0
  768. package/dist/src/tui/lessonswitch.js +103 -0
  769. package/dist/src/tui/lessonswitch.js.map +1 -0
  770. package/dist/src/tui/livecontrol.js +167 -0
  771. package/dist/src/tui/livecontrol.js.map +1 -0
  772. package/dist/src/tui/memforward.js +310 -0
  773. package/dist/src/tui/memforward.js.map +1 -0
  774. package/dist/src/tui/memincident.js +287 -0
  775. package/dist/src/tui/memincident.js.map +1 -0
  776. package/dist/src/tui/memory.js +485 -0
  777. package/dist/src/tui/memory.js.map +1 -0
  778. package/dist/src/tui/memtab.js +513 -0
  779. package/dist/src/tui/memtab.js.map +1 -0
  780. package/dist/src/tui/metricstab.js +979 -0
  781. package/dist/src/tui/metricstab.js.map +1 -0
  782. package/dist/src/tui/model.js +104 -0
  783. package/dist/src/tui/model.js.map +1 -0
  784. package/dist/src/tui/mouse.js +83 -0
  785. package/dist/src/tui/mouse.js.map +1 -0
  786. package/dist/src/tui/msg.js +196 -0
  787. package/dist/src/tui/msg.js.map +1 -0
  788. package/dist/src/tui/nativecompanion.js +321 -0
  789. package/dist/src/tui/nativecompanion.js.map +1 -0
  790. package/dist/src/tui/openurl.js +17 -0
  791. package/dist/src/tui/openurl.js.map +1 -0
  792. package/dist/src/tui/paint.js +501 -0
  793. package/dist/src/tui/paint.js.map +1 -0
  794. package/dist/src/tui/panes.js +74 -0
  795. package/dist/src/tui/panes.js.map +1 -0
  796. package/dist/src/tui/pipane.js +166 -0
  797. package/dist/src/tui/pipane.js.map +1 -0
  798. package/dist/src/tui/poll-hooks.js +11 -0
  799. package/dist/src/tui/poll-hooks.js.map +1 -0
  800. package/dist/src/tui/poll.js +113 -0
  801. package/dist/src/tui/poll.js.map +1 -0
  802. package/dist/src/tui/proposals.js +715 -0
  803. package/dist/src/tui/proposals.js.map +1 -0
  804. package/dist/src/tui/prpause.js +132 -0
  805. package/dist/src/tui/prpause.js.map +1 -0
  806. package/dist/src/tui/reload.js +351 -0
  807. package/dist/src/tui/reload.js.map +1 -0
  808. package/dist/src/tui/remote.js +312 -0
  809. package/dist/src/tui/remote.js.map +1 -0
  810. package/dist/src/tui/rollover.js +767 -0
  811. package/dist/src/tui/rollover.js.map +1 -0
  812. package/dist/src/tui/scantab.js +1053 -0
  813. package/dist/src/tui/scantab.js.map +1 -0
  814. package/dist/src/tui/setupentry.js +81 -0
  815. package/dist/src/tui/setupentry.js.map +1 -0
  816. package/dist/src/tui/sidebar.js +602 -0
  817. package/dist/src/tui/sidebar.js.map +1 -0
  818. package/dist/src/tui/sshtriage.js +393 -0
  819. package/dist/src/tui/sshtriage.js.map +1 -0
  820. package/dist/src/tui/startup.js +172 -0
  821. package/dist/src/tui/startup.js.map +1 -0
  822. package/dist/src/tui/tabs.js +41 -0
  823. package/dist/src/tui/tabs.js.map +1 -0
  824. package/dist/src/tui/termmirror.js +217 -0
  825. package/dist/src/tui/termmirror.js.map +1 -0
  826. package/dist/src/tui/theme.js +95 -0
  827. package/dist/src/tui/theme.js.map +1 -0
  828. package/dist/src/tui/ticketstab.js +224 -0
  829. package/dist/src/tui/ticketstab.js.map +1 -0
  830. package/dist/src/tui/tmuxsocket.js +101 -0
  831. package/dist/src/tui/tmuxsocket.js.map +1 -0
  832. package/dist/src/tui/trackertickets.js +77 -0
  833. package/dist/src/tui/trackertickets.js.map +1 -0
  834. package/dist/src/tui/unwedge.js +245 -0
  835. package/dist/src/tui/unwedge.js.map +1 -0
  836. package/dist/src/tui/viewer.js +479 -0
  837. package/dist/src/tui/viewer.js.map +1 -0
  838. package/dist/src/tui/viewerinput.js +125 -0
  839. package/dist/src/tui/viewerinput.js.map +1 -0
  840. package/dist/src/updatenotice.js +143 -0
  841. package/dist/src/updatenotice.js.map +1 -0
  842. package/dist/src/usage.js +1007 -0
  843. package/dist/src/usage.js.map +1 -0
  844. package/dist/src/verdicts.js +3848 -0
  845. package/dist/src/verdicts.js.map +1 -0
  846. package/dist/src/version.js +58 -0
  847. package/dist/src/version.js.map +1 -0
  848. package/dist/src/wakes.js +411 -0
  849. package/dist/src/wakes.js.map +1 -0
  850. package/dist/src/webhook.js +725 -0
  851. package/dist/src/webhook.js.map +1 -0
  852. package/dist/src/webhookheal.js +238 -0
  853. package/dist/src/webhookheal.js.map +1 -0
  854. package/dist/src/wire.js +1801 -0
  855. package/dist/src/wire.js.map +1 -0
  856. package/dist/src/worker-session-host.js +531 -0
  857. package/dist/src/worker-session-host.js.map +1 -0
  858. package/dist/src/workerbreaker.js +112 -0
  859. package/dist/src/workerbreaker.js.map +1 -0
  860. package/dist/src/workercontrol.js +49 -0
  861. package/dist/src/workercontrol.js.map +1 -0
  862. package/dist/src/workerlease.js +351 -0
  863. package/dist/src/workerlease.js.map +1 -0
  864. package/dist/src/workerliveness.js +84 -0
  865. package/dist/src/workerliveness.js.map +1 -0
  866. package/dist/src/workerlog.js +65 -0
  867. package/dist/src/workerlog.js.map +1 -0
  868. package/dist/src/workerruntime.js +10 -0
  869. package/dist/src/workerruntime.js.map +1 -0
  870. package/dist/src/workersupervisor.js +1206 -0
  871. package/dist/src/workersupervisor.js.map +1 -0
  872. package/dist/src/workerusage.js +23 -0
  873. package/dist/src/workerusage.js.map +1 -0
  874. package/dist/src/workerworld.js +332 -0
  875. package/dist/src/workerworld.js.map +1 -0
  876. package/dist/src/worktrees.js +984 -0
  877. package/dist/src/worktrees.js.map +1 -0
  878. package/docker/Dockerfile +284 -0
  879. package/docker/Dockerfile.dockerignore +35 -0
  880. package/docker/README.md +221 -0
  881. package/docker/companion/Dockerfile +139 -0
  882. package/docker/companion/agents/evidence.md +34 -0
  883. package/docker/companion/agents/explore.md +26 -0
  884. package/docker/companion/agents/pass-survey.md +49 -0
  885. package/docker/companion/agents/study.md +26 -0
  886. package/docker/companion/entrypoint.sh +343 -0
  887. package/docker/companion/memory-health.mjs +269 -0
  888. package/docker/entrypoint.sh +782 -0
  889. package/docker/memory/Dockerfile +191 -0
  890. package/docker/memory/Dockerfile.dockerignore +20 -0
  891. package/docker/memory/README.md +60 -0
  892. package/docker/memory/entrypoint.sh +163 -0
  893. package/docker/setid/qcr-setid.c +109 -0
  894. package/docker/tunnel/Dockerfile.cloudflared +51 -0
  895. package/docker/tunnel/Dockerfile.ngrok +40 -0
  896. package/docker/tunnel/sidecar.mjs +411 -0
  897. package/docker/vm/tmux.conf +26 -0
  898. package/docker-compose.yml +348 -0
  899. package/extensions/cli/bash-guard-ambient.ts +71 -0
  900. package/extensions/cli/bash-guard.ts +12 -0
  901. package/extensions/cli/companion-guard.ts +8 -0
  902. package/extensions/cli/debug-round.ts +9 -0
  903. package/extensions/cli/inject-bridge.ts +8 -0
  904. package/extensions/cli/ledger-pin.ts +13 -0
  905. package/extensions/cli/lens.ts +22 -0
  906. package/extensions/cli/muted-theme.ts +9 -0
  907. package/extensions/cli/onboarding.ts +8 -0
  908. package/extensions/cli/setup.ts +8 -0
  909. package/extensions/cli/tui-view.ts +8 -0
  910. package/extensions/companion-guard.ts +411 -0
  911. package/extensions/debug-round.ts +281 -0
  912. package/extensions/inject-bridge.ts +630 -0
  913. package/extensions/inline-bash.ts +102 -0
  914. package/extensions/muted-theme.json +68 -0
  915. package/extensions/muted-theme.ts +23 -0
  916. package/extensions/onboarding.ts +233 -0
  917. package/extensions/setup-replay.ts +336 -0
  918. package/extensions/setup-scan.ts +1236 -0
  919. package/extensions/setup-triage.ts +190 -0
  920. package/extensions/setup.ts +1428 -0
  921. package/extensions/tui-view.ts +489 -0
  922. package/extensions/vendor/openviking-pi/LICENSE +201 -0
  923. package/extensions/vendor/openviking-pi/NOTICE +68 -0
  924. package/extensions/vendor/openviking-pi/README.md +550 -0
  925. package/extensions/vendor/openviking-pi/client.ts +588 -0
  926. package/extensions/vendor/openviking-pi/config.json +28 -0
  927. package/extensions/vendor/openviking-pi/config.ts +271 -0
  928. package/extensions/vendor/openviking-pi/index.ts +523 -0
  929. package/extensions/vendor/openviking-pi/lib/capture-adapter.d.mts +10 -0
  930. package/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +88 -0
  931. package/extensions/vendor/openviking-pi/lib/takeover-core.d.mts +80 -0
  932. package/extensions/vendor/openviking-pi/lib/takeover-core.mjs +406 -0
  933. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.d.mts +1 -0
  934. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +42 -0
  935. package/extensions/vendor/openviking-pi/patches/0000-vendoring-and-build-conformance.patch +726 -0
  936. package/extensions/vendor/openviking-pi/patches/0001-remove-session-before-compact-handler.patch +101 -0
  937. package/extensions/vendor/openviking-pi/patches/0002-no-ambient-work-in-subagent-leaves.patch +202 -0
  938. package/extensions/vendor/openviking-pi/patches/0003-never-auto-create-openviking-sessions.patch +120 -0
  939. package/extensions/vendor/openviking-pi/patches/0004-viking-write-durable-batch-write.patch +521 -0
  940. package/extensions/vendor/openviking-pi/patches/0005-second-memory-namespace.patch +786 -0
  941. package/extensions/vendor/openviking-pi/patches/0006-writes-that-stick-and-honest-errors.patch +996 -0
  942. package/extensions/vendor/openviking-pi/patches/0007-bounded-recall-no-commit.patch +794 -0
  943. package/extensions/vendor/openviking-pi/patches/0008-pr-derived-recall.patch +379 -0
  944. package/extensions/vendor/openviking-pi/patches/0009-pr-session-tools-in-round-areas.patch +375 -0
  945. package/extensions/vendor/openviking-pi/patches/0010-typed-lessons.patch +448 -0
  946. package/extensions/vendor/openviking-pi/patches/0011-review-session-memory-boundary.patch +382 -0
  947. package/extensions/vendor/openviking-pi/patches/0012-typecheck-against-the-real-pi.patch +129 -0
  948. package/extensions/vendor/openviking-pi/patches/0013-createopenviking-factory.patch +1168 -0
  949. package/extensions/vendor/openviking-pi/qcr-hint.ts +313 -0
  950. package/extensions/vendor/openviking-pi/qcr-honest.ts +183 -0
  951. package/extensions/vendor/openviking-pi/qcr-hooks.ts +87 -0
  952. package/extensions/vendor/openviking-pi/qcr-leaf.ts +78 -0
  953. package/extensions/vendor/openviking-pi/qcr-lesson.ts +231 -0
  954. package/extensions/vendor/openviking-pi/qcr-namespaces.ts +198 -0
  955. package/extensions/vendor/openviking-pi/qcr-recall.ts +288 -0
  956. package/extensions/vendor/openviking-pi/qcr-shim.ts +142 -0
  957. package/extensions/vendor/openviking-pi/qcr-write.ts +427 -0
  958. package/extensions/vendor/openviking-pi/recall.ts +149 -0
  959. package/extensions/vendor/openviking-pi/shared/capture-utils.d.mts +9 -0
  960. package/extensions/vendor/openviking-pi/shared/capture-utils.mjs +515 -0
  961. package/extensions/vendor/openviking-pi/shared/credentials.d.mts +14 -0
  962. package/extensions/vendor/openviking-pi/shared/credentials.mjs +228 -0
  963. package/extensions/vendor/openviking-pi/shared/pending-queue.d.mts +19 -0
  964. package/extensions/vendor/openviking-pi/shared/pending-queue.mjs +458 -0
  965. package/extensions/vendor/openviking-pi/shared/profile-inject.d.mts +17 -0
  966. package/extensions/vendor/openviking-pi/shared/profile-inject.mjs +294 -0
  967. package/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +195 -0
  968. package/extensions/vendor/openviking-pi/shared/recall-core.d.mts +13 -0
  969. package/extensions/vendor/openviking-pi/shared/recall-core.mjs +609 -0
  970. package/extensions/vendor/openviking-pi/shared/retryable.mjs +9 -0
  971. package/extensions/vendor/openviking-pi/shared/session-model.d.mts +3 -0
  972. package/extensions/vendor/openviking-pi/shared/session-model.mjs +57 -0
  973. package/extensions/vendor/openviking-pi/shared/uri-guard.mjs +56 -0
  974. package/extensions/vendor/openviking-pi/shared/workspace-peer.d.mts +5 -0
  975. package/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  976. package/extensions/vendor/openviking-pi/sync.ts +163 -0
  977. package/extensions/vendor/openviking-pi/takeover.ts +36 -0
  978. package/extensions/vendor/openviking-pi/tools.ts +479 -0
  979. package/extensions/vendor/openviking-pi/upstream.json +48 -0
  980. package/package.json +138 -4
  981. package/profiles/default/README.md +21 -0
  982. package/profiles/default/addenda/.gitkeep +0 -0
  983. package/profiles/default/profile.toml +17 -0
  984. package/profiles/example-django/README.md +21 -0
  985. package/profiles/example-django/addenda/10-migration-discipline.md +13 -0
  986. package/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
  987. package/profiles/example-django/addenda/30-test-doctrine.md +12 -0
  988. package/profiles/example-django/addenda/40-orm-usage.md +19 -0
  989. package/profiles/example-django/addenda/50-declared-shape.md +10 -0
  990. package/profiles/example-django/addenda/60-config-placement.md +14 -0
  991. package/profiles/example-django/heuristics.toml +24 -0
  992. package/profiles/example-django/profile.toml +9 -0
  993. package/profiles/fast/README.md +24 -0
  994. package/profiles/fast/profile.toml +59 -0
  995. package/profiles/minimal/README.md +17 -0
  996. package/profiles/minimal/addenda/.gitkeep +0 -0
  997. package/profiles/minimal/profile.toml +8 -0
  998. package/profiles/snappy/README.md +24 -0
  999. package/profiles/snappy/addenda/10-race-as-question.md +6 -0
  1000. package/profiles/snappy/profile.toml +46 -0
  1001. package/prompts/companion-day-open.md +46 -0
  1002. package/prompts/companion-first-run.md +104 -0
  1003. package/prompts/companion.md +821 -0
  1004. package/prompts/conversation-system.md +117 -0
  1005. package/prompts/eod-sweep.md +120 -0
  1006. package/prompts/onboarding.md +74 -0
  1007. package/prompts/pass-common.md +52 -0
  1008. package/prompts/pass-quality-common.md +22 -0
  1009. package/prompts/round-first.md +874 -0
  1010. package/prompts/round-follow-up.md +991 -0
  1011. package/prompts/round-re-review.md +889 -0
  1012. package/prompts/round-recheck.md +196 -0
  1013. package/prompts/round-staleness.md +856 -0
  1014. package/schemas/review-result.v1.json +391 -0
  1015. package/schemas/scan-result.v1.json +421 -0
  1016. package/schemas/version.v1.json +57 -0
  1017. package/scripts/approve-pr.sh +16 -0
  1018. package/scripts/build-stamp.mjs +67 -0
  1019. package/scripts/commit-verdict.sh +155 -0
  1020. package/scripts/companion-e2e.sh +250 -0
  1021. package/scripts/companion-memory-forward.mjs +1966 -0
  1022. package/scripts/config-fingerprint.sh +28 -0
  1023. package/scripts/deploy-manifest.mjs +141 -0
  1024. package/scripts/deploy.sh +1435 -0
  1025. package/scripts/directory-lock.mjs +193 -0
  1026. package/scripts/heartbeat-fresh.mjs +54 -0
  1027. package/scripts/install-locator.sh +328 -0
  1028. package/scripts/install-wrapper.sh +76 -0
  1029. package/scripts/memory-search-check.mjs +98 -0
  1030. package/scripts/mint-token.sh +212 -0
  1031. package/scripts/openviking-embedder.py +392 -0
  1032. package/scripts/openviking-ov-conf.mjs +161 -0
  1033. package/scripts/openviking-provision.mjs +1122 -0
  1034. package/scripts/openviking-reembed.mjs +1154 -0
  1035. package/scripts/post-review.sh +16 -0
  1036. package/scripts/pr-checks.sh +256 -0
  1037. package/scripts/pr-context.py +174 -0
  1038. package/scripts/pr-context.sh +63 -0
  1039. package/scripts/pr-self.sh +144 -0
  1040. package/scripts/pr-threads.sh +145 -0
  1041. package/scripts/qcr +15 -0
  1042. package/scripts/qcr-host.sh +769 -0
  1043. package/scripts/render-review.sh +24 -0
  1044. package/scripts/reply-thread.sh +16 -0
  1045. package/scripts/required-passes.py +112 -0
  1046. package/scripts/smoke-companion.sh +211 -0
  1047. package/scripts/tui-deploy-runner.mjs +61 -0
  1048. package/scripts/verify-dist.mjs +201 -0
  1049. package/scripts/vm-ghcr-login.sh +188 -0
  1050. package/seeds/agents/pass-baseline.md +61 -0
  1051. package/seeds/agents/pass-contracts.md +30 -0
  1052. package/seeds/agents/pass-data-safety.md +54 -0
  1053. package/seeds/agents/pass-delivery.md +37 -0
  1054. package/seeds/agents/pass-prod-risk.md +24 -0
  1055. package/seeds/agents/pass-security.md +31 -0
  1056. package/seeds/agents/pass-statelessness.md +27 -0
  1057. package/seeds/agents/pass-ui.md +23 -0
  1058. package/seeds/agents/pass-validate.md +50 -0
  1059. package/seeds/prompts/conversation-system.md +117 -0
  1060. package/seeds/prompts/eod-sweep.md +120 -0
  1061. package/seeds/prompts/pass-common.md +52 -0
  1062. package/skills/companion/adjudicate/SKILL.md +247 -0
  1063. package/skills/companion/evidence/SKILL.md +150 -0
  1064. package/skills/companion/land/SKILL.md +200 -0
  1065. package/skills/companion/replay/SKILL.md +138 -0
  1066. package/skills/companion/setup/SKILL.md +167 -0
  1067. package/skills/companion/survey/SKILL.md +160 -0
  1068. package/skills/selfimprove/README.md +34 -0
  1069. package/skills/selfimprove/SKILL.md +127 -0
  1070. package/skills/selfimprove/agents/openai.yaml +2 -0
  1071. package/skills/selfimprove/commands/selfimprove.md +6 -0
  1072. package/skills/selfimprove/references/fix-loop.md +49 -0
  1073. package/skills/selfimprove/references/ledger.md +20 -0
  1074. package/skills/selfimprove/references/setup.md +40 -0
  1075. package/src/anomalies.ts +566 -0
  1076. package/src/answerworker.ts +251 -0
  1077. package/src/appstamp.ts +65 -0
  1078. package/src/archive/admission.ts +3 -0
  1079. package/src/archive/archivedb.ts +548 -0
  1080. package/src/archive/archiver.ts +1963 -0
  1081. package/src/archive/archivewrite.ts +279 -0
  1082. package/src/archive/bundle.ts +333 -0
  1083. package/src/archive/dbmove.ts +911 -0
  1084. package/src/archive/duplicatecounts.ts +98 -0
  1085. package/src/archive/eligibility.ts +181 -0
  1086. package/src/archive/extract.ts +342 -0
  1087. package/src/archive/fsutil.ts +415 -0
  1088. package/src/archive/gzfile.ts +370 -0
  1089. package/src/archive/kinds.ts +21 -0
  1090. package/src/archive/livecheckpoint.ts +217 -0
  1091. package/src/archive/liveretention.ts +180 -0
  1092. package/src/archive/manifest.ts +519 -0
  1093. package/src/archive/overseer.ts +336 -0
  1094. package/src/archive/piglobal.ts +174 -0
  1095. package/src/archive/plan.ts +612 -0
  1096. package/src/archive/prarchive.ts +984 -0
  1097. package/src/archive/prfiles.ts +406 -0
  1098. package/src/archive/report.ts +252 -0
  1099. package/src/archive/restore.ts +330 -0
  1100. package/src/archive/rows.ts +187 -0
  1101. package/src/archive/seal.ts +630 -0
  1102. package/src/archive/status.ts +719 -0
  1103. package/src/archive/storepass.ts +581 -0
  1104. package/src/backfill.ts +362 -0
  1105. package/src/bench/cost.ts +113 -0
  1106. package/src/bench/exec.ts +90 -0
  1107. package/src/bench/values.ts +13 -0
  1108. package/src/botcontrol.ts +176 -0
  1109. package/src/botworker.ts +953 -0
  1110. package/src/capture.ts +321 -0
  1111. package/src/cases.ts +1789 -0
  1112. package/src/channelfs.ts +26 -0
  1113. package/src/checklist.ts +506 -0
  1114. package/src/ciretry.ts +141 -0
  1115. package/src/cli.ts +2271 -0
  1116. package/src/cliops.ts +384 -0
  1117. package/src/clonedir.ts +15 -0
  1118. package/src/commandeffects.ts +57 -0
  1119. package/src/commands.ts +1678 -0
  1120. package/src/companioninbox.ts +239 -0
  1121. package/src/compare.ts +957 -0
  1122. package/src/config.ts +2050 -0
  1123. package/src/configcheck.ts +133 -0
  1124. package/src/coreext.ts +47 -0
  1125. package/src/daemon.ts +1302 -0
  1126. package/src/debuground.ts +927 -0
  1127. package/src/debugroundpi.ts +262 -0
  1128. package/src/diagnostics.ts +14 -0
  1129. package/src/digest.ts +183 -0
  1130. package/src/dispatch.ts +2250 -0
  1131. package/src/engine/answerguard.ts +27 -0
  1132. package/src/engine/botsdk.ts +336 -0
  1133. package/src/engine/caserunner-sdk.ts +423 -0
  1134. package/src/engine/debugpi.ts +235 -0
  1135. package/src/eod.ts +669 -0
  1136. package/src/eodpinwatch.ts +556 -0
  1137. package/src/escalation.ts +1253 -0
  1138. package/src/eventloop.ts +1045 -0
  1139. package/src/execboundary.ts +633 -0
  1140. package/src/feedback.ts +1162 -0
  1141. package/src/findingscheck.ts +298 -0
  1142. package/src/fsdenied.ts +24 -0
  1143. package/src/ghread.ts +242 -0
  1144. package/src/github.ts +1497 -0
  1145. package/src/homes.ts +175 -0
  1146. package/src/hostroute.ts +53 -0
  1147. package/src/improvements.ts +787 -0
  1148. package/src/install.ts +1103 -0
  1149. package/src/installkind.ts +50 -0
  1150. package/src/ipc/capability.ts +333 -0
  1151. package/src/ipc/client.ts +269 -0
  1152. package/src/ipc/control.ts +90 -0
  1153. package/src/ipc/ghreadshim.ts +94 -0
  1154. package/src/ipc/launcher.ts +65 -0
  1155. package/src/ipc/permits.ts +362 -0
  1156. package/src/ipc/postshim.ts +164 -0
  1157. package/src/ipc/protocol.ts +342 -0
  1158. package/src/ipc/server.ts +371 -0
  1159. package/src/ipc/workerspec.ts +218 -0
  1160. package/src/learner/learner.ts +1655 -0
  1161. package/src/learner/miner.ts +1290 -0
  1162. package/src/learner/packet.ts +340 -0
  1163. package/src/learner/receipt.ts +168 -0
  1164. package/src/learner/status.ts +107 -0
  1165. package/src/ledgercheck.ts +157 -0
  1166. package/src/lessonledger.ts +703 -0
  1167. package/src/lessonselect.ts +888 -0
  1168. package/src/lessonshadow.ts +810 -0
  1169. package/src/levers.ts +393 -0
  1170. package/src/live/projection.ts +491 -0
  1171. package/src/live/publish.ts +92 -0
  1172. package/src/live/read.ts +86 -0
  1173. package/src/livecli.ts +336 -0
  1174. package/src/loginhint.ts +56 -0
  1175. package/src/loginrefresh/atomic.ts +76 -0
  1176. package/src/loginrefresh/lock.ts +104 -0
  1177. package/src/loginrefresh/main.ts +59 -0
  1178. package/src/loginrefresh/pirefresh.ts +57 -0
  1179. package/src/loginrefresh/refresher.ts +326 -0
  1180. package/src/loginrefresh/supervisor.ts +273 -0
  1181. package/src/loginrefresh/types.ts +35 -0
  1182. package/src/memory/context.ts +385 -0
  1183. package/src/memory/datafence.ts +9 -0
  1184. package/src/memory/delivery.ts +171 -0
  1185. package/src/memory/eventtags.ts +80 -0
  1186. package/src/memory/health.ts +953 -0
  1187. package/src/memory/import.ts +664 -0
  1188. package/src/memory/layout.ts +261 -0
  1189. package/src/memory/legacy-file.ts +104 -0
  1190. package/src/memory/lessons.ts +447 -0
  1191. package/src/memory/ovsession.ts +601 -0
  1192. package/src/memory/relayout.ts +335 -0
  1193. package/src/memory/roundactivity.ts +209 -0
  1194. package/src/memory/selection.ts +989 -0
  1195. package/src/memory/shadowstatus.ts +125 -0
  1196. package/src/memory/store.ts +275 -0
  1197. package/src/memory/textidentity.ts +8 -0
  1198. package/src/metrics.ts +1056 -0
  1199. package/src/missingconfig.ts +7 -0
  1200. package/src/npmverbs.ts +264 -0
  1201. package/src/onboard/choices.ts +222 -0
  1202. package/src/onboard/engine.ts +518 -0
  1203. package/src/onboard/launch.ts +115 -0
  1204. package/src/onboard/steps/appslug.ts +265 -0
  1205. package/src/onboard/steps/bringup.ts +482 -0
  1206. package/src/onboard/steps/compose.ts +459 -0
  1207. package/src/onboard/steps/configdelivery.ts +58 -0
  1208. package/src/onboard/steps/configfill.ts +1352 -0
  1209. package/src/onboard/steps/deploysh.ts +105 -0
  1210. package/src/onboard/steps/embeddings.ts +550 -0
  1211. package/src/onboard/steps/escalation.ts +640 -0
  1212. package/src/onboard/steps/githubapp.ts +1414 -0
  1213. package/src/onboard/steps/golive.ts +577 -0
  1214. package/src/onboard/steps/index.ts +71 -0
  1215. package/src/onboard/steps/ingress.ts +907 -0
  1216. package/src/onboard/steps/inventory.ts +526 -0
  1217. package/src/onboard/steps/llmauth.ts +1095 -0
  1218. package/src/onboard/steps/memory.ts +1290 -0
  1219. package/src/onboard/steps/memorykeys.ts +85 -0
  1220. package/src/onboard/steps/preflight.ts +191 -0
  1221. package/src/onboard/steps/proof.ts +624 -0
  1222. package/src/onboard/steps/ssh.ts +377 -0
  1223. package/src/onboard/steps/topology.ts +337 -0
  1224. package/src/onboard/steps/transport.ts +665 -0
  1225. package/src/onboard/steps/verifyup.ts +448 -0
  1226. package/src/onboard/steps/vmdeploy.ts +442 -0
  1227. package/src/onboard/toml.ts +50 -0
  1228. package/src/opencli.ts +591 -0
  1229. package/src/openpr.ts +568 -0
  1230. package/src/openviking/client.ts +1131 -0
  1231. package/src/openviking/context.ts +263 -0
  1232. package/src/openviking/embedder.ts +516 -0
  1233. package/src/openviking/gapsink.ts +63 -0
  1234. package/src/openviking/health.ts +83 -0
  1235. package/src/openviking/index.ts +119 -0
  1236. package/src/openviking/lessonfind.ts +92 -0
  1237. package/src/openviking/probe.ts +129 -0
  1238. package/src/openviking/proc.ts +110 -0
  1239. package/src/openviking/provisionreport.ts +160 -0
  1240. package/src/openviking/reembed.ts +412 -0
  1241. package/src/openviking/relayout.ts +177 -0
  1242. package/src/openviking/sidecar-main.ts +38 -0
  1243. package/src/openviking/sidecar.ts +106 -0
  1244. package/src/openviking/store.ts +2025 -0
  1245. package/src/openviking/supervisor.ts +474 -0
  1246. package/src/openviking/types.ts +174 -0
  1247. package/src/operator-recovery.ts +237 -0
  1248. package/src/operatormessage.ts +52 -0
  1249. package/src/outcomes.ts +1670 -0
  1250. package/src/piauthcopy.ts +12 -0
  1251. package/src/picli.ts +49 -0
  1252. package/src/picwd.ts +25 -0
  1253. package/src/pilogin.ts +37 -0
  1254. package/src/pingpong.ts +1339 -0
  1255. package/src/posting-journal.ts +549 -0
  1256. package/src/posting-outbox.ts +802 -0
  1257. package/src/posting-receipt.ts +324 -0
  1258. package/src/posting.ts +603 -0
  1259. package/src/postops.ts +832 -0
  1260. package/src/pr-activity.ts +20 -0
  1261. package/src/pr-author.ts +6 -0
  1262. package/src/pr-conversation.ts +432 -0
  1263. package/src/pr-session-lifecycle.ts +631 -0
  1264. package/src/preflight.ts +391 -0
  1265. package/src/priorresolve.ts +343 -0
  1266. package/src/qcrbin.ts +186 -0
  1267. package/src/recheck.ts +1775 -0
  1268. package/src/reconcile.ts +1030 -0
  1269. package/src/recordedfindings.ts +27 -0
  1270. package/src/regression.ts +833 -0
  1271. package/src/replay.ts +816 -0
  1272. package/src/requiredpasses.ts +148 -0
  1273. package/src/resumecheck.ts +246 -0
  1274. package/src/reviewcli.ts +787 -0
  1275. package/src/reviewcontext.ts +35 -0
  1276. package/src/reviewdetach.ts +734 -0
  1277. package/src/reviewhistory.ts +427 -0
  1278. package/src/reviewhome.ts +36 -0
  1279. package/src/reviewmemory.ts +133 -0
  1280. package/src/reviewrendercli.ts +139 -0
  1281. package/src/round-work.ts +42 -0
  1282. package/src/runhost.ts +108 -0
  1283. package/src/scanauth.ts +36 -0
  1284. package/src/scanbox.ts +1081 -0
  1285. package/src/scancli.ts +1296 -0
  1286. package/src/scandriverlog.ts +32 -0
  1287. package/src/session-bridge.ts +139 -0
  1288. package/src/session-command-payload.ts +35 -0
  1289. package/src/session-command-supervisor.ts +1142 -0
  1290. package/src/sessionjsonl.ts +88 -0
  1291. package/src/sessions.ts +659 -0
  1292. package/src/setup/adapters.ts +335 -0
  1293. package/src/setup/baselines.ts +110 -0
  1294. package/src/setup/caserunner.ts +611 -0
  1295. package/src/setup/configcommit.ts +443 -0
  1296. package/src/setup/engine.ts +1001 -0
  1297. package/src/setup/facts.ts +627 -0
  1298. package/src/setup/findings.ts +1264 -0
  1299. package/src/setup/history.ts +443 -0
  1300. package/src/setup/interview.ts +243 -0
  1301. package/src/setup/ledger.ts +324 -0
  1302. package/src/setup/pins.ts +66 -0
  1303. package/src/setup/portrait.ts +635 -0
  1304. package/src/setup/presentation.ts +18 -0
  1305. package/src/setup/profile.ts +508 -0
  1306. package/src/setup/replay.ts +370 -0
  1307. package/src/setup/replaybuild.ts +392 -0
  1308. package/src/setup/replayrun.ts +1096 -0
  1309. package/src/setup/replaysource.ts +198 -0
  1310. package/src/setup/retune.ts +415 -0
  1311. package/src/setup/retunelog.ts +95 -0
  1312. package/src/setup/scan.ts +1033 -0
  1313. package/src/setup/scanbuild.ts +168 -0
  1314. package/src/setup/scanfacts.ts +107 -0
  1315. package/src/setup/scanlease.ts +297 -0
  1316. package/src/setup/scanreport.ts +373 -0
  1317. package/src/setup/scanrun.ts +2268 -0
  1318. package/src/setup/scantree.ts +259 -0
  1319. package/src/setup/stage2.ts +926 -0
  1320. package/src/setup/stage2request.ts +347 -0
  1321. package/src/setup/survey.ts +458 -0
  1322. package/src/setup/surveyrun.ts +758 -0
  1323. package/src/setup/textsniff.ts +95 -0
  1324. package/src/setup/trackersink.ts +433 -0
  1325. package/src/setup/triage.ts +768 -0
  1326. package/src/setup/tuning.ts +766 -0
  1327. package/src/setup/unitcut.ts +523 -0
  1328. package/src/singleflight.ts +86 -0
  1329. package/src/slack/announce.ts +911 -0
  1330. package/src/slack/api.ts +303 -0
  1331. package/src/slack/messages.ts +288 -0
  1332. package/src/slack/origin.ts +599 -0
  1333. package/src/slack/policy.ts +354 -0
  1334. package/src/slack/reply.ts +201 -0
  1335. package/src/slack/router.ts +285 -0
  1336. package/src/slack/socket.ts +384 -0
  1337. package/src/slack/types.ts +108 -0
  1338. package/src/sqlitehint.ts +32 -0
  1339. package/src/ssh-observation.ts +30 -0
  1340. package/src/state.ts +8243 -0
  1341. package/src/statemachine.ts +369 -0
  1342. package/src/stubs.ts +68 -0
  1343. package/src/takeover.ts +634 -0
  1344. package/src/takeoverpi.ts +293 -0
  1345. package/src/terminal-failure.ts +41 -0
  1346. package/src/thread-resolution-refusal.ts +2 -0
  1347. package/src/tmux.ts +153 -0
  1348. package/src/trackerid.ts +41 -0
  1349. package/src/transcriptindex.ts +665 -0
  1350. package/src/tui/actions.ts +484 -0
  1351. package/src/tui/alerts.ts +666 -0
  1352. package/src/tui/app.ts +1979 -0
  1353. package/src/tui/archiveops.ts +192 -0
  1354. package/src/tui/autofile.ts +233 -0
  1355. package/src/tui/board.ts +1432 -0
  1356. package/src/tui/candidates.ts +889 -0
  1357. package/src/tui/cellwidth.ts +148 -0
  1358. package/src/tui/changelog-store.ts +503 -0
  1359. package/src/tui/chord.ts +25 -0
  1360. package/src/tui/clipboard.ts +92 -0
  1361. package/src/tui/cmdbar.ts +296 -0
  1362. package/src/tui/companion.ts +1427 -0
  1363. package/src/tui/companionplan.ts +247 -0
  1364. package/src/tui/companiontab.ts +83 -0
  1365. package/src/tui/confighome.ts +155 -0
  1366. package/src/tui/connect.ts +68 -0
  1367. package/src/tui/deploy-ceremony.ts +104 -0
  1368. package/src/tui/deploy-drain.ts +129 -0
  1369. package/src/tui/deploy-process.ts +265 -0
  1370. package/src/tui/deploytab.ts +1523 -0
  1371. package/src/tui/design.ts +125 -0
  1372. package/src/tui/digesttab.ts +214 -0
  1373. package/src/tui/emptystate.ts +39 -0
  1374. package/src/tui/evidence.ts +999 -0
  1375. package/src/tui/feed.ts +604 -0
  1376. package/src/tui/feedbacktab.ts +1077 -0
  1377. package/src/tui/filters.ts +90 -0
  1378. package/src/tui/ghread.ts +321 -0
  1379. package/src/tui/historypull.ts +81 -0
  1380. package/src/tui/inboxpull.ts +236 -0
  1381. package/src/tui/index.ts +1565 -0
  1382. package/src/tui/issuesink.ts +238 -0
  1383. package/src/tui/jsonfile.ts +42 -0
  1384. package/src/tui/keys.ts +109 -0
  1385. package/src/tui/layout.ts +108 -0
  1386. package/src/tui/learning.ts +627 -0
  1387. package/src/tui/lessonswitch.ts +118 -0
  1388. package/src/tui/livecontrol.ts +228 -0
  1389. package/src/tui/memforward.ts +443 -0
  1390. package/src/tui/memincident.ts +363 -0
  1391. package/src/tui/memory.ts +620 -0
  1392. package/src/tui/memtab.ts +606 -0
  1393. package/src/tui/metricstab.ts +1177 -0
  1394. package/src/tui/model.ts +131 -0
  1395. package/src/tui/mouse.ts +98 -0
  1396. package/src/tui/msg.ts +268 -0
  1397. package/src/tui/nativecompanion.ts +417 -0
  1398. package/src/tui/openurl.ts +21 -0
  1399. package/src/tui/paint.ts +511 -0
  1400. package/src/tui/panes.ts +98 -0
  1401. package/src/tui/pipane.ts +219 -0
  1402. package/src/tui/poll-hooks.ts +12 -0
  1403. package/src/tui/poll.ts +147 -0
  1404. package/src/tui/proposals.ts +838 -0
  1405. package/src/tui/prpause.ts +150 -0
  1406. package/src/tui/reload.ts +436 -0
  1407. package/src/tui/remote.ts +413 -0
  1408. package/src/tui/rollover.ts +969 -0
  1409. package/src/tui/scantab.ts +1290 -0
  1410. package/src/tui/setupentry.ts +93 -0
  1411. package/src/tui/sidebar.ts +749 -0
  1412. package/src/tui/sshtriage.ts +510 -0
  1413. package/src/tui/startup.ts +231 -0
  1414. package/src/tui/tabs.ts +45 -0
  1415. package/src/tui/termmirror.ts +224 -0
  1416. package/src/tui/theme.ts +95 -0
  1417. package/src/tui/ticketstab.ts +310 -0
  1418. package/src/tui/tmuxsocket.ts +129 -0
  1419. package/src/tui/trackertickets.ts +84 -0
  1420. package/src/tui/unwedge.ts +286 -0
  1421. package/src/tui/viewer.ts +575 -0
  1422. package/src/tui/viewerinput.ts +173 -0
  1423. package/src/updatenotice.ts +178 -0
  1424. package/src/usage.ts +1154 -0
  1425. package/src/verdicts.ts +4689 -0
  1426. package/src/version.ts +80 -0
  1427. package/src/wakes.ts +476 -0
  1428. package/src/webhook.ts +942 -0
  1429. package/src/webhookheal.ts +276 -0
  1430. package/src/wire.ts +2153 -0
  1431. package/src/worker-session-host.ts +602 -0
  1432. package/src/workerbreaker.ts +156 -0
  1433. package/src/workercontrol.ts +104 -0
  1434. package/src/workerlease.ts +441 -0
  1435. package/src/workerliveness.ts +103 -0
  1436. package/src/workerlog.ts +79 -0
  1437. package/src/workerruntime.ts +30 -0
  1438. package/src/workersupervisor.ts +1538 -0
  1439. package/src/workerusage.ts +42 -0
  1440. package/src/workerworld.ts +427 -0
  1441. package/src/worktrees.ts +1138 -0
  1442. package/tests/fixtures/regression-cases.json +795 -0
  1443. package/tests/fixtures/seed-manifest.json +19 -0
@@ -0,0 +1,1142 @@
1
+ // Bounded daemon→Pi stage supervision.
2
+ //
3
+ // This is a reconciler over the ONE durable session-command slot, not another
4
+ // scheduler. Delivery remains inject-bridge-owned; round recovery remains the
5
+ // VerdictWatcher's existing self-requeue path. The supervisor only classifies
6
+ // finite start/finish obligations from durable command state + JSONL receipts.
7
+ import { roundStageDeadlines } from "@quickchatai/pi-quickreview/src/round-stage-deadlines.js";
8
+ import { existsSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import {
11
+ DEFAULT_MAX_PROMPT_REDELIVERIES,
12
+ DEFAULT_ROUND_FINALIZE_GRACE_MIN,
13
+ DEFAULT_ROUND_FIRST_PASS_MAX_MIN,
14
+ DEFAULT_ROUND_PASSES_MAX_MIN,
15
+ DEFAULT_ROUND_STAGE_SUPERVISOR_STALE_S,
16
+ DEFAULT_SESSION_COMMAND_MAX_START_RETRIES,
17
+ DEFAULT_SESSION_COMMAND_RUNNING_MAX_MIN,
18
+ DEFAULT_SESSION_COMMAND_UNKNOWN_GRACE_S,
19
+ DEFAULT_FOLLOW_UP_SWEEP_EXTRA_MIN,
20
+ resolveRoundStageBounds,
21
+ type Config,
22
+ } from "./config.js";
23
+ import {
24
+ sameSessionCommandOwner,
25
+ sessionCommandMarker,
26
+ } from "@quickchatai/pi-quickreview/src/session-command.js";
27
+ import {
28
+ isTerminalAgentStatus,
29
+ executionsComplete,
30
+ lensForAgent,
31
+ plannedFanoutAgents,
32
+ type RoundProgressSnapshot,
33
+ } from "@quickchatai/pi-quickreview/src/round-progress.js";
34
+ import type { RoundRow, SessionCommandRow, StateStore, SupervisorLeaseRow } from "./state.js";
35
+ import type {
36
+ RoundRecoveryDisposition,
37
+ SessionHooks,
38
+ } from "@quickchatai/pi-quickreview/src/types.js";
39
+
40
+ export const ROUND_STAGE_SUPERVISOR = "round-stage";
41
+
42
+ /** How far a progress snapshot's run start may sit from the command's durable
43
+ * start and still be the same run. */
44
+ const RUN_START_TOLERANCE_MS = 5_000;
45
+
46
+ function runStartsNear(commandStart: string, progressStart: string): boolean {
47
+ const started = Date.parse(commandStart);
48
+ const runStarted = Date.parse(progressStart);
49
+ return (
50
+ Number.isFinite(started) &&
51
+ Number.isFinite(runStarted) &&
52
+ Math.abs(runStarted - started) <= RUN_START_TOLERANCE_MS
53
+ );
54
+ }
55
+
56
+ export type RoundInfrastructureStage =
57
+ | "command_start"
58
+ | "first_pass_start"
59
+ | "passes_incomplete"
60
+ | "parent_finalize"
61
+ | "settled_without_verdict"
62
+ | "running_hard_bound";
63
+
64
+ export interface SessionCommandSupervisorDeps {
65
+ cfg: Config;
66
+ store: StateStore;
67
+ hooks: SessionHooks;
68
+ verdictDir: string;
69
+ /** Independent observational sidecar, trusted only when it names the
70
+ * command exactly. It corroborates a durable start that settled after the
71
+ * bridge died, supplies the start ORIGIN (and so the fixed hard deadline)
72
+ * when the bridge missed its start stamp, and drives the earlier pass-stage
73
+ * bounds; it never creates or renews a lease. */
74
+ progress?: (pr: number) => RoundProgressSnapshot | undefined;
75
+ /** Existing bounded round recovery. `requeued` = fresh round queued;
76
+ * `exhausted` = its recovery budget is spent and failed work remains owed;
77
+ * `retryable` = re-check later; `settled` = the round terminalized cleanly;
78
+ * `posted_wait` = its review is already posted, so the session keeps its
79
+ * command while it finishes (see `failRound` for each). */
80
+ onRoundFailure: (
81
+ pr: number,
82
+ roundNo: number,
83
+ stage: RoundInfrastructureStage,
84
+ detail: string,
85
+ ) => Promise<RoundRecoveryDisposition>;
86
+ now?: () => Date;
87
+ }
88
+
89
+ export interface RoundStageSupervisorHealth {
90
+ healthy: boolean;
91
+ stale_after_s: number;
92
+ last_attempt_at: string | null;
93
+ last_success_at: string | null;
94
+ last_error_at: string | null;
95
+ last_error: string | null;
96
+ }
97
+
98
+ export class SessionCommandSupervisor {
99
+ private readonly now: () => Date;
100
+ private inFlight = false;
101
+ /** Commands whose finalize hold was already logged (one event each). */
102
+ private readonly finalizeHeld = new Set<string>();
103
+
104
+ constructor(private readonly deps: SessionCommandSupervisorDeps) {
105
+ this.now = deps.now ?? (() => new Date());
106
+ }
107
+
108
+ /** One non-overlapping scan. A second timer firing while this awaits Pi
109
+ * evidence returns without touching success, so the durable lease ages and
110
+ * status becomes unhealthy even though the process heartbeat still moves. */
111
+ async scan(): Promise<void> {
112
+ if (this.inFlight) return;
113
+ this.inFlight = true;
114
+ const attemptedAt = this.now().toISOString();
115
+ try {
116
+ this.deps.store.markSupervisorAttempt(ROUND_STAGE_SUPERVISOR, attemptedAt);
117
+ const candidates = new Map<string, SessionCommandRow>();
118
+ for (const command of this.deps.store.dueSessionCommands(attemptedAt))
119
+ candidates.set(command.id, command);
120
+ // A bridge can die after archiving the settled file but before its ack
121
+ // UPDATE. Exact command-correlated progress lets us reconcile that gap
122
+ // immediately instead of waiting for the 45-minute hard deadline.
123
+ for (const command of this.deps.store.activeSessionCommands())
124
+ candidates.set(command.id, command);
125
+ // One command's failure (a kill that keeps failing, a missing hook)
126
+ // leaves the scan red, but never costs the commands after it their
127
+ // inspection: each is its own obligation.
128
+ let failed: { error: unknown } | undefined;
129
+ for (const command of candidates.values()) {
130
+ try {
131
+ await this.inspect(command);
132
+ } catch (error) {
133
+ failed ??= { error };
134
+ this.deps.store.logEvent("round_stage_supervisor_command_error", command.pr, {
135
+ command_id: command.id,
136
+ round_no: command.round_no,
137
+ error: String(error),
138
+ });
139
+ }
140
+ }
141
+ if (failed) throw failed.error;
142
+ this.deps.store.markSupervisorSuccess(ROUND_STAGE_SUPERVISOR, this.now().toISOString());
143
+ } catch (error) {
144
+ this.deps.store.markSupervisorError(
145
+ ROUND_STAGE_SUPERVISOR,
146
+ String(error),
147
+ this.now().toISOString(),
148
+ );
149
+ throw error;
150
+ } finally {
151
+ this.inFlight = false;
152
+ }
153
+ }
154
+
155
+ health(at = this.now()): RoundStageSupervisorHealth {
156
+ return roundStageSupervisorHealth(
157
+ this.deps.store.supervisorLease(ROUND_STAGE_SUPERVISOR),
158
+ this.deps.cfg.daemon.round_stage_supervisor_stale_s ?? DEFAULT_ROUND_STAGE_SUPERVISOR_STALE_S,
159
+ at,
160
+ );
161
+ }
162
+
163
+ private async finishTerminalRoundCommand(command: SessionCommandRow): Promise<void> {
164
+ // The merits lifecycle already won, but Pi never durably settled. Stop the
165
+ // stale parent before releasing the unique slot; a failed kill leaves the
166
+ // running row due and supervisor health red.
167
+ if (!this.deps.hooks.killSession)
168
+ throw new Error(`cannot release terminal-round command ${command.id}: kill hook unavailable`);
169
+ if ((await this.deps.hooks.killSession(command.pr, command)) === false) return;
170
+ if (!sameSessionCommandOwner(this.deps.store.getSessionCommand(command.id), command)) return;
171
+ const released =
172
+ command.started_at === null
173
+ ? this.deps.store.failActiveSessionCommand(
174
+ command.id,
175
+ `round ${command.round_no} terminal before correlated command start`,
176
+ )
177
+ : this.deps.store.ackSettledSessionCommand(command.id);
178
+ if (released) {
179
+ this.deps.store.logEvent("terminal_round_command_released", command.pr, {
180
+ command_id: command.id,
181
+ round_no: command.round_no,
182
+ });
183
+ }
184
+ }
185
+
186
+ /** Within the finalize grace of the verdict FILE that ended `round`. A
187
+ * round the daemon settled from its posting receipt (the session never
188
+ * wrote a usable verdict) has no healthy tail to wait for. */
189
+ private inVerdictTail(round: RoundRow): boolean {
190
+ const finished = Date.parse(round.finished_at ?? "");
191
+ if (!Number.isFinite(finished)) return false;
192
+ if (this.now().getTime() >= finished + this.finalizeGraceMin() * 60_000) return false;
193
+ const settledFromReceipt = this.deps.store.db
194
+ .prepare(
195
+ "SELECT 1 FROM events WHERE kind = 'verdict_settled_from_receipt' AND pr = ? AND json_extract(payload, '$.round_id') = ? LIMIT 1",
196
+ )
197
+ .get(round.pr, round.id);
198
+ return settledFromReceipt === undefined;
199
+ }
200
+
201
+ /** `[daemon] round_finalize_grace_min`. */
202
+ private finalizeGraceMin(): number {
203
+ return this.deps.cfg.daemon.round_finalize_grace_min ?? DEFAULT_ROUND_FINALIZE_GRACE_MIN;
204
+ }
205
+
206
+ private verdictPending(command: SessionCommandRow): boolean {
207
+ return (
208
+ command.round_no !== null &&
209
+ existsSync(join(this.deps.verdictDir, `pr-${command.pr}-round-${command.round_no}.json`))
210
+ );
211
+ }
212
+
213
+ private async inspect(snapshot: SessionCommandRow): Promise<void> {
214
+ const command = this.deps.store.getSessionCommand(snapshot.id);
215
+ if (!command) return;
216
+ const nowIso = this.now().toISOString();
217
+ const due = command.next_check_at <= nowIso;
218
+ const settled = this.progressShowsSettlement(command);
219
+ if (command.status === "running" && settled && this.awaitingSettlementAck(command)) return;
220
+ let runningRound: RoundRow | undefined;
221
+ if (command.kind === "round" && command.round_no !== null) {
222
+ const round = this.deps.store
223
+ .roundsFor(command.pr)
224
+ .find((row) => row.round_no === command.round_no);
225
+ if (!round) {
226
+ if (due && (command.status === "pending" || command.status === "running")) {
227
+ const reason = `orphan command ${command.id} references missing round ${command.round_no}`;
228
+ if (this.deps.store.failActiveSessionCommand(command.id, reason)) {
229
+ this.deps.store.logAnomaly(
230
+ "session_command_orphaned",
231
+ command.pr,
232
+ command.round_no,
233
+ reason,
234
+ );
235
+ }
236
+ }
237
+ return;
238
+ }
239
+ if (round.status !== "running") {
240
+ // A round its verdict file ended is the session's own finished work:
241
+ // the file is its last action, and its run settles moments later.
242
+ // That tail is left alone for the finalize grace — killing it would
243
+ // cost a healthy conversation — unless the run already settled (the
244
+ // bridge died before its ack) or the round was settled from its
245
+ // receipt because no verdict came.
246
+ if (
247
+ command.status === "running" &&
248
+ (round.status === "done" ||
249
+ (round.status === "cancelled" && round.cancel_cause === "no_new_evidence")) &&
250
+ !settled &&
251
+ this.inVerdictTail(round)
252
+ )
253
+ return;
254
+ // Operator cancellation/head movement already ended the round. Stop an
255
+ // owned Pi run immediately (not at its old hard deadline) before the
256
+ // cancelled command releases the successor slot. Pending was never
257
+ // submitted because bridge reservation precedes send, so it is safe
258
+ // to fail directly.
259
+ if (command.status === "running") await this.finishTerminalRoundCommand(command);
260
+ else if (command.status === "pending") {
261
+ this.deps.store.failPendingSessionCommand(
262
+ command.id,
263
+ `round ${command.round_no} terminal before command start`,
264
+ );
265
+ }
266
+ return;
267
+ }
268
+ runningRound = round;
269
+ const successor = this.deps.store.successorFor(command.pr);
270
+ if (
271
+ successor?.predecessor_round_id === round.id &&
272
+ command.started_at === null &&
273
+ (command.status === "pending" || command.status === "running")
274
+ ) {
275
+ await this.failRound(
276
+ command,
277
+ "command_start",
278
+ `round ${round.round_no} was superseded before command start by fresh head ${successor.head_sha}`,
279
+ );
280
+ return;
281
+ }
282
+ } else if (command.status === "running" && settled) {
283
+ await this.finishTerminalRoundCommand(command);
284
+ return;
285
+ }
286
+ if (command.status === "running" && settled) {
287
+ if (!due && this.hasDeferredStageCheck(command)) return;
288
+ if (this.verdictPending(command)) return; // the 10s verdict sweep owns it
289
+ await this.settledWithoutVerdict(command);
290
+ return;
291
+ }
292
+ if (this.verdictPending(command)) return; // the 10s verdict sweep owns it
293
+ if (command.status === "running" && command.started_at !== null && runningRound) {
294
+ // Initial stage detection precedes the ordinary hard-cap check. Once
295
+ // recovery explicitly defers, its durable retry time owns the next probe.
296
+ if (!due && this.hasDeferredStageCheck(command)) return;
297
+ if (await this.executionStageExpired(command, runningRound)) return;
298
+ }
299
+ if (!due) return;
300
+
301
+ if (command.status === "failed") {
302
+ const detail = command.failure ?? `command ${command.id} failed without detail`;
303
+ if (command.kind === "round") {
304
+ await this.failRound(
305
+ command,
306
+ command.started_at === null ? "command_start" : "running_hard_bound",
307
+ detail,
308
+ );
309
+ } else {
310
+ await this.recoverNonRound(command, detail);
311
+ }
312
+ return;
313
+ }
314
+ if (command.status === "acked") {
315
+ await this.settledWithoutVerdict(command);
316
+ return;
317
+ }
318
+ if (command.status !== "pending" && command.status !== "running") return;
319
+ if (command.started_at === null) {
320
+ await this.missingStart(command);
321
+ return;
322
+ }
323
+ if (this.progressShowsSettlement(command)) {
324
+ await this.settledWithoutVerdict(command);
325
+ return;
326
+ }
327
+ await this.runningHardBound(command);
328
+ }
329
+
330
+ private async missingStart(command: SessionCommandRow): Promise<void> {
331
+ let receipt: boolean | null = null;
332
+ let alive: boolean | null = null;
333
+ try {
334
+ alive = this.deps.hooks.sessionAlive ? await this.deps.hooks.sessionAlive(command.pr) : null;
335
+ } catch {
336
+ alive = null;
337
+ }
338
+ try {
339
+ receipt = this.deps.hooks.wakeReceiptPresent
340
+ ? await this.deps.hooks.wakeReceiptPresent(
341
+ command.pr,
342
+ sessionCommandMarker(command.id, command.payload_sha256),
343
+ Date.parse(command.created_at),
344
+ )
345
+ : null;
346
+ } catch {
347
+ receipt = null;
348
+ }
349
+
350
+ if (receipt === true && alive === false) {
351
+ const reason = `command ${command.id} has an accepted marker but its session is dead before durable settlement`;
352
+ this.deps.store.logEvent("session_command_evidence_contradictory", command.pr, {
353
+ command_id: command.id,
354
+ round_no: command.round_no,
355
+ receipt: true,
356
+ session_alive: false,
357
+ });
358
+ if (command.kind === "round" && command.round_no !== null) {
359
+ await this.failRound(command, "command_start", reason);
360
+ } else {
361
+ await this.recoverNonRound(command, reason);
362
+ }
363
+ return;
364
+ }
365
+
366
+ if (receipt === true) {
367
+ const progress = this.matchingProgress(command);
368
+ // If the bridge missed its SQLite start stamp, use exact progress
369
+ // identity when available. Otherwise the already-expired start lease is
370
+ // the conservative latest possible origin — never observation time,
371
+ // which would let a long daemon outage reset the hard cap.
372
+ const origin = progress?.run_started_at ?? command.next_check_at;
373
+ const hardAt = new Date(this.hardDeadlineMs(origin, command)).toISOString();
374
+ if (this.deps.store.observeSessionCommandStarted(command.id, origin, hardAt)) {
375
+ this.deps.store.logEvent("session_command_start_reconciled", command.pr, {
376
+ command_id: command.id,
377
+ round_no: command.round_no,
378
+ started_at: origin,
379
+ hard_deadline_at: hardAt,
380
+ });
381
+ const reconciled = this.deps.store.getSessionCommand(command.id);
382
+ if (reconciled && this.now().getTime() >= Date.parse(hardAt))
383
+ await this.runningHardBound(reconciled);
384
+ }
385
+ return;
386
+ }
387
+
388
+ // The worker's ack is its receipt: a command with no correlated start by
389
+ // its lease is definitively not delivered.
390
+ const reason = `command ${command.id} has no correlated start before ${command.next_check_at}`;
391
+ // A missing prompt is a delivery fault, so redelivery comes first.
392
+ // A live session with no order is IDLE, not wedged — the kill-and-replay
393
+ // recovery below costs its whole conversation, so it runs only when the
394
+ // session is provably dead or its bounded redeliveries are spent.
395
+ if (alive === true && (await this.redeliverFirst(command, reason))) return;
396
+ await this.recoverMissingStart(command, reason);
397
+ }
398
+
399
+ /**
400
+ * Redeliver a command that never started into the
401
+ * same live session — the same row and bytes, no kill — up to
402
+ * `[daemon] max_prompt_redeliveries` times. True when this check is
403
+ * answered (redelivered, or the command started/settled/was reserved
404
+ * meanwhile); false hands over to the kill-and-replay recovery: no
405
+ * redelivery hook, the budget spent, or no live, bridge-ready session.
406
+ */
407
+ private async redeliverFirst(command: SessionCommandRow, reason: string): Promise<boolean> {
408
+ const hook = this.deps.hooks.redeliverSessionCommand;
409
+ if (!hook) return false;
410
+ const cap = this.deps.cfg.daemon.max_prompt_redeliveries ?? DEFAULT_MAX_PROMPT_REDELIVERIES;
411
+ if (command.redeliveries >= cap) {
412
+ this.deps.store.logEvent("session_command_redelivery_exhausted", command.pr, {
413
+ command_id: command.id,
414
+ kind: command.kind,
415
+ round_no: command.round_no,
416
+ redeliveries: command.redeliveries,
417
+ cap,
418
+ reason,
419
+ });
420
+ return false;
421
+ }
422
+ let result: Awaited<ReturnType<typeof hook>>;
423
+ let error: string | null = null;
424
+ try {
425
+ // The row as THIS check found it due: the hook's CAS is on it, so a
426
+ // bridge reservation made since (a fresh lease) answers `raced`.
427
+ result = await hook.call(this.deps.hooks, command.id, {
428
+ attempt: command.attempt,
429
+ redeliveries: command.redeliveries,
430
+ next_check_at: command.next_check_at,
431
+ });
432
+ } catch (err) {
433
+ result = "redelivery_failed";
434
+ error = String(err);
435
+ }
436
+ const payload = {
437
+ command_id: command.id,
438
+ kind: command.kind,
439
+ round_no: command.round_no,
440
+ result,
441
+ redelivery: command.redeliveries + 1,
442
+ cap,
443
+ reason,
444
+ ...(error ? { error } : {}),
445
+ };
446
+ if (result === "redelivered") {
447
+ this.deps.store.logEvent("session_command_redelivered", command.pr, payload);
448
+ return true;
449
+ }
450
+ if (result === "started" || result === "settled") {
451
+ this.deps.store.logEvent("session_command_redelivery_raced", command.pr, payload);
452
+ return true;
453
+ }
454
+ if (result === "raced") {
455
+ // A bridge reserved it after this check found it due: its own start
456
+ // lease runs from that reservation and is never cut short. Only a row
457
+ // still due is looked at again one interval on (no hot loop).
458
+ const current = this.deps.store.getSessionCommand(command.id);
459
+ if (!current || current.next_check_at <= this.now().toISOString())
460
+ this.deps.store.scheduleSessionCommandCheck(
461
+ command.id,
462
+ this.deadlineFromNowSeconds(
463
+ this.deps.cfg.daemon.session_command_unknown_grace_s ??
464
+ DEFAULT_SESSION_COMMAND_UNKNOWN_GRACE_S,
465
+ ),
466
+ );
467
+ this.deps.store.logEvent("session_command_redelivery_raced", command.pr, payload);
468
+ return true;
469
+ }
470
+ this.deps.store.logEvent("session_command_redelivery_skipped", command.pr, payload);
471
+ return false;
472
+ }
473
+
474
+ /**
475
+ * Admit one automatic process recovery, for a round command and an ordinary
476
+ * wake alike, and hand back the retry hook to run it with.
477
+ *
478
+ * An unbound production adapter is an unhealthy supervisor, not spent
479
+ * recovery: it throws, keeping the command due so wiring can be repaired
480
+ * and the same bytes replayed without inventing operator debt at 0/N. The
481
+ * allowance is spent BEFORE any tmux/filesystem work, so a generation that
482
+ * dies before a bridge reserves the row still advances the finite bound.
483
+ */
484
+ private admitRecovery(
485
+ command: SessionCommandRow,
486
+ retryCap: number,
487
+ what: "round command" | "command",
488
+ ): NonNullable<SessionHooks["retrySessionCommand"]> {
489
+ const hook = this.deps.hooks.retrySessionCommand;
490
+ if (!hook) {
491
+ throw new Error(
492
+ `${what} ${command.id} retry hook unavailable with ${command.recovery_attempts}/${retryCap} recoveries spent`,
493
+ );
494
+ }
495
+ if (!this.deps.store.beginSessionCommandRecovery(command.id, command.recovery_attempts)) {
496
+ throw new Error(`${what} ${command.id} lost its automatic-recovery claim`);
497
+ }
498
+ return (id, reason) => hook.call(this.deps.hooks, id, reason);
499
+ }
500
+
501
+ private async recoverMissingStart(command: SessionCommandRow, reason: string): Promise<void> {
502
+ if (command.kind !== "round") {
503
+ await this.recoverNonRound(command, reason);
504
+ return;
505
+ }
506
+ const retryCap =
507
+ this.deps.cfg.daemon.session_command_max_start_retries ??
508
+ DEFAULT_SESSION_COMMAND_MAX_START_RETRIES;
509
+ // Process rebirths and bridge reservations are different counters; the
510
+ // admission spends the process-recovery allowance first (`admitRecovery`).
511
+ if (command.recovery_attempts < retryCap) {
512
+ const retry = this.admitRecovery(command, retryCap, "round command");
513
+ const recoveryAttempt = command.recovery_attempts + 1;
514
+ const result = await retry(command.id, reason);
515
+ if (result === "retried") {
516
+ const replayed = this.deps.store.getSessionCommand(command.id);
517
+ this.deps.store.logEvent("session_command_start_recovery", command.pr, {
518
+ command_id: command.id,
519
+ round_no: command.round_no,
520
+ recovery_attempt: recoveryAttempt,
521
+ delivery_attempt: replayed?.attempt ?? command.attempt,
522
+ retry_cap: retryCap,
523
+ reason,
524
+ });
525
+ return;
526
+ }
527
+ if (result === "round_finished") {
528
+ this.deps.store.failActiveSessionCommand(
529
+ command.id,
530
+ `round finished during start recovery: ${reason}`,
531
+ );
532
+ return;
533
+ }
534
+ if (result === "settled") {
535
+ this.deps.store.logEvent("session_command_start_settled_race", command.pr, {
536
+ command_id: command.id,
537
+ round_no: command.round_no,
538
+ recovery_attempt: recoveryAttempt,
539
+ });
540
+ return;
541
+ }
542
+ if (result === "raced") {
543
+ this.deps.store.logEvent("session_command_recovery_owner_changed", command.pr, {
544
+ command_id: command.id,
545
+ });
546
+ return; // The current reservation retains its own finite check/deadline.
547
+ }
548
+ if (result === "accepted_race") {
549
+ const raced = `command ${command.id} became accepted while start recovery stopped its old session`;
550
+ if (command.kind === "round" && command.round_no !== null)
551
+ await this.failRound(command, "command_start", raced);
552
+ else if (this.deps.store.failActiveSessionCommand(command.id, raced))
553
+ this.deps.store.logAnomaly("session_command_failed", command.pr, null, raced);
554
+ return;
555
+ }
556
+ // A failed rebirth leaves the same pending row due. Throw so the scan's
557
+ // durable health is red; the next finite tick retries instead of losing
558
+ // the only obligation by terminalizing it first.
559
+ const failed = this.deps.store.getSessionCommand(command.id);
560
+ throw new Error(
561
+ `command ${command.id} start recovery failed before replay: ${failed?.failure ?? reason}`,
562
+ );
563
+ }
564
+
565
+ const effectiveReason = command.failure?.trim() || reason;
566
+ this.deps.store.logEvent("session_command_start_failed", command.pr, {
567
+ command_id: command.id,
568
+ round_no: command.round_no,
569
+ recovery_attempts: command.recovery_attempts,
570
+ delivery_attempts: command.attempt,
571
+ retry_cap: retryCap,
572
+ reason: effectiveReason,
573
+ });
574
+ if (command.kind === "round" && command.round_no !== null) {
575
+ await this.failRound(command, "command_start", effectiveReason);
576
+ } else if (this.deps.store.failActiveSessionCommand(command.id, effectiveReason)) {
577
+ this.deps.store.logAnomaly(
578
+ "session_command_failed",
579
+ command.pr,
580
+ null,
581
+ `${effectiveReason}; ordinary wake remains failed and blocks successors`,
582
+ );
583
+ }
584
+ }
585
+
586
+ private hasDeferredStageCheck(command: SessionCommandRow): boolean {
587
+ return (
588
+ this.deps.store.db
589
+ .prepare(
590
+ `SELECT 1 FROM events WHERE pr = ? AND kind IN ('round_stage_recovery_deferred', 'round_stage_posted_tail_wait')
591
+ AND json_extract(payload, '$.command_id') = ?
592
+ AND json_extract(payload, '$.next_check_at') = ? LIMIT 1`,
593
+ )
594
+ .get(command.pr, command.id, command.next_check_at) !== undefined
595
+ );
596
+ }
597
+
598
+ private matchingProgress(command: SessionCommandRow): RoundProgressSnapshot | undefined {
599
+ if (!this.deps.progress) return undefined;
600
+ const progress = this.deps.progress(command.pr);
601
+ if (
602
+ !progress ||
603
+ progress.pr !== command.pr ||
604
+ progress.session !== command.session ||
605
+ progress.command_id !== command.id ||
606
+ progress.command_sha256 !== command.payload_sha256
607
+ )
608
+ return undefined;
609
+ return progress;
610
+ }
611
+
612
+ /** v2 milestones are observational proof for earlier finite bounds. Missing,
613
+ * legacy or mismatched telemetry stays UNKNOWN and falls through to the
614
+ * immutable hard runtime cap; activity can never renew a lease. */
615
+ private correlatedExecutionProgress(
616
+ command: SessionCommandRow,
617
+ ): RoundProgressSnapshot | undefined {
618
+ if (command.started_at === null) return undefined;
619
+ const progress = this.matchingProgress(command);
620
+ if (!progress || progress.version !== 2) return undefined;
621
+ const runStarted = Date.parse(progress.run_started_at);
622
+ const accepted = Date.parse(progress.command_accepted_at ?? "");
623
+ if (
624
+ !runStartsNear(command.started_at, progress.run_started_at) ||
625
+ !Number.isFinite(accepted) ||
626
+ accepted < runStarted
627
+ )
628
+ return undefined;
629
+ return progress;
630
+ }
631
+
632
+ private async executionStageExpired(
633
+ command: SessionCommandRow,
634
+ round: RoundRow,
635
+ ): Promise<boolean> {
636
+ const progress = this.correlatedExecutionProgress(command);
637
+ if (!progress) return false;
638
+ const started = Date.parse(command.started_at!);
639
+ const now = this.now().getTime();
640
+ const minute = 60_000;
641
+ const sweepOwed = round.sweep_owed === 1;
642
+ const passesMaxMin =
643
+ (this.deps.cfg.daemon.round_passes_max_min ?? DEFAULT_ROUND_PASSES_MAX_MIN) +
644
+ (sweepOwed ? this.sweepExtraMin() : 0);
645
+ const deadlines = roundStageDeadlines(
646
+ started,
647
+ resolveRoundStageBounds(this.deps.cfg.daemon),
648
+ sweepOwed,
649
+ );
650
+ const firstPassAt = deadlines.first_pass_start;
651
+ const passesAt = deadlines.passes_complete;
652
+ const hardAt = deadlines.running_hard_bound;
653
+ const planned = round.lenses
654
+ .split(",")
655
+ .map((name) => name.trim())
656
+ .filter(Boolean);
657
+
658
+ // The extension's generic subagent milestone is descriptive only. The
659
+ // finite gate opens solely when exact correlated progress names one of the
660
+ // authoritative planned DISCOVERY lenses — validator-first, an added lens
661
+ // or a foreign tool cannot buy a later failure class.
662
+ const fanoutAgents = plannedFanoutAgents(progress, planned);
663
+ const plannedFanout = fanoutAgents.length > 0;
664
+ if (plannedFanout) {
665
+ const firstStarted = fanoutAgents.map((agent) => agent.started_at!).sort()[0]!;
666
+ this.deps.store.recordRoundFanoutStarted(round.id, command.id, firstStarted);
667
+ }
668
+ if (!plannedFanout && now >= firstPassAt) {
669
+ await this.failRound(
670
+ command,
671
+ "first_pass_start",
672
+ `command ${command.id} was accepted and preparing, but no planned pass started (fanout milestone absent) within ${this.deps.cfg.daemon.round_first_pass_max_min ?? DEFAULT_ROUND_FIRST_PASS_MAX_MIN} minutes`,
673
+ );
674
+ return true;
675
+ }
676
+ if (!plannedFanout) return false;
677
+
678
+ const terminal = isTerminalAgentStatus;
679
+ // A sweep-owed round's planned (delta-stage) lens is judged by its FIRST
680
+ // execution only: a later run of the same lens is the sweep's, started
681
+ // after the delta stage, and counts as ADDED — never as this lens missing.
682
+ const deltaStage = sweepOwed ? firstExecutionPerLens(progress.agents) : null;
683
+ // A lens with several plan rows (a split baseline) owes one execution per row.
684
+ const rowCounts = plannedRowCounts(round);
685
+ const missing = planned.filter((name) => {
686
+ if (deltaStage) {
687
+ const first = deltaStage.get(name);
688
+ return first === undefined || !terminal(first.status);
689
+ }
690
+ const executions = progress.agents.filter((agent) => lensForAgent(agent.agent) === name);
691
+ return executions.length < (rowCounts.get(name) ?? 1) || !executionsComplete(executions);
692
+ });
693
+ const addedRunning = progress.agents
694
+ .filter(
695
+ (agent) =>
696
+ (!planned.includes(lensForAgent(agent.agent)) ||
697
+ (deltaStage !== null && deltaStage.get(lensForAgent(agent.agent)) !== agent)) &&
698
+ !terminal(agent.status),
699
+ )
700
+ .map((agent) => agent.agent);
701
+ if ((missing.length > 0 || addedRunning.length > 0) && now >= passesAt) {
702
+ const outstanding = [...missing, ...addedRunning].join(", ");
703
+ await this.failRound(
704
+ command,
705
+ "passes_incomplete",
706
+ `command ${command.id} did not terminalize every planned/observed pass within ${passesMaxMin} minutes; outstanding: ${outstanding}`,
707
+ );
708
+ return true;
709
+ }
710
+ if (missing.length > 0 || addedRunning.length > 0) return false;
711
+
712
+ const finished = progress.agents.map((agent) => Date.parse(agent.finished_at ?? ""));
713
+ if (
714
+ planned.length === 0 ||
715
+ finished.length === 0 ||
716
+ finished.some((value) => !Number.isFinite(value))
717
+ )
718
+ return false;
719
+ const allFinishedAt = Math.max(...finished);
720
+ const finalizeAt = Math.min(allFinishedAt + this.finalizeGraceMin() * minute, hardAt);
721
+ if (now < finalizeAt) return false;
722
+ // The grace measures how long the PARENT has been left with
723
+ // nothing to wait for — and a parent whose run is still ACTIVE (writing
724
+ // its ledger, validating, posting) is not idle. While the correlated
725
+ // snapshot says `active`, finalize does not fire. This is not a lease
726
+ // renewal: nothing here moves a deadline, and activity still can never
727
+ // renew one. The fixed start-derived hard bound binds unconditionally.
728
+ //
729
+ // Staleness: `active` is trusted only from the snapshot already matched
730
+ // above on command id + payload sha + run start (`correlatedExecution
731
+ // Progress`), never from its age — a parent deep in one long model turn
732
+ // writes nothing for minutes, and an updated_at freshness rule would
733
+ // bring back exactly the kill this fixes. A frozen snapshot (the
734
+ // extension or pi died mid-run) is caught two ways: a session tmux
735
+ // provably reports dead is not trusted (finalize fires as before), and
736
+ // anything else waits at most for the hard bound.
737
+ if (progress.parent_status === "active" && (await this.parentMayBeRunning(command))) {
738
+ if (now >= hardAt) {
739
+ await this.runningHardBound(command);
740
+ return true;
741
+ }
742
+ if (!this.finalizeHeld.has(command.id)) {
743
+ if (this.finalizeHeld.size >= 1_000) this.finalizeHeld.clear(); // a log dedupe, never state
744
+ this.finalizeHeld.add(command.id);
745
+ this.deps.store.logEvent("round_finalize_held_parent_active", command.pr, {
746
+ command_id: command.id,
747
+ round_no: command.round_no,
748
+ passes_finished_at: new Date(allFinishedAt).toISOString(),
749
+ hard_deadline_at: new Date(hardAt).toISOString(),
750
+ });
751
+ }
752
+ return false;
753
+ }
754
+ await this.failRound(
755
+ command,
756
+ "parent_finalize",
757
+ `command ${command.id} left all observed passes terminal without a verdict for ${this.finalizeGraceMin()} minutes`,
758
+ );
759
+ return true;
760
+ }
761
+
762
+ /** False only when the session is PROVABLY gone (tmux says so). Unknown
763
+ * (no hook, a probe that threw) keeps the active snapshot's word: the hard
764
+ * bound is the backstop for everything this cannot see. */
765
+ private async parentMayBeRunning(command: SessionCommandRow): Promise<boolean> {
766
+ if (!this.deps.hooks.sessionAlive) return true;
767
+ try {
768
+ return (await this.deps.hooks.sessionAlive(command.pr)) !== false;
769
+ } catch {
770
+ return true;
771
+ }
772
+ }
773
+
774
+ private progressShowsSettlement(command: SessionCommandRow): boolean {
775
+ if (command.started_at === null) return false;
776
+ const progress = this.matchingProgress(command);
777
+ if (!progress || progress.parent_status !== "settled") return false;
778
+ const started = Date.parse(command.started_at);
779
+ const updated = Date.parse(progress.updated_at);
780
+ return (
781
+ runStartsNear(command.started_at, progress.run_started_at) &&
782
+ Number.isFinite(updated) &&
783
+ updated >= started
784
+ );
785
+ }
786
+
787
+ /** agent_settled progress precedes the bridge's zero-delay ack callback.
788
+ * Give that callback one finite grace, persisted across daemon restarts.
789
+ * Later observations never extend it and the immutable hard bound wins. */
790
+ private awaitingSettlementAck(command: SessionCommandRow): boolean {
791
+ const prior = this.deps.store.db
792
+ .prepare(
793
+ `SELECT json_extract(payload, '$.wait_until') AS wait_until FROM events
794
+ WHERE kind='session_command_settlement_ack_wait' AND pr=?
795
+ AND json_extract(payload, '$.command_id')=?
796
+ AND json_extract(payload, '$.attempt')=?
797
+ ORDER BY id DESC LIMIT 1`,
798
+ )
799
+ .get(command.pr, command.id, command.attempt) as { wait_until: string } | undefined;
800
+ const until = prior
801
+ ? Date.parse(prior.wait_until)
802
+ : Math.min(this.now().getTime() + 1_000, this.hardDeadlineMs(command.started_at!, command));
803
+ if (!Number.isFinite(until) || this.now().getTime() >= until) return false;
804
+ if (!prior)
805
+ this.deps.store.logEvent("session_command_settlement_ack_wait", command.pr, {
806
+ command_id: command.id,
807
+ attempt: command.attempt,
808
+ wait_until: new Date(until).toISOString(),
809
+ });
810
+ this.deps.store.scheduleSessionCommandCheck(command.id, new Date(until).toISOString());
811
+ return true;
812
+ }
813
+
814
+ private async settledWithoutVerdict(command: SessionCommandRow): Promise<void> {
815
+ const reason = `command ${command.id} settled without verdict for round ${command.round_no}`;
816
+ if (command.status === "running") {
817
+ // Pi settled but the bridge did not durably ack. Its callback returned
818
+ // with an in-memory barrier still armed, so merely repairing SQLite
819
+ // would strand the successor file. Restart that stale bridge first.
820
+ if (!this.deps.hooks.killSession)
821
+ throw new Error(
822
+ `cannot recover unacked settled command ${command.id}: kill hook unavailable`,
823
+ );
824
+ if ((await this.deps.hooks.killSession(command.pr, command)) === false) return;
825
+ if (!sameSessionCommandOwner(this.deps.store.getSessionCommand(command.id), command)) return;
826
+ }
827
+ this.deps.store.logEvent("round_settled_without_verdict", command.pr, {
828
+ command_id: command.id,
829
+ round_no: command.round_no,
830
+ settled_at: command.settled_at,
831
+ });
832
+ if (command.round_no !== null) await this.failRound(command, "settled_without_verdict", reason);
833
+ }
834
+
835
+ /** `[daemon] follow_up_sweep_extra_min`. */
836
+ private sweepExtraMin(): number {
837
+ return this.deps.cfg.daemon.follow_up_sweep_extra_min ?? DEFAULT_FOLLOW_UP_SWEEP_EXTRA_MIN;
838
+ }
839
+
840
+ /** The command's fixed running cap in minutes: the configured bound, plus
841
+ * the sweep allowance when it carries a round whose pre-approval sweep is
842
+ * owed. Derived from the round ROW, never from progress. */
843
+ private runningMaxMin(command: SessionCommandRow, round?: RoundRow): number {
844
+ const base =
845
+ this.deps.cfg.daemon.session_command_running_max_min ??
846
+ DEFAULT_SESSION_COMMAND_RUNNING_MAX_MIN;
847
+ if (command.kind !== "round" || command.round_no === null) return base;
848
+ const row =
849
+ round ??
850
+ this.deps.store.roundsFor(command.pr).find((item) => item.round_no === command.round_no);
851
+ return row?.sweep_owed === 1 ? base + this.sweepExtraMin() : base;
852
+ }
853
+
854
+ /** The fixed running deadline (epoch ms) of a command whose run began at
855
+ * `origin`: the origin plus `runningMaxMin`. */
856
+ private hardDeadlineMs(origin: string, command: SessionCommandRow, round?: RoundRow): number {
857
+ return Date.parse(origin) + this.runningMaxMin(command, round) * 60_000;
858
+ }
859
+
860
+ private async runningHardBound(command: SessionCommandRow): Promise<void> {
861
+ const maxMin = this.runningMaxMin(command);
862
+ const hardAt = new Date(this.hardDeadlineMs(command.started_at!, command)).toISOString();
863
+ if (this.now().getTime() < Date.parse(hardAt)) {
864
+ // Upgrade/restart reconciliation: an older bridge may have written a
865
+ // shorter advisory check. Move it to the FIXED start-derived cap; never
866
+ // derive this from activity or progress telemetry.
867
+ this.deps.store.scheduleSessionCommandCheck(command.id, hardAt);
868
+ return;
869
+ }
870
+ const reason = `command ${command.id} exceeded its fixed ${maxMin}-minute running bound (started ${command.started_at})`;
871
+ this.deps.store.logEvent("session_command_running_bound_exhausted", command.pr, {
872
+ command_id: command.id,
873
+ round_no: command.round_no,
874
+ started_at: command.started_at,
875
+ hard_deadline_at: hardAt,
876
+ });
877
+ if (command.kind === "round" && command.round_no !== null) {
878
+ await this.failRound(command, "running_hard_bound", reason);
879
+ } else {
880
+ await this.recoverNonRound(command, reason);
881
+ }
882
+ }
883
+
884
+ /** Ordinary wakes own conversation work rather than a merits round. Replay
885
+ * the same row/bytes after the production hook fences the old Pi; never
886
+ * convert the payload back into the capped held-wake queue. */
887
+ private async recoverNonRound(command: SessionCommandRow, reason: string): Promise<void> {
888
+ const retryCap =
889
+ this.deps.cfg.daemon.session_command_max_start_retries ??
890
+ DEFAULT_SESSION_COMMAND_MAX_START_RETRIES;
891
+ const effectiveReason = command.failure?.trim() || reason;
892
+ if (command.recovery_attempts < retryCap) {
893
+ const retry = this.admitRecovery(command, retryCap, "command");
894
+ const recoveryAttempt = command.recovery_attempts + 1;
895
+ const result = await retry(command.id, effectiveReason);
896
+ if (result === "retried") {
897
+ const replayed = this.deps.store.getSessionCommand(command.id);
898
+ this.deps.store.logEvent("session_command_nonround_recovery", command.pr, {
899
+ command_id: command.id,
900
+ kind: command.kind,
901
+ recovery_attempt: recoveryAttempt,
902
+ retry_cap: retryCap,
903
+ delivery_attempt: replayed?.attempt ?? command.attempt,
904
+ reason: effectiveReason,
905
+ });
906
+ return;
907
+ }
908
+ if (result === "settled") {
909
+ this.deps.store.logEvent("session_command_nonround_settled_race", command.pr, {
910
+ command_id: command.id,
911
+ kind: command.kind,
912
+ reason: effectiveReason,
913
+ });
914
+ return;
915
+ }
916
+ if (result === "raced") {
917
+ this.deps.store.logEvent("session_command_recovery_owner_changed", command.pr, {
918
+ command_id: command.id,
919
+ });
920
+ return; // The current reservation retains its own finite check/deadline.
921
+ }
922
+ if (result === "accepted_race") {
923
+ const next = this.deadlineFromNowSeconds(
924
+ this.deps.cfg.daemon.session_command_unknown_grace_s ??
925
+ DEFAULT_SESSION_COMMAND_UNKNOWN_GRACE_S,
926
+ );
927
+ this.deps.store.scheduleSessionCommandCheck(command.id, next);
928
+ this.deps.store.logEvent("session_command_nonround_recovery_deferred", command.pr, {
929
+ command_id: command.id,
930
+ next_check_at: next,
931
+ reason: "acceptance won recovery race",
932
+ });
933
+ return;
934
+ }
935
+ // A failed fence/rebirth leaves the same command as the only obligation.
936
+ // Keep supervisor health red; never release it or submit a successor.
937
+ const failed = this.deps.store.getSessionCommand(command.id);
938
+ throw new Error(
939
+ `command ${command.id} non-round recovery failed before replay: ${failed?.failure ?? effectiveReason}`,
940
+ );
941
+ }
942
+
943
+ if (!this.deps.hooks.killSession) {
944
+ throw new Error(`cannot exhaust non-round command ${command.id}: kill hook unavailable`);
945
+ }
946
+ if ((await this.deps.hooks.killSession(command.pr, command)) === false) return;
947
+ const current = this.deps.store.getSessionCommand(command.id);
948
+ // Settlement or explicit operator cancellation may win while the fence is
949
+ // in flight. Both terminalize this supervisor obligation; never reopen a
950
+ // failure over the operator's successful reset.
951
+ if (!current || current.status === "acked" || current.status === "cancelled") return;
952
+ if (current.status === "pending" || current.status === "running") {
953
+ if (!this.deps.store.failActiveSessionCommand(command.id, effectiveReason)) return;
954
+ }
955
+ const failed = this.deps.store.getSessionCommand(command.id);
956
+ if (!failed || failed.status !== "failed") return;
957
+ const row = this.deps.store.getPr(command.pr);
958
+ this.deps.store.openReviewFailure({
959
+ pr: command.pr,
960
+ command_id: command.id,
961
+ round_id: null,
962
+ round_no: null,
963
+ head_sha: row?.head_sha ?? "",
964
+ stage: "session_command",
965
+ detail: effectiveReason,
966
+ attempts: failed.recovery_attempts,
967
+ retry_cap: retryCap,
968
+ });
969
+ this.deps.store.logAnomaly(
970
+ "session_command_recovery_exhausted",
971
+ command.pr,
972
+ null,
973
+ `${effectiveReason}; automatic process recovery exhausted and operator recovery is required`,
974
+ );
975
+ }
976
+
977
+ private async failRound(
978
+ command: SessionCommandRow,
979
+ stage: RoundInfrastructureStage,
980
+ detail: string,
981
+ ): Promise<void> {
982
+ const disposition = await this.deps.onRoundFailure(
983
+ command.pr,
984
+ command.round_no!,
985
+ stage,
986
+ `${detail}; command=${command.id}`,
987
+ );
988
+ if (disposition === "retryable" || disposition === "posted_wait") {
989
+ let next = this.deadlineFromNowSeconds(
990
+ this.deps.cfg.daemon.session_command_unknown_grace_s ??
991
+ DEFAULT_SESSION_COMMAND_UNKNOWN_GRACE_S,
992
+ );
993
+ if (disposition === "posted_wait") {
994
+ // A posted tail's fixed end is an earlier obligation than the retry
995
+ // interval; preserve that boundary without probing every scan.
996
+ const tail = this.deps.store.db
997
+ .prepare(
998
+ `SELECT json_extract(payload, '$.wait_until') AS wait_until FROM events
999
+ WHERE pr = ? AND kind = 'round_stage_posted_wait'
1000
+ AND json_extract(payload, '$.round_no') = ? ORDER BY id DESC LIMIT 1`,
1001
+ )
1002
+ .get(command.pr, command.round_no) as { wait_until: string } | undefined;
1003
+ if (tail && Number.isFinite(Date.parse(tail.wait_until)) && tail.wait_until < next)
1004
+ next = tail.wait_until;
1005
+ }
1006
+ this.deps.store.scheduleSessionCommandCheck(command.id, next);
1007
+ this.deps.store.logEvent(
1008
+ disposition === "posted_wait"
1009
+ ? "round_stage_posted_tail_wait"
1010
+ : "round_stage_recovery_deferred",
1011
+ command.pr,
1012
+ {
1013
+ command_id: command.id,
1014
+ round_no: command.round_no,
1015
+ stage,
1016
+ disposition,
1017
+ next_check_at: next,
1018
+ detail,
1019
+ },
1020
+ );
1021
+ return;
1022
+ }
1023
+ if (disposition === "settled") {
1024
+ // The round terminalized cleanly (a guard-2 refusal recorded as a
1025
+ // no-op, or a round settled from its posting receipt). The command was
1026
+ // delivered and did its work; failing it here would leave a blocking
1027
+ // failed command on a PR that owes nothing.
1028
+ this.deps.store.logEvent("round_stage_recovery", command.pr, {
1029
+ command_id: command.id,
1030
+ round_no: command.round_no,
1031
+ stage,
1032
+ disposition,
1033
+ detail,
1034
+ });
1035
+ return;
1036
+ }
1037
+
1038
+ const current = this.deps.store.getSessionCommand(command.id);
1039
+ if (current?.status === "acked") this.deps.store.failSettledSessionCommand(command.id, detail);
1040
+ else if (current?.status === "pending" || current?.status === "running")
1041
+ this.deps.store.failActiveSessionCommand(command.id, detail);
1042
+ this.deps.store.logEvent("round_stage_recovery", command.pr, {
1043
+ command_id: command.id,
1044
+ round_no: command.round_no,
1045
+ stage,
1046
+ disposition,
1047
+ detail,
1048
+ });
1049
+ if (disposition === "exhausted") {
1050
+ // The recovery callback owns the atomic round+command+failure handoff.
1051
+ // Never open it again here: operator `u` may already have recovered the
1052
+ // incident while this awaited callback was returning. A historical row
1053
+ // (open or recovered) proves the callback committed the obligation.
1054
+ const failure = this.deps.store.reviewFailureForCommand(command.id);
1055
+ if (!failure || failure.round_no !== command.round_no || failure.stage !== stage) {
1056
+ throw new Error(
1057
+ `round failure callback returned exhausted without durable exact debt for command ${command.id}`,
1058
+ );
1059
+ }
1060
+ if (failure.work_owed === 1) {
1061
+ this.deps.store.logAnomaly(
1062
+ "round_stage_recovery_exhausted",
1063
+ command.pr,
1064
+ command.round_no,
1065
+ `${stage}: ${detail}; automatic recovery exhausted and work remains owed as ${failure.incident_id}`,
1066
+ );
1067
+ } else {
1068
+ this.deps.store.logEvent("round_stage_recovery_already_resolved", command.pr, {
1069
+ command_id: command.id,
1070
+ round_no: command.round_no,
1071
+ stage,
1072
+ incident_id: failure.incident_id,
1073
+ recovery: failure.recovery,
1074
+ });
1075
+ }
1076
+ }
1077
+ }
1078
+
1079
+ private deadlineFromNowSeconds(seconds: number): string {
1080
+ return new Date(this.now().getTime() + seconds * 1000).toISOString();
1081
+ }
1082
+ }
1083
+
1084
+ export function roundStageSupervisorHealth(
1085
+ lease: SupervisorLeaseRow | undefined,
1086
+ staleAfterS: number,
1087
+ now: Date,
1088
+ ): RoundStageSupervisorHealth {
1089
+ const reference = lease?.last_success_at ?? lease?.last_attempt_at ?? null;
1090
+ const ageMs = reference === null ? 0 : now.getTime() - Date.parse(reference);
1091
+ return {
1092
+ healthy:
1093
+ reference !== null &&
1094
+ Number.isFinite(ageMs) &&
1095
+ ageMs <= staleAfterS * 1000 &&
1096
+ lease?.last_error == null,
1097
+ stale_after_s: staleAfterS,
1098
+ last_attempt_at: lease?.last_attempt_at ?? null,
1099
+ last_success_at: lease?.last_success_at ?? null,
1100
+ last_error_at: lease?.last_error_at ?? null,
1101
+ last_error: lease?.last_error ?? null,
1102
+ };
1103
+ }
1104
+
1105
+ /** Each lens's FIRST execution, by start (list order breaks ties and stands in
1106
+ * for an execution with no start milestone) — a follow-up round's delta
1107
+ * stage. */
1108
+ function firstExecutionPerLens(
1109
+ agents: RoundProgressSnapshot["agents"],
1110
+ ): Map<string, RoundProgressSnapshot["agents"][number]> {
1111
+ const first = new Map<string, RoundProgressSnapshot["agents"][number]>();
1112
+ for (const agent of agents) {
1113
+ const lens = lensForAgent(agent.agent);
1114
+ const held = first.get(lens);
1115
+ if (
1116
+ held === undefined ||
1117
+ (agent.started_at !== undefined &&
1118
+ held.started_at !== undefined &&
1119
+ agent.started_at < held.started_at)
1120
+ )
1121
+ first.set(lens, agent);
1122
+ }
1123
+ return first;
1124
+ }
1125
+
1126
+ /** Plan rows per lens name from the round's recorded `pass_plan`; empty when
1127
+ * it is absent or unreadable (every lens then owes one execution). */
1128
+ function plannedRowCounts(round: RoundRow): Map<string, number> {
1129
+ const counts = new Map<string, number>();
1130
+ if (!round.pass_plan) return counts;
1131
+ try {
1132
+ const rows: unknown = JSON.parse(round.pass_plan);
1133
+ if (!Array.isArray(rows)) return counts;
1134
+ for (const row of rows) {
1135
+ const lens = (row as { lens?: unknown } | null)?.lens;
1136
+ if (typeof lens === "string") counts.set(lens, (counts.get(lens) ?? 0) + 1);
1137
+ }
1138
+ } catch {
1139
+ return new Map();
1140
+ }
1141
+ return counts;
1142
+ }