@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,1030 @@
1
+ // The reconcile poll — the correctness backbone.
2
+ // GitHub never redelivers a failed webhook, so every 5 minutes (and on
3
+ // startup) the daemon rebuilds the truth from the API and forces local state
4
+ // to match. GitHub always wins. Every correction is logged as a
5
+ // `reconcile_correction` event: a rising correction rate is the webhook-health
6
+ // signal the operator watches.
7
+ import {
8
+ capturedFromIssueComment,
9
+ capturedFromReview,
10
+ capturedFromReviewComment,
11
+ isHumanCapture,
12
+ recordCapturedComment,
13
+ type CapturedComment,
14
+ } from "./capture.js";
15
+ import type { CheckSummary } from "@quickchatai/pi-quickreview/src/cigate.js";
16
+ import { retryWithheldApproval } from "./ciretry.js";
17
+ import {
18
+ auditUngatedReviews,
19
+ commentsByReview,
20
+ hasUngatedApproval,
21
+ ungatedReviewMessage,
22
+ } from "./execboundary.js";
23
+ import { ledgerFeedbackSignal } from "./feedback.js";
24
+ import { wakeOrHold } from "./wakes.js";
25
+ import { recheckFingerprint } from "./recheck.js";
26
+ import { recheckPromptMarker } from "@quickchatai/pi-quickreview/src/types.js";
27
+ import { standingVerdict } from "@quickchatai/pi-quickreview/src/standing-review.js";
28
+ import { DEFAULT_ROUND_STALL_GRACE_MIN, type Config } from "./config.js";
29
+ import type { IssueCommentFull, PrRef, ReviewCommentFull, ReviewFull } from "./github.js";
30
+ import type { OutcomeCapture, OutcomeSweepReport } from "./outcomes.js";
31
+ import { applyEvent, isBotAuthor, mergedOverBlock } from "./statemachine.js";
32
+ import type { RoundRow, StateStore } from "./state.js";
33
+ import type { OvSessionSweepReport, SessionHooks } from "@quickchatai/pi-quickreview/src/types.js";
34
+ import { performance } from "node:perf_hooks";
35
+ import { yieldToLoop } from "@quickchatai/pi-quickreview/src/yieldloop.js";
36
+
37
+ export interface ReconcileSearchItem {
38
+ number: number;
39
+ title: string;
40
+ user: { login: string; type: string };
41
+ updated_at: string;
42
+ }
43
+
44
+ /** The read-only slice of GitHubAdapter reconcile needs. */
45
+ export interface ReconcileAdapter {
46
+ searchLabelTriggered(): Promise<ReconcileSearchItem[]>;
47
+ searchTeamTriggered(): Promise<ReconcileSearchItem[]>;
48
+ listOpenPrs(): Promise<PrRef[]>;
49
+ getPr(n: number): Promise<PrRef>;
50
+ listBotReviewComments(n: number): Promise<number[]>;
51
+ /** Checks at a ref — the withheld-approval backstop reads CI through this.
52
+ * Optional: a stub-wired daemon without it simply has no backstop. */
53
+ listChecks?(ref: string): Promise<CheckSummary[]>;
54
+ /** The comment-capture sweep's three READ sources. All optional and
55
+ * all-or-nothing: a stub-wired daemon without them simply has no backstop.
56
+ * Reads only — capture never writes to GitHub. */
57
+ listReviewCommentsFull?(n: number): Promise<ReviewCommentFull[]>;
58
+ listIssueComments?(n: number): Promise<IssueCommentFull[]>;
59
+ listReviewsFull?(n: number): Promise<ReviewFull[]>;
60
+ }
61
+
62
+ /**
63
+ * Per-pass bound on the comment-capture sweep: three API reads per
64
+ * PR, so the sweep must never grow with the whole tracked history. Freshest
65
+ * local activity first — a PR nobody has touched in weeks is not where a
66
+ * missed comment lives, and the ones left out are picked up on a later pass as
67
+ * soon as they move.
68
+ */
69
+ export const COMMENT_SWEEP_MAX_PRS = 25;
70
+
71
+ /**
72
+ * How long after a PR closes the capture sweep still includes it. The
73
+ * closed-sync step earlier in the SAME pass is what marks a PR closed, so a
74
+ * blanket `state !== "closed"` filter would skip exactly the PR that closed
75
+ * while the daemon was down — the scenario the sweep exists to recover. The
76
+ * rule: a closed PR is swept when it transitioned this pass, or when its row
77
+ * last moved (which for a closed PR is the close itself — nothing writes the
78
+ * row after that) within this window. The watermark below makes the repeat
79
+ * cost of the window three API reads an hour per closed PR (a closed PR has
80
+ * no GitHub timestamp in the open list to say a comment arrived), and one
81
+ * skipped filter check on every other pass.
82
+ */
83
+ export const COMMENT_SWEEP_CLOSED_WINDOW_MS = 24 * 60 * 60 * 1000;
84
+
85
+ export interface ReconcileDeps {
86
+ cfg: Config;
87
+ store: StateStore;
88
+ adapter: ReconcileAdapter;
89
+ hooks: SessionHooks;
90
+ now?: () => Date;
91
+ log?: (msg: string, extra?: unknown) => void;
92
+ /** Registry backfill is an API call per open PR; the daemon runs it every
93
+ * Nth poll. Default true. */
94
+ backfillRegistry?: boolean;
95
+ /** Backstop for the recheck's push trigger: the webhook's `onSynchronize`
96
+ * is the fast path, but a lost/dead webhook means a post-review push is
97
+ * otherwise never rechecked — the withheld-approval retry no-ops on a moved
98
+ * head ("a push re-reviews through its own route") while that route never
99
+ * fires. Same idiom as the withheld-approval sweep: the daemon wires
100
+ * runRecheck here, never a copy. */
101
+ onHeadPush?: (pr: number, head_sha: string) => Promise<void>;
102
+ /** Backstop: the merged-over-block feedback signal for closes the
103
+ * webhook missed (GitHub never redelivers). The daemon wires the same
104
+ * engine sink the webhook path uses; dedupe is the store's. */
105
+ onMergedOverBlock?: (pr: number) => Promise<void> | void;
106
+ /** Backstop: capture comments the webhook never saw (GitHub never
107
+ * redelivers, so a comment posted while the daemon was down would otherwise
108
+ * be permanent evidence loss). Default on when the adapter can read;
109
+ * `false` disables it for a poll that must stay cheap. */
110
+ captureComments?: boolean;
111
+ /** The outcome capture: handed the bot's OWN inline comments
112
+ * from the comment sweep's existing read (no extra GitHub call), then run
113
+ * as its own bounded step after it. Absent ⇒ no outcome capture. Its
114
+ * failures are its own and never reach `errors`. */
115
+ outcomes?: Pick<OutcomeCapture, "observeBotComments" | "sweep">;
116
+ /** The undelivered-recheck sweep. `false` skips it for this pass — the
117
+ * daemon's boot pass, whose health lifts a deploy drain and which must not
118
+ * wait on reading session transcripts. */
119
+ receiptSweep?: boolean;
120
+ /** How long the sweep may keep STARTING claims in one pass; the rest are
121
+ * carried to the next. Default RECEIPT_SWEEP_BUDGET_MS. */
122
+ receiptSweepBudgetMs?: number;
123
+ }
124
+
125
+ /**
126
+ * Wall-clock budget of the undelivered-recheck sweep per pass. Every read in
127
+ * it is asynchronous and chunked, so this bounds how long the PASS takes (the
128
+ * steps after it wait), not how long the loop blocks — that is a chunk.
129
+ */
130
+ export const RECEIPT_SWEEP_BUDGET_MS = 20_000;
131
+
132
+ export interface ReconcileReport {
133
+ ran_at: string;
134
+ open_prs: number;
135
+ triggered: number[];
136
+ closed: number[];
137
+ backfilled_comments: number;
138
+ /** Human comments the sweep captured that the webhook had missed.
139
+ * A rising number is the same webhook-health signal `corrections` is. */
140
+ captured_comments: number;
141
+ corrections: number;
142
+ errors: string[];
143
+ /** The raw-tier sweep's outcome — present only when the hooks
144
+ * manage a raw tier. Deliberately NOT part of `errors`: memory never
145
+ * blocks, and the boot's first healthy pass (which lifts a deploy drain)
146
+ * must not wait on the memory engine. */
147
+ ov_sessions?: OvSessionSweepReport;
148
+ /** The outcome capture's pass, when it captured anything or
149
+ * failed. Like `ov_sessions`, deliberately NOT part of `errors`: it is
150
+ * bookkeeping, and the boot's first healthy pass must not wait on it. */
151
+ outcomes?: OutcomeSweepReport;
152
+ /** The undelivered-recheck sweep's pass: claims
153
+ * asked, found delivered (recorded, never asked again), released as lost,
154
+ * and carried to the next pass by the budget. Absent when it did not run. */
155
+ receipt_sweep?: { asked: number; delivered: number; released: number; carried: number };
156
+ }
157
+
158
+ function correction(
159
+ deps: ReconcileDeps,
160
+ pr: number | null,
161
+ what: string,
162
+ detail: unknown,
163
+ report: ReconcileReport,
164
+ ): void {
165
+ report.corrections++;
166
+ deps.store.logEvent("reconcile_correction", pr, { what, ...(detail as object) });
167
+ (deps.log ?? (() => {}))(`reconcile: correction ${what}${pr ? ` #${pr}` : ""}`, detail);
168
+ }
169
+
170
+ /** Startup repair: a DB round marked running whose worker did not survive the
171
+ * restart will never produce a verdict — it would sit as a phantom until its
172
+ * deadline, holding a capacity slot and then corrupting the PR via the
173
+ * overdue path. Cancel it; if it was the PR's newest round and the PR still
174
+ * says reviewing, requeue so the lost work is redone. `inFlightPrs` are the
175
+ * PRs a worker still runs for, or whose round command waits for the next one
176
+ * (`inFlightPrs` in src/workerliveness.ts); a boot that finds no worker at all
177
+ * finds every PR idle with its JSONL.
178
+ *
179
+ * A round that still owes a POSTING is no phantom: its review is finished and
180
+ * the outbox delivers it without any session (docs/architecture/
181
+ * posting-delivery.md). Nor is one whose review is already posted but not yet
182
+ * settled. Cancelling either would make the outbox abandon the review or the
183
+ * requeue run the lenses again for a review already on GitHub, so it is left
184
+ * running (`postingOwed`) and settles from its receipt like any delivered
185
+ * round. */
186
+ export function reconcileOrphanedRounds(
187
+ store: StateStore,
188
+ inFlightPrs: Iterable<number>,
189
+ opts: {
190
+ now?: () => Date;
191
+ log?: (msg: string, extra?: unknown) => void;
192
+ /** Does this round still owe a review posting the outbox delivers on its
193
+ * own, or the settlement of one already posted? Absent ⇒ no round does. */
194
+ postingOwed?: (round: RoundRow) => boolean;
195
+ },
196
+ ): { cancelled: number[]; requeued: number[]; kept_for_posting: number[] } {
197
+ const live = new Set(inFlightPrs);
198
+ const now = opts.now ?? (() => new Date());
199
+ const log = opts.log ?? (() => {});
200
+ const cancelled: number[] = [];
201
+ const requeued: number[] = [];
202
+ const keptForPosting: number[] = [];
203
+ for (const round of store.runningRounds()) {
204
+ if (live.has(round.pr)) continue;
205
+ let owed = false;
206
+ try {
207
+ owed = opts.postingOwed?.(round) === true;
208
+ } catch (err) {
209
+ log(`startup: #${round.pr} round ${round.round_no} posting debt unreadable`, err);
210
+ }
211
+ if (owed) {
212
+ store.logEvent("orphaned_round_posting_owed", round.pr, {
213
+ round_id: round.id,
214
+ round_no: round.round_no,
215
+ posting_key: round.posting_key,
216
+ });
217
+ keptForPosting.push(round.pr);
218
+ log(
219
+ `startup: #${round.pr} round ${round.round_no} kept — session lost, but its review posting is still owed or unsettled`,
220
+ );
221
+ continue;
222
+ }
223
+ // `orphan_sweep` is the quiet cause: a worker lives and dies with its
224
+ // container, so a clean redeploy orphans every round in flight by
225
+ // construction. It is counted and grouped like every other cause, and it
226
+ // raises nothing.
227
+ const replaced = store.db.transaction(() => {
228
+ store.markRoundCancelled(round.id, "orphaned — worker lost across a restart", "orphan_sweep");
229
+ store.logEvent("round_orphaned", round.pr, { round_id: round.id, round_no: round.round_no });
230
+ const row = store.getPr(round.pr);
231
+ if (row?.state !== "reviewing" || store.hasLaterRound(round.pr, round.round_no)) return false;
232
+ const successorPromoted = store.promoteSuccessor(round.pr);
233
+ if (!successorPromoted)
234
+ store.upsertPr({ ...row, state: "queued", trigger_ts: now().toISOString() });
235
+ store.logEvent("orphaned_round_requeued", round.pr, {
236
+ round_id: round.id,
237
+ round_no: round.round_no,
238
+ successor_promoted: successorPromoted,
239
+ });
240
+ return true;
241
+ })();
242
+ cancelled.push(round.pr);
243
+ log(`startup: #${round.pr} round ${round.round_no} cancelled (session lost)`);
244
+ if (replaced) {
245
+ requeued.push(round.pr);
246
+ log(`startup: #${round.pr} requeued — its in-flight round was lost`);
247
+ }
248
+ }
249
+ return { cancelled, requeued, kept_for_posting: keptForPosting };
250
+ }
251
+
252
+ /** One reconcile pass. Never throws: per-step failures land in
253
+ * `report.errors` so a single bad PR or a flaky API call cannot stall the
254
+ * daemon. */
255
+ export async function reconcileOnce(deps: ReconcileDeps): Promise<ReconcileReport> {
256
+ const { store, cfg, adapter } = deps;
257
+ const now = deps.now ?? (() => new Date());
258
+ const botLogin = cfg.github.bot_login;
259
+ const report: ReconcileReport = {
260
+ ran_at: now().toISOString(),
261
+ open_prs: 0,
262
+ triggered: [],
263
+ closed: [],
264
+ backfilled_comments: 0,
265
+ captured_comments: 0,
266
+ corrections: 0,
267
+ errors: [],
268
+ };
269
+
270
+ const step = async (name: string, fn: () => Promise<void>): Promise<void> => {
271
+ try {
272
+ // Every step starts on a fresh event-loop turn, so a pass is never one
273
+ // synchronous span even when its reads answer without real I/O (a
274
+ // cache, a stub) — the longest span is one step's own work.
275
+ await yieldToLoop();
276
+ await fn();
277
+ } catch (err) {
278
+ report.errors.push(`${name}: ${String(err)}`);
279
+ (deps.log ?? (() => {}))(`reconcile: step ${name} failed`, err);
280
+ }
281
+ };
282
+
283
+ // ---- 1. open-PR truth ---------------------------------------------------
284
+ const open = new Map<number, PrRef>();
285
+ let openListed = false;
286
+ await step("listOpenPrs", async () => {
287
+ for (const pr of await adapter.listOpenPrs()) open.set(pr.number, pr);
288
+ openListed = true;
289
+ report.open_prs = open.size;
290
+ for (const pr of open.values()) {
291
+ if (isBotAuthor(pr.author, botLogin)) continue;
292
+ const local = store.getPr(pr.number);
293
+ if (!local) continue; // untriggered PRs are not tracked (no sweeps)
294
+ if (local.head_sha !== pr.head_sha || local.title !== pr.title) {
295
+ const pushed = store.db.transaction(() => {
296
+ const before = store.getPr(pr.number);
297
+ const result = applyEvent(
298
+ store,
299
+ pr.number,
300
+ { type: "track" },
301
+ { title: pr.title, head_sha: pr.head_sha, author: pr.author },
302
+ { botLogin, now },
303
+ );
304
+ const changed =
305
+ !result.skipped && before !== undefined && before.head_sha !== pr.head_sha;
306
+ if (changed)
307
+ store.logEvent("head_push", pr.number, { head_sha: pr.head_sha, source: "reconcile" });
308
+ return changed;
309
+ })();
310
+ if (pushed && deps.onHeadPush) {
311
+ // After the track so the recheck reads the updated row. Errors are
312
+ // contained: a failed recheck must not abort the reconcile pass.
313
+ try {
314
+ await deps.onHeadPush(pr.number, pr.head_sha);
315
+ } catch (err) {
316
+ report.errors.push(`onHeadPush #${pr.number}: ${String(err)}`);
317
+ (deps.log ?? (() => {}))(`reconcile: onHeadPush failed #${pr.number}`, err);
318
+ }
319
+ }
320
+ } else if (deps.onHeadPush) {
321
+ // Lost-recheck backstop: change-detection
322
+ // fires onHeadPush exactly once, so a recheck that failed to deliver
323
+ // (or died with the process) never retried once the head was tracked.
324
+ // A standing reviewed head that differs from the current head, with
325
+ // this exact question unclaimed, is re-asked; claimed questions
326
+ // (nudged, or answered trivially) dedupe before any classification.
327
+ const reviewed = store.reviewedHead(pr.number);
328
+ if (
329
+ reviewed &&
330
+ standingVerdict(reviewed) === "APPROVE" &&
331
+ reviewed.head_sha !== pr.head_sha &&
332
+ !store.hasRecheck(pr.number, recheckFingerprint({ trigger: "push" }, pr.head_sha))
333
+ ) {
334
+ (deps.log ?? (() => {}))(
335
+ `reconcile: recheck backstop #${pr.number} — reviewed ${reviewed.head_sha.slice(0, 7)} != head ${pr.head_sha.slice(0, 7)}, unclaimed`,
336
+ );
337
+ try {
338
+ await deps.onHeadPush(pr.number, pr.head_sha);
339
+ } catch (err) {
340
+ report.errors.push(`onHeadPush(backstop) #${pr.number}: ${String(err)}`);
341
+ (deps.log ?? (() => {}))(`reconcile: onHeadPush backstop failed #${pr.number}`, err);
342
+ }
343
+ }
344
+ }
345
+ // GitHub owns head truth. A successor can outlive its predecessor and
346
+ // can also survive a crash after the PR row was corrected, so enforce
347
+ // this independently of whether THIS pass observed a local head change.
348
+ // The store preserves predecessor, first-request FIFO time, and sticky
349
+ // human provenance while coalescing only the target head.
350
+ const successor = store.successorFor(pr.number);
351
+ if (successor && successor.head_sha !== pr.head_sha) {
352
+ store.recordSuccessor({
353
+ pr: pr.number,
354
+ predecessor_round_id: successor.predecessor_round_id,
355
+ head_sha: pr.head_sha,
356
+ provenance: successor.provenance,
357
+ reason: "reconcile-authoritative-head",
358
+ });
359
+ }
360
+ if (local.state === "closed") {
361
+ // GitHub says open, we say closed → GitHub wins.
362
+ correction(deps, pr.number, "reopened", { local: local.state }, report);
363
+ applyEvent(
364
+ store,
365
+ pr.number,
366
+ { type: "reopened" },
367
+ { title: pr.title, head_sha: pr.head_sha, author: pr.author },
368
+ { botLogin, now },
369
+ );
370
+ }
371
+ }
372
+ });
373
+
374
+ // ---- 2. triggered-set derivation (both searches) ------------------------
375
+ await step("triggered-set", async () => {
376
+ const [labelled, teamed] = await Promise.all([
377
+ adapter.searchLabelTriggered(),
378
+ adapter.searchTeamTriggered(),
379
+ ]);
380
+ const kinds = ["label", "team_request"] as const;
381
+ const searches = { label: labelled, team_request: teamed };
382
+ const current = {
383
+ label: new Set(labelled.map((item) => item.number)),
384
+ team_request: new Set(teamed.map((item) => item.number)),
385
+ };
386
+
387
+ // Snapshot BEFORE writing this poll. GitHub searches expose current levels,
388
+ // not the edge that created them; this durable previous observation is what
389
+ // distinguishes a new human request from residue left by an older round.
390
+ const previous = new Map<string, boolean | undefined>();
391
+ for (const pr of open.keys()) {
392
+ if (!store.getPr(pr)) continue; // untriggered PRs acquire observations when first triggered
393
+ for (const kind of kinds) previous.set(`${pr}:${kind}`, store.triggerLevel(pr, kind));
394
+ }
395
+
396
+ const grouped = new Map<
397
+ number,
398
+ { item: ReconcileSearchItem; kinds: Array<(typeof kinds)[number]> }
399
+ >();
400
+ for (const kind of kinds) {
401
+ for (const item of searches[kind]) {
402
+ if (isBotAuthor(item.user?.login ?? "", botLogin) || item.user?.type === "Bot") continue;
403
+ const group = grouped.get(item.number) ?? { item, kinds: [] };
404
+ group.kinds.push(kind);
405
+ grouped.set(item.number, group);
406
+ }
407
+ }
408
+
409
+ // Record both presence and absence. Remove→re-add is a fresh edge even
410
+ // when its webhook was lost; rows survive daemon restarts. A paused PR's
411
+ // presence is not recorded: the pause defers handling a fresh request, and
412
+ // acknowledging its level now would leave no edge to act on after the
413
+ // resume. Its absence is recorded — that only ever makes a later edge.
414
+ for (const pr of open.keys()) {
415
+ const row = store.getPr(pr);
416
+ if (!row && !grouped.has(pr)) continue;
417
+ for (const kind of kinds) {
418
+ const present = current[kind].has(pr);
419
+ if (row?.paused && present) continue;
420
+ store.observeTriggerLevel(pr, kind, present);
421
+ }
422
+ }
423
+
424
+ for (const [pr, group] of grouped) {
425
+ const ref = open.get(pr);
426
+ const local = store.getPr(pr);
427
+ // A search can lag the close: a PR closed with its trigger still on it
428
+ // is listed for a pass. Closed is terminal — nothing to queue, nothing
429
+ // to correct.
430
+ if (local?.state === "closed") continue;
431
+ // A tracked PR the searches list but the open list (read this pass)
432
+ // does not is closed on GitHub with the search lagging, or the open
433
+ // list is the one lagging. The closed-sync below settles which, from
434
+ // the PR itself; triggering it first would overwrite the state that
435
+ // sync reads (a merge over a standing block) and count a correction
436
+ // for a PR that owes no review. A PR never tracked here is skipped the
437
+ // same way: nothing would close it, and a genuinely open one the list
438
+ // lags on is picked up by the next pass.
439
+ if (openListed && !ref) continue;
440
+ const meta = {
441
+ title: ref?.title ?? group.item.title,
442
+ head_sha: ref?.head_sha ?? local?.head_sha ?? "",
443
+ author: ref?.author ?? group.item.user?.login ?? "",
444
+ trigger_ts: local?.trigger_ts ?? group.item.updated_at ?? now().toISOString(),
445
+ };
446
+ report.triggered.push(pr);
447
+ if (local?.paused) continue; // overseer pause-pr: no re-trigger until resumed
448
+
449
+ // Only an observed absent→present transition is a fresh edge. Undefined
450
+ // is bootstrap history for an existing row (the table is additive on
451
+ // deploy), not proof a person just acted. A PR never tracked before is
452
+ // different: its first trigger is the human ask that brings it in.
453
+ const freshKind =
454
+ local === undefined
455
+ ? group.kinds[0]
456
+ : group.kinds.find(
457
+ (kind) =>
458
+ store.triggerEdgePending(pr, kind) || previous.get(`${pr}:${kind}`) === false,
459
+ );
460
+ if (local?.state === "reviewing") {
461
+ // A fresh request can upgrade an already-recorded pushed-head
462
+ // successor to human provenance. Same-head requests need no second
463
+ // round: the active one already covers that head.
464
+ if (freshKind)
465
+ applyEvent(store, pr, { type: "trigger", source: freshKind }, meta, {
466
+ botLogin,
467
+ now,
468
+ reason: `reconcile:${freshKind}:reviewing`,
469
+ });
470
+ continue;
471
+ }
472
+ if (local?.state === "queued") {
473
+ // Already queued, but a fresh request upgrades a system-queued round
474
+ // to the person's ask, so dispatch never skips it as a trivial
475
+ // system re-trigger. The edge is recorded above and will not be seen
476
+ // again.
477
+ if (freshKind)
478
+ applyEvent(store, pr, { type: "trigger", source: freshKind }, meta, {
479
+ botLogin,
480
+ now,
481
+ reason: `reconcile:${freshKind}:queued`,
482
+ });
483
+ continue;
484
+ }
485
+ const reviewed = store.reviewedHead(pr);
486
+ const pushHandled =
487
+ !freshKind &&
488
+ reviewed !== undefined &&
489
+ standingVerdict(reviewed) === "APPROVE" &&
490
+ reviewed.head_sha !== meta.head_sha &&
491
+ store.hasRecheck(pr, recheckFingerprint({ trigger: "push" }, meta.head_sha));
492
+ if (pushHandled) {
493
+ // The targeted APPROVE path already owns this head. A standing label or
494
+ // team request is residue, not a second blank-slate review. A genuinely
495
+ // new edge still bypasses this branch and gets a full review.
496
+ store.logEvent("standing_trigger_suppressed", pr, {
497
+ head_sha: meta.head_sha,
498
+ kinds: group.kinds,
499
+ });
500
+ deps.log?.(
501
+ `reconcile: suppressed standing trigger for #${pr} at rechecked head ${meta.head_sha.slice(0, 10)}`,
502
+ );
503
+ continue;
504
+ }
505
+
506
+ // Dry-run never consumes triggers on GitHub, so an already-reviewed
507
+ // head would re-queue forever; suppress until the head moves.
508
+ if (cfg.dry_run && meta.head_sha && store.lastVerdictHead(pr) === meta.head_sha) {
509
+ if (freshKind) store.acknowledgeTriggerEdges(pr);
510
+ deps.log?.(
511
+ `dry-run: suppressing re-trigger of #${pr} at reviewed head ${meta.head_sha.slice(0, 10)}`,
512
+ );
513
+ continue;
514
+ }
515
+ const source = freshKind ?? "reconcile";
516
+ correction(
517
+ deps,
518
+ pr,
519
+ "triggered-not-queued",
520
+ { local: local?.state ?? null, source, kinds: group.kinds },
521
+ report,
522
+ );
523
+ applyEvent(store, pr, { type: "trigger", source }, meta, {
524
+ botLogin,
525
+ now,
526
+ reason: `reconcile:${source}`,
527
+ });
528
+ }
529
+ });
530
+
531
+ // Commits outside a round never dispatch a review. A head advance WHILE an
532
+ // older round owns the PR is different: it is recorded as durable successor
533
+ // work. Promote obligations whose predecessor became terminal across a
534
+ // crash/restart; queue publication is idempotent and retains the evidence.
535
+ await step("successor-obligations", async () => {
536
+ for (const row of store.allPrs()) {
537
+ if (store.successorFor(row.number)) store.promoteSuccessor(row.number);
538
+ }
539
+ });
540
+
541
+ // ---- 2b. undelivered recheck-claim sweep ---------------------------------
542
+ // `claimRecheck` is written BEFORE the nudge goes out, `releaseRecheck`
543
+ // fires only on a synchronous throw (which a bridge-level drop is not), and
544
+ // `rechecks` has no deadline or expiry of its own. Without this sweep a
545
+ // dropped nudge would leave a claim that suppresses the push-backstop above
546
+ // (`!store.hasRecheck(...)`) forever: a delta on an APPROVED PR would never
547
+ // be audited, and the approval would stand over code nobody read.
548
+ //
549
+ // The receipt makes it recoverable. A claim past the grace window whose
550
+ // marker never reached the session is released, and the backstop re-asks on
551
+ // the next pass. Every ambiguity is a no-op: only a provable absence counts.
552
+ //
553
+ // Bounded so it never holds the event loop: it asks only about claims that
554
+ // can still be lost nudges (`recheckClaimsAwaitingReceipt` — a real nudge,
555
+ // receipt not yet found, PR not closed), records a found receipt so it is
556
+ // never asked again, yields a real event-loop turn between claims, stops starting new
557
+ // claims past its time budget (the rest are asked next pass, least
558
+ // recently asked first), and is skipped on the boot's first pass, whose
559
+ // health is what lifts a deploy drain.
560
+ await step("undelivered-rechecks", async () => {
561
+ const receipt = deps.hooks.wakeReceiptPresent;
562
+ if (!receipt) return;
563
+ if (deps.receiptSweep === false) {
564
+ (deps.log ?? (() => {}))(
565
+ "reconcile: undelivered-recheck sweep deferred to the next pass (boot)",
566
+ );
567
+ return;
568
+ }
569
+ const graceMs = (cfg.daemon.round_stall_grace_min ?? DEFAULT_ROUND_STALL_GRACE_MIN) * 60_000;
570
+ const cutoff = new Date(now().getTime() - graceMs).toISOString();
571
+ const budgetMs = deps.receiptSweepBudgetMs ?? RECEIPT_SWEEP_BUDGET_MS;
572
+ const claims = store.recheckClaimsAwaitingReceipt(cutoff);
573
+ const sweep = { asked: 0, delivered: 0, released: 0, carried: 0 };
574
+ const started = performance.now();
575
+ for (const [i, claim] of claims.entries()) {
576
+ // Always at least one claim, so a tiny budget still makes progress.
577
+ if (i > 0 && performance.now() - started > budgetMs) {
578
+ sweep.carried = claims.length - i;
579
+ break;
580
+ }
581
+ // A real macrotask turn per claim: whatever the receipt hook does, the
582
+ // sweep is never one synchronous span.
583
+ await yieldToLoop();
584
+ // A held or still-pending nudge is not a lost one.
585
+ if (store.hasRunningRound(claim.pr) || store.hasHeldWakes(claim.pr)) {
586
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
587
+ continue;
588
+ }
589
+ const claimedMs = Date.parse(claim.created_at);
590
+ if (!Number.isFinite(claimedMs)) continue;
591
+ sweep.asked++;
592
+ const landed = await receipt.call(
593
+ deps.hooks,
594
+ claim.pr,
595
+ recheckPromptMarker(claim.pr, claim.fingerprint),
596
+ claimedMs,
597
+ );
598
+ if (landed === true) {
599
+ // Delivered is a fact: recorded once, never re-read.
600
+ store.markRecheckReceipt(claim.pr, claim.fingerprint);
601
+ sweep.delivered++;
602
+ continue;
603
+ }
604
+ if (landed !== false) {
605
+ // No evidence either way — never guess; ask again on a later pass.
606
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
607
+ continue;
608
+ }
609
+ if (claim.trigger === "ci" || claim.trigger === "base_advance") {
610
+ const enabled =
611
+ cfg.recheck.enabled &&
612
+ (claim.trigger === "ci" ? cfg.recheck.on_ci : cfg.recheck.on_base_advance);
613
+ if (!enabled || store.drainState().draining) {
614
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
615
+ continue;
616
+ }
617
+ const delivery = store.recheckDelivery(claim.pr, claim.fingerprint);
618
+ if (
619
+ !delivery ||
620
+ delivery.reason !== `recheck:${claim.trigger}` ||
621
+ !delivery.payload
622
+ .split(/\r?\n/)
623
+ .includes(recheckPromptMarker(claim.pr, claim.fingerprint))
624
+ ) {
625
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
626
+ if (!store.lastEventAt("recheck_payload_unknown", claim.pr))
627
+ store.logEvent("recheck_payload_unknown", claim.pr, { fingerprint: claim.fingerprint });
628
+ continue;
629
+ }
630
+ const row = store.getPr(claim.pr);
631
+ const standing = store.reviewedHead(claim.pr);
632
+ if (
633
+ row?.head_sha.toLowerCase() !== claim.head_sha.toLowerCase() ||
634
+ (standing && standingVerdict(standing) !== "APPROVE")
635
+ ) {
636
+ store.releaseRecheck(claim.pr, claim.fingerprint);
637
+ store.logEvent("recheck_delivery_superseded", claim.pr, {
638
+ fingerprint: claim.fingerprint,
639
+ });
640
+ continue;
641
+ }
642
+ if (!standing) {
643
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
644
+ continue;
645
+ }
646
+ await wakeOrHold(
647
+ { store, inject: deps.hooks.inject.bind(deps.hooks), log: deps.log },
648
+ claim.pr,
649
+ delivery.payload,
650
+ delivery.reason,
651
+ { holdOnFailure: true, deferWhilePaused: true },
652
+ );
653
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
654
+ continue;
655
+ }
656
+ store.releaseRecheck(claim.pr, claim.fingerprint);
657
+ sweep.released++;
658
+ correction(
659
+ deps,
660
+ claim.pr,
661
+ "recheck-claim-released-undelivered",
662
+ {
663
+ fingerprint: claim.fingerprint,
664
+ head_sha: claim.head_sha,
665
+ trigger: claim.trigger,
666
+ claimed_at: claim.created_at,
667
+ },
668
+ report,
669
+ );
670
+ }
671
+ report.receipt_sweep = sweep;
672
+ if (sweep.carried > 0)
673
+ (deps.log ?? (() => {}))(
674
+ `reconcile: undelivered-recheck sweep hit its ${budgetMs} ms budget — ${sweep.carried} claim(s) carried to the next pass`,
675
+ );
676
+ });
677
+
678
+ // ---- 2c. stale-trigger residue sweep -------------------------------------
679
+ // A settled PR (tracked/awaiting_author, no round running) never
680
+ // legitimately carries `stale_recheck` or a `trigger_ts`: both are consumed
681
+ // by dispatch and cleared when a round settles. Left behind, they would
682
+ // misclassify the NEXT explicit re-review as a staleness round and let it
683
+ // jump the FIFO on an old timestamp. Swept after the triggered-set step, so
684
+ // a PR GitHub still lists as triggered has already been re-queued and is
685
+ // never touched.
686
+ await step("stale-trigger-residue", async () => {
687
+ for (const local of store.allPrs()) {
688
+ if (local.state !== "tracked" && local.state !== "awaiting_author") continue;
689
+ if (!local.stale_recheck && local.trigger_ts === null) continue;
690
+ if (store.hasRunningRound(local.number)) continue;
691
+ correction(
692
+ deps,
693
+ local.number,
694
+ "stale-trigger-residue-cleared",
695
+ { state: local.state, stale_recheck: local.stale_recheck, trigger_ts: local.trigger_ts },
696
+ report,
697
+ );
698
+ store.upsertPr({ ...local, stale_recheck: 0, trigger_ts: null });
699
+ }
700
+ });
701
+
702
+ // ---- 3. open-PR sync: locally-live PRs GitHub no longer lists as open ----
703
+ await step("closed-sync", async () => {
704
+ for (const local of store.allPrs()) {
705
+ if (local.state === "closed") continue;
706
+ if (open.has(local.number)) continue;
707
+ let ref: PrRef | null = null;
708
+ try {
709
+ ref = await adapter.getPr(local.number);
710
+ } catch (err) {
711
+ report.errors.push(`getPr #${local.number}: ${String(err)}`);
712
+ continue;
713
+ }
714
+ if (ref.state !== "closed") continue; // listing lag — leave it alone
715
+ correction(
716
+ deps,
717
+ local.number,
718
+ "pr-closed",
719
+ { merged: ref.merged, local: local.state },
720
+ report,
721
+ );
722
+ // The existing feedback ledger is the durable owed-memory intent. Commit
723
+ // it with closure, before a callback can fail or the process can stop.
724
+ const overBlock = store.db.transaction(() => {
725
+ const priorState = store.getPr(local.number)?.state;
726
+ if (priorState === "closed") return false;
727
+ const result = applyEvent(
728
+ store,
729
+ local.number,
730
+ { type: "closed" },
731
+ { title: ref.title, head_sha: ref.head_sha, author: ref.author },
732
+ { botLogin, now },
733
+ );
734
+ if (result.skipped) return false;
735
+ store.logEvent("pr_closed", local.number, { merged: ref.merged, source: "reconcile" });
736
+ const over = mergedOverBlock(ref.merged, priorState);
737
+ if (over)
738
+ ledgerFeedbackSignal(
739
+ store,
740
+ { kind: "merged_over_block", pr: local.number },
741
+ {
742
+ timezone: cfg.ops.timezone,
743
+ now: now(),
744
+ memoryEnabled: cfg.openviking.enabled,
745
+ },
746
+ );
747
+ return over;
748
+ })();
749
+ if (overBlock && deps.onMergedOverBlock) {
750
+ try {
751
+ await deps.onMergedOverBlock(local.number);
752
+ } catch (err) {
753
+ report.errors.push(`onMergedOverBlock #${local.number}: ${String(err)}`);
754
+ }
755
+ }
756
+ report.closed.push(local.number);
757
+ try {
758
+ await deps.hooks.archiveAndClose(local.number);
759
+ } catch (err) {
760
+ report.errors.push(`archiveAndClose #${local.number}: ${String(err)}`);
761
+ }
762
+ }
763
+ });
764
+
765
+ // ---- 4. withheld-approval backstop ---------------------------------------
766
+ // cigate.ts promises that a PR whose approval was withheld for red CI is
767
+ // re-queued "by the next completion (or the reconcile poll)". The
768
+ // `ci_completed` webhook is the fast path; this sweep is the backstop for a
769
+ // lost delivery — without it a missed green would leave the PR waiting on a
770
+ // verdict that is never re-attempted. Same idiom as every other step:
771
+ // GitHub (the CI state at the recorded head) always wins, corrections
772
+ // logged. The retry itself is retryWithheldApproval — the exact function the
773
+ // webhook path calls — never a copy.
774
+ if (adapter.listChecks) {
775
+ await step("withheld-approvals", async () => {
776
+ for (const local of store.allPrs()) {
777
+ if (local.state === "closed") continue;
778
+ const mark = store.approvalWithheld(local.number);
779
+ if (!mark) continue;
780
+ const outcome = await retryWithheldApproval(
781
+ {
782
+ cfg,
783
+ store,
784
+ adapter: { listChecks: (ref) => adapter.listChecks!(ref) },
785
+ now,
786
+ ...(deps.log ? { log: deps.log } : {}),
787
+ },
788
+ { pr: local.number, head_sha: mark.head_sha },
789
+ );
790
+ if (outcome.action === "requeued")
791
+ correction(
792
+ deps,
793
+ local.number,
794
+ "withheld-approval-requeued",
795
+ { head_sha: mark.head_sha, ci: outcome.ci },
796
+ report,
797
+ );
798
+ }
799
+ });
800
+ }
801
+
802
+ // ---- 5. bot-comment registry backfill ----------------------------------
803
+ if (deps.backfillRegistry !== false) {
804
+ await step("registry-backfill", async () => {
805
+ for (const local of store.allPrs()) {
806
+ if (local.state === "closed") continue;
807
+ try {
808
+ for (const id of await adapter.listBotReviewComments(local.number)) {
809
+ if (store.isBotComment(id, "review_comment")) continue;
810
+ store.registerBotComment(id, local.number);
811
+ report.backfilled_comments++;
812
+ }
813
+ } catch (err) {
814
+ report.errors.push(`backfill #${local.number}: ${String(err)}`);
815
+ }
816
+ }
817
+ });
818
+ }
819
+
820
+ // ---- 5b. human-comment capture sweep -------------------------------------
821
+ // The webhook is the fast path and GitHub never redelivers, so a comment
822
+ // posted while the daemon was down would otherwise be permanent evidence
823
+ // loss rather than a delayed signal. This is the backstop, and it
824
+ // is deliberately shaped like every other sweep here: READ-ONLY (three list
825
+ // calls per PR, no mutation anywhere in the path), bounded
826
+ // (COMMENT_SWEEP_MAX_PRS, freshest first, one API page per source), and
827
+ // idempotent — dedupe is GitHub's own `(source, comment_id)` identity in
828
+ // `pr_comments`, so re-running captures nothing twice and an edited comment
829
+ // is still the same comment.
830
+ //
831
+ // It captures ONLY: nothing here routes, wakes a session, stamps a mark or
832
+ // feeds the [feedback] engine. A tagged comment picked up here gets the tag
833
+ // recorded and nothing else — the same-day addendum stays tag-gated on the
834
+ // webhook's feedback path, where a human is in the loop.
835
+ if (
836
+ deps.captureComments !== false &&
837
+ adapter.listReviewCommentsFull &&
838
+ adapter.listIssueComments &&
839
+ adapter.listReviewsFull
840
+ ) {
841
+ await step("comment-capture", async () => {
842
+ // Recently-closed PRs stay in: closed-sync above marks a
843
+ // closed-during-downtime PR closed in this very pass, and its comments
844
+ // are what this backstop exists to recover. `updated_at` is the close
845
+ // instant for a closed row.
846
+ const nowMs = now().getTime();
847
+ const closedRecently = (updated_at: string): boolean => {
848
+ const t = Date.parse(updated_at);
849
+ return Number.isFinite(t) && nowMs - t <= COMMENT_SWEEP_CLOSED_WINDOW_MS;
850
+ };
851
+ // A failed open-PR list is UNKNOWN remote state, not a change: keep the
852
+ // stored remote half, or every PR would re-sweep on the failing pass
853
+ // and again on the recovering one. A closed PR has left the open list
854
+ // and with it GitHub's timestamp, so nothing remote moves when a
855
+ // comment lands on it after the close: inside the recent-close window
856
+ // its remote half is the current hour instead, and it is re-swept once
857
+ // an hour.
858
+ const nowHour = now().toISOString().slice(0, 13);
859
+ const remoteHalf = (p: { number: number; state: string }): string => {
860
+ if (!openListed) return store.lastCommentSweep(p.number)?.split("|")[1] ?? "";
861
+ const listed = open.get(p.number);
862
+ if (listed) return listed.updated_at;
863
+ return p.state === "closed" ? `closed@${nowHour}` : "";
864
+ };
865
+ const sweepMark = (p: { number: number; state: string; updated_at: string }): string =>
866
+ `${p.updated_at}|${remoteHalf(p)}`;
867
+ const candidates = store
868
+ .allPrs()
869
+ .filter(
870
+ (p) =>
871
+ p.state !== "closed" ||
872
+ report.closed.includes(p.number) ||
873
+ closedRecently(p.updated_at),
874
+ )
875
+ // Change gating (without it every tracked PR costs three reads every
876
+ // pass): a PR whose row has not moved since the last successful sweep
877
+ // of it has produced no webhook the sweep could have missed a
878
+ // *newer* version of than last time — skip it. The watermark is the
879
+ // row's own `updated_at` PAIRED with GitHub's `updated_at` for the PR
880
+ // (from the open-PR list above), recorded per PR after a clean sweep.
881
+ // The remote half is load-bearing: capturing a comment never moves
882
+ // the local row, so a comment whose webhook was lost (the daemon was
883
+ // down, no push, no title change) only shows up as GitHub's
884
+ // timestamp moving.
885
+ .filter((p) => store.lastCommentSweep(p.number) !== sweepMark(p))
886
+ .sort((a, b) =>
887
+ a.updated_at < b.updated_at ? 1 : a.updated_at > b.updated_at ? -1 : a.number - b.number,
888
+ )
889
+ .slice(0, COMMENT_SWEEP_MAX_PRS);
890
+ for (const local of candidates) {
891
+ const n = local.number;
892
+ let rows: CapturedComment[];
893
+ let reviewsFetched: ReviewFull[] = [];
894
+ let inlineFetched: ReviewCommentFull[] = [];
895
+ try {
896
+ const [inline, top, reviews] = await Promise.all([
897
+ adapter.listReviewCommentsFull!(n),
898
+ adapter.listIssueComments!(n),
899
+ adapter.listReviewsFull!(n),
900
+ ]);
901
+ reviewsFetched = reviews;
902
+ inlineFetched = inline;
903
+ rows = [
904
+ ...inline.map((c) => capturedFromReviewComment(n, c)),
905
+ ...top.map((c) => capturedFromIssueComment(n, c)),
906
+ ...reviews.map((r) => capturedFromReview(n, r)),
907
+ ];
908
+ } catch (err) {
909
+ report.errors.push(`comment-capture #${n}: ${String(err)}`);
910
+ continue;
911
+ }
912
+ // The bot's own inline comments in this very read are the
913
+ // link facts the outcome capture needs (which finding each one
914
+ // carried) — kept here, at no extra API call. Never breaks the sweep.
915
+ if (deps.outcomes) {
916
+ try {
917
+ deps.outcomes.observeBotComments(n, inlineFetched);
918
+ } catch (err) {
919
+ (deps.log ?? (() => {}))(`reconcile: outcome facts #${n} failed`, err);
920
+ }
921
+ }
922
+ for (const c of rows) {
923
+ if (!isHumanCapture(c, botLogin)) continue;
924
+ if (recordCapturedComment(store, c, "reconcile")) report.captured_comments++;
925
+ }
926
+ // ---- the exec boundary's OUTCOME layer ------------------------------
927
+ // The bot's OWN reviews, which `isHumanCapture` discards above, are the
928
+ // one piece of evidence that does not care HOW a write was made. The
929
+ // command-string guard is pattern-based and not closed; a review here
930
+ // that the daemon has no record of posting is a violation whichever
931
+ // way it got there — and this costs no
932
+ // API call, because `listReviewsFull` was already fetched above.
933
+ // Detection only: nothing below mutates GitHub, and nothing here can
934
+ // withdraw, retract or edit a review (AGENTS.md invariant 2 — structural,
935
+ // not prompted; there is no such call in this module or its imports).
936
+ try {
937
+ const ungated = auditUngatedReviews(
938
+ reviewsFetched,
939
+ local.head_sha,
940
+ {
941
+ reviewIds: store.postedReviewIds(n),
942
+ reviewedHead: store.reviewedHead(n) ?? undefined,
943
+ migrationPrecheck: store.lastEventAt("migration_collision_comment", n) !== undefined,
944
+ postingKeys: new Set(
945
+ store.roundsFor(n).flatMap((r) => (r.posting_key ? [r.posting_key] : [])),
946
+ ),
947
+ reviewComments: commentsByReview(inlineFetched),
948
+ gatedCommentIds: store.botCommentIds(n),
949
+ },
950
+ { botLogin, appSlug: cfg.github.app_slug },
951
+ );
952
+ if (ungated.length > 0) {
953
+ store.logEvent("ungated_review_detected", n, {
954
+ head_sha: local.head_sha,
955
+ reviews: ungated,
956
+ });
957
+ const message = ungatedReviewMessage(n, ungated);
958
+ // An unaccounted APPROVE wakes; anything else stays a durable row.
959
+ // The asymmetry is the blocker bar's: an approval posted outside
960
+ // the gate defeats rule 1, the CI hard-gate and every posting
961
+ // guard at once, and it is the outcome any bypass of the exec
962
+ // boundary is reaching for.
963
+ if (hasUngatedApproval(ungated))
964
+ store.logAnomaly("ungated_approval", n, null, message, message);
965
+ else store.logAnomaly("ungated_review", n, null, message);
966
+ report.errors.push(
967
+ `ungated-review #${n}: ${ungated.length} unaccounted bot review(s) at the head`,
968
+ );
969
+ }
970
+ } catch (err) {
971
+ // Never let the audit break the sweep it rides on.
972
+ report.errors.push(`ungated-review-audit #${n}: ${String(err)}`);
973
+ }
974
+ // Watermark only a CLEAN sweep of this PR — a failed read `continue`s
975
+ // above without one, so it is retried on the next pass.
976
+ store.markCommentSweep(n, sweepMark(local));
977
+ }
978
+ });
979
+ }
980
+
981
+ // ---- outcome capture -------------------------------------------------------
982
+ // What became of every posted finding: link each bot comment to its finding,
983
+ // then decide each finding's fate from the replies, thread decisions, pushes
984
+ // and later rounds already recorded. Local reads only (state.db and the base
985
+ // clone's git) — no GitHub call and no gate. Bounded and change-gated inside
986
+ // `sweep`, and never an error of this pass: it is bookkeeping.
987
+ if (deps.outcomes) {
988
+ try {
989
+ const swept = await deps.outcomes.sweep();
990
+ if (swept.captured > 0 || swept.errors.length > 0) report.outcomes = swept;
991
+ } catch (err) {
992
+ (deps.log ?? (() => {}))("reconcile: outcome capture failed", err);
993
+ }
994
+ }
995
+
996
+ // ---- the raw-tier sweep -----------------------------------------------------
997
+ // The `pr-<n>` OpenViking sessions of closed PRs that are still on the
998
+ // server (a delete that failed, a close the daemon never saw) — bounded per
999
+ // pass, every outcome logged by the hook. Run AFTER the closed-sync above,
1000
+ // so a PR closed this pass is already closed in the registry. Never an
1001
+ // error of this pass, whatever happens: memory never blocks reconcile.
1002
+ if (deps.hooks.sweepStaleOvSessions) {
1003
+ try {
1004
+ const swept = await deps.hooks.sweepStaleOvSessions();
1005
+ if (swept) report.ov_sessions = swept;
1006
+ } catch (err) {
1007
+ (deps.log ?? (() => {}))("reconcile: stale openviking-session sweep threw", err);
1008
+ }
1009
+ }
1010
+
1011
+ // No retired-park migration runs here: `awaiting_human` is not a member of
1012
+ // `PrLifecycleState`, so no row can carry it for a pass to find.
1013
+
1014
+ store.logEvent("reconcile_pass", null, {
1015
+ open_prs: report.open_prs,
1016
+ triggered: report.triggered.length,
1017
+ closed: report.closed.length,
1018
+ captured_comments: report.captured_comments,
1019
+ corrections: report.corrections,
1020
+ errors: report.errors.length,
1021
+ ...(report.ov_sessions
1022
+ ? {
1023
+ ov_sessions_deleted: report.ov_sessions.deleted.length,
1024
+ ov_sessions_failed: report.ov_sessions.failed.length,
1025
+ ...(report.ov_sessions.error ? { ov_sessions_error: report.ov_sessions.error } : {}),
1026
+ }
1027
+ : {}),
1028
+ });
1029
+ return report;
1030
+ }