@quickchatai/quickreview 0.0.0-stage → 1.2.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 (1479) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +401 -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 +1099 -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/login-route.js +5 -0
  62. package/dist/extensions/cli/login-route.js.map +1 -0
  63. package/dist/extensions/cli/muted-theme.js +5 -0
  64. package/dist/extensions/cli/muted-theme.js.map +1 -0
  65. package/dist/extensions/cli/onboarding.js +5 -0
  66. package/dist/extensions/cli/onboarding.js.map +1 -0
  67. package/dist/extensions/cli/setup.js +5 -0
  68. package/dist/extensions/cli/setup.js.map +1 -0
  69. package/dist/extensions/cli/tui-view.js +5 -0
  70. package/dist/extensions/cli/tui-view.js.map +1 -0
  71. package/dist/extensions/companion-guard.js +361 -0
  72. package/dist/extensions/companion-guard.js.map +1 -0
  73. package/dist/extensions/debug-round.js +204 -0
  74. package/dist/extensions/debug-round.js.map +1 -0
  75. package/dist/extensions/inject-bridge.js +603 -0
  76. package/dist/extensions/inject-bridge.js.map +1 -0
  77. package/dist/extensions/login-route.js +180 -0
  78. package/dist/extensions/login-route.js.map +1 -0
  79. package/dist/extensions/muted-theme.js +12 -0
  80. package/dist/extensions/muted-theme.js.map +1 -0
  81. package/dist/extensions/onboarding.js +198 -0
  82. package/dist/extensions/onboarding.js.map +1 -0
  83. package/dist/extensions/setup-replay.js +269 -0
  84. package/dist/extensions/setup-replay.js.map +1 -0
  85. package/dist/extensions/setup-scan.js +998 -0
  86. package/dist/extensions/setup-scan.js.map +1 -0
  87. package/dist/extensions/setup-triage.js +175 -0
  88. package/dist/extensions/setup-triage.js.map +1 -0
  89. package/dist/extensions/setup.js +1160 -0
  90. package/dist/extensions/setup.js.map +1 -0
  91. package/dist/extensions/tui-view.js +389 -0
  92. package/dist/extensions/tui-view.js.map +1 -0
  93. package/dist/extensions/vendor/openviking-pi/client.js +376 -0
  94. package/dist/extensions/vendor/openviking-pi/client.js.map +1 -0
  95. package/dist/extensions/vendor/openviking-pi/config.js +189 -0
  96. package/dist/extensions/vendor/openviking-pi/config.js.map +1 -0
  97. package/dist/extensions/vendor/openviking-pi/index.js +421 -0
  98. package/dist/extensions/vendor/openviking-pi/index.js.map +1 -0
  99. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +86 -0
  100. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs.map +1 -0
  101. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs +408 -0
  102. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs.map +1 -0
  103. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +41 -0
  104. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs.map +1 -0
  105. package/dist/extensions/vendor/openviking-pi/qcr-hint.js +290 -0
  106. package/dist/extensions/vendor/openviking-pi/qcr-hint.js.map +1 -0
  107. package/dist/extensions/vendor/openviking-pi/qcr-honest.js +148 -0
  108. package/dist/extensions/vendor/openviking-pi/qcr-honest.js.map +1 -0
  109. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js +68 -0
  110. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js.map +1 -0
  111. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js +77 -0
  112. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js.map +1 -0
  113. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js +216 -0
  114. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js.map +1 -0
  115. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js +154 -0
  116. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js.map +1 -0
  117. package/dist/extensions/vendor/openviking-pi/qcr-recall.js +254 -0
  118. package/dist/extensions/vendor/openviking-pi/qcr-recall.js.map +1 -0
  119. package/dist/extensions/vendor/openviking-pi/qcr-shim.js +94 -0
  120. package/dist/extensions/vendor/openviking-pi/qcr-shim.js.map +1 -0
  121. package/dist/extensions/vendor/openviking-pi/qcr-write.js +333 -0
  122. package/dist/extensions/vendor/openviking-pi/qcr-write.js.map +1 -0
  123. package/dist/extensions/vendor/openviking-pi/recall.js +108 -0
  124. package/dist/extensions/vendor/openviking-pi/recall.js.map +1 -0
  125. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs +529 -0
  126. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs.map +1 -0
  127. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs +205 -0
  128. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs.map +1 -0
  129. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs +442 -0
  130. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs.map +1 -0
  131. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs +286 -0
  132. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs.map +1 -0
  133. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +189 -0
  134. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs.map +1 -0
  135. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs +580 -0
  136. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs.map +1 -0
  137. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs +11 -0
  138. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs.map +1 -0
  139. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs +63 -0
  140. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs.map +1 -0
  141. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs +58 -0
  142. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs.map +1 -0
  143. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  144. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs.map +1 -0
  145. package/dist/extensions/vendor/openviking-pi/sync.js +127 -0
  146. package/dist/extensions/vendor/openviking-pi/sync.js.map +1 -0
  147. package/dist/extensions/vendor/openviking-pi/takeover.js +25 -0
  148. package/dist/extensions/vendor/openviking-pi/takeover.js.map +1 -0
  149. package/dist/extensions/vendor/openviking-pi/tools.js +417 -0
  150. package/dist/extensions/vendor/openviking-pi/tools.js.map +1 -0
  151. package/dist/src/anomalies.js +483 -0
  152. package/dist/src/anomalies.js.map +1 -0
  153. package/dist/src/answerworker.js +180 -0
  154. package/dist/src/answerworker.js.map +1 -0
  155. package/dist/src/appstamp.js +68 -0
  156. package/dist/src/appstamp.js.map +1 -0
  157. package/dist/src/archive/admission.js +3 -0
  158. package/dist/src/archive/admission.js.map +1 -0
  159. package/dist/src/archive/archivedb.js +474 -0
  160. package/dist/src/archive/archivedb.js.map +1 -0
  161. package/dist/src/archive/archiver.js +1770 -0
  162. package/dist/src/archive/archiver.js.map +1 -0
  163. package/dist/src/archive/archivewrite.js +198 -0
  164. package/dist/src/archive/archivewrite.js.map +1 -0
  165. package/dist/src/archive/bundle.js +266 -0
  166. package/dist/src/archive/bundle.js.map +1 -0
  167. package/dist/src/archive/dbmove.js +638 -0
  168. package/dist/src/archive/dbmove.js.map +1 -0
  169. package/dist/src/archive/duplicatecounts.js +80 -0
  170. package/dist/src/archive/duplicatecounts.js.map +1 -0
  171. package/dist/src/archive/eligibility.js +113 -0
  172. package/dist/src/archive/eligibility.js.map +1 -0
  173. package/dist/src/archive/extract.js +288 -0
  174. package/dist/src/archive/extract.js.map +1 -0
  175. package/dist/src/archive/fsutil.js +330 -0
  176. package/dist/src/archive/fsutil.js.map +1 -0
  177. package/dist/src/archive/gzfile.js +277 -0
  178. package/dist/src/archive/gzfile.js.map +1 -0
  179. package/dist/src/archive/kinds.js +22 -0
  180. package/dist/src/archive/kinds.js.map +1 -0
  181. package/dist/src/archive/livecheckpoint.js +178 -0
  182. package/dist/src/archive/livecheckpoint.js.map +1 -0
  183. package/dist/src/archive/liveretention.js +145 -0
  184. package/dist/src/archive/liveretention.js.map +1 -0
  185. package/dist/src/archive/manifest.js +284 -0
  186. package/dist/src/archive/manifest.js.map +1 -0
  187. package/dist/src/archive/overseer.js +283 -0
  188. package/dist/src/archive/overseer.js.map +1 -0
  189. package/dist/src/archive/piglobal.js +129 -0
  190. package/dist/src/archive/piglobal.js.map +1 -0
  191. package/dist/src/archive/plan.js +398 -0
  192. package/dist/src/archive/plan.js.map +1 -0
  193. package/dist/src/archive/prarchive.js +831 -0
  194. package/dist/src/archive/prarchive.js.map +1 -0
  195. package/dist/src/archive/prfiles.js +303 -0
  196. package/dist/src/archive/prfiles.js.map +1 -0
  197. package/dist/src/archive/report.js +169 -0
  198. package/dist/src/archive/report.js.map +1 -0
  199. package/dist/src/archive/restore.js +276 -0
  200. package/dist/src/archive/restore.js.map +1 -0
  201. package/dist/src/archive/rows.js +106 -0
  202. package/dist/src/archive/rows.js.map +1 -0
  203. package/dist/src/archive/seal.js +480 -0
  204. package/dist/src/archive/seal.js.map +1 -0
  205. package/dist/src/archive/status.js +528 -0
  206. package/dist/src/archive/status.js.map +1 -0
  207. package/dist/src/archive/storepass.js +409 -0
  208. package/dist/src/archive/storepass.js.map +1 -0
  209. package/dist/src/backfill.js +217 -0
  210. package/dist/src/backfill.js.map +1 -0
  211. package/dist/src/bench/cost.js +87 -0
  212. package/dist/src/bench/exec.js +76 -0
  213. package/dist/src/bench/values.js +14 -0
  214. package/dist/src/botcontrol.js +127 -0
  215. package/dist/src/botcontrol.js.map +1 -0
  216. package/dist/src/botworker.js +805 -0
  217. package/dist/src/botworker.js.map +1 -0
  218. package/dist/src/capture.js +234 -0
  219. package/dist/src/capture.js.map +1 -0
  220. package/dist/src/cases.js +1491 -0
  221. package/dist/src/cases.js.map +1 -0
  222. package/dist/src/channelfs.js +27 -0
  223. package/dist/src/channelfs.js.map +1 -0
  224. package/dist/src/checklist.js +312 -0
  225. package/dist/src/checklist.js.map +1 -0
  226. package/dist/src/ciretry.js +92 -0
  227. package/dist/src/ciretry.js.map +1 -0
  228. package/dist/src/cli.js +1947 -0
  229. package/dist/src/cli.js.map +1 -0
  230. package/dist/src/cliops.js +334 -0
  231. package/dist/src/cliops.js.map +1 -0
  232. package/dist/src/clonedir.js +15 -0
  233. package/dist/src/clonedir.js.map +1 -0
  234. package/dist/src/commandeffects.js +43 -0
  235. package/dist/src/commandeffects.js.map +1 -0
  236. package/dist/src/commands.js +1335 -0
  237. package/dist/src/commands.js.map +1 -0
  238. package/dist/src/companioninbox.js +203 -0
  239. package/dist/src/companioninbox.js.map +1 -0
  240. package/dist/src/compare.js +673 -0
  241. package/dist/src/compare.js.map +1 -0
  242. package/dist/src/config.js +1041 -0
  243. package/dist/src/config.js.map +1 -0
  244. package/dist/src/configcheck.js +111 -0
  245. package/dist/src/configcheck.js.map +1 -0
  246. package/dist/src/coreext.js +43 -0
  247. package/dist/src/coreext.js.map +1 -0
  248. package/dist/src/daemon.js +945 -0
  249. package/dist/src/daemon.js.map +1 -0
  250. package/dist/src/debuground.js +731 -0
  251. package/dist/src/debuground.js.map +1 -0
  252. package/dist/src/debugroundpi.js +223 -0
  253. package/dist/src/debugroundpi.js.map +1 -0
  254. package/dist/src/diagnostics.js +14 -0
  255. package/dist/src/diagnostics.js.map +1 -0
  256. package/dist/src/digest.js +139 -0
  257. package/dist/src/digest.js.map +1 -0
  258. package/dist/src/dispatch.js +1727 -0
  259. package/dist/src/dispatch.js.map +1 -0
  260. package/dist/src/engine/answerguard.js +18 -0
  261. package/dist/src/engine/answerguard.js.map +1 -0
  262. package/dist/src/engine/botsdk.js +262 -0
  263. package/dist/src/engine/botsdk.js.map +1 -0
  264. package/dist/src/engine/caserunner-sdk.js +332 -0
  265. package/dist/src/engine/caserunner-sdk.js.map +1 -0
  266. package/dist/src/engine/debugpi.js +206 -0
  267. package/dist/src/engine/debugpi.js.map +1 -0
  268. package/dist/src/eod.js +473 -0
  269. package/dist/src/eod.js.map +1 -0
  270. package/dist/src/eodpinwatch.js +391 -0
  271. package/dist/src/eodpinwatch.js.map +1 -0
  272. package/dist/src/escalation.js +1009 -0
  273. package/dist/src/escalation.js.map +1 -0
  274. package/dist/src/eventloop.js +779 -0
  275. package/dist/src/eventloop.js.map +1 -0
  276. package/dist/src/execboundary.js +437 -0
  277. package/dist/src/execboundary.js.map +1 -0
  278. package/dist/src/feedback.js +915 -0
  279. package/dist/src/feedback.js.map +1 -0
  280. package/dist/src/findingscheck.js +200 -0
  281. package/dist/src/findingscheck.js.map +1 -0
  282. package/dist/src/fsdenied.js +26 -0
  283. package/dist/src/fsdenied.js.map +1 -0
  284. package/dist/src/ghread.js +181 -0
  285. package/dist/src/ghread.js.map +1 -0
  286. package/dist/src/github.js +1098 -0
  287. package/dist/src/github.js.map +1 -0
  288. package/dist/src/githubtoken.js +346 -0
  289. package/dist/src/githubtoken.js.map +1 -0
  290. package/dist/src/homes.js +103 -0
  291. package/dist/src/homes.js.map +1 -0
  292. package/dist/src/hostroute.js +24 -0
  293. package/dist/src/hostroute.js.map +1 -0
  294. package/dist/src/improvements.js +625 -0
  295. package/dist/src/improvements.js.map +1 -0
  296. package/dist/src/install.js +946 -0
  297. package/dist/src/install.js.map +1 -0
  298. package/dist/src/installkind.js +40 -0
  299. package/dist/src/installkind.js.map +1 -0
  300. package/dist/src/ipc/capability.js +286 -0
  301. package/dist/src/ipc/capability.js.map +1 -0
  302. package/dist/src/ipc/client.js +226 -0
  303. package/dist/src/ipc/client.js.map +1 -0
  304. package/dist/src/ipc/control.js +70 -0
  305. package/dist/src/ipc/control.js.map +1 -0
  306. package/dist/src/ipc/ghreadshim.js +77 -0
  307. package/dist/src/ipc/ghreadshim.js.map +1 -0
  308. package/dist/src/ipc/launcher.js +65 -0
  309. package/dist/src/ipc/launcher.js.map +1 -0
  310. package/dist/src/ipc/permits.js +293 -0
  311. package/dist/src/ipc/permits.js.map +1 -0
  312. package/dist/src/ipc/postshim.js +137 -0
  313. package/dist/src/ipc/postshim.js.map +1 -0
  314. package/dist/src/ipc/protocol.js +239 -0
  315. package/dist/src/ipc/protocol.js.map +1 -0
  316. package/dist/src/ipc/server.js +312 -0
  317. package/dist/src/ipc/server.js.map +1 -0
  318. package/dist/src/ipc/workerspec.js +148 -0
  319. package/dist/src/ipc/workerspec.js.map +1 -0
  320. package/dist/src/learner/learner.js +1272 -0
  321. package/dist/src/learner/learner.js.map +1 -0
  322. package/dist/src/learner/miner.js +948 -0
  323. package/dist/src/learner/miner.js.map +1 -0
  324. package/dist/src/learner/packet.js +216 -0
  325. package/dist/src/learner/packet.js.map +1 -0
  326. package/dist/src/learner/receipt.js +135 -0
  327. package/dist/src/learner/receipt.js.map +1 -0
  328. package/dist/src/learner/status.js +38 -0
  329. package/dist/src/learner/status.js.map +1 -0
  330. package/dist/src/ledgercheck.js +120 -0
  331. package/dist/src/ledgercheck.js.map +1 -0
  332. package/dist/src/lessonledger.js +451 -0
  333. package/dist/src/lessonledger.js.map +1 -0
  334. package/dist/src/lessonselect.js +639 -0
  335. package/dist/src/lessonselect.js.map +1 -0
  336. package/dist/src/lessonshadow.js +540 -0
  337. package/dist/src/lessonshadow.js.map +1 -0
  338. package/dist/src/levers.js +302 -0
  339. package/dist/src/levers.js.map +1 -0
  340. package/dist/src/live/projection.js +450 -0
  341. package/dist/src/live/projection.js.map +1 -0
  342. package/dist/src/live/publish.js +83 -0
  343. package/dist/src/live/publish.js.map +1 -0
  344. package/dist/src/live/read.js +60 -0
  345. package/dist/src/live/read.js.map +1 -0
  346. package/dist/src/livecli.js +288 -0
  347. package/dist/src/livecli.js.map +1 -0
  348. package/dist/src/loginhint.js +47 -0
  349. package/dist/src/loginhint.js.map +1 -0
  350. package/dist/src/loginrefresh/atomic.js +66 -0
  351. package/dist/src/loginrefresh/atomic.js.map +1 -0
  352. package/dist/src/loginrefresh/lock.js +93 -0
  353. package/dist/src/loginrefresh/lock.js.map +1 -0
  354. package/dist/src/loginrefresh/main.js +58 -0
  355. package/dist/src/loginrefresh/main.js.map +1 -0
  356. package/dist/src/loginrefresh/pirefresh.js +52 -0
  357. package/dist/src/loginrefresh/pirefresh.js.map +1 -0
  358. package/dist/src/loginrefresh/refresher.js +286 -0
  359. package/dist/src/loginrefresh/refresher.js.map +1 -0
  360. package/dist/src/loginrefresh/supervisor.js +253 -0
  361. package/dist/src/loginrefresh/supervisor.js.map +1 -0
  362. package/dist/src/loginrefresh/types.js +4 -0
  363. package/dist/src/loginrefresh/types.js.map +1 -0
  364. package/dist/src/memory/context.js +251 -0
  365. package/dist/src/memory/context.js.map +1 -0
  366. package/dist/src/memory/datafence.js +5 -0
  367. package/dist/src/memory/datafence.js.map +1 -0
  368. package/dist/src/memory/delivery.js +131 -0
  369. package/dist/src/memory/delivery.js.map +1 -0
  370. package/dist/src/memory/eventtags.js +81 -0
  371. package/dist/src/memory/eventtags.js.map +1 -0
  372. package/dist/src/memory/health.js +713 -0
  373. package/dist/src/memory/health.js.map +1 -0
  374. package/dist/src/memory/import.js +504 -0
  375. package/dist/src/memory/import.js.map +1 -0
  376. package/dist/src/memory/layout.js +252 -0
  377. package/dist/src/memory/layout.js.map +1 -0
  378. package/dist/src/memory/legacy-file.js +100 -0
  379. package/dist/src/memory/legacy-file.js.map +1 -0
  380. package/dist/src/memory/lessons.js +370 -0
  381. package/dist/src/memory/lessons.js.map +1 -0
  382. package/dist/src/memory/ovsession.js +449 -0
  383. package/dist/src/memory/ovsession.js.map +1 -0
  384. package/dist/src/memory/relayout.js +259 -0
  385. package/dist/src/memory/relayout.js.map +1 -0
  386. package/dist/src/memory/roundactivity.js +180 -0
  387. package/dist/src/memory/roundactivity.js.map +1 -0
  388. package/dist/src/memory/selection.js +690 -0
  389. package/dist/src/memory/selection.js.map +1 -0
  390. package/dist/src/memory/shadowstatus.js +69 -0
  391. package/dist/src/memory/shadowstatus.js.map +1 -0
  392. package/dist/src/memory/store.js +83 -0
  393. package/dist/src/memory/store.js.map +1 -0
  394. package/dist/src/memory/textidentity.js +8 -0
  395. package/dist/src/memory/textidentity.js.map +1 -0
  396. package/dist/src/metrics.js +773 -0
  397. package/dist/src/metrics.js.map +1 -0
  398. package/dist/src/missingconfig.js +8 -0
  399. package/dist/src/missingconfig.js.map +1 -0
  400. package/dist/src/npmverbs.js +228 -0
  401. package/dist/src/npmverbs.js.map +1 -0
  402. package/dist/src/onboard/choices.js +219 -0
  403. package/dist/src/onboard/choices.js.map +1 -0
  404. package/dist/src/onboard/engine.js +329 -0
  405. package/dist/src/onboard/engine.js.map +1 -0
  406. package/dist/src/onboard/launch.js +75 -0
  407. package/dist/src/onboard/launch.js.map +1 -0
  408. package/dist/src/onboard/pipin.js +22 -0
  409. package/dist/src/onboard/pipin.js.map +1 -0
  410. package/dist/src/onboard/stepforward.js +41 -0
  411. package/dist/src/onboard/stepforward.js.map +1 -0
  412. package/dist/src/onboard/steps/appslug.js +214 -0
  413. package/dist/src/onboard/steps/appslug.js.map +1 -0
  414. package/dist/src/onboard/steps/bringup.js +408 -0
  415. package/dist/src/onboard/steps/bringup.js.map +1 -0
  416. package/dist/src/onboard/steps/compose.js +372 -0
  417. package/dist/src/onboard/steps/compose.js.map +1 -0
  418. package/dist/src/onboard/steps/configdelivery.js +50 -0
  419. package/dist/src/onboard/steps/configdelivery.js.map +1 -0
  420. package/dist/src/onboard/steps/configfill.js +1218 -0
  421. package/dist/src/onboard/steps/configfill.js.map +1 -0
  422. package/dist/src/onboard/steps/deploysh.js +80 -0
  423. package/dist/src/onboard/steps/deploysh.js.map +1 -0
  424. package/dist/src/onboard/steps/embeddings.js +472 -0
  425. package/dist/src/onboard/steps/embeddings.js.map +1 -0
  426. package/dist/src/onboard/steps/escalation.js +571 -0
  427. package/dist/src/onboard/steps/escalation.js.map +1 -0
  428. package/dist/src/onboard/steps/githubaccount.js +595 -0
  429. package/dist/src/onboard/steps/githubaccount.js.map +1 -0
  430. package/dist/src/onboard/steps/githubapp.js +1150 -0
  431. package/dist/src/onboard/steps/githubapp.js.map +1 -0
  432. package/dist/src/onboard/steps/golive.js +508 -0
  433. package/dist/src/onboard/steps/golive.js.map +1 -0
  434. package/dist/src/onboard/steps/index.js +78 -0
  435. package/dist/src/onboard/steps/index.js.map +1 -0
  436. package/dist/src/onboard/steps/ingress.js +817 -0
  437. package/dist/src/onboard/steps/ingress.js.map +1 -0
  438. package/dist/src/onboard/steps/inventory.js +420 -0
  439. package/dist/src/onboard/steps/inventory.js.map +1 -0
  440. package/dist/src/onboard/steps/llmauth.js +966 -0
  441. package/dist/src/onboard/steps/llmauth.js.map +1 -0
  442. package/dist/src/onboard/steps/memory.js +1112 -0
  443. package/dist/src/onboard/steps/memory.js.map +1 -0
  444. package/dist/src/onboard/steps/memorykeys.js +43 -0
  445. package/dist/src/onboard/steps/memorykeys.js.map +1 -0
  446. package/dist/src/onboard/steps/preflight.js +172 -0
  447. package/dist/src/onboard/steps/preflight.js.map +1 -0
  448. package/dist/src/onboard/steps/proof.js +812 -0
  449. package/dist/src/onboard/steps/proof.js.map +1 -0
  450. package/dist/src/onboard/steps/ssh.js +300 -0
  451. package/dist/src/onboard/steps/ssh.js.map +1 -0
  452. package/dist/src/onboard/steps/topology.js +291 -0
  453. package/dist/src/onboard/steps/topology.js.map +1 -0
  454. package/dist/src/onboard/steps/transport.js +519 -0
  455. package/dist/src/onboard/steps/transport.js.map +1 -0
  456. package/dist/src/onboard/steps/tuiroute.js +102 -0
  457. package/dist/src/onboard/steps/tuiroute.js.map +1 -0
  458. package/dist/src/onboard/steps/verifyup.js +378 -0
  459. package/dist/src/onboard/steps/verifyup.js.map +1 -0
  460. package/dist/src/onboard/steps/vmdeploy.js +368 -0
  461. package/dist/src/onboard/steps/vmdeploy.js.map +1 -0
  462. package/dist/src/onboard/toml.js +53 -0
  463. package/dist/src/onboard/toml.js.map +1 -0
  464. package/dist/src/onboard/toolnames.js +30 -0
  465. package/dist/src/onboard/toolnames.js.map +1 -0
  466. package/dist/src/opencli.js +508 -0
  467. package/dist/src/opencli.js.map +1 -0
  468. package/dist/src/openpr.js +457 -0
  469. package/dist/src/openpr.js.map +1 -0
  470. package/dist/src/openviking/client.js +821 -0
  471. package/dist/src/openviking/client.js.map +1 -0
  472. package/dist/src/openviking/context.js +218 -0
  473. package/dist/src/openviking/context.js.map +1 -0
  474. package/dist/src/openviking/embedder.js +457 -0
  475. package/dist/src/openviking/embedder.js.map +1 -0
  476. package/dist/src/openviking/gapsink.js +38 -0
  477. package/dist/src/openviking/gapsink.js.map +1 -0
  478. package/dist/src/openviking/health.js +69 -0
  479. package/dist/src/openviking/health.js.map +1 -0
  480. package/dist/src/openviking/index.js +24 -0
  481. package/dist/src/openviking/index.js.map +1 -0
  482. package/dist/src/openviking/lessonfind.js +54 -0
  483. package/dist/src/openviking/lessonfind.js.map +1 -0
  484. package/dist/src/openviking/probe.js +89 -0
  485. package/dist/src/openviking/probe.js.map +1 -0
  486. package/dist/src/openviking/proc.js +95 -0
  487. package/dist/src/openviking/proc.js.map +1 -0
  488. package/dist/src/openviking/provisionreport.js +144 -0
  489. package/dist/src/openviking/provisionreport.js.map +1 -0
  490. package/dist/src/openviking/reembed.js +317 -0
  491. package/dist/src/openviking/reembed.js.map +1 -0
  492. package/dist/src/openviking/relayout.js +153 -0
  493. package/dist/src/openviking/relayout.js.map +1 -0
  494. package/dist/src/openviking/sidecar-main.js +39 -0
  495. package/dist/src/openviking/sidecar-main.js.map +1 -0
  496. package/dist/src/openviking/sidecar.js +79 -0
  497. package/dist/src/openviking/sidecar.js.map +1 -0
  498. package/dist/src/openviking/store.js +1758 -0
  499. package/dist/src/openviking/store.js.map +1 -0
  500. package/dist/src/openviking/supervisor.js +422 -0
  501. package/dist/src/openviking/supervisor.js.map +1 -0
  502. package/dist/src/openviking/types.js +5 -0
  503. package/dist/src/openviking/types.js.map +1 -0
  504. package/dist/src/operator-recovery.js +172 -0
  505. package/dist/src/operator-recovery.js.map +1 -0
  506. package/dist/src/operatormessage.js +44 -0
  507. package/dist/src/operatormessage.js.map +1 -0
  508. package/dist/src/operatorwrite.js +23 -0
  509. package/dist/src/operatorwrite.js.map +1 -0
  510. package/dist/src/outcomes.js +1364 -0
  511. package/dist/src/outcomes.js.map +1 -0
  512. package/dist/src/piauthcopy.js +5 -0
  513. package/dist/src/piauthcopy.js.map +1 -0
  514. package/dist/src/picli.js +45 -0
  515. package/dist/src/picli.js.map +1 -0
  516. package/dist/src/picwd.js +25 -0
  517. package/dist/src/picwd.js.map +1 -0
  518. package/dist/src/pilogin.js +35 -0
  519. package/dist/src/pilogin.js.map +1 -0
  520. package/dist/src/pingpong.js +1028 -0
  521. package/dist/src/pingpong.js.map +1 -0
  522. package/dist/src/posting-journal.js +442 -0
  523. package/dist/src/posting-journal.js.map +1 -0
  524. package/dist/src/posting-outbox.js +666 -0
  525. package/dist/src/posting-outbox.js.map +1 -0
  526. package/dist/src/posting-receipt.js +216 -0
  527. package/dist/src/posting-receipt.js.map +1 -0
  528. package/dist/src/posting.js +348 -0
  529. package/dist/src/posting.js.map +1 -0
  530. package/dist/src/postops.js +637 -0
  531. package/dist/src/postops.js.map +1 -0
  532. package/dist/src/pr-activity.js +11 -0
  533. package/dist/src/pr-activity.js.map +1 -0
  534. package/dist/src/pr-author.js +5 -0
  535. package/dist/src/pr-author.js.map +1 -0
  536. package/dist/src/pr-conversation.js +355 -0
  537. package/dist/src/pr-conversation.js.map +1 -0
  538. package/dist/src/pr-session-lifecycle.js +542 -0
  539. package/dist/src/pr-session-lifecycle.js.map +1 -0
  540. package/dist/src/preflight.js +341 -0
  541. package/dist/src/preflight.js.map +1 -0
  542. package/dist/src/priorresolve.js +275 -0
  543. package/dist/src/priorresolve.js.map +1 -0
  544. package/dist/src/qcrbin.js +180 -0
  545. package/dist/src/qcrbin.js.map +1 -0
  546. package/dist/src/recheck.js +1399 -0
  547. package/dist/src/recheck.js.map +1 -0
  548. package/dist/src/reconcile.js +840 -0
  549. package/dist/src/reconcile.js.map +1 -0
  550. package/dist/src/recordedfindings.js +15 -0
  551. package/dist/src/recordedfindings.js.map +1 -0
  552. package/dist/src/regression.js +546 -0
  553. package/dist/src/regression.js.map +1 -0
  554. package/dist/src/replay.js +598 -0
  555. package/dist/src/replay.js.map +1 -0
  556. package/dist/src/requiredpasses.js +113 -0
  557. package/dist/src/requiredpasses.js.map +1 -0
  558. package/dist/src/resumecheck.js +168 -0
  559. package/dist/src/resumecheck.js.map +1 -0
  560. package/dist/src/reviewcli.js +671 -0
  561. package/dist/src/reviewcli.js.map +1 -0
  562. package/dist/src/reviewcontext.js +22 -0
  563. package/dist/src/reviewcontext.js.map +1 -0
  564. package/dist/src/reviewdetach.js +574 -0
  565. package/dist/src/reviewdetach.js.map +1 -0
  566. package/dist/src/reviewhistory.js +310 -0
  567. package/dist/src/reviewhistory.js.map +1 -0
  568. package/dist/src/reviewhome.js +26 -0
  569. package/dist/src/reviewhome.js.map +1 -0
  570. package/dist/src/reviewmemory.js +110 -0
  571. package/dist/src/reviewmemory.js.map +1 -0
  572. package/dist/src/reviewnow.js +45 -0
  573. package/dist/src/reviewnow.js.map +1 -0
  574. package/dist/src/reviewrendercli.js +104 -0
  575. package/dist/src/reviewrendercli.js.map +1 -0
  576. package/dist/src/round-work.js +20 -0
  577. package/dist/src/round-work.js.map +1 -0
  578. package/dist/src/runhost.js +72 -0
  579. package/dist/src/runhost.js.map +1 -0
  580. package/dist/src/scanauth.js +25 -0
  581. package/dist/src/scanauth.js.map +1 -0
  582. package/dist/src/scanbox.js +846 -0
  583. package/dist/src/scanbox.js.map +1 -0
  584. package/dist/src/scancli.js +1074 -0
  585. package/dist/src/scancli.js.map +1 -0
  586. package/dist/src/scandriverlog.js +30 -0
  587. package/dist/src/scandriverlog.js.map +1 -0
  588. package/dist/src/session-bridge.js +75 -0
  589. package/dist/src/session-bridge.js.map +1 -0
  590. package/dist/src/session-command-payload.js +29 -0
  591. package/dist/src/session-command-payload.js.map +1 -0
  592. package/dist/src/session-command-supervisor.js +939 -0
  593. package/dist/src/session-command-supervisor.js.map +1 -0
  594. package/dist/src/sessionjsonl.js +85 -0
  595. package/dist/src/sessionjsonl.js.map +1 -0
  596. package/dist/src/sessions.js +541 -0
  597. package/dist/src/sessions.js.map +1 -0
  598. package/dist/src/setup/adapters.js +330 -0
  599. package/dist/src/setup/adapters.js.map +1 -0
  600. package/dist/src/setup/baselines.js +64 -0
  601. package/dist/src/setup/baselines.js.map +1 -0
  602. package/dist/src/setup/caserunner.js +554 -0
  603. package/dist/src/setup/caserunner.js.map +1 -0
  604. package/dist/src/setup/configcommit.js +358 -0
  605. package/dist/src/setup/configcommit.js.map +1 -0
  606. package/dist/src/setup/engine.js +672 -0
  607. package/dist/src/setup/engine.js.map +1 -0
  608. package/dist/src/setup/facts.js +593 -0
  609. package/dist/src/setup/facts.js.map +1 -0
  610. package/dist/src/setup/findings.js +948 -0
  611. package/dist/src/setup/findings.js.map +1 -0
  612. package/dist/src/setup/history.js +338 -0
  613. package/dist/src/setup/history.js.map +1 -0
  614. package/dist/src/setup/interview.js +185 -0
  615. package/dist/src/setup/interview.js.map +1 -0
  616. package/dist/src/setup/ledger.js +207 -0
  617. package/dist/src/setup/ledger.js.map +1 -0
  618. package/dist/src/setup/pins.js +43 -0
  619. package/dist/src/setup/pins.js.map +1 -0
  620. package/dist/src/setup/portrait.js +432 -0
  621. package/dist/src/setup/portrait.js.map +1 -0
  622. package/dist/src/setup/presentation.js +9 -0
  623. package/dist/src/setup/presentation.js.map +1 -0
  624. package/dist/src/setup/profile.js +417 -0
  625. package/dist/src/setup/profile.js.map +1 -0
  626. package/dist/src/setup/replay.js +240 -0
  627. package/dist/src/setup/replay.js.map +1 -0
  628. package/dist/src/setup/replaybuild.js +311 -0
  629. package/dist/src/setup/replaybuild.js.map +1 -0
  630. package/dist/src/setup/replayrun.js +806 -0
  631. package/dist/src/setup/replayrun.js.map +1 -0
  632. package/dist/src/setup/replaysource.js +169 -0
  633. package/dist/src/setup/replaysource.js.map +1 -0
  634. package/dist/src/setup/retune.js +333 -0
  635. package/dist/src/setup/retune.js.map +1 -0
  636. package/dist/src/setup/retunelog.js +51 -0
  637. package/dist/src/setup/retunelog.js.map +1 -0
  638. package/dist/src/setup/scan.js +725 -0
  639. package/dist/src/setup/scan.js.map +1 -0
  640. package/dist/src/setup/scanbuild.js +133 -0
  641. package/dist/src/setup/scanbuild.js.map +1 -0
  642. package/dist/src/setup/scanfacts.js +96 -0
  643. package/dist/src/setup/scanfacts.js.map +1 -0
  644. package/dist/src/setup/scanlease.js +251 -0
  645. package/dist/src/setup/scanlease.js.map +1 -0
  646. package/dist/src/setup/scanreport.js +289 -0
  647. package/dist/src/setup/scanreport.js.map +1 -0
  648. package/dist/src/setup/scanrun.js +1733 -0
  649. package/dist/src/setup/scanrun.js.map +1 -0
  650. package/dist/src/setup/scantree.js +257 -0
  651. package/dist/src/setup/scantree.js.map +1 -0
  652. package/dist/src/setup/stage2.js +617 -0
  653. package/dist/src/setup/stage2.js.map +1 -0
  654. package/dist/src/setup/stage2request.js +259 -0
  655. package/dist/src/setup/stage2request.js.map +1 -0
  656. package/dist/src/setup/survey.js +307 -0
  657. package/dist/src/setup/survey.js.map +1 -0
  658. package/dist/src/setup/surveyrun.js +549 -0
  659. package/dist/src/setup/surveyrun.js.map +1 -0
  660. package/dist/src/setup/textsniff.js +89 -0
  661. package/dist/src/setup/textsniff.js.map +1 -0
  662. package/dist/src/setup/trackersink.js +395 -0
  663. package/dist/src/setup/trackersink.js.map +1 -0
  664. package/dist/src/setup/triage.js +636 -0
  665. package/dist/src/setup/triage.js.map +1 -0
  666. package/dist/src/setup/tuning.js +585 -0
  667. package/dist/src/setup/tuning.js.map +1 -0
  668. package/dist/src/setup/unitcut.js +437 -0
  669. package/dist/src/setup/unitcut.js.map +1 -0
  670. package/dist/src/singleflight.js +72 -0
  671. package/dist/src/singleflight.js.map +1 -0
  672. package/dist/src/slack/announce.js +725 -0
  673. package/dist/src/slack/announce.js.map +1 -0
  674. package/dist/src/slack/api.js +227 -0
  675. package/dist/src/slack/api.js.map +1 -0
  676. package/dist/src/slack/messages.js +158 -0
  677. package/dist/src/slack/messages.js.map +1 -0
  678. package/dist/src/slack/origin.js +550 -0
  679. package/dist/src/slack/origin.js.map +1 -0
  680. package/dist/src/slack/policy.js +225 -0
  681. package/dist/src/slack/policy.js.map +1 -0
  682. package/dist/src/slack/reply.js +153 -0
  683. package/dist/src/slack/reply.js.map +1 -0
  684. package/dist/src/slack/router.js +189 -0
  685. package/dist/src/slack/router.js.map +1 -0
  686. package/dist/src/slack/socket.js +323 -0
  687. package/dist/src/slack/socket.js.map +1 -0
  688. package/dist/src/slack/types.js +11 -0
  689. package/dist/src/slack/types.js.map +1 -0
  690. package/dist/src/sqlitehint.js +30 -0
  691. package/dist/src/sqlitehint.js.map +1 -0
  692. package/dist/src/ssh-observation.js +25 -0
  693. package/dist/src/ssh-observation.js.map +1 -0
  694. package/dist/src/state.js +5869 -0
  695. package/dist/src/state.js.map +1 -0
  696. package/dist/src/statemachine.js +223 -0
  697. package/dist/src/statemachine.js.map +1 -0
  698. package/dist/src/stubs.js +52 -0
  699. package/dist/src/stubs.js.map +1 -0
  700. package/dist/src/takeover.js +506 -0
  701. package/dist/src/takeover.js.map +1 -0
  702. package/dist/src/takeoverpi.js +262 -0
  703. package/dist/src/takeoverpi.js.map +1 -0
  704. package/dist/src/terminal-failure.js +26 -0
  705. package/dist/src/terminal-failure.js.map +1 -0
  706. package/dist/src/thread-resolution-refusal.js +4 -0
  707. package/dist/src/thread-resolution-refusal.js.map +1 -0
  708. package/dist/src/tmux.js +126 -0
  709. package/dist/src/tmux.js.map +1 -0
  710. package/dist/src/trackerid.js +43 -0
  711. package/dist/src/trackerid.js.map +1 -0
  712. package/dist/src/transcriptindex.js +512 -0
  713. package/dist/src/transcriptindex.js.map +1 -0
  714. package/dist/src/tui/actions.js +404 -0
  715. package/dist/src/tui/actions.js.map +1 -0
  716. package/dist/src/tui/alerts.js +523 -0
  717. package/dist/src/tui/alerts.js.map +1 -0
  718. package/dist/src/tui/app.js +1884 -0
  719. package/dist/src/tui/app.js.map +1 -0
  720. package/dist/src/tui/archiveops.js +164 -0
  721. package/dist/src/tui/archiveops.js.map +1 -0
  722. package/dist/src/tui/autofile.js +191 -0
  723. package/dist/src/tui/autofile.js.map +1 -0
  724. package/dist/src/tui/board.js +1219 -0
  725. package/dist/src/tui/board.js.map +1 -0
  726. package/dist/src/tui/candidates.js +699 -0
  727. package/dist/src/tui/candidates.js.map +1 -0
  728. package/dist/src/tui/cellwidth.js +151 -0
  729. package/dist/src/tui/cellwidth.js.map +1 -0
  730. package/dist/src/tui/changelog-store.js +404 -0
  731. package/dist/src/tui/changelog-store.js.map +1 -0
  732. package/dist/src/tui/chord.js +26 -0
  733. package/dist/src/tui/chord.js.map +1 -0
  734. package/dist/src/tui/clipboard.js +81 -0
  735. package/dist/src/tui/clipboard.js.map +1 -0
  736. package/dist/src/tui/cmdbar.js +256 -0
  737. package/dist/src/tui/cmdbar.js.map +1 -0
  738. package/dist/src/tui/companion.js +1339 -0
  739. package/dist/src/tui/companion.js.map +1 -0
  740. package/dist/src/tui/companionplan.js +200 -0
  741. package/dist/src/tui/companionplan.js.map +1 -0
  742. package/dist/src/tui/companiontab.js +61 -0
  743. package/dist/src/tui/companiontab.js.map +1 -0
  744. package/dist/src/tui/confighome.js +105 -0
  745. package/dist/src/tui/confighome.js.map +1 -0
  746. package/dist/src/tui/connect.js +50 -0
  747. package/dist/src/tui/connect.js.map +1 -0
  748. package/dist/src/tui/deploy-ceremony.js +75 -0
  749. package/dist/src/tui/deploy-ceremony.js.map +1 -0
  750. package/dist/src/tui/deploy-drain.js +93 -0
  751. package/dist/src/tui/deploy-drain.js.map +1 -0
  752. package/dist/src/tui/deploy-process.js +234 -0
  753. package/dist/src/tui/deploy-process.js.map +1 -0
  754. package/dist/src/tui/deploytab.js +1263 -0
  755. package/dist/src/tui/deploytab.js.map +1 -0
  756. package/dist/src/tui/design.js +111 -0
  757. package/dist/src/tui/design.js.map +1 -0
  758. package/dist/src/tui/digesttab.js +148 -0
  759. package/dist/src/tui/digesttab.js.map +1 -0
  760. package/dist/src/tui/emptystate.js +32 -0
  761. package/dist/src/tui/emptystate.js.map +1 -0
  762. package/dist/src/tui/evidence.js +790 -0
  763. package/dist/src/tui/evidence.js.map +1 -0
  764. package/dist/src/tui/feed.js +415 -0
  765. package/dist/src/tui/feed.js.map +1 -0
  766. package/dist/src/tui/feedbacktab.js +907 -0
  767. package/dist/src/tui/feedbacktab.js.map +1 -0
  768. package/dist/src/tui/filters.js +75 -0
  769. package/dist/src/tui/filters.js.map +1 -0
  770. package/dist/src/tui/ghread.js +328 -0
  771. package/dist/src/tui/ghread.js.map +1 -0
  772. package/dist/src/tui/historypull.js +61 -0
  773. package/dist/src/tui/historypull.js.map +1 -0
  774. package/dist/src/tui/inboxpull.js +197 -0
  775. package/dist/src/tui/inboxpull.js.map +1 -0
  776. package/dist/src/tui/index.js +1511 -0
  777. package/dist/src/tui/index.js.map +1 -0
  778. package/dist/src/tui/issuesink.js +206 -0
  779. package/dist/src/tui/issuesink.js.map +1 -0
  780. package/dist/src/tui/jsonfile.js +32 -0
  781. package/dist/src/tui/jsonfile.js.map +1 -0
  782. package/dist/src/tui/keys.js +97 -0
  783. package/dist/src/tui/keys.js.map +1 -0
  784. package/dist/src/tui/layout.js +70 -0
  785. package/dist/src/tui/layout.js.map +1 -0
  786. package/dist/src/tui/learning.js +469 -0
  787. package/dist/src/tui/learning.js.map +1 -0
  788. package/dist/src/tui/lessonswitch.js +103 -0
  789. package/dist/src/tui/lessonswitch.js.map +1 -0
  790. package/dist/src/tui/livecontrol.js +167 -0
  791. package/dist/src/tui/livecontrol.js.map +1 -0
  792. package/dist/src/tui/memforward.js +347 -0
  793. package/dist/src/tui/memforward.js.map +1 -0
  794. package/dist/src/tui/memincident.js +287 -0
  795. package/dist/src/tui/memincident.js.map +1 -0
  796. package/dist/src/tui/memory.js +485 -0
  797. package/dist/src/tui/memory.js.map +1 -0
  798. package/dist/src/tui/memtab.js +513 -0
  799. package/dist/src/tui/memtab.js.map +1 -0
  800. package/dist/src/tui/metricstab.js +979 -0
  801. package/dist/src/tui/metricstab.js.map +1 -0
  802. package/dist/src/tui/model.js +129 -0
  803. package/dist/src/tui/model.js.map +1 -0
  804. package/dist/src/tui/mouse.js +83 -0
  805. package/dist/src/tui/mouse.js.map +1 -0
  806. package/dist/src/tui/msg.js +196 -0
  807. package/dist/src/tui/msg.js.map +1 -0
  808. package/dist/src/tui/nativecompanion.js +321 -0
  809. package/dist/src/tui/nativecompanion.js.map +1 -0
  810. package/dist/src/tui/openurl.js +17 -0
  811. package/dist/src/tui/openurl.js.map +1 -0
  812. package/dist/src/tui/paint.js +501 -0
  813. package/dist/src/tui/paint.js.map +1 -0
  814. package/dist/src/tui/panes.js +74 -0
  815. package/dist/src/tui/panes.js.map +1 -0
  816. package/dist/src/tui/pipane.js +166 -0
  817. package/dist/src/tui/pipane.js.map +1 -0
  818. package/dist/src/tui/poll-hooks.js +11 -0
  819. package/dist/src/tui/poll-hooks.js.map +1 -0
  820. package/dist/src/tui/poll.js +113 -0
  821. package/dist/src/tui/poll.js.map +1 -0
  822. package/dist/src/tui/proposals.js +715 -0
  823. package/dist/src/tui/proposals.js.map +1 -0
  824. package/dist/src/tui/prpause.js +139 -0
  825. package/dist/src/tui/prpause.js.map +1 -0
  826. package/dist/src/tui/reload.js +351 -0
  827. package/dist/src/tui/reload.js.map +1 -0
  828. package/dist/src/tui/remote.js +318 -0
  829. package/dist/src/tui/remote.js.map +1 -0
  830. package/dist/src/tui/rollover.js +767 -0
  831. package/dist/src/tui/rollover.js.map +1 -0
  832. package/dist/src/tui/route.js +143 -0
  833. package/dist/src/tui/route.js.map +1 -0
  834. package/dist/src/tui/scantab.js +1053 -0
  835. package/dist/src/tui/scantab.js.map +1 -0
  836. package/dist/src/tui/setupentry.js +81 -0
  837. package/dist/src/tui/setupentry.js.map +1 -0
  838. package/dist/src/tui/setupstate.js +29 -0
  839. package/dist/src/tui/setupstate.js.map +1 -0
  840. package/dist/src/tui/sidebar.js +602 -0
  841. package/dist/src/tui/sidebar.js.map +1 -0
  842. package/dist/src/tui/sshtriage.js +490 -0
  843. package/dist/src/tui/sshtriage.js.map +1 -0
  844. package/dist/src/tui/startup.js +172 -0
  845. package/dist/src/tui/startup.js.map +1 -0
  846. package/dist/src/tui/tabs.js +41 -0
  847. package/dist/src/tui/tabs.js.map +1 -0
  848. package/dist/src/tui/termmirror.js +217 -0
  849. package/dist/src/tui/termmirror.js.map +1 -0
  850. package/dist/src/tui/theme.js +96 -0
  851. package/dist/src/tui/theme.js.map +1 -0
  852. package/dist/src/tui/ticketstab.js +224 -0
  853. package/dist/src/tui/ticketstab.js.map +1 -0
  854. package/dist/src/tui/tmuxsocket.js +101 -0
  855. package/dist/src/tui/tmuxsocket.js.map +1 -0
  856. package/dist/src/tui/trackertickets.js +77 -0
  857. package/dist/src/tui/trackertickets.js.map +1 -0
  858. package/dist/src/tui/unwedge.js +235 -0
  859. package/dist/src/tui/unwedge.js.map +1 -0
  860. package/dist/src/tui/viewer.js +479 -0
  861. package/dist/src/tui/viewer.js.map +1 -0
  862. package/dist/src/tui/viewerinput.js +125 -0
  863. package/dist/src/tui/viewerinput.js.map +1 -0
  864. package/dist/src/updatenotice.js +143 -0
  865. package/dist/src/updatenotice.js.map +1 -0
  866. package/dist/src/usage.js +1007 -0
  867. package/dist/src/usage.js.map +1 -0
  868. package/dist/src/verdicts.js +3860 -0
  869. package/dist/src/verdicts.js.map +1 -0
  870. package/dist/src/version.js +58 -0
  871. package/dist/src/version.js.map +1 -0
  872. package/dist/src/wakes.js +411 -0
  873. package/dist/src/wakes.js.map +1 -0
  874. package/dist/src/webhook.js +736 -0
  875. package/dist/src/webhook.js.map +1 -0
  876. package/dist/src/webhookheal.js +238 -0
  877. package/dist/src/webhookheal.js.map +1 -0
  878. package/dist/src/wire.js +1823 -0
  879. package/dist/src/wire.js.map +1 -0
  880. package/dist/src/worker-session-host.js +531 -0
  881. package/dist/src/worker-session-host.js.map +1 -0
  882. package/dist/src/workerbreaker.js +112 -0
  883. package/dist/src/workerbreaker.js.map +1 -0
  884. package/dist/src/workercontrol.js +49 -0
  885. package/dist/src/workercontrol.js.map +1 -0
  886. package/dist/src/workerlease.js +351 -0
  887. package/dist/src/workerlease.js.map +1 -0
  888. package/dist/src/workerliveness.js +84 -0
  889. package/dist/src/workerliveness.js.map +1 -0
  890. package/dist/src/workerlog.js +65 -0
  891. package/dist/src/workerlog.js.map +1 -0
  892. package/dist/src/workerruntime.js +10 -0
  893. package/dist/src/workerruntime.js.map +1 -0
  894. package/dist/src/workersupervisor.js +1206 -0
  895. package/dist/src/workersupervisor.js.map +1 -0
  896. package/dist/src/workerusage.js +23 -0
  897. package/dist/src/workerusage.js.map +1 -0
  898. package/dist/src/workerworld.js +338 -0
  899. package/dist/src/workerworld.js.map +1 -0
  900. package/dist/src/worktrees.js +984 -0
  901. package/dist/src/worktrees.js.map +1 -0
  902. package/docker/Dockerfile +284 -0
  903. package/docker/Dockerfile.dockerignore +35 -0
  904. package/docker/README.md +221 -0
  905. package/docker/companion/Dockerfile +139 -0
  906. package/docker/companion/agents/evidence.md +34 -0
  907. package/docker/companion/agents/explore.md +26 -0
  908. package/docker/companion/agents/pass-survey.md +49 -0
  909. package/docker/companion/agents/study.md +26 -0
  910. package/docker/companion/entrypoint.sh +362 -0
  911. package/docker/companion/memory-health.mjs +269 -0
  912. package/docker/entrypoint.sh +799 -0
  913. package/docker/memory/Dockerfile +191 -0
  914. package/docker/memory/Dockerfile.dockerignore +20 -0
  915. package/docker/memory/README.md +60 -0
  916. package/docker/memory/entrypoint.sh +163 -0
  917. package/docker/setid/qcr-setid.c +109 -0
  918. package/docker/tunnel/Dockerfile.cloudflared +51 -0
  919. package/docker/tunnel/Dockerfile.ngrok +40 -0
  920. package/docker/tunnel/sidecar.mjs +411 -0
  921. package/docker/vm/tmux.conf +26 -0
  922. package/docker-compose.yml +348 -0
  923. package/extensions/cli/bash-guard-ambient.ts +71 -0
  924. package/extensions/cli/bash-guard.ts +12 -0
  925. package/extensions/cli/companion-guard.ts +8 -0
  926. package/extensions/cli/debug-round.ts +9 -0
  927. package/extensions/cli/inject-bridge.ts +8 -0
  928. package/extensions/cli/ledger-pin.ts +13 -0
  929. package/extensions/cli/lens.ts +22 -0
  930. package/extensions/cli/login-route.ts +10 -0
  931. package/extensions/cli/muted-theme.ts +9 -0
  932. package/extensions/cli/onboarding.ts +8 -0
  933. package/extensions/cli/setup.ts +8 -0
  934. package/extensions/cli/tui-view.ts +8 -0
  935. package/extensions/companion-guard.ts +411 -0
  936. package/extensions/debug-round.ts +281 -0
  937. package/extensions/inject-bridge.ts +630 -0
  938. package/extensions/inline-bash.ts +102 -0
  939. package/extensions/login-route.ts +220 -0
  940. package/extensions/muted-theme.json +68 -0
  941. package/extensions/muted-theme.ts +23 -0
  942. package/extensions/onboarding.ts +262 -0
  943. package/extensions/setup-replay.ts +336 -0
  944. package/extensions/setup-scan.ts +1236 -0
  945. package/extensions/setup-triage.ts +190 -0
  946. package/extensions/setup.ts +1428 -0
  947. package/extensions/tui-view.ts +489 -0
  948. package/extensions/vendor/openviking-pi/LICENSE +201 -0
  949. package/extensions/vendor/openviking-pi/NOTICE +68 -0
  950. package/extensions/vendor/openviking-pi/README.md +550 -0
  951. package/extensions/vendor/openviking-pi/client.ts +588 -0
  952. package/extensions/vendor/openviking-pi/config.json +28 -0
  953. package/extensions/vendor/openviking-pi/config.ts +271 -0
  954. package/extensions/vendor/openviking-pi/index.ts +523 -0
  955. package/extensions/vendor/openviking-pi/lib/capture-adapter.d.mts +10 -0
  956. package/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +88 -0
  957. package/extensions/vendor/openviking-pi/lib/takeover-core.d.mts +80 -0
  958. package/extensions/vendor/openviking-pi/lib/takeover-core.mjs +406 -0
  959. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.d.mts +1 -0
  960. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +42 -0
  961. package/extensions/vendor/openviking-pi/patches/0000-vendoring-and-build-conformance.patch +726 -0
  962. package/extensions/vendor/openviking-pi/patches/0001-remove-session-before-compact-handler.patch +101 -0
  963. package/extensions/vendor/openviking-pi/patches/0002-no-ambient-work-in-subagent-leaves.patch +202 -0
  964. package/extensions/vendor/openviking-pi/patches/0003-never-auto-create-openviking-sessions.patch +120 -0
  965. package/extensions/vendor/openviking-pi/patches/0004-viking-write-durable-batch-write.patch +521 -0
  966. package/extensions/vendor/openviking-pi/patches/0005-second-memory-namespace.patch +786 -0
  967. package/extensions/vendor/openviking-pi/patches/0006-writes-that-stick-and-honest-errors.patch +996 -0
  968. package/extensions/vendor/openviking-pi/patches/0007-bounded-recall-no-commit.patch +794 -0
  969. package/extensions/vendor/openviking-pi/patches/0008-pr-derived-recall.patch +379 -0
  970. package/extensions/vendor/openviking-pi/patches/0009-pr-session-tools-in-round-areas.patch +375 -0
  971. package/extensions/vendor/openviking-pi/patches/0010-typed-lessons.patch +448 -0
  972. package/extensions/vendor/openviking-pi/patches/0011-review-session-memory-boundary.patch +382 -0
  973. package/extensions/vendor/openviking-pi/patches/0012-typecheck-against-the-real-pi.patch +129 -0
  974. package/extensions/vendor/openviking-pi/patches/0013-createopenviking-factory.patch +1168 -0
  975. package/extensions/vendor/openviking-pi/qcr-hint.ts +313 -0
  976. package/extensions/vendor/openviking-pi/qcr-honest.ts +183 -0
  977. package/extensions/vendor/openviking-pi/qcr-hooks.ts +87 -0
  978. package/extensions/vendor/openviking-pi/qcr-leaf.ts +78 -0
  979. package/extensions/vendor/openviking-pi/qcr-lesson.ts +231 -0
  980. package/extensions/vendor/openviking-pi/qcr-namespaces.ts +198 -0
  981. package/extensions/vendor/openviking-pi/qcr-recall.ts +288 -0
  982. package/extensions/vendor/openviking-pi/qcr-shim.ts +142 -0
  983. package/extensions/vendor/openviking-pi/qcr-write.ts +427 -0
  984. package/extensions/vendor/openviking-pi/recall.ts +149 -0
  985. package/extensions/vendor/openviking-pi/shared/capture-utils.d.mts +9 -0
  986. package/extensions/vendor/openviking-pi/shared/capture-utils.mjs +515 -0
  987. package/extensions/vendor/openviking-pi/shared/credentials.d.mts +14 -0
  988. package/extensions/vendor/openviking-pi/shared/credentials.mjs +228 -0
  989. package/extensions/vendor/openviking-pi/shared/pending-queue.d.mts +19 -0
  990. package/extensions/vendor/openviking-pi/shared/pending-queue.mjs +458 -0
  991. package/extensions/vendor/openviking-pi/shared/profile-inject.d.mts +17 -0
  992. package/extensions/vendor/openviking-pi/shared/profile-inject.mjs +294 -0
  993. package/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +195 -0
  994. package/extensions/vendor/openviking-pi/shared/recall-core.d.mts +13 -0
  995. package/extensions/vendor/openviking-pi/shared/recall-core.mjs +609 -0
  996. package/extensions/vendor/openviking-pi/shared/retryable.mjs +9 -0
  997. package/extensions/vendor/openviking-pi/shared/session-model.d.mts +3 -0
  998. package/extensions/vendor/openviking-pi/shared/session-model.mjs +57 -0
  999. package/extensions/vendor/openviking-pi/shared/uri-guard.mjs +56 -0
  1000. package/extensions/vendor/openviking-pi/shared/workspace-peer.d.mts +5 -0
  1001. package/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  1002. package/extensions/vendor/openviking-pi/sync.ts +163 -0
  1003. package/extensions/vendor/openviking-pi/takeover.ts +36 -0
  1004. package/extensions/vendor/openviking-pi/tools.ts +479 -0
  1005. package/extensions/vendor/openviking-pi/upstream.json +48 -0
  1006. package/package.json +138 -4
  1007. package/profiles/default/README.md +21 -0
  1008. package/profiles/default/addenda/.gitkeep +0 -0
  1009. package/profiles/default/profile.toml +17 -0
  1010. package/profiles/example-django/README.md +21 -0
  1011. package/profiles/example-django/addenda/10-migration-discipline.md +13 -0
  1012. package/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
  1013. package/profiles/example-django/addenda/30-test-doctrine.md +12 -0
  1014. package/profiles/example-django/addenda/40-orm-usage.md +19 -0
  1015. package/profiles/example-django/addenda/50-declared-shape.md +10 -0
  1016. package/profiles/example-django/addenda/60-config-placement.md +14 -0
  1017. package/profiles/example-django/heuristics.toml +24 -0
  1018. package/profiles/example-django/profile.toml +9 -0
  1019. package/profiles/fast/README.md +24 -0
  1020. package/profiles/fast/profile.toml +59 -0
  1021. package/profiles/minimal/README.md +17 -0
  1022. package/profiles/minimal/addenda/.gitkeep +0 -0
  1023. package/profiles/minimal/profile.toml +8 -0
  1024. package/profiles/snappy/README.md +24 -0
  1025. package/profiles/snappy/addenda/10-race-as-question.md +6 -0
  1026. package/profiles/snappy/profile.toml +46 -0
  1027. package/prompts/companion-day-open.md +46 -0
  1028. package/prompts/companion-first-run.md +104 -0
  1029. package/prompts/companion.md +821 -0
  1030. package/prompts/conversation-system.md +117 -0
  1031. package/prompts/eod-sweep.md +120 -0
  1032. package/prompts/onboarding.md +113 -0
  1033. package/prompts/pass-common.md +52 -0
  1034. package/prompts/pass-quality-common.md +22 -0
  1035. package/prompts/round-first.md +874 -0
  1036. package/prompts/round-follow-up.md +991 -0
  1037. package/prompts/round-re-review.md +889 -0
  1038. package/prompts/round-recheck.md +196 -0
  1039. package/prompts/round-staleness.md +856 -0
  1040. package/schemas/review-result.v1.json +391 -0
  1041. package/schemas/scan-result.v1.json +421 -0
  1042. package/schemas/version.v1.json +57 -0
  1043. package/scripts/approve-pr.sh +16 -0
  1044. package/scripts/build-stamp.mjs +67 -0
  1045. package/scripts/commit-verdict.sh +155 -0
  1046. package/scripts/companion-e2e.sh +250 -0
  1047. package/scripts/companion-memory-forward.mjs +1966 -0
  1048. package/scripts/config-fingerprint.sh +28 -0
  1049. package/scripts/deploy-manifest.mjs +141 -0
  1050. package/scripts/deploy.sh +1435 -0
  1051. package/scripts/directory-lock.mjs +193 -0
  1052. package/scripts/heartbeat-fresh.mjs +54 -0
  1053. package/scripts/install-locator.sh +328 -0
  1054. package/scripts/install-wrapper.sh +76 -0
  1055. package/scripts/memory-search-check.mjs +98 -0
  1056. package/scripts/mint-token.sh +233 -0
  1057. package/scripts/openviking-embedder.py +392 -0
  1058. package/scripts/openviking-ov-conf.mjs +161 -0
  1059. package/scripts/openviking-provision.mjs +1122 -0
  1060. package/scripts/openviking-reembed.mjs +1154 -0
  1061. package/scripts/post-review.sh +16 -0
  1062. package/scripts/pr-checks.sh +256 -0
  1063. package/scripts/pr-context.py +174 -0
  1064. package/scripts/pr-context.sh +63 -0
  1065. package/scripts/pr-self.sh +144 -0
  1066. package/scripts/pr-threads.sh +145 -0
  1067. package/scripts/qcr +15 -0
  1068. package/scripts/qcr-host.sh +769 -0
  1069. package/scripts/render-review.sh +24 -0
  1070. package/scripts/reply-thread.sh +16 -0
  1071. package/scripts/required-passes.py +112 -0
  1072. package/scripts/smoke-companion.sh +211 -0
  1073. package/scripts/tui-deploy-runner.mjs +61 -0
  1074. package/scripts/verify-dist.mjs +201 -0
  1075. package/scripts/vm-ghcr-login.sh +188 -0
  1076. package/seeds/agents/pass-baseline.md +61 -0
  1077. package/seeds/agents/pass-contracts.md +30 -0
  1078. package/seeds/agents/pass-data-safety.md +54 -0
  1079. package/seeds/agents/pass-delivery.md +37 -0
  1080. package/seeds/agents/pass-prod-risk.md +24 -0
  1081. package/seeds/agents/pass-security.md +31 -0
  1082. package/seeds/agents/pass-statelessness.md +27 -0
  1083. package/seeds/agents/pass-ui.md +23 -0
  1084. package/seeds/agents/pass-validate.md +50 -0
  1085. package/seeds/prompts/conversation-system.md +117 -0
  1086. package/seeds/prompts/eod-sweep.md +120 -0
  1087. package/seeds/prompts/pass-common.md +52 -0
  1088. package/skills/companion/adjudicate/SKILL.md +247 -0
  1089. package/skills/companion/evidence/SKILL.md +150 -0
  1090. package/skills/companion/land/SKILL.md +200 -0
  1091. package/skills/companion/replay/SKILL.md +138 -0
  1092. package/skills/companion/setup/SKILL.md +167 -0
  1093. package/skills/companion/survey/SKILL.md +160 -0
  1094. package/skills/selfimprove/README.md +34 -0
  1095. package/skills/selfimprove/SKILL.md +127 -0
  1096. package/skills/selfimprove/agents/openai.yaml +2 -0
  1097. package/skills/selfimprove/commands/selfimprove.md +6 -0
  1098. package/skills/selfimprove/references/fix-loop.md +49 -0
  1099. package/skills/selfimprove/references/ledger.md +20 -0
  1100. package/skills/selfimprove/references/setup.md +40 -0
  1101. package/src/anomalies.ts +566 -0
  1102. package/src/answerworker.ts +251 -0
  1103. package/src/appstamp.ts +65 -0
  1104. package/src/archive/admission.ts +3 -0
  1105. package/src/archive/archivedb.ts +548 -0
  1106. package/src/archive/archiver.ts +1963 -0
  1107. package/src/archive/archivewrite.ts +279 -0
  1108. package/src/archive/bundle.ts +333 -0
  1109. package/src/archive/dbmove.ts +911 -0
  1110. package/src/archive/duplicatecounts.ts +98 -0
  1111. package/src/archive/eligibility.ts +181 -0
  1112. package/src/archive/extract.ts +342 -0
  1113. package/src/archive/fsutil.ts +415 -0
  1114. package/src/archive/gzfile.ts +370 -0
  1115. package/src/archive/kinds.ts +21 -0
  1116. package/src/archive/livecheckpoint.ts +217 -0
  1117. package/src/archive/liveretention.ts +180 -0
  1118. package/src/archive/manifest.ts +519 -0
  1119. package/src/archive/overseer.ts +336 -0
  1120. package/src/archive/piglobal.ts +174 -0
  1121. package/src/archive/plan.ts +612 -0
  1122. package/src/archive/prarchive.ts +984 -0
  1123. package/src/archive/prfiles.ts +406 -0
  1124. package/src/archive/report.ts +252 -0
  1125. package/src/archive/restore.ts +330 -0
  1126. package/src/archive/rows.ts +187 -0
  1127. package/src/archive/seal.ts +630 -0
  1128. package/src/archive/status.ts +719 -0
  1129. package/src/archive/storepass.ts +581 -0
  1130. package/src/backfill.ts +362 -0
  1131. package/src/bench/cost.ts +113 -0
  1132. package/src/bench/exec.ts +90 -0
  1133. package/src/bench/values.ts +13 -0
  1134. package/src/botcontrol.ts +176 -0
  1135. package/src/botworker.ts +953 -0
  1136. package/src/capture.ts +321 -0
  1137. package/src/cases.ts +1789 -0
  1138. package/src/channelfs.ts +26 -0
  1139. package/src/checklist.ts +506 -0
  1140. package/src/ciretry.ts +142 -0
  1141. package/src/cli.ts +2306 -0
  1142. package/src/cliops.ts +385 -0
  1143. package/src/clonedir.ts +15 -0
  1144. package/src/commandeffects.ts +57 -0
  1145. package/src/commands.ts +1704 -0
  1146. package/src/companioninbox.ts +239 -0
  1147. package/src/compare.ts +957 -0
  1148. package/src/config.ts +2070 -0
  1149. package/src/configcheck.ts +133 -0
  1150. package/src/coreext.ts +47 -0
  1151. package/src/daemon.ts +1327 -0
  1152. package/src/debuground.ts +927 -0
  1153. package/src/debugroundpi.ts +272 -0
  1154. package/src/diagnostics.ts +14 -0
  1155. package/src/digest.ts +183 -0
  1156. package/src/dispatch.ts +2251 -0
  1157. package/src/engine/answerguard.ts +27 -0
  1158. package/src/engine/botsdk.ts +336 -0
  1159. package/src/engine/caserunner-sdk.ts +423 -0
  1160. package/src/engine/debugpi.ts +247 -0
  1161. package/src/eod.ts +669 -0
  1162. package/src/eodpinwatch.ts +556 -0
  1163. package/src/escalation.ts +1253 -0
  1164. package/src/eventloop.ts +1045 -0
  1165. package/src/execboundary.ts +645 -0
  1166. package/src/feedback.ts +1162 -0
  1167. package/src/findingscheck.ts +298 -0
  1168. package/src/fsdenied.ts +24 -0
  1169. package/src/ghread.ts +242 -0
  1170. package/src/github.ts +1539 -0
  1171. package/src/githubtoken.ts +435 -0
  1172. package/src/homes.ts +175 -0
  1173. package/src/hostroute.ts +53 -0
  1174. package/src/improvements.ts +787 -0
  1175. package/src/install.ts +1103 -0
  1176. package/src/installkind.ts +50 -0
  1177. package/src/ipc/capability.ts +333 -0
  1178. package/src/ipc/client.ts +269 -0
  1179. package/src/ipc/control.ts +90 -0
  1180. package/src/ipc/ghreadshim.ts +94 -0
  1181. package/src/ipc/launcher.ts +65 -0
  1182. package/src/ipc/permits.ts +362 -0
  1183. package/src/ipc/postshim.ts +164 -0
  1184. package/src/ipc/protocol.ts +342 -0
  1185. package/src/ipc/server.ts +371 -0
  1186. package/src/ipc/workerspec.ts +218 -0
  1187. package/src/learner/learner.ts +1655 -0
  1188. package/src/learner/miner.ts +1290 -0
  1189. package/src/learner/packet.ts +340 -0
  1190. package/src/learner/receipt.ts +168 -0
  1191. package/src/learner/status.ts +107 -0
  1192. package/src/ledgercheck.ts +157 -0
  1193. package/src/lessonledger.ts +703 -0
  1194. package/src/lessonselect.ts +888 -0
  1195. package/src/lessonshadow.ts +810 -0
  1196. package/src/levers.ts +393 -0
  1197. package/src/live/projection.ts +491 -0
  1198. package/src/live/publish.ts +92 -0
  1199. package/src/live/read.ts +86 -0
  1200. package/src/livecli.ts +336 -0
  1201. package/src/loginhint.ts +61 -0
  1202. package/src/loginrefresh/atomic.ts +76 -0
  1203. package/src/loginrefresh/lock.ts +104 -0
  1204. package/src/loginrefresh/main.ts +59 -0
  1205. package/src/loginrefresh/pirefresh.ts +60 -0
  1206. package/src/loginrefresh/refresher.ts +326 -0
  1207. package/src/loginrefresh/supervisor.ts +273 -0
  1208. package/src/loginrefresh/types.ts +35 -0
  1209. package/src/memory/context.ts +385 -0
  1210. package/src/memory/datafence.ts +9 -0
  1211. package/src/memory/delivery.ts +171 -0
  1212. package/src/memory/eventtags.ts +80 -0
  1213. package/src/memory/health.ts +953 -0
  1214. package/src/memory/import.ts +664 -0
  1215. package/src/memory/layout.ts +261 -0
  1216. package/src/memory/legacy-file.ts +104 -0
  1217. package/src/memory/lessons.ts +447 -0
  1218. package/src/memory/ovsession.ts +601 -0
  1219. package/src/memory/relayout.ts +335 -0
  1220. package/src/memory/roundactivity.ts +209 -0
  1221. package/src/memory/selection.ts +989 -0
  1222. package/src/memory/shadowstatus.ts +125 -0
  1223. package/src/memory/store.ts +275 -0
  1224. package/src/memory/textidentity.ts +8 -0
  1225. package/src/metrics.ts +1056 -0
  1226. package/src/missingconfig.ts +7 -0
  1227. package/src/npmverbs.ts +266 -0
  1228. package/src/onboard/choices.ts +255 -0
  1229. package/src/onboard/engine.ts +537 -0
  1230. package/src/onboard/launch.ts +103 -0
  1231. package/src/onboard/pipin.ts +31 -0
  1232. package/src/onboard/stepforward.ts +61 -0
  1233. package/src/onboard/steps/appslug.ts +268 -0
  1234. package/src/onboard/steps/bringup.ts +482 -0
  1235. package/src/onboard/steps/compose.ts +490 -0
  1236. package/src/onboard/steps/configdelivery.ts +58 -0
  1237. package/src/onboard/steps/configfill.ts +1440 -0
  1238. package/src/onboard/steps/deploysh.ts +105 -0
  1239. package/src/onboard/steps/embeddings.ts +550 -0
  1240. package/src/onboard/steps/escalation.ts +640 -0
  1241. package/src/onboard/steps/githubaccount.ts +716 -0
  1242. package/src/onboard/steps/githubapp.ts +1498 -0
  1243. package/src/onboard/steps/golive.ts +579 -0
  1244. package/src/onboard/steps/index.ts +82 -0
  1245. package/src/onboard/steps/ingress.ts +974 -0
  1246. package/src/onboard/steps/inventory.ts +526 -0
  1247. package/src/onboard/steps/llmauth.ts +1180 -0
  1248. package/src/onboard/steps/memory.ts +1347 -0
  1249. package/src/onboard/steps/memorykeys.ts +85 -0
  1250. package/src/onboard/steps/preflight.ts +191 -0
  1251. package/src/onboard/steps/proof.ts +1042 -0
  1252. package/src/onboard/steps/ssh.ts +377 -0
  1253. package/src/onboard/steps/topology.ts +338 -0
  1254. package/src/onboard/steps/transport.ts +680 -0
  1255. package/src/onboard/steps/tuiroute.ts +119 -0
  1256. package/src/onboard/steps/verifyup.ts +467 -0
  1257. package/src/onboard/steps/vmdeploy.ts +442 -0
  1258. package/src/onboard/toml.ts +50 -0
  1259. package/src/onboard/toolnames.ts +34 -0
  1260. package/src/opencli.ts +591 -0
  1261. package/src/openpr.ts +568 -0
  1262. package/src/openviking/client.ts +1131 -0
  1263. package/src/openviking/context.ts +263 -0
  1264. package/src/openviking/embedder.ts +516 -0
  1265. package/src/openviking/gapsink.ts +63 -0
  1266. package/src/openviking/health.ts +83 -0
  1267. package/src/openviking/index.ts +119 -0
  1268. package/src/openviking/lessonfind.ts +92 -0
  1269. package/src/openviking/probe.ts +129 -0
  1270. package/src/openviking/proc.ts +110 -0
  1271. package/src/openviking/provisionreport.ts +160 -0
  1272. package/src/openviking/reembed.ts +412 -0
  1273. package/src/openviking/relayout.ts +177 -0
  1274. package/src/openviking/sidecar-main.ts +38 -0
  1275. package/src/openviking/sidecar.ts +106 -0
  1276. package/src/openviking/store.ts +2025 -0
  1277. package/src/openviking/supervisor.ts +474 -0
  1278. package/src/openviking/types.ts +174 -0
  1279. package/src/operator-recovery.ts +237 -0
  1280. package/src/operatormessage.ts +52 -0
  1281. package/src/operatorwrite.ts +25 -0
  1282. package/src/outcomes.ts +1677 -0
  1283. package/src/piauthcopy.ts +12 -0
  1284. package/src/picli.ts +49 -0
  1285. package/src/picwd.ts +25 -0
  1286. package/src/pilogin.ts +37 -0
  1287. package/src/pingpong.ts +1339 -0
  1288. package/src/posting-journal.ts +554 -0
  1289. package/src/posting-outbox.ts +810 -0
  1290. package/src/posting-receipt.ts +341 -0
  1291. package/src/posting.ts +603 -0
  1292. package/src/postops.ts +832 -0
  1293. package/src/pr-activity.ts +20 -0
  1294. package/src/pr-author.ts +6 -0
  1295. package/src/pr-conversation.ts +432 -0
  1296. package/src/pr-session-lifecycle.ts +631 -0
  1297. package/src/preflight.ts +391 -0
  1298. package/src/priorresolve.ts +343 -0
  1299. package/src/qcrbin.ts +186 -0
  1300. package/src/recheck.ts +1776 -0
  1301. package/src/reconcile.ts +1056 -0
  1302. package/src/recordedfindings.ts +27 -0
  1303. package/src/regression.ts +833 -0
  1304. package/src/replay.ts +816 -0
  1305. package/src/requiredpasses.ts +148 -0
  1306. package/src/resumecheck.ts +246 -0
  1307. package/src/reviewcli.ts +787 -0
  1308. package/src/reviewcontext.ts +35 -0
  1309. package/src/reviewdetach.ts +734 -0
  1310. package/src/reviewhistory.ts +441 -0
  1311. package/src/reviewhome.ts +36 -0
  1312. package/src/reviewmemory.ts +133 -0
  1313. package/src/reviewnow.ts +76 -0
  1314. package/src/reviewrendercli.ts +139 -0
  1315. package/src/round-work.ts +42 -0
  1316. package/src/runhost.ts +108 -0
  1317. package/src/scanauth.ts +36 -0
  1318. package/src/scanbox.ts +1081 -0
  1319. package/src/scancli.ts +1296 -0
  1320. package/src/scandriverlog.ts +32 -0
  1321. package/src/session-bridge.ts +139 -0
  1322. package/src/session-command-payload.ts +35 -0
  1323. package/src/session-command-supervisor.ts +1142 -0
  1324. package/src/sessionjsonl.ts +88 -0
  1325. package/src/sessions.ts +659 -0
  1326. package/src/setup/adapters.ts +335 -0
  1327. package/src/setup/baselines.ts +110 -0
  1328. package/src/setup/caserunner.ts +611 -0
  1329. package/src/setup/configcommit.ts +443 -0
  1330. package/src/setup/engine.ts +1001 -0
  1331. package/src/setup/facts.ts +627 -0
  1332. package/src/setup/findings.ts +1264 -0
  1333. package/src/setup/history.ts +443 -0
  1334. package/src/setup/interview.ts +243 -0
  1335. package/src/setup/ledger.ts +324 -0
  1336. package/src/setup/pins.ts +66 -0
  1337. package/src/setup/portrait.ts +635 -0
  1338. package/src/setup/presentation.ts +18 -0
  1339. package/src/setup/profile.ts +508 -0
  1340. package/src/setup/replay.ts +370 -0
  1341. package/src/setup/replaybuild.ts +392 -0
  1342. package/src/setup/replayrun.ts +1096 -0
  1343. package/src/setup/replaysource.ts +198 -0
  1344. package/src/setup/retune.ts +415 -0
  1345. package/src/setup/retunelog.ts +95 -0
  1346. package/src/setup/scan.ts +1033 -0
  1347. package/src/setup/scanbuild.ts +168 -0
  1348. package/src/setup/scanfacts.ts +107 -0
  1349. package/src/setup/scanlease.ts +297 -0
  1350. package/src/setup/scanreport.ts +373 -0
  1351. package/src/setup/scanrun.ts +2268 -0
  1352. package/src/setup/scantree.ts +259 -0
  1353. package/src/setup/stage2.ts +926 -0
  1354. package/src/setup/stage2request.ts +347 -0
  1355. package/src/setup/survey.ts +458 -0
  1356. package/src/setup/surveyrun.ts +758 -0
  1357. package/src/setup/textsniff.ts +95 -0
  1358. package/src/setup/trackersink.ts +433 -0
  1359. package/src/setup/triage.ts +768 -0
  1360. package/src/setup/tuning.ts +766 -0
  1361. package/src/setup/unitcut.ts +523 -0
  1362. package/src/singleflight.ts +86 -0
  1363. package/src/slack/announce.ts +911 -0
  1364. package/src/slack/api.ts +303 -0
  1365. package/src/slack/messages.ts +288 -0
  1366. package/src/slack/origin.ts +599 -0
  1367. package/src/slack/policy.ts +354 -0
  1368. package/src/slack/reply.ts +201 -0
  1369. package/src/slack/router.ts +285 -0
  1370. package/src/slack/socket.ts +384 -0
  1371. package/src/slack/types.ts +108 -0
  1372. package/src/sqlitehint.ts +32 -0
  1373. package/src/ssh-observation.ts +30 -0
  1374. package/src/state.ts +8261 -0
  1375. package/src/statemachine.ts +372 -0
  1376. package/src/stubs.ts +68 -0
  1377. package/src/takeover.ts +634 -0
  1378. package/src/takeoverpi.ts +306 -0
  1379. package/src/terminal-failure.ts +41 -0
  1380. package/src/thread-resolution-refusal.ts +2 -0
  1381. package/src/tmux.ts +153 -0
  1382. package/src/trackerid.ts +41 -0
  1383. package/src/transcriptindex.ts +665 -0
  1384. package/src/tui/actions.ts +484 -0
  1385. package/src/tui/alerts.ts +666 -0
  1386. package/src/tui/app.ts +2026 -0
  1387. package/src/tui/archiveops.ts +192 -0
  1388. package/src/tui/autofile.ts +233 -0
  1389. package/src/tui/board.ts +1529 -0
  1390. package/src/tui/candidates.ts +889 -0
  1391. package/src/tui/cellwidth.ts +148 -0
  1392. package/src/tui/changelog-store.ts +503 -0
  1393. package/src/tui/chord.ts +25 -0
  1394. package/src/tui/clipboard.ts +92 -0
  1395. package/src/tui/cmdbar.ts +299 -0
  1396. package/src/tui/companion.ts +1495 -0
  1397. package/src/tui/companionplan.ts +247 -0
  1398. package/src/tui/companiontab.ts +83 -0
  1399. package/src/tui/confighome.ts +155 -0
  1400. package/src/tui/connect.ts +74 -0
  1401. package/src/tui/deploy-ceremony.ts +104 -0
  1402. package/src/tui/deploy-drain.ts +129 -0
  1403. package/src/tui/deploy-process.ts +265 -0
  1404. package/src/tui/deploytab.ts +1523 -0
  1405. package/src/tui/design.ts +125 -0
  1406. package/src/tui/digesttab.ts +214 -0
  1407. package/src/tui/emptystate.ts +39 -0
  1408. package/src/tui/evidence.ts +999 -0
  1409. package/src/tui/feed.ts +604 -0
  1410. package/src/tui/feedbacktab.ts +1077 -0
  1411. package/src/tui/filters.ts +94 -0
  1412. package/src/tui/ghread.ts +388 -0
  1413. package/src/tui/historypull.ts +81 -0
  1414. package/src/tui/inboxpull.ts +236 -0
  1415. package/src/tui/index.ts +1656 -0
  1416. package/src/tui/issuesink.ts +238 -0
  1417. package/src/tui/jsonfile.ts +42 -0
  1418. package/src/tui/keys.ts +109 -0
  1419. package/src/tui/layout.ts +108 -0
  1420. package/src/tui/learning.ts +627 -0
  1421. package/src/tui/lessonswitch.ts +118 -0
  1422. package/src/tui/livecontrol.ts +228 -0
  1423. package/src/tui/memforward.ts +492 -0
  1424. package/src/tui/memincident.ts +363 -0
  1425. package/src/tui/memory.ts +620 -0
  1426. package/src/tui/memtab.ts +606 -0
  1427. package/src/tui/metricstab.ts +1177 -0
  1428. package/src/tui/model.ts +165 -0
  1429. package/src/tui/mouse.ts +98 -0
  1430. package/src/tui/msg.ts +268 -0
  1431. package/src/tui/nativecompanion.ts +417 -0
  1432. package/src/tui/openurl.ts +21 -0
  1433. package/src/tui/paint.ts +511 -0
  1434. package/src/tui/panes.ts +98 -0
  1435. package/src/tui/pipane.ts +219 -0
  1436. package/src/tui/poll-hooks.ts +12 -0
  1437. package/src/tui/poll.ts +147 -0
  1438. package/src/tui/proposals.ts +838 -0
  1439. package/src/tui/prpause.ts +159 -0
  1440. package/src/tui/reload.ts +436 -0
  1441. package/src/tui/remote.ts +421 -0
  1442. package/src/tui/rollover.ts +969 -0
  1443. package/src/tui/route.ts +173 -0
  1444. package/src/tui/scantab.ts +1290 -0
  1445. package/src/tui/setupentry.ts +93 -0
  1446. package/src/tui/setupstate.ts +52 -0
  1447. package/src/tui/sidebar.ts +749 -0
  1448. package/src/tui/sshtriage.ts +631 -0
  1449. package/src/tui/startup.ts +231 -0
  1450. package/src/tui/tabs.ts +45 -0
  1451. package/src/tui/termmirror.ts +224 -0
  1452. package/src/tui/theme.ts +96 -0
  1453. package/src/tui/ticketstab.ts +310 -0
  1454. package/src/tui/tmuxsocket.ts +129 -0
  1455. package/src/tui/trackertickets.ts +84 -0
  1456. package/src/tui/unwedge.ts +274 -0
  1457. package/src/tui/viewer.ts +575 -0
  1458. package/src/tui/viewerinput.ts +173 -0
  1459. package/src/updatenotice.ts +178 -0
  1460. package/src/usage.ts +1154 -0
  1461. package/src/verdicts.ts +4707 -0
  1462. package/src/version.ts +80 -0
  1463. package/src/wakes.ts +476 -0
  1464. package/src/webhook.ts +951 -0
  1465. package/src/webhookheal.ts +276 -0
  1466. package/src/wire.ts +2182 -0
  1467. package/src/worker-session-host.ts +602 -0
  1468. package/src/workerbreaker.ts +156 -0
  1469. package/src/workercontrol.ts +104 -0
  1470. package/src/workerlease.ts +441 -0
  1471. package/src/workerliveness.ts +103 -0
  1472. package/src/workerlog.ts +79 -0
  1473. package/src/workerruntime.ts +30 -0
  1474. package/src/workersupervisor.ts +1538 -0
  1475. package/src/workerusage.ts +42 -0
  1476. package/src/workerworld.ts +433 -0
  1477. package/src/worktrees.ts +1138 -0
  1478. package/tests/fixtures/regression-cases.json +795 -0
  1479. package/tests/fixtures/seed-manifest.json +19 -0
@@ -0,0 +1,1056 @@
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 {
33
+ botAccountLogin,
34
+ isOwnContent,
35
+ isPersonMode,
36
+ } from "@quickchatai/pi-quickreview/src/identity.js";
37
+ import type { OpenPrSummary, RoundRow, StateStore } from "./state.js";
38
+ import type { OvSessionSweepReport, SessionHooks } from "@quickchatai/pi-quickreview/src/types.js";
39
+ import { performance } from "node:perf_hooks";
40
+ import { yieldToLoop } from "@quickchatai/pi-quickreview/src/yieldloop.js";
41
+
42
+ export interface ReconcileSearchItem {
43
+ number: number;
44
+ title: string;
45
+ user: { login: string; type: string };
46
+ updated_at: string;
47
+ }
48
+
49
+ /** The read-only slice of GitHubAdapter reconcile needs. */
50
+ export interface ReconcileAdapter {
51
+ searchLabelTriggered(): Promise<ReconcileSearchItem[]>;
52
+ searchTeamTriggered(): Promise<ReconcileSearchItem[]>;
53
+ listOpenPrs(): Promise<PrRef[]>;
54
+ getPr(n: number): Promise<PrRef>;
55
+ listBotReviewComments(n: number): Promise<number[]>;
56
+ /** Checks at a ref — the withheld-approval backstop reads CI through this.
57
+ * Optional: a stub-wired daemon without it simply has no backstop. */
58
+ listChecks?(ref: string): Promise<CheckSummary[]>;
59
+ /** The comment-capture sweep's three READ sources. All optional and
60
+ * all-or-nothing: a stub-wired daemon without them simply has no backstop.
61
+ * Reads only — capture never writes to GitHub. */
62
+ listReviewCommentsFull?(n: number): Promise<ReviewCommentFull[]>;
63
+ listIssueComments?(n: number): Promise<IssueCommentFull[]>;
64
+ listReviewsFull?(n: number): Promise<ReviewFull[]>;
65
+ }
66
+
67
+ /**
68
+ * Per-pass bound on the comment-capture sweep: three API reads per
69
+ * PR, so the sweep must never grow with the whole tracked history. Freshest
70
+ * local activity first — a PR nobody has touched in weeks is not where a
71
+ * missed comment lives, and the ones left out are picked up on a later pass as
72
+ * soon as they move.
73
+ */
74
+ export const COMMENT_SWEEP_MAX_PRS = 25;
75
+
76
+ /**
77
+ * How long after a PR closes the capture sweep still includes it. The
78
+ * closed-sync step earlier in the SAME pass is what marks a PR closed, so a
79
+ * blanket `state !== "closed"` filter would skip exactly the PR that closed
80
+ * while the daemon was down — the scenario the sweep exists to recover. The
81
+ * rule: a closed PR is swept when it transitioned this pass, or when its row
82
+ * last moved (which for a closed PR is the close itself — nothing writes the
83
+ * row after that) within this window. The watermark below makes the repeat
84
+ * cost of the window three API reads an hour per closed PR (a closed PR has
85
+ * no GitHub timestamp in the open list to say a comment arrived), and one
86
+ * skipped filter check on every other pass.
87
+ */
88
+ export const COMMENT_SWEEP_CLOSED_WINDOW_MS = 24 * 60 * 60 * 1000;
89
+
90
+ export interface ReconcileDeps {
91
+ cfg: Config;
92
+ store: StateStore;
93
+ adapter: ReconcileAdapter;
94
+ hooks: SessionHooks;
95
+ now?: () => Date;
96
+ log?: (msg: string, extra?: unknown) => void;
97
+ /** Registry backfill is an API call per open PR; the daemon runs it every
98
+ * Nth poll. Default true. */
99
+ backfillRegistry?: boolean;
100
+ /** Backstop for the recheck's push trigger: the webhook's `onSynchronize`
101
+ * is the fast path, but a lost/dead webhook means a post-review push is
102
+ * otherwise never rechecked — the withheld-approval retry no-ops on a moved
103
+ * head ("a push re-reviews through its own route") while that route never
104
+ * fires. Same idiom as the withheld-approval sweep: the daemon wires
105
+ * runRecheck here, never a copy. */
106
+ onHeadPush?: (pr: number, head_sha: string) => Promise<void>;
107
+ /** Backstop: the merged-over-block feedback signal for closes the
108
+ * webhook missed (GitHub never redelivers). The daemon wires the same
109
+ * engine sink the webhook path uses; dedupe is the store's. */
110
+ onMergedOverBlock?: (pr: number) => Promise<void> | void;
111
+ /** Backstop: capture comments the webhook never saw (GitHub never
112
+ * redelivers, so a comment posted while the daemon was down would otherwise
113
+ * be permanent evidence loss). Default on when the adapter can read;
114
+ * `false` disables it for a poll that must stay cheap. */
115
+ captureComments?: boolean;
116
+ /** The outcome capture: handed the bot's OWN inline comments
117
+ * from the comment sweep's existing read (no extra GitHub call), then run
118
+ * as its own bounded step after it. Absent ⇒ no outcome capture. Its
119
+ * failures are its own and never reach `errors`. */
120
+ outcomes?: Pick<OutcomeCapture, "observeBotComments" | "sweep">;
121
+ /** The undelivered-recheck sweep. `false` skips it for this pass — the
122
+ * daemon's boot pass, whose health lifts a deploy drain and which must not
123
+ * wait on reading session transcripts. */
124
+ receiptSweep?: boolean;
125
+ /** How long the sweep may keep STARTING claims in one pass; the rest are
126
+ * carried to the next. Default RECEIPT_SWEEP_BUDGET_MS. */
127
+ receiptSweepBudgetMs?: number;
128
+ }
129
+
130
+ /**
131
+ * Wall-clock budget of the undelivered-recheck sweep per pass. Every read in
132
+ * it is asynchronous and chunked, so this bounds how long the PASS takes (the
133
+ * steps after it wait), not how long the loop blocks — that is a chunk.
134
+ */
135
+ export const RECEIPT_SWEEP_BUDGET_MS = 20_000;
136
+
137
+ export interface ReconcileReport {
138
+ ran_at: string;
139
+ open_prs: number;
140
+ /** The open PRs this pass listed, tracked or not; absent when the list
141
+ * step failed. The daemon publishes it in status.json for the board. */
142
+ open_list?: OpenPrSummary[];
143
+ triggered: number[];
144
+ closed: number[];
145
+ backfilled_comments: number;
146
+ /** Human comments the sweep captured that the webhook had missed.
147
+ * A rising number is the same webhook-health signal `corrections` is. */
148
+ captured_comments: number;
149
+ corrections: number;
150
+ errors: string[];
151
+ /** The raw-tier sweep's outcome — present only when the hooks
152
+ * manage a raw tier. Deliberately NOT part of `errors`: memory never
153
+ * blocks, and the boot's first healthy pass (which lifts a deploy drain)
154
+ * must not wait on the memory engine. */
155
+ ov_sessions?: OvSessionSweepReport;
156
+ /** The outcome capture's pass, when it captured anything or
157
+ * failed. Like `ov_sessions`, deliberately NOT part of `errors`: it is
158
+ * bookkeeping, and the boot's first healthy pass must not wait on it. */
159
+ outcomes?: OutcomeSweepReport;
160
+ /** The undelivered-recheck sweep's pass: claims
161
+ * asked, found delivered (recorded, never asked again), released as lost,
162
+ * and carried to the next pass by the budget. Absent when it did not run. */
163
+ receipt_sweep?: { asked: number; delivered: number; released: number; carried: number };
164
+ }
165
+
166
+ function correction(
167
+ deps: ReconcileDeps,
168
+ pr: number | null,
169
+ what: string,
170
+ detail: unknown,
171
+ report: ReconcileReport,
172
+ ): void {
173
+ report.corrections++;
174
+ deps.store.logEvent("reconcile_correction", pr, { what, ...(detail as object) });
175
+ (deps.log ?? (() => {}))(`reconcile: correction ${what}${pr ? ` #${pr}` : ""}`, detail);
176
+ }
177
+
178
+ /** Startup repair: a DB round marked running whose worker did not survive the
179
+ * restart will never produce a verdict — it would sit as a phantom until its
180
+ * deadline, holding a capacity slot and then corrupting the PR via the
181
+ * overdue path. Cancel it; if it was the PR's newest round and the PR still
182
+ * says reviewing, requeue so the lost work is redone. `inFlightPrs` are the
183
+ * PRs a worker still runs for, or whose round command waits for the next one
184
+ * (`inFlightPrs` in src/workerliveness.ts); a boot that finds no worker at all
185
+ * finds every PR idle with its JSONL.
186
+ *
187
+ * A round that still owes a POSTING is no phantom: its review is finished and
188
+ * the outbox delivers it without any session (docs/architecture/
189
+ * posting-delivery.md). Nor is one whose review is already posted but not yet
190
+ * settled. Cancelling either would make the outbox abandon the review or the
191
+ * requeue run the lenses again for a review already on GitHub, so it is left
192
+ * running (`postingOwed`) and settles from its receipt like any delivered
193
+ * round. */
194
+ export function reconcileOrphanedRounds(
195
+ store: StateStore,
196
+ inFlightPrs: Iterable<number>,
197
+ opts: {
198
+ now?: () => Date;
199
+ log?: (msg: string, extra?: unknown) => void;
200
+ /** Does this round still owe a review posting the outbox delivers on its
201
+ * own, or the settlement of one already posted? Absent ⇒ no round does. */
202
+ postingOwed?: (round: RoundRow) => boolean;
203
+ },
204
+ ): { cancelled: number[]; requeued: number[]; kept_for_posting: number[] } {
205
+ const live = new Set(inFlightPrs);
206
+ const now = opts.now ?? (() => new Date());
207
+ const log = opts.log ?? (() => {});
208
+ const cancelled: number[] = [];
209
+ const requeued: number[] = [];
210
+ const keptForPosting: number[] = [];
211
+ for (const round of store.runningRounds()) {
212
+ if (live.has(round.pr)) continue;
213
+ let owed = false;
214
+ try {
215
+ owed = opts.postingOwed?.(round) === true;
216
+ } catch (err) {
217
+ log(`startup: #${round.pr} round ${round.round_no} posting debt unreadable`, err);
218
+ }
219
+ if (owed) {
220
+ store.logEvent("orphaned_round_posting_owed", round.pr, {
221
+ round_id: round.id,
222
+ round_no: round.round_no,
223
+ posting_key: round.posting_key,
224
+ });
225
+ keptForPosting.push(round.pr);
226
+ log(
227
+ `startup: #${round.pr} round ${round.round_no} kept — session lost, but its review posting is still owed or unsettled`,
228
+ );
229
+ continue;
230
+ }
231
+ // `orphan_sweep` is the quiet cause: a worker lives and dies with its
232
+ // container, so a clean redeploy orphans every round in flight by
233
+ // construction. It is counted and grouped like every other cause, and it
234
+ // raises nothing.
235
+ const replaced = store.db.transaction(() => {
236
+ store.markRoundCancelled(round.id, "orphaned — worker lost across a restart", "orphan_sweep");
237
+ store.logEvent("round_orphaned", round.pr, { round_id: round.id, round_no: round.round_no });
238
+ const row = store.getPr(round.pr);
239
+ if (row?.state !== "reviewing" || store.hasLaterRound(round.pr, round.round_no)) return false;
240
+ const successorPromoted = store.promoteSuccessor(round.pr);
241
+ if (!successorPromoted)
242
+ store.upsertPr({ ...row, state: "queued", trigger_ts: now().toISOString() });
243
+ store.logEvent("orphaned_round_requeued", round.pr, {
244
+ round_id: round.id,
245
+ round_no: round.round_no,
246
+ successor_promoted: successorPromoted,
247
+ });
248
+ return true;
249
+ })();
250
+ cancelled.push(round.pr);
251
+ log(`startup: #${round.pr} round ${round.round_no} cancelled (session lost)`);
252
+ if (replaced) {
253
+ requeued.push(round.pr);
254
+ log(`startup: #${round.pr} requeued — its in-flight round was lost`);
255
+ }
256
+ }
257
+ return { cancelled, requeued, kept_for_posting: keptForPosting };
258
+ }
259
+
260
+ /** One reconcile pass. Never throws: per-step failures land in
261
+ * `report.errors` so a single bad PR or a flaky API call cannot stall the
262
+ * daemon. */
263
+ export async function reconcileOnce(deps: ReconcileDeps): Promise<ReconcileReport> {
264
+ const { store, cfg, adapter } = deps;
265
+ const now = deps.now ?? (() => new Date());
266
+ // The bot ACCOUNT: whose PRs are a bot's and whose captured comments are not
267
+ // a human's. "" in person mode (`[github] auth = "user"`), where the
268
+ // configured login is the person's: their PRs are reviewed, and their own
269
+ // comments are told from the reviewer's by its marker (identity.ts).
270
+ const botLogin = botAccountLogin(cfg.github);
271
+ const report: ReconcileReport = {
272
+ ran_at: now().toISOString(),
273
+ open_prs: 0,
274
+ triggered: [],
275
+ closed: [],
276
+ backfilled_comments: 0,
277
+ captured_comments: 0,
278
+ corrections: 0,
279
+ errors: [],
280
+ };
281
+
282
+ const step = async (name: string, fn: () => Promise<void>): Promise<void> => {
283
+ try {
284
+ // Every step starts on a fresh event-loop turn, so a pass is never one
285
+ // synchronous span even when its reads answer without real I/O (a
286
+ // cache, a stub) — the longest span is one step's own work.
287
+ await yieldToLoop();
288
+ await fn();
289
+ } catch (err) {
290
+ report.errors.push(`${name}: ${String(err)}`);
291
+ (deps.log ?? (() => {}))(`reconcile: step ${name} failed`, err);
292
+ }
293
+ };
294
+
295
+ // ---- 1. open-PR truth ---------------------------------------------------
296
+ const open = new Map<number, PrRef>();
297
+ let openListed = false;
298
+ await step("listOpenPrs", async () => {
299
+ for (const pr of await adapter.listOpenPrs()) open.set(pr.number, pr);
300
+ openListed = true;
301
+ report.open_prs = open.size;
302
+ report.open_list = [...open.values()].map((p) => ({
303
+ number: p.number,
304
+ title: p.title,
305
+ author: p.author,
306
+ draft: p.draft,
307
+ updated_at: p.updated_at,
308
+ }));
309
+ for (const pr of open.values()) {
310
+ if (isBotAuthor(pr.author, botLogin)) continue;
311
+ const local = store.getPr(pr.number);
312
+ if (!local) continue; // untriggered PRs are not tracked (no sweeps)
313
+ if (local.head_sha !== pr.head_sha || local.title !== pr.title) {
314
+ const pushed = store.db.transaction(() => {
315
+ const before = store.getPr(pr.number);
316
+ const result = applyEvent(
317
+ store,
318
+ pr.number,
319
+ { type: "track" },
320
+ { title: pr.title, head_sha: pr.head_sha, author: pr.author },
321
+ { botLogin, now },
322
+ );
323
+ const changed =
324
+ !result.skipped && before !== undefined && before.head_sha !== pr.head_sha;
325
+ if (changed)
326
+ store.logEvent("head_push", pr.number, { head_sha: pr.head_sha, source: "reconcile" });
327
+ return changed;
328
+ })();
329
+ if (pushed && deps.onHeadPush) {
330
+ // After the track so the recheck reads the updated row. Errors are
331
+ // contained: a failed recheck must not abort the reconcile pass.
332
+ try {
333
+ await deps.onHeadPush(pr.number, pr.head_sha);
334
+ } catch (err) {
335
+ report.errors.push(`onHeadPush #${pr.number}: ${String(err)}`);
336
+ (deps.log ?? (() => {}))(`reconcile: onHeadPush failed #${pr.number}`, err);
337
+ }
338
+ }
339
+ } else if (deps.onHeadPush) {
340
+ // Lost-recheck backstop: change-detection
341
+ // fires onHeadPush exactly once, so a recheck that failed to deliver
342
+ // (or died with the process) never retried once the head was tracked.
343
+ // A standing reviewed head that differs from the current head, with
344
+ // this exact question unclaimed, is re-asked; claimed questions
345
+ // (nudged, or answered trivially) dedupe before any classification.
346
+ const reviewed = store.reviewedHead(pr.number);
347
+ if (
348
+ reviewed &&
349
+ standingVerdict(reviewed) === "APPROVE" &&
350
+ reviewed.head_sha !== pr.head_sha &&
351
+ !store.hasRecheck(pr.number, recheckFingerprint({ trigger: "push" }, pr.head_sha))
352
+ ) {
353
+ (deps.log ?? (() => {}))(
354
+ `reconcile: recheck backstop #${pr.number} — reviewed ${reviewed.head_sha.slice(0, 7)} != head ${pr.head_sha.slice(0, 7)}, unclaimed`,
355
+ );
356
+ try {
357
+ await deps.onHeadPush(pr.number, pr.head_sha);
358
+ } catch (err) {
359
+ report.errors.push(`onHeadPush(backstop) #${pr.number}: ${String(err)}`);
360
+ (deps.log ?? (() => {}))(`reconcile: onHeadPush backstop failed #${pr.number}`, err);
361
+ }
362
+ }
363
+ }
364
+ // GitHub owns head truth. A successor can outlive its predecessor and
365
+ // can also survive a crash after the PR row was corrected, so enforce
366
+ // this independently of whether THIS pass observed a local head change.
367
+ // The store preserves predecessor, first-request FIFO time, and sticky
368
+ // human provenance while coalescing only the target head.
369
+ const successor = store.successorFor(pr.number);
370
+ if (successor && successor.head_sha !== pr.head_sha) {
371
+ store.recordSuccessor({
372
+ pr: pr.number,
373
+ predecessor_round_id: successor.predecessor_round_id,
374
+ head_sha: pr.head_sha,
375
+ provenance: successor.provenance,
376
+ reason: "reconcile-authoritative-head",
377
+ });
378
+ }
379
+ if (local.state === "closed") {
380
+ // GitHub says open, we say closed → GitHub wins.
381
+ correction(deps, pr.number, "reopened", { local: local.state }, report);
382
+ applyEvent(
383
+ store,
384
+ pr.number,
385
+ { type: "reopened" },
386
+ { title: pr.title, head_sha: pr.head_sha, author: pr.author },
387
+ { botLogin, now },
388
+ );
389
+ }
390
+ }
391
+ });
392
+
393
+ // ---- 2. triggered-set derivation (both searches) ------------------------
394
+ await step("triggered-set", async () => {
395
+ const [labelled, teamed] = await Promise.all([
396
+ adapter.searchLabelTriggered(),
397
+ adapter.searchTeamTriggered(),
398
+ ]);
399
+ const kinds = ["label", "team_request"] as const;
400
+ const searches = { label: labelled, team_request: teamed };
401
+ const current = {
402
+ label: new Set(labelled.map((item) => item.number)),
403
+ team_request: new Set(teamed.map((item) => item.number)),
404
+ };
405
+
406
+ // Snapshot BEFORE writing this poll. GitHub searches expose current levels,
407
+ // not the edge that created them; this durable previous observation is what
408
+ // distinguishes a new human request from residue left by an older round.
409
+ const previous = new Map<string, boolean | undefined>();
410
+ for (const pr of open.keys()) {
411
+ if (!store.getPr(pr)) continue; // untriggered PRs acquire observations when first triggered
412
+ for (const kind of kinds) previous.set(`${pr}:${kind}`, store.triggerLevel(pr, kind));
413
+ }
414
+
415
+ const grouped = new Map<
416
+ number,
417
+ { item: ReconcileSearchItem; kinds: Array<(typeof kinds)[number]> }
418
+ >();
419
+ for (const kind of kinds) {
420
+ for (const item of searches[kind]) {
421
+ if (isBotAuthor(item.user?.login ?? "", botLogin) || item.user?.type === "Bot") continue;
422
+ const group = grouped.get(item.number) ?? { item, kinds: [] };
423
+ group.kinds.push(kind);
424
+ grouped.set(item.number, group);
425
+ }
426
+ }
427
+
428
+ // Record both presence and absence. Remove→re-add is a fresh edge even
429
+ // when its webhook was lost; rows survive daemon restarts. A paused PR's
430
+ // presence is not recorded: the pause defers handling a fresh request, and
431
+ // acknowledging its level now would leave no edge to act on after the
432
+ // resume. Its absence is recorded — that only ever makes a later edge.
433
+ for (const pr of open.keys()) {
434
+ const row = store.getPr(pr);
435
+ if (!row && !grouped.has(pr)) continue;
436
+ for (const kind of kinds) {
437
+ const present = current[kind].has(pr);
438
+ if (row?.paused && present) continue;
439
+ store.observeTriggerLevel(pr, kind, present);
440
+ }
441
+ }
442
+
443
+ for (const [pr, group] of grouped) {
444
+ const ref = open.get(pr);
445
+ const local = store.getPr(pr);
446
+ // A search can lag the close: a PR closed with its trigger still on it
447
+ // is listed for a pass. Closed is terminal — nothing to queue, nothing
448
+ // to correct.
449
+ if (local?.state === "closed") continue;
450
+ // A tracked PR the searches list but the open list (read this pass)
451
+ // does not is closed on GitHub with the search lagging, or the open
452
+ // list is the one lagging. The closed-sync below settles which, from
453
+ // the PR itself; triggering it first would overwrite the state that
454
+ // sync reads (a merge over a standing block) and count a correction
455
+ // for a PR that owes no review. A PR never tracked here is skipped the
456
+ // same way: nothing would close it, and a genuinely open one the list
457
+ // lags on is picked up by the next pass.
458
+ if (openListed && !ref) continue;
459
+ const meta = {
460
+ title: ref?.title ?? group.item.title,
461
+ head_sha: ref?.head_sha ?? local?.head_sha ?? "",
462
+ author: ref?.author ?? group.item.user?.login ?? "",
463
+ trigger_ts: local?.trigger_ts ?? group.item.updated_at ?? now().toISOString(),
464
+ };
465
+ report.triggered.push(pr);
466
+ if (local?.paused) continue; // overseer pause-pr: no re-trigger until resumed
467
+
468
+ // Only an observed absent→present transition is a fresh edge. Undefined
469
+ // is bootstrap history for an existing row (the table is additive on
470
+ // deploy), not proof a person just acted. A PR never tracked before is
471
+ // different: its first trigger is the human ask that brings it in.
472
+ const freshKind =
473
+ local === undefined
474
+ ? group.kinds[0]
475
+ : group.kinds.find(
476
+ (kind) =>
477
+ store.triggerEdgePending(pr, kind) || previous.get(`${pr}:${kind}`) === false,
478
+ );
479
+ if (local?.state === "reviewing") {
480
+ // A fresh request can upgrade an already-recorded pushed-head
481
+ // successor to human provenance. Same-head requests need no second
482
+ // round: the active one already covers that head.
483
+ if (freshKind)
484
+ applyEvent(store, pr, { type: "trigger", source: freshKind }, meta, {
485
+ botLogin,
486
+ now,
487
+ reason: `reconcile:${freshKind}:reviewing`,
488
+ });
489
+ continue;
490
+ }
491
+ if (local?.state === "queued") {
492
+ // Already queued, but a fresh request upgrades a system-queued round
493
+ // to the person's ask, so dispatch never skips it as a trivial
494
+ // system re-trigger. The edge is recorded above and will not be seen
495
+ // again.
496
+ if (freshKind)
497
+ applyEvent(store, pr, { type: "trigger", source: freshKind }, meta, {
498
+ botLogin,
499
+ now,
500
+ reason: `reconcile:${freshKind}:queued`,
501
+ });
502
+ continue;
503
+ }
504
+ const reviewed = store.reviewedHead(pr);
505
+ const pushHandled =
506
+ !freshKind &&
507
+ reviewed !== undefined &&
508
+ standingVerdict(reviewed) === "APPROVE" &&
509
+ reviewed.head_sha !== meta.head_sha &&
510
+ store.hasRecheck(pr, recheckFingerprint({ trigger: "push" }, meta.head_sha));
511
+ if (pushHandled) {
512
+ // The targeted APPROVE path already owns this head. A standing label or
513
+ // team request is residue, not a second blank-slate review. A genuinely
514
+ // new edge still bypasses this branch and gets a full review.
515
+ store.logEvent("standing_trigger_suppressed", pr, {
516
+ head_sha: meta.head_sha,
517
+ kinds: group.kinds,
518
+ });
519
+ deps.log?.(
520
+ `reconcile: suppressed standing trigger for #${pr} at rechecked head ${meta.head_sha.slice(0, 10)}`,
521
+ );
522
+ continue;
523
+ }
524
+
525
+ // Dry-run never consumes triggers on GitHub, so an already-reviewed
526
+ // head would re-queue forever; suppress until the head moves.
527
+ if (cfg.dry_run && meta.head_sha && store.lastVerdictHead(pr) === meta.head_sha) {
528
+ if (freshKind) store.acknowledgeTriggerEdges(pr);
529
+ deps.log?.(
530
+ `dry-run: suppressing re-trigger of #${pr} at reviewed head ${meta.head_sha.slice(0, 10)}`,
531
+ );
532
+ continue;
533
+ }
534
+ const source = freshKind ?? "reconcile";
535
+ correction(
536
+ deps,
537
+ pr,
538
+ "triggered-not-queued",
539
+ { local: local?.state ?? null, source, kinds: group.kinds },
540
+ report,
541
+ );
542
+ applyEvent(store, pr, { type: "trigger", source }, meta, {
543
+ botLogin,
544
+ now,
545
+ reason: `reconcile:${source}`,
546
+ });
547
+ }
548
+ });
549
+
550
+ // Commits outside a round never dispatch a review. A head advance WHILE an
551
+ // older round owns the PR is different: it is recorded as durable successor
552
+ // work. Promote obligations whose predecessor became terminal across a
553
+ // crash/restart; queue publication is idempotent and retains the evidence.
554
+ await step("successor-obligations", async () => {
555
+ for (const row of store.allPrs()) {
556
+ if (store.successorFor(row.number)) store.promoteSuccessor(row.number);
557
+ }
558
+ });
559
+
560
+ // ---- 2b. undelivered recheck-claim sweep ---------------------------------
561
+ // `claimRecheck` is written BEFORE the nudge goes out, `releaseRecheck`
562
+ // fires only on a synchronous throw (which a bridge-level drop is not), and
563
+ // `rechecks` has no deadline or expiry of its own. Without this sweep a
564
+ // dropped nudge would leave a claim that suppresses the push-backstop above
565
+ // (`!store.hasRecheck(...)`) forever: a delta on an APPROVED PR would never
566
+ // be audited, and the approval would stand over code nobody read.
567
+ //
568
+ // The receipt makes it recoverable. A claim past the grace window whose
569
+ // marker never reached the session is released, and the backstop re-asks on
570
+ // the next pass. Every ambiguity is a no-op: only a provable absence counts.
571
+ //
572
+ // Bounded so it never holds the event loop: it asks only about claims that
573
+ // can still be lost nudges (`recheckClaimsAwaitingReceipt` — a real nudge,
574
+ // receipt not yet found, PR not closed), records a found receipt so it is
575
+ // never asked again, yields a real event-loop turn between claims, stops starting new
576
+ // claims past its time budget (the rest are asked next pass, least
577
+ // recently asked first), and is skipped on the boot's first pass, whose
578
+ // health is what lifts a deploy drain.
579
+ await step("undelivered-rechecks", async () => {
580
+ const receipt = deps.hooks.wakeReceiptPresent;
581
+ if (!receipt) return;
582
+ if (deps.receiptSweep === false) {
583
+ (deps.log ?? (() => {}))(
584
+ "reconcile: undelivered-recheck sweep deferred to the next pass (boot)",
585
+ );
586
+ return;
587
+ }
588
+ const graceMs = (cfg.daemon.round_stall_grace_min ?? DEFAULT_ROUND_STALL_GRACE_MIN) * 60_000;
589
+ const cutoff = new Date(now().getTime() - graceMs).toISOString();
590
+ const budgetMs = deps.receiptSweepBudgetMs ?? RECEIPT_SWEEP_BUDGET_MS;
591
+ const claims = store.recheckClaimsAwaitingReceipt(cutoff);
592
+ const sweep = { asked: 0, delivered: 0, released: 0, carried: 0 };
593
+ const started = performance.now();
594
+ for (const [i, claim] of claims.entries()) {
595
+ // Always at least one claim, so a tiny budget still makes progress.
596
+ if (i > 0 && performance.now() - started > budgetMs) {
597
+ sweep.carried = claims.length - i;
598
+ break;
599
+ }
600
+ // A real macrotask turn per claim: whatever the receipt hook does, the
601
+ // sweep is never one synchronous span.
602
+ await yieldToLoop();
603
+ // A held or still-pending nudge is not a lost one.
604
+ if (store.hasRunningRound(claim.pr) || store.hasHeldWakes(claim.pr)) {
605
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
606
+ continue;
607
+ }
608
+ const claimedMs = Date.parse(claim.created_at);
609
+ if (!Number.isFinite(claimedMs)) continue;
610
+ sweep.asked++;
611
+ const landed = await receipt.call(
612
+ deps.hooks,
613
+ claim.pr,
614
+ recheckPromptMarker(claim.pr, claim.fingerprint),
615
+ claimedMs,
616
+ );
617
+ if (landed === true) {
618
+ // Delivered is a fact: recorded once, never re-read.
619
+ store.markRecheckReceipt(claim.pr, claim.fingerprint);
620
+ sweep.delivered++;
621
+ continue;
622
+ }
623
+ if (landed !== false) {
624
+ // No evidence either way — never guess; ask again on a later pass.
625
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
626
+ continue;
627
+ }
628
+ if (claim.trigger === "ci" || claim.trigger === "base_advance") {
629
+ const enabled =
630
+ cfg.recheck.enabled &&
631
+ (claim.trigger === "ci" ? cfg.recheck.on_ci : cfg.recheck.on_base_advance);
632
+ if (!enabled || store.drainState().draining) {
633
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
634
+ continue;
635
+ }
636
+ const delivery = store.recheckDelivery(claim.pr, claim.fingerprint);
637
+ if (
638
+ !delivery ||
639
+ delivery.reason !== `recheck:${claim.trigger}` ||
640
+ !delivery.payload
641
+ .split(/\r?\n/)
642
+ .includes(recheckPromptMarker(claim.pr, claim.fingerprint))
643
+ ) {
644
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
645
+ if (!store.lastEventAt("recheck_payload_unknown", claim.pr))
646
+ store.logEvent("recheck_payload_unknown", claim.pr, { fingerprint: claim.fingerprint });
647
+ continue;
648
+ }
649
+ const row = store.getPr(claim.pr);
650
+ const standing = store.reviewedHead(claim.pr);
651
+ if (
652
+ row?.head_sha.toLowerCase() !== claim.head_sha.toLowerCase() ||
653
+ (standing && standingVerdict(standing) !== "APPROVE")
654
+ ) {
655
+ store.releaseRecheck(claim.pr, claim.fingerprint);
656
+ store.logEvent("recheck_delivery_superseded", claim.pr, {
657
+ fingerprint: claim.fingerprint,
658
+ });
659
+ continue;
660
+ }
661
+ if (!standing) {
662
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
663
+ continue;
664
+ }
665
+ await wakeOrHold(
666
+ { store, inject: deps.hooks.inject.bind(deps.hooks), log: deps.log },
667
+ claim.pr,
668
+ delivery.payload,
669
+ delivery.reason,
670
+ { holdOnFailure: true, deferWhilePaused: true },
671
+ );
672
+ store.markRecheckReceiptChecked(claim.pr, claim.fingerprint);
673
+ continue;
674
+ }
675
+ store.releaseRecheck(claim.pr, claim.fingerprint);
676
+ sweep.released++;
677
+ correction(
678
+ deps,
679
+ claim.pr,
680
+ "recheck-claim-released-undelivered",
681
+ {
682
+ fingerprint: claim.fingerprint,
683
+ head_sha: claim.head_sha,
684
+ trigger: claim.trigger,
685
+ claimed_at: claim.created_at,
686
+ },
687
+ report,
688
+ );
689
+ }
690
+ report.receipt_sweep = sweep;
691
+ if (sweep.carried > 0)
692
+ (deps.log ?? (() => {}))(
693
+ `reconcile: undelivered-recheck sweep hit its ${budgetMs} ms budget — ${sweep.carried} claim(s) carried to the next pass`,
694
+ );
695
+ });
696
+
697
+ // ---- 2c. stale-trigger residue sweep -------------------------------------
698
+ // A settled PR (tracked/awaiting_author, no round running) never
699
+ // legitimately carries `stale_recheck` or a `trigger_ts`: both are consumed
700
+ // by dispatch and cleared when a round settles. Left behind, they would
701
+ // misclassify the NEXT explicit re-review as a staleness round and let it
702
+ // jump the FIFO on an old timestamp. Swept after the triggered-set step, so
703
+ // a PR GitHub still lists as triggered has already been re-queued and is
704
+ // never touched.
705
+ await step("stale-trigger-residue", async () => {
706
+ for (const local of store.allPrs()) {
707
+ if (local.state !== "tracked" && local.state !== "awaiting_author") continue;
708
+ if (!local.stale_recheck && local.trigger_ts === null) continue;
709
+ if (store.hasRunningRound(local.number)) continue;
710
+ correction(
711
+ deps,
712
+ local.number,
713
+ "stale-trigger-residue-cleared",
714
+ { state: local.state, stale_recheck: local.stale_recheck, trigger_ts: local.trigger_ts },
715
+ report,
716
+ );
717
+ store.upsertPr({ ...local, stale_recheck: 0, trigger_ts: null });
718
+ }
719
+ });
720
+
721
+ // ---- 3. open-PR sync: locally-live PRs GitHub no longer lists as open ----
722
+ await step("closed-sync", async () => {
723
+ for (const local of store.allPrs()) {
724
+ if (local.state === "closed") continue;
725
+ if (open.has(local.number)) continue;
726
+ let ref: PrRef | null = null;
727
+ try {
728
+ ref = await adapter.getPr(local.number);
729
+ } catch (err) {
730
+ report.errors.push(`getPr #${local.number}: ${String(err)}`);
731
+ continue;
732
+ }
733
+ if (ref.state !== "closed") continue; // listing lag — leave it alone
734
+ correction(
735
+ deps,
736
+ local.number,
737
+ "pr-closed",
738
+ { merged: ref.merged, local: local.state },
739
+ report,
740
+ );
741
+ // The existing feedback ledger is the durable owed-memory intent. Commit
742
+ // it with closure, before a callback can fail or the process can stop.
743
+ const overBlock = store.db.transaction(() => {
744
+ const priorState = store.getPr(local.number)?.state;
745
+ if (priorState === "closed") return false;
746
+ const result = applyEvent(
747
+ store,
748
+ local.number,
749
+ { type: "closed" },
750
+ { title: ref.title, head_sha: ref.head_sha, author: ref.author },
751
+ { botLogin, now },
752
+ );
753
+ if (result.skipped) return false;
754
+ store.logEvent("pr_closed", local.number, { merged: ref.merged, source: "reconcile" });
755
+ const over = mergedOverBlock(ref.merged, priorState);
756
+ if (over)
757
+ ledgerFeedbackSignal(
758
+ store,
759
+ { kind: "merged_over_block", pr: local.number },
760
+ {
761
+ timezone: cfg.ops.timezone,
762
+ now: now(),
763
+ memoryEnabled: cfg.openviking.enabled,
764
+ },
765
+ );
766
+ return over;
767
+ })();
768
+ if (overBlock && deps.onMergedOverBlock) {
769
+ try {
770
+ await deps.onMergedOverBlock(local.number);
771
+ } catch (err) {
772
+ report.errors.push(`onMergedOverBlock #${local.number}: ${String(err)}`);
773
+ }
774
+ }
775
+ report.closed.push(local.number);
776
+ try {
777
+ await deps.hooks.archiveAndClose(local.number);
778
+ } catch (err) {
779
+ report.errors.push(`archiveAndClose #${local.number}: ${String(err)}`);
780
+ }
781
+ }
782
+ });
783
+
784
+ // ---- 4. withheld-approval backstop ---------------------------------------
785
+ // cigate.ts promises that a PR whose approval was withheld for red CI is
786
+ // re-queued "by the next completion (or the reconcile poll)". The
787
+ // `ci_completed` webhook is the fast path; this sweep is the backstop for a
788
+ // lost delivery — without it a missed green would leave the PR waiting on a
789
+ // verdict that is never re-attempted. Same idiom as every other step:
790
+ // GitHub (the CI state at the recorded head) always wins, corrections
791
+ // logged. The retry itself is retryWithheldApproval — the exact function the
792
+ // webhook path calls — never a copy.
793
+ if (adapter.listChecks) {
794
+ await step("withheld-approvals", async () => {
795
+ for (const local of store.allPrs()) {
796
+ if (local.state === "closed") continue;
797
+ const mark = store.approvalWithheld(local.number);
798
+ if (!mark) continue;
799
+ const outcome = await retryWithheldApproval(
800
+ {
801
+ cfg,
802
+ store,
803
+ adapter: { listChecks: (ref) => adapter.listChecks!(ref) },
804
+ now,
805
+ ...(deps.log ? { log: deps.log } : {}),
806
+ },
807
+ { pr: local.number, head_sha: mark.head_sha },
808
+ );
809
+ if (outcome.action === "requeued")
810
+ correction(
811
+ deps,
812
+ local.number,
813
+ "withheld-approval-requeued",
814
+ { head_sha: mark.head_sha, ci: outcome.ci },
815
+ report,
816
+ );
817
+ }
818
+ });
819
+ }
820
+
821
+ // ---- 5. bot-comment registry backfill ----------------------------------
822
+ if (deps.backfillRegistry !== false) {
823
+ await step("registry-backfill", async () => {
824
+ for (const local of store.allPrs()) {
825
+ if (local.state === "closed") continue;
826
+ try {
827
+ for (const id of await adapter.listBotReviewComments(local.number)) {
828
+ if (store.isBotComment(id, "review_comment")) continue;
829
+ store.registerBotComment(id, local.number);
830
+ report.backfilled_comments++;
831
+ }
832
+ } catch (err) {
833
+ report.errors.push(`backfill #${local.number}: ${String(err)}`);
834
+ }
835
+ }
836
+ });
837
+ }
838
+
839
+ // ---- 5b. human-comment capture sweep -------------------------------------
840
+ // The webhook is the fast path and GitHub never redelivers, so a comment
841
+ // posted while the daemon was down would otherwise be permanent evidence
842
+ // loss rather than a delayed signal. This is the backstop, and it
843
+ // is deliberately shaped like every other sweep here: READ-ONLY (three list
844
+ // calls per PR, no mutation anywhere in the path), bounded
845
+ // (COMMENT_SWEEP_MAX_PRS, freshest first, one API page per source), and
846
+ // idempotent — dedupe is GitHub's own `(source, comment_id)` identity in
847
+ // `pr_comments`, so re-running captures nothing twice and an edited comment
848
+ // is still the same comment.
849
+ //
850
+ // It captures ONLY: nothing here routes, wakes a session, stamps a mark or
851
+ // feeds the [feedback] engine. A tagged comment picked up here gets the tag
852
+ // recorded and nothing else — the same-day addendum stays tag-gated on the
853
+ // webhook's feedback path, where a human is in the loop.
854
+ if (
855
+ deps.captureComments !== false &&
856
+ adapter.listReviewCommentsFull &&
857
+ adapter.listIssueComments &&
858
+ adapter.listReviewsFull
859
+ ) {
860
+ await step("comment-capture", async () => {
861
+ // Recently-closed PRs stay in: closed-sync above marks a
862
+ // closed-during-downtime PR closed in this very pass, and its comments
863
+ // are what this backstop exists to recover. `updated_at` is the close
864
+ // instant for a closed row.
865
+ const nowMs = now().getTime();
866
+ const closedRecently = (updated_at: string): boolean => {
867
+ const t = Date.parse(updated_at);
868
+ return Number.isFinite(t) && nowMs - t <= COMMENT_SWEEP_CLOSED_WINDOW_MS;
869
+ };
870
+ // A failed open-PR list is UNKNOWN remote state, not a change: keep the
871
+ // stored remote half, or every PR would re-sweep on the failing pass
872
+ // and again on the recovering one. A closed PR has left the open list
873
+ // and with it GitHub's timestamp, so nothing remote moves when a
874
+ // comment lands on it after the close: inside the recent-close window
875
+ // its remote half is the current hour instead, and it is re-swept once
876
+ // an hour.
877
+ const nowHour = now().toISOString().slice(0, 13);
878
+ const remoteHalf = (p: { number: number; state: string }): string => {
879
+ if (!openListed) return store.lastCommentSweep(p.number)?.split("|")[1] ?? "";
880
+ const listed = open.get(p.number);
881
+ if (listed) return listed.updated_at;
882
+ return p.state === "closed" ? `closed@${nowHour}` : "";
883
+ };
884
+ const sweepMark = (p: { number: number; state: string; updated_at: string }): string =>
885
+ `${p.updated_at}|${remoteHalf(p)}`;
886
+ const candidates = store
887
+ .allPrs()
888
+ .filter(
889
+ (p) =>
890
+ p.state !== "closed" ||
891
+ report.closed.includes(p.number) ||
892
+ closedRecently(p.updated_at),
893
+ )
894
+ // Change gating (without it every tracked PR costs three reads every
895
+ // pass): a PR whose row has not moved since the last successful sweep
896
+ // of it has produced no webhook the sweep could have missed a
897
+ // *newer* version of than last time — skip it. The watermark is the
898
+ // row's own `updated_at` PAIRED with GitHub's `updated_at` for the PR
899
+ // (from the open-PR list above), recorded per PR after a clean sweep.
900
+ // The remote half is load-bearing: capturing a comment never moves
901
+ // the local row, so a comment whose webhook was lost (the daemon was
902
+ // down, no push, no title change) only shows up as GitHub's
903
+ // timestamp moving.
904
+ .filter((p) => store.lastCommentSweep(p.number) !== sweepMark(p))
905
+ .sort((a, b) =>
906
+ a.updated_at < b.updated_at ? 1 : a.updated_at > b.updated_at ? -1 : a.number - b.number,
907
+ )
908
+ .slice(0, COMMENT_SWEEP_MAX_PRS);
909
+ for (const local of candidates) {
910
+ const n = local.number;
911
+ let rows: CapturedComment[];
912
+ let reviewsFetched: ReviewFull[] = [];
913
+ let inlineFetched: ReviewCommentFull[] = [];
914
+ try {
915
+ const [inline, top, reviews] = await Promise.all([
916
+ adapter.listReviewCommentsFull!(n),
917
+ adapter.listIssueComments!(n),
918
+ adapter.listReviewsFull!(n),
919
+ ]);
920
+ reviewsFetched = reviews;
921
+ inlineFetched = inline;
922
+ rows = [
923
+ ...inline.map((c) => capturedFromReviewComment(n, c)),
924
+ ...top.map((c) => capturedFromIssueComment(n, c)),
925
+ ...reviews.map((r) => capturedFromReview(n, r)),
926
+ ];
927
+ } catch (err) {
928
+ report.errors.push(`comment-capture #${n}: ${String(err)}`);
929
+ continue;
930
+ }
931
+ // The bot's own inline comments in this very read are the
932
+ // link facts the outcome capture needs (which finding each one
933
+ // carried) — kept here, at no extra API call. Never breaks the sweep.
934
+ if (deps.outcomes) {
935
+ try {
936
+ deps.outcomes.observeBotComments(n, inlineFetched);
937
+ } catch (err) {
938
+ (deps.log ?? (() => {}))(`reconcile: outcome facts #${n} failed`, err);
939
+ }
940
+ }
941
+ for (const c of rows) {
942
+ if (!isHumanCapture(c, botLogin)) continue;
943
+ // Person mode: the reviewer's own words under the person's login.
944
+ if (isOwnContent(cfg.github, c.author, c.body)) continue;
945
+ if (recordCapturedComment(store, c, "reconcile")) report.captured_comments++;
946
+ }
947
+ // ---- the exec boundary's OUTCOME layer ------------------------------
948
+ // The bot's OWN reviews, which `isHumanCapture` discards above, are the
949
+ // one piece of evidence that does not care HOW a write was made. The
950
+ // command-string guard is pattern-based and not closed; a review here
951
+ // that the daemon has no record of posting is a violation whichever
952
+ // way it got there — and this costs no
953
+ // API call, because `listReviewsFull` was already fetched above.
954
+ // Detection only: nothing below mutates GitHub, and nothing here can
955
+ // withdraw, retract or edit a review (AGENTS.md invariant 2 — structural,
956
+ // not prompted; there is no such call in this module or its imports).
957
+ try {
958
+ const ungated = auditUngatedReviews(
959
+ reviewsFetched,
960
+ local.head_sha,
961
+ {
962
+ reviewIds: store.postedReviewIds(n),
963
+ reviewedHead: store.reviewedHead(n) ?? undefined,
964
+ migrationPrecheck: store.lastEventAt("migration_collision_comment", n) !== undefined,
965
+ postingKeys: new Set(
966
+ store.roundsFor(n).flatMap((r) => (r.posting_key ? [r.posting_key] : [])),
967
+ ),
968
+ reviewComments: commentsByReview(inlineFetched),
969
+ gatedCommentIds: store.botCommentIds(n),
970
+ },
971
+ {
972
+ botLogin: cfg.github.bot_login,
973
+ appSlug: cfg.github.app_slug,
974
+ // Person mode: only marker-bearing reviews are the reviewer's.
975
+ personMode: isPersonMode(cfg.github),
976
+ },
977
+ );
978
+ if (ungated.length > 0) {
979
+ store.logEvent("ungated_review_detected", n, {
980
+ head_sha: local.head_sha,
981
+ reviews: ungated,
982
+ });
983
+ const message = ungatedReviewMessage(n, ungated);
984
+ // An unaccounted APPROVE wakes; anything else stays a durable row.
985
+ // The asymmetry is the blocker bar's: an approval posted outside
986
+ // the gate defeats rule 1, the CI hard-gate and every posting
987
+ // guard at once, and it is the outcome any bypass of the exec
988
+ // boundary is reaching for.
989
+ if (hasUngatedApproval(ungated))
990
+ store.logAnomaly("ungated_approval", n, null, message, message);
991
+ else store.logAnomaly("ungated_review", n, null, message);
992
+ report.errors.push(
993
+ `ungated-review #${n}: ${ungated.length} unaccounted bot review(s) at the head`,
994
+ );
995
+ }
996
+ } catch (err) {
997
+ // Never let the audit break the sweep it rides on.
998
+ report.errors.push(`ungated-review-audit #${n}: ${String(err)}`);
999
+ }
1000
+ // Watermark only a CLEAN sweep of this PR — a failed read `continue`s
1001
+ // above without one, so it is retried on the next pass.
1002
+ store.markCommentSweep(n, sweepMark(local));
1003
+ }
1004
+ });
1005
+ }
1006
+
1007
+ // ---- outcome capture -------------------------------------------------------
1008
+ // What became of every posted finding: link each bot comment to its finding,
1009
+ // then decide each finding's fate from the replies, thread decisions, pushes
1010
+ // and later rounds already recorded. Local reads only (state.db and the base
1011
+ // clone's git) — no GitHub call and no gate. Bounded and change-gated inside
1012
+ // `sweep`, and never an error of this pass: it is bookkeeping.
1013
+ if (deps.outcomes) {
1014
+ try {
1015
+ const swept = await deps.outcomes.sweep();
1016
+ if (swept.captured > 0 || swept.errors.length > 0) report.outcomes = swept;
1017
+ } catch (err) {
1018
+ (deps.log ?? (() => {}))("reconcile: outcome capture failed", err);
1019
+ }
1020
+ }
1021
+
1022
+ // ---- the raw-tier sweep -----------------------------------------------------
1023
+ // The `pr-<n>` OpenViking sessions of closed PRs that are still on the
1024
+ // server (a delete that failed, a close the daemon never saw) — bounded per
1025
+ // pass, every outcome logged by the hook. Run AFTER the closed-sync above,
1026
+ // so a PR closed this pass is already closed in the registry. Never an
1027
+ // error of this pass, whatever happens: memory never blocks reconcile.
1028
+ if (deps.hooks.sweepStaleOvSessions) {
1029
+ try {
1030
+ const swept = await deps.hooks.sweepStaleOvSessions();
1031
+ if (swept) report.ov_sessions = swept;
1032
+ } catch (err) {
1033
+ (deps.log ?? (() => {}))("reconcile: stale openviking-session sweep threw", err);
1034
+ }
1035
+ }
1036
+
1037
+ // No retired-park migration runs here: `awaiting_human` is not a member of
1038
+ // `PrLifecycleState`, so no row can carry it for a pass to find.
1039
+
1040
+ store.logEvent("reconcile_pass", null, {
1041
+ open_prs: report.open_prs,
1042
+ triggered: report.triggered.length,
1043
+ closed: report.closed.length,
1044
+ captured_comments: report.captured_comments,
1045
+ corrections: report.corrections,
1046
+ errors: report.errors.length,
1047
+ ...(report.ov_sessions
1048
+ ? {
1049
+ ov_sessions_deleted: report.ov_sessions.deleted.length,
1050
+ ov_sessions_failed: report.ov_sessions.failed.length,
1051
+ ...(report.ov_sessions.error ? { ov_sessions_error: report.ov_sessions.error } : {}),
1052
+ }
1053
+ : {}),
1054
+ });
1055
+ return report;
1056
+ }