@quickchatai/quickreview 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1443) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +385 -2
  3. package/THIRD-PARTY-NOTICES.md +134 -0
  4. package/agents/pass-abstraction.md +64 -0
  5. package/agents/pass-ask-human.md +134 -0
  6. package/agents/pass-backcompat.md +67 -0
  7. package/agents/pass-baseline.md +61 -0
  8. package/agents/pass-behaviour-delta.md +64 -0
  9. package/agents/pass-bounds.md +36 -0
  10. package/agents/pass-claims.md +31 -0
  11. package/agents/pass-concurrency.md +168 -0
  12. package/agents/pass-consistency.md +57 -0
  13. package/agents/pass-contracts.md +30 -0
  14. package/agents/pass-data-safety.md +54 -0
  15. package/agents/pass-deferred.md +35 -0
  16. package/agents/pass-delivery.md +37 -0
  17. package/agents/pass-duplication.md +60 -0
  18. package/agents/pass-intent.md +63 -0
  19. package/agents/pass-lint-conformance.md +46 -0
  20. package/agents/pass-maintainability.md +67 -0
  21. package/agents/pass-placement.md +68 -0
  22. package/agents/pass-prod-risk.md +24 -0
  23. package/agents/pass-rollout.md +32 -0
  24. package/agents/pass-roundtrip.md +46 -0
  25. package/agents/pass-security.md +31 -0
  26. package/agents/pass-simplicity.md +68 -0
  27. package/agents/pass-statelessness.md +27 -0
  28. package/agents/pass-style.md +37 -0
  29. package/agents/pass-sweep.md +57 -0
  30. package/agents/pass-tests.md +58 -0
  31. package/agents/pass-ui.md +23 -0
  32. package/agents/pass-validate.md +50 -0
  33. package/agents/pass-widened.md +46 -0
  34. package/agents/scan/pass-scan.md +86 -0
  35. package/bin/qcr.js +11 -0
  36. package/config.example.toml +1067 -0
  37. package/deploy/ansible/README.md +356 -0
  38. package/deploy/ansible/group_vars/all.yml +212 -0
  39. package/deploy/ansible/inventory.example.ini +25 -0
  40. package/deploy/ansible/playbook.yml +360 -0
  41. package/deploy/collect-secrets.sh +289 -0
  42. package/deploy/collect-slack-secrets.mjs +1190 -0
  43. package/deploy/github-app-manifest.json +31 -0
  44. package/deploy/manifest.schema.json +75 -0
  45. package/deploy/qcr-update.sh +803 -0
  46. package/deploy/reviewer/AGENTS.override.md +12 -0
  47. package/dist/extensions/cli/bash-guard-ambient.js +42 -0
  48. package/dist/extensions/cli/bash-guard-ambient.js.map +1 -0
  49. package/dist/extensions/cli/bash-guard.js +5 -0
  50. package/dist/extensions/cli/bash-guard.js.map +1 -0
  51. package/dist/extensions/cli/companion-guard.js +5 -0
  52. package/dist/extensions/cli/companion-guard.js.map +1 -0
  53. package/dist/extensions/cli/debug-round.js +8 -0
  54. package/dist/extensions/cli/debug-round.js.map +1 -0
  55. package/dist/extensions/cli/inject-bridge.js +5 -0
  56. package/dist/extensions/cli/inject-bridge.js.map +1 -0
  57. package/dist/extensions/cli/ledger-pin.js +5 -0
  58. package/dist/extensions/cli/ledger-pin.js.map +1 -0
  59. package/dist/extensions/cli/lens.js +13 -0
  60. package/dist/extensions/cli/lens.js.map +1 -0
  61. package/dist/extensions/cli/muted-theme.js +5 -0
  62. package/dist/extensions/cli/muted-theme.js.map +1 -0
  63. package/dist/extensions/cli/onboarding.js +5 -0
  64. package/dist/extensions/cli/onboarding.js.map +1 -0
  65. package/dist/extensions/cli/setup.js +5 -0
  66. package/dist/extensions/cli/setup.js.map +1 -0
  67. package/dist/extensions/cli/tui-view.js +5 -0
  68. package/dist/extensions/cli/tui-view.js.map +1 -0
  69. package/dist/extensions/companion-guard.js +361 -0
  70. package/dist/extensions/companion-guard.js.map +1 -0
  71. package/dist/extensions/debug-round.js +204 -0
  72. package/dist/extensions/debug-round.js.map +1 -0
  73. package/dist/extensions/inject-bridge.js +603 -0
  74. package/dist/extensions/inject-bridge.js.map +1 -0
  75. package/dist/extensions/muted-theme.js +12 -0
  76. package/dist/extensions/muted-theme.js.map +1 -0
  77. package/dist/extensions/onboarding.js +175 -0
  78. package/dist/extensions/onboarding.js.map +1 -0
  79. package/dist/extensions/setup-replay.js +269 -0
  80. package/dist/extensions/setup-replay.js.map +1 -0
  81. package/dist/extensions/setup-scan.js +998 -0
  82. package/dist/extensions/setup-scan.js.map +1 -0
  83. package/dist/extensions/setup-triage.js +175 -0
  84. package/dist/extensions/setup-triage.js.map +1 -0
  85. package/dist/extensions/setup.js +1160 -0
  86. package/dist/extensions/setup.js.map +1 -0
  87. package/dist/extensions/tui-view.js +389 -0
  88. package/dist/extensions/tui-view.js.map +1 -0
  89. package/dist/extensions/vendor/openviking-pi/client.js +376 -0
  90. package/dist/extensions/vendor/openviking-pi/client.js.map +1 -0
  91. package/dist/extensions/vendor/openviking-pi/config.js +189 -0
  92. package/dist/extensions/vendor/openviking-pi/config.js.map +1 -0
  93. package/dist/extensions/vendor/openviking-pi/index.js +421 -0
  94. package/dist/extensions/vendor/openviking-pi/index.js.map +1 -0
  95. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +86 -0
  96. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs.map +1 -0
  97. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs +408 -0
  98. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs.map +1 -0
  99. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +41 -0
  100. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs.map +1 -0
  101. package/dist/extensions/vendor/openviking-pi/qcr-hint.js +290 -0
  102. package/dist/extensions/vendor/openviking-pi/qcr-hint.js.map +1 -0
  103. package/dist/extensions/vendor/openviking-pi/qcr-honest.js +148 -0
  104. package/dist/extensions/vendor/openviking-pi/qcr-honest.js.map +1 -0
  105. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js +68 -0
  106. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js.map +1 -0
  107. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js +77 -0
  108. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js.map +1 -0
  109. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js +216 -0
  110. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js.map +1 -0
  111. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js +154 -0
  112. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js.map +1 -0
  113. package/dist/extensions/vendor/openviking-pi/qcr-recall.js +254 -0
  114. package/dist/extensions/vendor/openviking-pi/qcr-recall.js.map +1 -0
  115. package/dist/extensions/vendor/openviking-pi/qcr-shim.js +94 -0
  116. package/dist/extensions/vendor/openviking-pi/qcr-shim.js.map +1 -0
  117. package/dist/extensions/vendor/openviking-pi/qcr-write.js +333 -0
  118. package/dist/extensions/vendor/openviking-pi/qcr-write.js.map +1 -0
  119. package/dist/extensions/vendor/openviking-pi/recall.js +108 -0
  120. package/dist/extensions/vendor/openviking-pi/recall.js.map +1 -0
  121. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs +529 -0
  122. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs.map +1 -0
  123. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs +205 -0
  124. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs.map +1 -0
  125. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs +442 -0
  126. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs.map +1 -0
  127. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs +286 -0
  128. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs.map +1 -0
  129. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +189 -0
  130. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs.map +1 -0
  131. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs +580 -0
  132. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs.map +1 -0
  133. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs +11 -0
  134. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs.map +1 -0
  135. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs +63 -0
  136. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs.map +1 -0
  137. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs +58 -0
  138. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs.map +1 -0
  139. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  140. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs.map +1 -0
  141. package/dist/extensions/vendor/openviking-pi/sync.js +127 -0
  142. package/dist/extensions/vendor/openviking-pi/sync.js.map +1 -0
  143. package/dist/extensions/vendor/openviking-pi/takeover.js +25 -0
  144. package/dist/extensions/vendor/openviking-pi/takeover.js.map +1 -0
  145. package/dist/extensions/vendor/openviking-pi/tools.js +417 -0
  146. package/dist/extensions/vendor/openviking-pi/tools.js.map +1 -0
  147. package/dist/src/anomalies.js +483 -0
  148. package/dist/src/anomalies.js.map +1 -0
  149. package/dist/src/answerworker.js +180 -0
  150. package/dist/src/answerworker.js.map +1 -0
  151. package/dist/src/appstamp.js +68 -0
  152. package/dist/src/appstamp.js.map +1 -0
  153. package/dist/src/archive/admission.js +3 -0
  154. package/dist/src/archive/admission.js.map +1 -0
  155. package/dist/src/archive/archivedb.js +474 -0
  156. package/dist/src/archive/archivedb.js.map +1 -0
  157. package/dist/src/archive/archiver.js +1770 -0
  158. package/dist/src/archive/archiver.js.map +1 -0
  159. package/dist/src/archive/archivewrite.js +198 -0
  160. package/dist/src/archive/archivewrite.js.map +1 -0
  161. package/dist/src/archive/bundle.js +266 -0
  162. package/dist/src/archive/bundle.js.map +1 -0
  163. package/dist/src/archive/dbmove.js +638 -0
  164. package/dist/src/archive/dbmove.js.map +1 -0
  165. package/dist/src/archive/duplicatecounts.js +80 -0
  166. package/dist/src/archive/duplicatecounts.js.map +1 -0
  167. package/dist/src/archive/eligibility.js +113 -0
  168. package/dist/src/archive/eligibility.js.map +1 -0
  169. package/dist/src/archive/extract.js +288 -0
  170. package/dist/src/archive/extract.js.map +1 -0
  171. package/dist/src/archive/fsutil.js +330 -0
  172. package/dist/src/archive/fsutil.js.map +1 -0
  173. package/dist/src/archive/gzfile.js +277 -0
  174. package/dist/src/archive/gzfile.js.map +1 -0
  175. package/dist/src/archive/kinds.js +22 -0
  176. package/dist/src/archive/kinds.js.map +1 -0
  177. package/dist/src/archive/livecheckpoint.js +178 -0
  178. package/dist/src/archive/livecheckpoint.js.map +1 -0
  179. package/dist/src/archive/liveretention.js +145 -0
  180. package/dist/src/archive/liveretention.js.map +1 -0
  181. package/dist/src/archive/manifest.js +284 -0
  182. package/dist/src/archive/manifest.js.map +1 -0
  183. package/dist/src/archive/overseer.js +283 -0
  184. package/dist/src/archive/overseer.js.map +1 -0
  185. package/dist/src/archive/piglobal.js +129 -0
  186. package/dist/src/archive/piglobal.js.map +1 -0
  187. package/dist/src/archive/plan.js +398 -0
  188. package/dist/src/archive/plan.js.map +1 -0
  189. package/dist/src/archive/prarchive.js +831 -0
  190. package/dist/src/archive/prarchive.js.map +1 -0
  191. package/dist/src/archive/prfiles.js +303 -0
  192. package/dist/src/archive/prfiles.js.map +1 -0
  193. package/dist/src/archive/report.js +169 -0
  194. package/dist/src/archive/report.js.map +1 -0
  195. package/dist/src/archive/restore.js +276 -0
  196. package/dist/src/archive/restore.js.map +1 -0
  197. package/dist/src/archive/rows.js +106 -0
  198. package/dist/src/archive/rows.js.map +1 -0
  199. package/dist/src/archive/seal.js +480 -0
  200. package/dist/src/archive/seal.js.map +1 -0
  201. package/dist/src/archive/status.js +528 -0
  202. package/dist/src/archive/status.js.map +1 -0
  203. package/dist/src/archive/storepass.js +409 -0
  204. package/dist/src/archive/storepass.js.map +1 -0
  205. package/dist/src/backfill.js +217 -0
  206. package/dist/src/backfill.js.map +1 -0
  207. package/dist/src/bench/cost.js +87 -0
  208. package/dist/src/bench/exec.js +76 -0
  209. package/dist/src/bench/values.js +14 -0
  210. package/dist/src/botcontrol.js +127 -0
  211. package/dist/src/botcontrol.js.map +1 -0
  212. package/dist/src/botworker.js +805 -0
  213. package/dist/src/botworker.js.map +1 -0
  214. package/dist/src/capture.js +234 -0
  215. package/dist/src/capture.js.map +1 -0
  216. package/dist/src/cases.js +1491 -0
  217. package/dist/src/cases.js.map +1 -0
  218. package/dist/src/channelfs.js +27 -0
  219. package/dist/src/channelfs.js.map +1 -0
  220. package/dist/src/checklist.js +312 -0
  221. package/dist/src/checklist.js.map +1 -0
  222. package/dist/src/ciretry.js +91 -0
  223. package/dist/src/ciretry.js.map +1 -0
  224. package/dist/src/cli.js +1916 -0
  225. package/dist/src/cli.js.map +1 -0
  226. package/dist/src/cliops.js +333 -0
  227. package/dist/src/cliops.js.map +1 -0
  228. package/dist/src/clonedir.js +15 -0
  229. package/dist/src/clonedir.js.map +1 -0
  230. package/dist/src/commandeffects.js +43 -0
  231. package/dist/src/commandeffects.js.map +1 -0
  232. package/dist/src/commands.js +1312 -0
  233. package/dist/src/commands.js.map +1 -0
  234. package/dist/src/companioninbox.js +203 -0
  235. package/dist/src/companioninbox.js.map +1 -0
  236. package/dist/src/compare.js +673 -0
  237. package/dist/src/compare.js.map +1 -0
  238. package/dist/src/config.js +1027 -0
  239. package/dist/src/config.js.map +1 -0
  240. package/dist/src/configcheck.js +111 -0
  241. package/dist/src/configcheck.js.map +1 -0
  242. package/dist/src/coreext.js +43 -0
  243. package/dist/src/coreext.js.map +1 -0
  244. package/dist/src/daemon.js +929 -0
  245. package/dist/src/daemon.js.map +1 -0
  246. package/dist/src/debuground.js +731 -0
  247. package/dist/src/debuground.js.map +1 -0
  248. package/dist/src/debugroundpi.js +219 -0
  249. package/dist/src/debugroundpi.js.map +1 -0
  250. package/dist/src/diagnostics.js +14 -0
  251. package/dist/src/diagnostics.js.map +1 -0
  252. package/dist/src/digest.js +139 -0
  253. package/dist/src/digest.js.map +1 -0
  254. package/dist/src/dispatch.js +1726 -0
  255. package/dist/src/dispatch.js.map +1 -0
  256. package/dist/src/engine/answerguard.js +18 -0
  257. package/dist/src/engine/answerguard.js.map +1 -0
  258. package/dist/src/engine/botsdk.js +262 -0
  259. package/dist/src/engine/botsdk.js.map +1 -0
  260. package/dist/src/engine/caserunner-sdk.js +332 -0
  261. package/dist/src/engine/caserunner-sdk.js.map +1 -0
  262. package/dist/src/engine/debugpi.js +194 -0
  263. package/dist/src/engine/debugpi.js.map +1 -0
  264. package/dist/src/eod.js +473 -0
  265. package/dist/src/eod.js.map +1 -0
  266. package/dist/src/eodpinwatch.js +391 -0
  267. package/dist/src/eodpinwatch.js.map +1 -0
  268. package/dist/src/escalation.js +1009 -0
  269. package/dist/src/escalation.js.map +1 -0
  270. package/dist/src/eventloop.js +779 -0
  271. package/dist/src/eventloop.js.map +1 -0
  272. package/dist/src/execboundary.js +430 -0
  273. package/dist/src/execboundary.js.map +1 -0
  274. package/dist/src/feedback.js +915 -0
  275. package/dist/src/feedback.js.map +1 -0
  276. package/dist/src/findingscheck.js +200 -0
  277. package/dist/src/findingscheck.js.map +1 -0
  278. package/dist/src/fsdenied.js +26 -0
  279. package/dist/src/fsdenied.js.map +1 -0
  280. package/dist/src/ghread.js +181 -0
  281. package/dist/src/ghread.js.map +1 -0
  282. package/dist/src/github.js +1063 -0
  283. package/dist/src/github.js.map +1 -0
  284. package/dist/src/homes.js +103 -0
  285. package/dist/src/homes.js.map +1 -0
  286. package/dist/src/hostroute.js +24 -0
  287. package/dist/src/hostroute.js.map +1 -0
  288. package/dist/src/improvements.js +625 -0
  289. package/dist/src/improvements.js.map +1 -0
  290. package/dist/src/install.js +946 -0
  291. package/dist/src/install.js.map +1 -0
  292. package/dist/src/installkind.js +40 -0
  293. package/dist/src/installkind.js.map +1 -0
  294. package/dist/src/ipc/capability.js +286 -0
  295. package/dist/src/ipc/capability.js.map +1 -0
  296. package/dist/src/ipc/client.js +226 -0
  297. package/dist/src/ipc/client.js.map +1 -0
  298. package/dist/src/ipc/control.js +70 -0
  299. package/dist/src/ipc/control.js.map +1 -0
  300. package/dist/src/ipc/ghreadshim.js +77 -0
  301. package/dist/src/ipc/ghreadshim.js.map +1 -0
  302. package/dist/src/ipc/launcher.js +65 -0
  303. package/dist/src/ipc/launcher.js.map +1 -0
  304. package/dist/src/ipc/permits.js +293 -0
  305. package/dist/src/ipc/permits.js.map +1 -0
  306. package/dist/src/ipc/postshim.js +137 -0
  307. package/dist/src/ipc/postshim.js.map +1 -0
  308. package/dist/src/ipc/protocol.js +239 -0
  309. package/dist/src/ipc/protocol.js.map +1 -0
  310. package/dist/src/ipc/server.js +312 -0
  311. package/dist/src/ipc/server.js.map +1 -0
  312. package/dist/src/ipc/workerspec.js +148 -0
  313. package/dist/src/ipc/workerspec.js.map +1 -0
  314. package/dist/src/learner/learner.js +1272 -0
  315. package/dist/src/learner/learner.js.map +1 -0
  316. package/dist/src/learner/miner.js +948 -0
  317. package/dist/src/learner/miner.js.map +1 -0
  318. package/dist/src/learner/packet.js +216 -0
  319. package/dist/src/learner/packet.js.map +1 -0
  320. package/dist/src/learner/receipt.js +135 -0
  321. package/dist/src/learner/receipt.js.map +1 -0
  322. package/dist/src/learner/status.js +38 -0
  323. package/dist/src/learner/status.js.map +1 -0
  324. package/dist/src/ledgercheck.js +120 -0
  325. package/dist/src/ledgercheck.js.map +1 -0
  326. package/dist/src/lessonledger.js +451 -0
  327. package/dist/src/lessonledger.js.map +1 -0
  328. package/dist/src/lessonselect.js +639 -0
  329. package/dist/src/lessonselect.js.map +1 -0
  330. package/dist/src/lessonshadow.js +540 -0
  331. package/dist/src/lessonshadow.js.map +1 -0
  332. package/dist/src/levers.js +302 -0
  333. package/dist/src/levers.js.map +1 -0
  334. package/dist/src/live/projection.js +450 -0
  335. package/dist/src/live/projection.js.map +1 -0
  336. package/dist/src/live/publish.js +83 -0
  337. package/dist/src/live/publish.js.map +1 -0
  338. package/dist/src/live/read.js +60 -0
  339. package/dist/src/live/read.js.map +1 -0
  340. package/dist/src/livecli.js +288 -0
  341. package/dist/src/livecli.js.map +1 -0
  342. package/dist/src/loginhint.js +42 -0
  343. package/dist/src/loginhint.js.map +1 -0
  344. package/dist/src/loginrefresh/atomic.js +66 -0
  345. package/dist/src/loginrefresh/atomic.js.map +1 -0
  346. package/dist/src/loginrefresh/lock.js +93 -0
  347. package/dist/src/loginrefresh/lock.js.map +1 -0
  348. package/dist/src/loginrefresh/main.js +58 -0
  349. package/dist/src/loginrefresh/main.js.map +1 -0
  350. package/dist/src/loginrefresh/pirefresh.js +49 -0
  351. package/dist/src/loginrefresh/pirefresh.js.map +1 -0
  352. package/dist/src/loginrefresh/refresher.js +286 -0
  353. package/dist/src/loginrefresh/refresher.js.map +1 -0
  354. package/dist/src/loginrefresh/supervisor.js +253 -0
  355. package/dist/src/loginrefresh/supervisor.js.map +1 -0
  356. package/dist/src/loginrefresh/types.js +4 -0
  357. package/dist/src/loginrefresh/types.js.map +1 -0
  358. package/dist/src/memory/context.js +251 -0
  359. package/dist/src/memory/context.js.map +1 -0
  360. package/dist/src/memory/datafence.js +5 -0
  361. package/dist/src/memory/datafence.js.map +1 -0
  362. package/dist/src/memory/delivery.js +131 -0
  363. package/dist/src/memory/delivery.js.map +1 -0
  364. package/dist/src/memory/eventtags.js +81 -0
  365. package/dist/src/memory/eventtags.js.map +1 -0
  366. package/dist/src/memory/health.js +713 -0
  367. package/dist/src/memory/health.js.map +1 -0
  368. package/dist/src/memory/import.js +504 -0
  369. package/dist/src/memory/import.js.map +1 -0
  370. package/dist/src/memory/layout.js +252 -0
  371. package/dist/src/memory/layout.js.map +1 -0
  372. package/dist/src/memory/legacy-file.js +100 -0
  373. package/dist/src/memory/legacy-file.js.map +1 -0
  374. package/dist/src/memory/lessons.js +370 -0
  375. package/dist/src/memory/lessons.js.map +1 -0
  376. package/dist/src/memory/ovsession.js +449 -0
  377. package/dist/src/memory/ovsession.js.map +1 -0
  378. package/dist/src/memory/relayout.js +259 -0
  379. package/dist/src/memory/relayout.js.map +1 -0
  380. package/dist/src/memory/roundactivity.js +180 -0
  381. package/dist/src/memory/roundactivity.js.map +1 -0
  382. package/dist/src/memory/selection.js +690 -0
  383. package/dist/src/memory/selection.js.map +1 -0
  384. package/dist/src/memory/shadowstatus.js +69 -0
  385. package/dist/src/memory/shadowstatus.js.map +1 -0
  386. package/dist/src/memory/store.js +83 -0
  387. package/dist/src/memory/store.js.map +1 -0
  388. package/dist/src/memory/textidentity.js +8 -0
  389. package/dist/src/memory/textidentity.js.map +1 -0
  390. package/dist/src/metrics.js +773 -0
  391. package/dist/src/metrics.js.map +1 -0
  392. package/dist/src/missingconfig.js +8 -0
  393. package/dist/src/missingconfig.js.map +1 -0
  394. package/dist/src/npmverbs.js +226 -0
  395. package/dist/src/npmverbs.js.map +1 -0
  396. package/dist/src/onboard/choices.js +191 -0
  397. package/dist/src/onboard/choices.js.map +1 -0
  398. package/dist/src/onboard/engine.js +344 -0
  399. package/dist/src/onboard/engine.js.map +1 -0
  400. package/dist/src/onboard/launch.js +83 -0
  401. package/dist/src/onboard/launch.js.map +1 -0
  402. package/dist/src/onboard/steps/appslug.js +211 -0
  403. package/dist/src/onboard/steps/appslug.js.map +1 -0
  404. package/dist/src/onboard/steps/bringup.js +408 -0
  405. package/dist/src/onboard/steps/bringup.js.map +1 -0
  406. package/dist/src/onboard/steps/compose.js +343 -0
  407. package/dist/src/onboard/steps/compose.js.map +1 -0
  408. package/dist/src/onboard/steps/configdelivery.js +50 -0
  409. package/dist/src/onboard/steps/configdelivery.js.map +1 -0
  410. package/dist/src/onboard/steps/configfill.js +1148 -0
  411. package/dist/src/onboard/steps/configfill.js.map +1 -0
  412. package/dist/src/onboard/steps/deploysh.js +80 -0
  413. package/dist/src/onboard/steps/deploysh.js.map +1 -0
  414. package/dist/src/onboard/steps/embeddings.js +472 -0
  415. package/dist/src/onboard/steps/embeddings.js.map +1 -0
  416. package/dist/src/onboard/steps/escalation.js +571 -0
  417. package/dist/src/onboard/steps/escalation.js.map +1 -0
  418. package/dist/src/onboard/steps/githubapp.js +1092 -0
  419. package/dist/src/onboard/steps/githubapp.js.map +1 -0
  420. package/dist/src/onboard/steps/golive.js +506 -0
  421. package/dist/src/onboard/steps/golive.js.map +1 -0
  422. package/dist/src/onboard/steps/index.js +67 -0
  423. package/dist/src/onboard/steps/index.js.map +1 -0
  424. package/dist/src/onboard/steps/ingress.js +762 -0
  425. package/dist/src/onboard/steps/ingress.js.map +1 -0
  426. package/dist/src/onboard/steps/inventory.js +420 -0
  427. package/dist/src/onboard/steps/inventory.js.map +1 -0
  428. package/dist/src/onboard/steps/llmauth.js +893 -0
  429. package/dist/src/onboard/steps/llmauth.js.map +1 -0
  430. package/dist/src/onboard/steps/memory.js +1060 -0
  431. package/dist/src/onboard/steps/memory.js.map +1 -0
  432. package/dist/src/onboard/steps/memorykeys.js +43 -0
  433. package/dist/src/onboard/steps/memorykeys.js.map +1 -0
  434. package/dist/src/onboard/steps/preflight.js +172 -0
  435. package/dist/src/onboard/steps/preflight.js.map +1 -0
  436. package/dist/src/onboard/steps/proof.js +502 -0
  437. package/dist/src/onboard/steps/proof.js.map +1 -0
  438. package/dist/src/onboard/steps/ssh.js +300 -0
  439. package/dist/src/onboard/steps/ssh.js.map +1 -0
  440. package/dist/src/onboard/steps/topology.js +291 -0
  441. package/dist/src/onboard/steps/topology.js.map +1 -0
  442. package/dist/src/onboard/steps/transport.js +511 -0
  443. package/dist/src/onboard/steps/transport.js.map +1 -0
  444. package/dist/src/onboard/steps/verifyup.js +362 -0
  445. package/dist/src/onboard/steps/verifyup.js.map +1 -0
  446. package/dist/src/onboard/steps/vmdeploy.js +368 -0
  447. package/dist/src/onboard/steps/vmdeploy.js.map +1 -0
  448. package/dist/src/onboard/toml.js +53 -0
  449. package/dist/src/onboard/toml.js.map +1 -0
  450. package/dist/src/opencli.js +508 -0
  451. package/dist/src/opencli.js.map +1 -0
  452. package/dist/src/openpr.js +457 -0
  453. package/dist/src/openpr.js.map +1 -0
  454. package/dist/src/openviking/client.js +821 -0
  455. package/dist/src/openviking/client.js.map +1 -0
  456. package/dist/src/openviking/context.js +218 -0
  457. package/dist/src/openviking/context.js.map +1 -0
  458. package/dist/src/openviking/embedder.js +457 -0
  459. package/dist/src/openviking/embedder.js.map +1 -0
  460. package/dist/src/openviking/gapsink.js +38 -0
  461. package/dist/src/openviking/gapsink.js.map +1 -0
  462. package/dist/src/openviking/health.js +69 -0
  463. package/dist/src/openviking/health.js.map +1 -0
  464. package/dist/src/openviking/index.js +24 -0
  465. package/dist/src/openviking/index.js.map +1 -0
  466. package/dist/src/openviking/lessonfind.js +54 -0
  467. package/dist/src/openviking/lessonfind.js.map +1 -0
  468. package/dist/src/openviking/probe.js +89 -0
  469. package/dist/src/openviking/probe.js.map +1 -0
  470. package/dist/src/openviking/proc.js +95 -0
  471. package/dist/src/openviking/proc.js.map +1 -0
  472. package/dist/src/openviking/provisionreport.js +144 -0
  473. package/dist/src/openviking/provisionreport.js.map +1 -0
  474. package/dist/src/openviking/reembed.js +317 -0
  475. package/dist/src/openviking/reembed.js.map +1 -0
  476. package/dist/src/openviking/relayout.js +153 -0
  477. package/dist/src/openviking/relayout.js.map +1 -0
  478. package/dist/src/openviking/sidecar-main.js +39 -0
  479. package/dist/src/openviking/sidecar-main.js.map +1 -0
  480. package/dist/src/openviking/sidecar.js +79 -0
  481. package/dist/src/openviking/sidecar.js.map +1 -0
  482. package/dist/src/openviking/store.js +1758 -0
  483. package/dist/src/openviking/store.js.map +1 -0
  484. package/dist/src/openviking/supervisor.js +422 -0
  485. package/dist/src/openviking/supervisor.js.map +1 -0
  486. package/dist/src/openviking/types.js +5 -0
  487. package/dist/src/openviking/types.js.map +1 -0
  488. package/dist/src/operator-recovery.js +172 -0
  489. package/dist/src/operator-recovery.js.map +1 -0
  490. package/dist/src/operatormessage.js +44 -0
  491. package/dist/src/operatormessage.js.map +1 -0
  492. package/dist/src/outcomes.js +1361 -0
  493. package/dist/src/outcomes.js.map +1 -0
  494. package/dist/src/piauthcopy.js +5 -0
  495. package/dist/src/piauthcopy.js.map +1 -0
  496. package/dist/src/picli.js +45 -0
  497. package/dist/src/picli.js.map +1 -0
  498. package/dist/src/picwd.js +25 -0
  499. package/dist/src/picwd.js.map +1 -0
  500. package/dist/src/pilogin.js +35 -0
  501. package/dist/src/pilogin.js.map +1 -0
  502. package/dist/src/pingpong.js +1028 -0
  503. package/dist/src/pingpong.js.map +1 -0
  504. package/dist/src/posting-journal.js +441 -0
  505. package/dist/src/posting-journal.js.map +1 -0
  506. package/dist/src/posting-outbox.js +662 -0
  507. package/dist/src/posting-outbox.js.map +1 -0
  508. package/dist/src/posting-receipt.js +203 -0
  509. package/dist/src/posting-receipt.js.map +1 -0
  510. package/dist/src/posting.js +348 -0
  511. package/dist/src/posting.js.map +1 -0
  512. package/dist/src/postops.js +637 -0
  513. package/dist/src/postops.js.map +1 -0
  514. package/dist/src/pr-activity.js +11 -0
  515. package/dist/src/pr-activity.js.map +1 -0
  516. package/dist/src/pr-author.js +5 -0
  517. package/dist/src/pr-author.js.map +1 -0
  518. package/dist/src/pr-conversation.js +355 -0
  519. package/dist/src/pr-conversation.js.map +1 -0
  520. package/dist/src/pr-session-lifecycle.js +542 -0
  521. package/dist/src/pr-session-lifecycle.js.map +1 -0
  522. package/dist/src/preflight.js +341 -0
  523. package/dist/src/preflight.js.map +1 -0
  524. package/dist/src/priorresolve.js +275 -0
  525. package/dist/src/priorresolve.js.map +1 -0
  526. package/dist/src/qcrbin.js +180 -0
  527. package/dist/src/qcrbin.js.map +1 -0
  528. package/dist/src/recheck.js +1398 -0
  529. package/dist/src/recheck.js.map +1 -0
  530. package/dist/src/reconcile.js +820 -0
  531. package/dist/src/reconcile.js.map +1 -0
  532. package/dist/src/recordedfindings.js +15 -0
  533. package/dist/src/recordedfindings.js.map +1 -0
  534. package/dist/src/regression.js +546 -0
  535. package/dist/src/regression.js.map +1 -0
  536. package/dist/src/replay.js +598 -0
  537. package/dist/src/replay.js.map +1 -0
  538. package/dist/src/requiredpasses.js +113 -0
  539. package/dist/src/requiredpasses.js.map +1 -0
  540. package/dist/src/resumecheck.js +168 -0
  541. package/dist/src/resumecheck.js.map +1 -0
  542. package/dist/src/reviewcli.js +671 -0
  543. package/dist/src/reviewcli.js.map +1 -0
  544. package/dist/src/reviewcontext.js +22 -0
  545. package/dist/src/reviewcontext.js.map +1 -0
  546. package/dist/src/reviewdetach.js +574 -0
  547. package/dist/src/reviewdetach.js.map +1 -0
  548. package/dist/src/reviewhistory.js +284 -0
  549. package/dist/src/reviewhistory.js.map +1 -0
  550. package/dist/src/reviewhome.js +26 -0
  551. package/dist/src/reviewhome.js.map +1 -0
  552. package/dist/src/reviewmemory.js +110 -0
  553. package/dist/src/reviewmemory.js.map +1 -0
  554. package/dist/src/reviewrendercli.js +104 -0
  555. package/dist/src/reviewrendercli.js.map +1 -0
  556. package/dist/src/round-work.js +20 -0
  557. package/dist/src/round-work.js.map +1 -0
  558. package/dist/src/runhost.js +72 -0
  559. package/dist/src/runhost.js.map +1 -0
  560. package/dist/src/scanauth.js +25 -0
  561. package/dist/src/scanauth.js.map +1 -0
  562. package/dist/src/scanbox.js +846 -0
  563. package/dist/src/scanbox.js.map +1 -0
  564. package/dist/src/scancli.js +1074 -0
  565. package/dist/src/scancli.js.map +1 -0
  566. package/dist/src/scandriverlog.js +30 -0
  567. package/dist/src/scandriverlog.js.map +1 -0
  568. package/dist/src/session-bridge.js +75 -0
  569. package/dist/src/session-bridge.js.map +1 -0
  570. package/dist/src/session-command-payload.js +29 -0
  571. package/dist/src/session-command-payload.js.map +1 -0
  572. package/dist/src/session-command-supervisor.js +939 -0
  573. package/dist/src/session-command-supervisor.js.map +1 -0
  574. package/dist/src/sessionjsonl.js +85 -0
  575. package/dist/src/sessionjsonl.js.map +1 -0
  576. package/dist/src/sessions.js +541 -0
  577. package/dist/src/sessions.js.map +1 -0
  578. package/dist/src/setup/adapters.js +330 -0
  579. package/dist/src/setup/adapters.js.map +1 -0
  580. package/dist/src/setup/baselines.js +64 -0
  581. package/dist/src/setup/baselines.js.map +1 -0
  582. package/dist/src/setup/caserunner.js +554 -0
  583. package/dist/src/setup/caserunner.js.map +1 -0
  584. package/dist/src/setup/configcommit.js +358 -0
  585. package/dist/src/setup/configcommit.js.map +1 -0
  586. package/dist/src/setup/engine.js +672 -0
  587. package/dist/src/setup/engine.js.map +1 -0
  588. package/dist/src/setup/facts.js +593 -0
  589. package/dist/src/setup/facts.js.map +1 -0
  590. package/dist/src/setup/findings.js +948 -0
  591. package/dist/src/setup/findings.js.map +1 -0
  592. package/dist/src/setup/history.js +338 -0
  593. package/dist/src/setup/history.js.map +1 -0
  594. package/dist/src/setup/interview.js +185 -0
  595. package/dist/src/setup/interview.js.map +1 -0
  596. package/dist/src/setup/ledger.js +207 -0
  597. package/dist/src/setup/ledger.js.map +1 -0
  598. package/dist/src/setup/pins.js +43 -0
  599. package/dist/src/setup/pins.js.map +1 -0
  600. package/dist/src/setup/portrait.js +432 -0
  601. package/dist/src/setup/portrait.js.map +1 -0
  602. package/dist/src/setup/presentation.js +9 -0
  603. package/dist/src/setup/presentation.js.map +1 -0
  604. package/dist/src/setup/profile.js +417 -0
  605. package/dist/src/setup/profile.js.map +1 -0
  606. package/dist/src/setup/replay.js +240 -0
  607. package/dist/src/setup/replay.js.map +1 -0
  608. package/dist/src/setup/replaybuild.js +311 -0
  609. package/dist/src/setup/replaybuild.js.map +1 -0
  610. package/dist/src/setup/replayrun.js +806 -0
  611. package/dist/src/setup/replayrun.js.map +1 -0
  612. package/dist/src/setup/replaysource.js +169 -0
  613. package/dist/src/setup/replaysource.js.map +1 -0
  614. package/dist/src/setup/retune.js +333 -0
  615. package/dist/src/setup/retune.js.map +1 -0
  616. package/dist/src/setup/retunelog.js +51 -0
  617. package/dist/src/setup/retunelog.js.map +1 -0
  618. package/dist/src/setup/scan.js +725 -0
  619. package/dist/src/setup/scan.js.map +1 -0
  620. package/dist/src/setup/scanbuild.js +133 -0
  621. package/dist/src/setup/scanbuild.js.map +1 -0
  622. package/dist/src/setup/scanfacts.js +96 -0
  623. package/dist/src/setup/scanfacts.js.map +1 -0
  624. package/dist/src/setup/scanlease.js +251 -0
  625. package/dist/src/setup/scanlease.js.map +1 -0
  626. package/dist/src/setup/scanreport.js +289 -0
  627. package/dist/src/setup/scanreport.js.map +1 -0
  628. package/dist/src/setup/scanrun.js +1733 -0
  629. package/dist/src/setup/scanrun.js.map +1 -0
  630. package/dist/src/setup/scantree.js +257 -0
  631. package/dist/src/setup/scantree.js.map +1 -0
  632. package/dist/src/setup/stage2.js +617 -0
  633. package/dist/src/setup/stage2.js.map +1 -0
  634. package/dist/src/setup/stage2request.js +259 -0
  635. package/dist/src/setup/stage2request.js.map +1 -0
  636. package/dist/src/setup/survey.js +307 -0
  637. package/dist/src/setup/survey.js.map +1 -0
  638. package/dist/src/setup/surveyrun.js +549 -0
  639. package/dist/src/setup/surveyrun.js.map +1 -0
  640. package/dist/src/setup/textsniff.js +89 -0
  641. package/dist/src/setup/textsniff.js.map +1 -0
  642. package/dist/src/setup/trackersink.js +395 -0
  643. package/dist/src/setup/trackersink.js.map +1 -0
  644. package/dist/src/setup/triage.js +636 -0
  645. package/dist/src/setup/triage.js.map +1 -0
  646. package/dist/src/setup/tuning.js +585 -0
  647. package/dist/src/setup/tuning.js.map +1 -0
  648. package/dist/src/setup/unitcut.js +437 -0
  649. package/dist/src/setup/unitcut.js.map +1 -0
  650. package/dist/src/singleflight.js +72 -0
  651. package/dist/src/singleflight.js.map +1 -0
  652. package/dist/src/slack/announce.js +725 -0
  653. package/dist/src/slack/announce.js.map +1 -0
  654. package/dist/src/slack/api.js +227 -0
  655. package/dist/src/slack/api.js.map +1 -0
  656. package/dist/src/slack/messages.js +158 -0
  657. package/dist/src/slack/messages.js.map +1 -0
  658. package/dist/src/slack/origin.js +550 -0
  659. package/dist/src/slack/origin.js.map +1 -0
  660. package/dist/src/slack/policy.js +225 -0
  661. package/dist/src/slack/policy.js.map +1 -0
  662. package/dist/src/slack/reply.js +153 -0
  663. package/dist/src/slack/reply.js.map +1 -0
  664. package/dist/src/slack/router.js +189 -0
  665. package/dist/src/slack/router.js.map +1 -0
  666. package/dist/src/slack/socket.js +323 -0
  667. package/dist/src/slack/socket.js.map +1 -0
  668. package/dist/src/slack/types.js +11 -0
  669. package/dist/src/slack/types.js.map +1 -0
  670. package/dist/src/sqlitehint.js +30 -0
  671. package/dist/src/sqlitehint.js.map +1 -0
  672. package/dist/src/ssh-observation.js +25 -0
  673. package/dist/src/ssh-observation.js.map +1 -0
  674. package/dist/src/state.js +5869 -0
  675. package/dist/src/state.js.map +1 -0
  676. package/dist/src/statemachine.js +220 -0
  677. package/dist/src/statemachine.js.map +1 -0
  678. package/dist/src/stubs.js +52 -0
  679. package/dist/src/stubs.js.map +1 -0
  680. package/dist/src/takeover.js +506 -0
  681. package/dist/src/takeover.js.map +1 -0
  682. package/dist/src/takeoverpi.js +249 -0
  683. package/dist/src/takeoverpi.js.map +1 -0
  684. package/dist/src/terminal-failure.js +26 -0
  685. package/dist/src/terminal-failure.js.map +1 -0
  686. package/dist/src/thread-resolution-refusal.js +4 -0
  687. package/dist/src/thread-resolution-refusal.js.map +1 -0
  688. package/dist/src/tmux.js +126 -0
  689. package/dist/src/tmux.js.map +1 -0
  690. package/dist/src/trackerid.js +43 -0
  691. package/dist/src/trackerid.js.map +1 -0
  692. package/dist/src/transcriptindex.js +512 -0
  693. package/dist/src/transcriptindex.js.map +1 -0
  694. package/dist/src/tui/actions.js +404 -0
  695. package/dist/src/tui/actions.js.map +1 -0
  696. package/dist/src/tui/alerts.js +523 -0
  697. package/dist/src/tui/alerts.js.map +1 -0
  698. package/dist/src/tui/app.js +1835 -0
  699. package/dist/src/tui/app.js.map +1 -0
  700. package/dist/src/tui/archiveops.js +164 -0
  701. package/dist/src/tui/archiveops.js.map +1 -0
  702. package/dist/src/tui/autofile.js +191 -0
  703. package/dist/src/tui/autofile.js.map +1 -0
  704. package/dist/src/tui/board.js +1143 -0
  705. package/dist/src/tui/board.js.map +1 -0
  706. package/dist/src/tui/candidates.js +699 -0
  707. package/dist/src/tui/candidates.js.map +1 -0
  708. package/dist/src/tui/cellwidth.js +151 -0
  709. package/dist/src/tui/cellwidth.js.map +1 -0
  710. package/dist/src/tui/changelog-store.js +404 -0
  711. package/dist/src/tui/changelog-store.js.map +1 -0
  712. package/dist/src/tui/chord.js +26 -0
  713. package/dist/src/tui/chord.js.map +1 -0
  714. package/dist/src/tui/clipboard.js +81 -0
  715. package/dist/src/tui/clipboard.js.map +1 -0
  716. package/dist/src/tui/cmdbar.js +253 -0
  717. package/dist/src/tui/cmdbar.js.map +1 -0
  718. package/dist/src/tui/companion.js +1275 -0
  719. package/dist/src/tui/companion.js.map +1 -0
  720. package/dist/src/tui/companionplan.js +200 -0
  721. package/dist/src/tui/companionplan.js.map +1 -0
  722. package/dist/src/tui/companiontab.js +61 -0
  723. package/dist/src/tui/companiontab.js.map +1 -0
  724. package/dist/src/tui/confighome.js +105 -0
  725. package/dist/src/tui/confighome.js.map +1 -0
  726. package/dist/src/tui/connect.js +44 -0
  727. package/dist/src/tui/connect.js.map +1 -0
  728. package/dist/src/tui/deploy-ceremony.js +75 -0
  729. package/dist/src/tui/deploy-ceremony.js.map +1 -0
  730. package/dist/src/tui/deploy-drain.js +93 -0
  731. package/dist/src/tui/deploy-drain.js.map +1 -0
  732. package/dist/src/tui/deploy-process.js +234 -0
  733. package/dist/src/tui/deploy-process.js.map +1 -0
  734. package/dist/src/tui/deploytab.js +1263 -0
  735. package/dist/src/tui/deploytab.js.map +1 -0
  736. package/dist/src/tui/design.js +111 -0
  737. package/dist/src/tui/design.js.map +1 -0
  738. package/dist/src/tui/digesttab.js +148 -0
  739. package/dist/src/tui/digesttab.js.map +1 -0
  740. package/dist/src/tui/emptystate.js +32 -0
  741. package/dist/src/tui/emptystate.js.map +1 -0
  742. package/dist/src/tui/evidence.js +790 -0
  743. package/dist/src/tui/evidence.js.map +1 -0
  744. package/dist/src/tui/feed.js +415 -0
  745. package/dist/src/tui/feed.js.map +1 -0
  746. package/dist/src/tui/feedbacktab.js +907 -0
  747. package/dist/src/tui/feedbacktab.js.map +1 -0
  748. package/dist/src/tui/filters.js +72 -0
  749. package/dist/src/tui/filters.js.map +1 -0
  750. package/dist/src/tui/ghread.js +272 -0
  751. package/dist/src/tui/ghread.js.map +1 -0
  752. package/dist/src/tui/historypull.js +61 -0
  753. package/dist/src/tui/historypull.js.map +1 -0
  754. package/dist/src/tui/inboxpull.js +197 -0
  755. package/dist/src/tui/inboxpull.js.map +1 -0
  756. package/dist/src/tui/index.js +1425 -0
  757. package/dist/src/tui/index.js.map +1 -0
  758. package/dist/src/tui/issuesink.js +206 -0
  759. package/dist/src/tui/issuesink.js.map +1 -0
  760. package/dist/src/tui/jsonfile.js +32 -0
  761. package/dist/src/tui/jsonfile.js.map +1 -0
  762. package/dist/src/tui/keys.js +97 -0
  763. package/dist/src/tui/keys.js.map +1 -0
  764. package/dist/src/tui/layout.js +70 -0
  765. package/dist/src/tui/layout.js.map +1 -0
  766. package/dist/src/tui/learning.js +469 -0
  767. package/dist/src/tui/learning.js.map +1 -0
  768. package/dist/src/tui/lessonswitch.js +103 -0
  769. package/dist/src/tui/lessonswitch.js.map +1 -0
  770. package/dist/src/tui/livecontrol.js +167 -0
  771. package/dist/src/tui/livecontrol.js.map +1 -0
  772. package/dist/src/tui/memforward.js +310 -0
  773. package/dist/src/tui/memforward.js.map +1 -0
  774. package/dist/src/tui/memincident.js +287 -0
  775. package/dist/src/tui/memincident.js.map +1 -0
  776. package/dist/src/tui/memory.js +485 -0
  777. package/dist/src/tui/memory.js.map +1 -0
  778. package/dist/src/tui/memtab.js +513 -0
  779. package/dist/src/tui/memtab.js.map +1 -0
  780. package/dist/src/tui/metricstab.js +979 -0
  781. package/dist/src/tui/metricstab.js.map +1 -0
  782. package/dist/src/tui/model.js +104 -0
  783. package/dist/src/tui/model.js.map +1 -0
  784. package/dist/src/tui/mouse.js +83 -0
  785. package/dist/src/tui/mouse.js.map +1 -0
  786. package/dist/src/tui/msg.js +196 -0
  787. package/dist/src/tui/msg.js.map +1 -0
  788. package/dist/src/tui/nativecompanion.js +321 -0
  789. package/dist/src/tui/nativecompanion.js.map +1 -0
  790. package/dist/src/tui/openurl.js +17 -0
  791. package/dist/src/tui/openurl.js.map +1 -0
  792. package/dist/src/tui/paint.js +501 -0
  793. package/dist/src/tui/paint.js.map +1 -0
  794. package/dist/src/tui/panes.js +74 -0
  795. package/dist/src/tui/panes.js.map +1 -0
  796. package/dist/src/tui/pipane.js +166 -0
  797. package/dist/src/tui/pipane.js.map +1 -0
  798. package/dist/src/tui/poll-hooks.js +11 -0
  799. package/dist/src/tui/poll-hooks.js.map +1 -0
  800. package/dist/src/tui/poll.js +113 -0
  801. package/dist/src/tui/poll.js.map +1 -0
  802. package/dist/src/tui/proposals.js +715 -0
  803. package/dist/src/tui/proposals.js.map +1 -0
  804. package/dist/src/tui/prpause.js +132 -0
  805. package/dist/src/tui/prpause.js.map +1 -0
  806. package/dist/src/tui/reload.js +351 -0
  807. package/dist/src/tui/reload.js.map +1 -0
  808. package/dist/src/tui/remote.js +312 -0
  809. package/dist/src/tui/remote.js.map +1 -0
  810. package/dist/src/tui/rollover.js +767 -0
  811. package/dist/src/tui/rollover.js.map +1 -0
  812. package/dist/src/tui/scantab.js +1053 -0
  813. package/dist/src/tui/scantab.js.map +1 -0
  814. package/dist/src/tui/setupentry.js +81 -0
  815. package/dist/src/tui/setupentry.js.map +1 -0
  816. package/dist/src/tui/sidebar.js +602 -0
  817. package/dist/src/tui/sidebar.js.map +1 -0
  818. package/dist/src/tui/sshtriage.js +393 -0
  819. package/dist/src/tui/sshtriage.js.map +1 -0
  820. package/dist/src/tui/startup.js +172 -0
  821. package/dist/src/tui/startup.js.map +1 -0
  822. package/dist/src/tui/tabs.js +41 -0
  823. package/dist/src/tui/tabs.js.map +1 -0
  824. package/dist/src/tui/termmirror.js +217 -0
  825. package/dist/src/tui/termmirror.js.map +1 -0
  826. package/dist/src/tui/theme.js +95 -0
  827. package/dist/src/tui/theme.js.map +1 -0
  828. package/dist/src/tui/ticketstab.js +224 -0
  829. package/dist/src/tui/ticketstab.js.map +1 -0
  830. package/dist/src/tui/tmuxsocket.js +101 -0
  831. package/dist/src/tui/tmuxsocket.js.map +1 -0
  832. package/dist/src/tui/trackertickets.js +77 -0
  833. package/dist/src/tui/trackertickets.js.map +1 -0
  834. package/dist/src/tui/unwedge.js +245 -0
  835. package/dist/src/tui/unwedge.js.map +1 -0
  836. package/dist/src/tui/viewer.js +479 -0
  837. package/dist/src/tui/viewer.js.map +1 -0
  838. package/dist/src/tui/viewerinput.js +125 -0
  839. package/dist/src/tui/viewerinput.js.map +1 -0
  840. package/dist/src/updatenotice.js +143 -0
  841. package/dist/src/updatenotice.js.map +1 -0
  842. package/dist/src/usage.js +1007 -0
  843. package/dist/src/usage.js.map +1 -0
  844. package/dist/src/verdicts.js +3848 -0
  845. package/dist/src/verdicts.js.map +1 -0
  846. package/dist/src/version.js +58 -0
  847. package/dist/src/version.js.map +1 -0
  848. package/dist/src/wakes.js +411 -0
  849. package/dist/src/wakes.js.map +1 -0
  850. package/dist/src/webhook.js +725 -0
  851. package/dist/src/webhook.js.map +1 -0
  852. package/dist/src/webhookheal.js +238 -0
  853. package/dist/src/webhookheal.js.map +1 -0
  854. package/dist/src/wire.js +1801 -0
  855. package/dist/src/wire.js.map +1 -0
  856. package/dist/src/worker-session-host.js +531 -0
  857. package/dist/src/worker-session-host.js.map +1 -0
  858. package/dist/src/workerbreaker.js +112 -0
  859. package/dist/src/workerbreaker.js.map +1 -0
  860. package/dist/src/workercontrol.js +49 -0
  861. package/dist/src/workercontrol.js.map +1 -0
  862. package/dist/src/workerlease.js +351 -0
  863. package/dist/src/workerlease.js.map +1 -0
  864. package/dist/src/workerliveness.js +84 -0
  865. package/dist/src/workerliveness.js.map +1 -0
  866. package/dist/src/workerlog.js +65 -0
  867. package/dist/src/workerlog.js.map +1 -0
  868. package/dist/src/workerruntime.js +10 -0
  869. package/dist/src/workerruntime.js.map +1 -0
  870. package/dist/src/workersupervisor.js +1206 -0
  871. package/dist/src/workersupervisor.js.map +1 -0
  872. package/dist/src/workerusage.js +23 -0
  873. package/dist/src/workerusage.js.map +1 -0
  874. package/dist/src/workerworld.js +332 -0
  875. package/dist/src/workerworld.js.map +1 -0
  876. package/dist/src/worktrees.js +984 -0
  877. package/dist/src/worktrees.js.map +1 -0
  878. package/docker/Dockerfile +284 -0
  879. package/docker/Dockerfile.dockerignore +35 -0
  880. package/docker/README.md +221 -0
  881. package/docker/companion/Dockerfile +139 -0
  882. package/docker/companion/agents/evidence.md +34 -0
  883. package/docker/companion/agents/explore.md +26 -0
  884. package/docker/companion/agents/pass-survey.md +49 -0
  885. package/docker/companion/agents/study.md +26 -0
  886. package/docker/companion/entrypoint.sh +343 -0
  887. package/docker/companion/memory-health.mjs +269 -0
  888. package/docker/entrypoint.sh +782 -0
  889. package/docker/memory/Dockerfile +191 -0
  890. package/docker/memory/Dockerfile.dockerignore +20 -0
  891. package/docker/memory/README.md +60 -0
  892. package/docker/memory/entrypoint.sh +163 -0
  893. package/docker/setid/qcr-setid.c +109 -0
  894. package/docker/tunnel/Dockerfile.cloudflared +51 -0
  895. package/docker/tunnel/Dockerfile.ngrok +40 -0
  896. package/docker/tunnel/sidecar.mjs +411 -0
  897. package/docker/vm/tmux.conf +26 -0
  898. package/docker-compose.yml +348 -0
  899. package/extensions/cli/bash-guard-ambient.ts +71 -0
  900. package/extensions/cli/bash-guard.ts +12 -0
  901. package/extensions/cli/companion-guard.ts +8 -0
  902. package/extensions/cli/debug-round.ts +9 -0
  903. package/extensions/cli/inject-bridge.ts +8 -0
  904. package/extensions/cli/ledger-pin.ts +13 -0
  905. package/extensions/cli/lens.ts +22 -0
  906. package/extensions/cli/muted-theme.ts +9 -0
  907. package/extensions/cli/onboarding.ts +8 -0
  908. package/extensions/cli/setup.ts +8 -0
  909. package/extensions/cli/tui-view.ts +8 -0
  910. package/extensions/companion-guard.ts +411 -0
  911. package/extensions/debug-round.ts +281 -0
  912. package/extensions/inject-bridge.ts +630 -0
  913. package/extensions/inline-bash.ts +102 -0
  914. package/extensions/muted-theme.json +68 -0
  915. package/extensions/muted-theme.ts +23 -0
  916. package/extensions/onboarding.ts +233 -0
  917. package/extensions/setup-replay.ts +336 -0
  918. package/extensions/setup-scan.ts +1236 -0
  919. package/extensions/setup-triage.ts +190 -0
  920. package/extensions/setup.ts +1428 -0
  921. package/extensions/tui-view.ts +489 -0
  922. package/extensions/vendor/openviking-pi/LICENSE +201 -0
  923. package/extensions/vendor/openviking-pi/NOTICE +68 -0
  924. package/extensions/vendor/openviking-pi/README.md +550 -0
  925. package/extensions/vendor/openviking-pi/client.ts +588 -0
  926. package/extensions/vendor/openviking-pi/config.json +28 -0
  927. package/extensions/vendor/openviking-pi/config.ts +271 -0
  928. package/extensions/vendor/openviking-pi/index.ts +523 -0
  929. package/extensions/vendor/openviking-pi/lib/capture-adapter.d.mts +10 -0
  930. package/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +88 -0
  931. package/extensions/vendor/openviking-pi/lib/takeover-core.d.mts +80 -0
  932. package/extensions/vendor/openviking-pi/lib/takeover-core.mjs +406 -0
  933. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.d.mts +1 -0
  934. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +42 -0
  935. package/extensions/vendor/openviking-pi/patches/0000-vendoring-and-build-conformance.patch +726 -0
  936. package/extensions/vendor/openviking-pi/patches/0001-remove-session-before-compact-handler.patch +101 -0
  937. package/extensions/vendor/openviking-pi/patches/0002-no-ambient-work-in-subagent-leaves.patch +202 -0
  938. package/extensions/vendor/openviking-pi/patches/0003-never-auto-create-openviking-sessions.patch +120 -0
  939. package/extensions/vendor/openviking-pi/patches/0004-viking-write-durable-batch-write.patch +521 -0
  940. package/extensions/vendor/openviking-pi/patches/0005-second-memory-namespace.patch +786 -0
  941. package/extensions/vendor/openviking-pi/patches/0006-writes-that-stick-and-honest-errors.patch +996 -0
  942. package/extensions/vendor/openviking-pi/patches/0007-bounded-recall-no-commit.patch +794 -0
  943. package/extensions/vendor/openviking-pi/patches/0008-pr-derived-recall.patch +379 -0
  944. package/extensions/vendor/openviking-pi/patches/0009-pr-session-tools-in-round-areas.patch +375 -0
  945. package/extensions/vendor/openviking-pi/patches/0010-typed-lessons.patch +448 -0
  946. package/extensions/vendor/openviking-pi/patches/0011-review-session-memory-boundary.patch +382 -0
  947. package/extensions/vendor/openviking-pi/patches/0012-typecheck-against-the-real-pi.patch +129 -0
  948. package/extensions/vendor/openviking-pi/patches/0013-createopenviking-factory.patch +1168 -0
  949. package/extensions/vendor/openviking-pi/qcr-hint.ts +313 -0
  950. package/extensions/vendor/openviking-pi/qcr-honest.ts +183 -0
  951. package/extensions/vendor/openviking-pi/qcr-hooks.ts +87 -0
  952. package/extensions/vendor/openviking-pi/qcr-leaf.ts +78 -0
  953. package/extensions/vendor/openviking-pi/qcr-lesson.ts +231 -0
  954. package/extensions/vendor/openviking-pi/qcr-namespaces.ts +198 -0
  955. package/extensions/vendor/openviking-pi/qcr-recall.ts +288 -0
  956. package/extensions/vendor/openviking-pi/qcr-shim.ts +142 -0
  957. package/extensions/vendor/openviking-pi/qcr-write.ts +427 -0
  958. package/extensions/vendor/openviking-pi/recall.ts +149 -0
  959. package/extensions/vendor/openviking-pi/shared/capture-utils.d.mts +9 -0
  960. package/extensions/vendor/openviking-pi/shared/capture-utils.mjs +515 -0
  961. package/extensions/vendor/openviking-pi/shared/credentials.d.mts +14 -0
  962. package/extensions/vendor/openviking-pi/shared/credentials.mjs +228 -0
  963. package/extensions/vendor/openviking-pi/shared/pending-queue.d.mts +19 -0
  964. package/extensions/vendor/openviking-pi/shared/pending-queue.mjs +458 -0
  965. package/extensions/vendor/openviking-pi/shared/profile-inject.d.mts +17 -0
  966. package/extensions/vendor/openviking-pi/shared/profile-inject.mjs +294 -0
  967. package/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +195 -0
  968. package/extensions/vendor/openviking-pi/shared/recall-core.d.mts +13 -0
  969. package/extensions/vendor/openviking-pi/shared/recall-core.mjs +609 -0
  970. package/extensions/vendor/openviking-pi/shared/retryable.mjs +9 -0
  971. package/extensions/vendor/openviking-pi/shared/session-model.d.mts +3 -0
  972. package/extensions/vendor/openviking-pi/shared/session-model.mjs +57 -0
  973. package/extensions/vendor/openviking-pi/shared/uri-guard.mjs +56 -0
  974. package/extensions/vendor/openviking-pi/shared/workspace-peer.d.mts +5 -0
  975. package/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  976. package/extensions/vendor/openviking-pi/sync.ts +163 -0
  977. package/extensions/vendor/openviking-pi/takeover.ts +36 -0
  978. package/extensions/vendor/openviking-pi/tools.ts +479 -0
  979. package/extensions/vendor/openviking-pi/upstream.json +48 -0
  980. package/package.json +138 -4
  981. package/profiles/default/README.md +21 -0
  982. package/profiles/default/addenda/.gitkeep +0 -0
  983. package/profiles/default/profile.toml +17 -0
  984. package/profiles/example-django/README.md +21 -0
  985. package/profiles/example-django/addenda/10-migration-discipline.md +13 -0
  986. package/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
  987. package/profiles/example-django/addenda/30-test-doctrine.md +12 -0
  988. package/profiles/example-django/addenda/40-orm-usage.md +19 -0
  989. package/profiles/example-django/addenda/50-declared-shape.md +10 -0
  990. package/profiles/example-django/addenda/60-config-placement.md +14 -0
  991. package/profiles/example-django/heuristics.toml +24 -0
  992. package/profiles/example-django/profile.toml +9 -0
  993. package/profiles/fast/README.md +24 -0
  994. package/profiles/fast/profile.toml +59 -0
  995. package/profiles/minimal/README.md +17 -0
  996. package/profiles/minimal/addenda/.gitkeep +0 -0
  997. package/profiles/minimal/profile.toml +8 -0
  998. package/profiles/snappy/README.md +24 -0
  999. package/profiles/snappy/addenda/10-race-as-question.md +6 -0
  1000. package/profiles/snappy/profile.toml +46 -0
  1001. package/prompts/companion-day-open.md +46 -0
  1002. package/prompts/companion-first-run.md +104 -0
  1003. package/prompts/companion.md +821 -0
  1004. package/prompts/conversation-system.md +117 -0
  1005. package/prompts/eod-sweep.md +120 -0
  1006. package/prompts/onboarding.md +74 -0
  1007. package/prompts/pass-common.md +52 -0
  1008. package/prompts/pass-quality-common.md +22 -0
  1009. package/prompts/round-first.md +874 -0
  1010. package/prompts/round-follow-up.md +991 -0
  1011. package/prompts/round-re-review.md +889 -0
  1012. package/prompts/round-recheck.md +196 -0
  1013. package/prompts/round-staleness.md +856 -0
  1014. package/schemas/review-result.v1.json +391 -0
  1015. package/schemas/scan-result.v1.json +421 -0
  1016. package/schemas/version.v1.json +57 -0
  1017. package/scripts/approve-pr.sh +16 -0
  1018. package/scripts/build-stamp.mjs +67 -0
  1019. package/scripts/commit-verdict.sh +155 -0
  1020. package/scripts/companion-e2e.sh +250 -0
  1021. package/scripts/companion-memory-forward.mjs +1966 -0
  1022. package/scripts/config-fingerprint.sh +28 -0
  1023. package/scripts/deploy-manifest.mjs +141 -0
  1024. package/scripts/deploy.sh +1435 -0
  1025. package/scripts/directory-lock.mjs +193 -0
  1026. package/scripts/heartbeat-fresh.mjs +54 -0
  1027. package/scripts/install-locator.sh +328 -0
  1028. package/scripts/install-wrapper.sh +76 -0
  1029. package/scripts/memory-search-check.mjs +98 -0
  1030. package/scripts/mint-token.sh +212 -0
  1031. package/scripts/openviking-embedder.py +392 -0
  1032. package/scripts/openviking-ov-conf.mjs +161 -0
  1033. package/scripts/openviking-provision.mjs +1122 -0
  1034. package/scripts/openviking-reembed.mjs +1154 -0
  1035. package/scripts/post-review.sh +16 -0
  1036. package/scripts/pr-checks.sh +256 -0
  1037. package/scripts/pr-context.py +174 -0
  1038. package/scripts/pr-context.sh +63 -0
  1039. package/scripts/pr-self.sh +144 -0
  1040. package/scripts/pr-threads.sh +145 -0
  1041. package/scripts/qcr +15 -0
  1042. package/scripts/qcr-host.sh +769 -0
  1043. package/scripts/render-review.sh +24 -0
  1044. package/scripts/reply-thread.sh +16 -0
  1045. package/scripts/required-passes.py +112 -0
  1046. package/scripts/smoke-companion.sh +211 -0
  1047. package/scripts/tui-deploy-runner.mjs +61 -0
  1048. package/scripts/verify-dist.mjs +201 -0
  1049. package/scripts/vm-ghcr-login.sh +188 -0
  1050. package/seeds/agents/pass-baseline.md +61 -0
  1051. package/seeds/agents/pass-contracts.md +30 -0
  1052. package/seeds/agents/pass-data-safety.md +54 -0
  1053. package/seeds/agents/pass-delivery.md +37 -0
  1054. package/seeds/agents/pass-prod-risk.md +24 -0
  1055. package/seeds/agents/pass-security.md +31 -0
  1056. package/seeds/agents/pass-statelessness.md +27 -0
  1057. package/seeds/agents/pass-ui.md +23 -0
  1058. package/seeds/agents/pass-validate.md +50 -0
  1059. package/seeds/prompts/conversation-system.md +117 -0
  1060. package/seeds/prompts/eod-sweep.md +120 -0
  1061. package/seeds/prompts/pass-common.md +52 -0
  1062. package/skills/companion/adjudicate/SKILL.md +247 -0
  1063. package/skills/companion/evidence/SKILL.md +150 -0
  1064. package/skills/companion/land/SKILL.md +200 -0
  1065. package/skills/companion/replay/SKILL.md +138 -0
  1066. package/skills/companion/setup/SKILL.md +167 -0
  1067. package/skills/companion/survey/SKILL.md +160 -0
  1068. package/skills/selfimprove/README.md +34 -0
  1069. package/skills/selfimprove/SKILL.md +127 -0
  1070. package/skills/selfimprove/agents/openai.yaml +2 -0
  1071. package/skills/selfimprove/commands/selfimprove.md +6 -0
  1072. package/skills/selfimprove/references/fix-loop.md +49 -0
  1073. package/skills/selfimprove/references/ledger.md +20 -0
  1074. package/skills/selfimprove/references/setup.md +40 -0
  1075. package/src/anomalies.ts +566 -0
  1076. package/src/answerworker.ts +251 -0
  1077. package/src/appstamp.ts +65 -0
  1078. package/src/archive/admission.ts +3 -0
  1079. package/src/archive/archivedb.ts +548 -0
  1080. package/src/archive/archiver.ts +1963 -0
  1081. package/src/archive/archivewrite.ts +279 -0
  1082. package/src/archive/bundle.ts +333 -0
  1083. package/src/archive/dbmove.ts +911 -0
  1084. package/src/archive/duplicatecounts.ts +98 -0
  1085. package/src/archive/eligibility.ts +181 -0
  1086. package/src/archive/extract.ts +342 -0
  1087. package/src/archive/fsutil.ts +415 -0
  1088. package/src/archive/gzfile.ts +370 -0
  1089. package/src/archive/kinds.ts +21 -0
  1090. package/src/archive/livecheckpoint.ts +217 -0
  1091. package/src/archive/liveretention.ts +180 -0
  1092. package/src/archive/manifest.ts +519 -0
  1093. package/src/archive/overseer.ts +336 -0
  1094. package/src/archive/piglobal.ts +174 -0
  1095. package/src/archive/plan.ts +612 -0
  1096. package/src/archive/prarchive.ts +984 -0
  1097. package/src/archive/prfiles.ts +406 -0
  1098. package/src/archive/report.ts +252 -0
  1099. package/src/archive/restore.ts +330 -0
  1100. package/src/archive/rows.ts +187 -0
  1101. package/src/archive/seal.ts +630 -0
  1102. package/src/archive/status.ts +719 -0
  1103. package/src/archive/storepass.ts +581 -0
  1104. package/src/backfill.ts +362 -0
  1105. package/src/bench/cost.ts +113 -0
  1106. package/src/bench/exec.ts +90 -0
  1107. package/src/bench/values.ts +13 -0
  1108. package/src/botcontrol.ts +176 -0
  1109. package/src/botworker.ts +953 -0
  1110. package/src/capture.ts +321 -0
  1111. package/src/cases.ts +1789 -0
  1112. package/src/channelfs.ts +26 -0
  1113. package/src/checklist.ts +506 -0
  1114. package/src/ciretry.ts +141 -0
  1115. package/src/cli.ts +2271 -0
  1116. package/src/cliops.ts +384 -0
  1117. package/src/clonedir.ts +15 -0
  1118. package/src/commandeffects.ts +57 -0
  1119. package/src/commands.ts +1678 -0
  1120. package/src/companioninbox.ts +239 -0
  1121. package/src/compare.ts +957 -0
  1122. package/src/config.ts +2050 -0
  1123. package/src/configcheck.ts +133 -0
  1124. package/src/coreext.ts +47 -0
  1125. package/src/daemon.ts +1302 -0
  1126. package/src/debuground.ts +927 -0
  1127. package/src/debugroundpi.ts +262 -0
  1128. package/src/diagnostics.ts +14 -0
  1129. package/src/digest.ts +183 -0
  1130. package/src/dispatch.ts +2250 -0
  1131. package/src/engine/answerguard.ts +27 -0
  1132. package/src/engine/botsdk.ts +336 -0
  1133. package/src/engine/caserunner-sdk.ts +423 -0
  1134. package/src/engine/debugpi.ts +235 -0
  1135. package/src/eod.ts +669 -0
  1136. package/src/eodpinwatch.ts +556 -0
  1137. package/src/escalation.ts +1253 -0
  1138. package/src/eventloop.ts +1045 -0
  1139. package/src/execboundary.ts +633 -0
  1140. package/src/feedback.ts +1162 -0
  1141. package/src/findingscheck.ts +298 -0
  1142. package/src/fsdenied.ts +24 -0
  1143. package/src/ghread.ts +242 -0
  1144. package/src/github.ts +1497 -0
  1145. package/src/homes.ts +175 -0
  1146. package/src/hostroute.ts +53 -0
  1147. package/src/improvements.ts +787 -0
  1148. package/src/install.ts +1103 -0
  1149. package/src/installkind.ts +50 -0
  1150. package/src/ipc/capability.ts +333 -0
  1151. package/src/ipc/client.ts +269 -0
  1152. package/src/ipc/control.ts +90 -0
  1153. package/src/ipc/ghreadshim.ts +94 -0
  1154. package/src/ipc/launcher.ts +65 -0
  1155. package/src/ipc/permits.ts +362 -0
  1156. package/src/ipc/postshim.ts +164 -0
  1157. package/src/ipc/protocol.ts +342 -0
  1158. package/src/ipc/server.ts +371 -0
  1159. package/src/ipc/workerspec.ts +218 -0
  1160. package/src/learner/learner.ts +1655 -0
  1161. package/src/learner/miner.ts +1290 -0
  1162. package/src/learner/packet.ts +340 -0
  1163. package/src/learner/receipt.ts +168 -0
  1164. package/src/learner/status.ts +107 -0
  1165. package/src/ledgercheck.ts +157 -0
  1166. package/src/lessonledger.ts +703 -0
  1167. package/src/lessonselect.ts +888 -0
  1168. package/src/lessonshadow.ts +810 -0
  1169. package/src/levers.ts +393 -0
  1170. package/src/live/projection.ts +491 -0
  1171. package/src/live/publish.ts +92 -0
  1172. package/src/live/read.ts +86 -0
  1173. package/src/livecli.ts +336 -0
  1174. package/src/loginhint.ts +56 -0
  1175. package/src/loginrefresh/atomic.ts +76 -0
  1176. package/src/loginrefresh/lock.ts +104 -0
  1177. package/src/loginrefresh/main.ts +59 -0
  1178. package/src/loginrefresh/pirefresh.ts +57 -0
  1179. package/src/loginrefresh/refresher.ts +326 -0
  1180. package/src/loginrefresh/supervisor.ts +273 -0
  1181. package/src/loginrefresh/types.ts +35 -0
  1182. package/src/memory/context.ts +385 -0
  1183. package/src/memory/datafence.ts +9 -0
  1184. package/src/memory/delivery.ts +171 -0
  1185. package/src/memory/eventtags.ts +80 -0
  1186. package/src/memory/health.ts +953 -0
  1187. package/src/memory/import.ts +664 -0
  1188. package/src/memory/layout.ts +261 -0
  1189. package/src/memory/legacy-file.ts +104 -0
  1190. package/src/memory/lessons.ts +447 -0
  1191. package/src/memory/ovsession.ts +601 -0
  1192. package/src/memory/relayout.ts +335 -0
  1193. package/src/memory/roundactivity.ts +209 -0
  1194. package/src/memory/selection.ts +989 -0
  1195. package/src/memory/shadowstatus.ts +125 -0
  1196. package/src/memory/store.ts +275 -0
  1197. package/src/memory/textidentity.ts +8 -0
  1198. package/src/metrics.ts +1056 -0
  1199. package/src/missingconfig.ts +7 -0
  1200. package/src/npmverbs.ts +264 -0
  1201. package/src/onboard/choices.ts +222 -0
  1202. package/src/onboard/engine.ts +518 -0
  1203. package/src/onboard/launch.ts +115 -0
  1204. package/src/onboard/steps/appslug.ts +265 -0
  1205. package/src/onboard/steps/bringup.ts +482 -0
  1206. package/src/onboard/steps/compose.ts +459 -0
  1207. package/src/onboard/steps/configdelivery.ts +58 -0
  1208. package/src/onboard/steps/configfill.ts +1352 -0
  1209. package/src/onboard/steps/deploysh.ts +105 -0
  1210. package/src/onboard/steps/embeddings.ts +550 -0
  1211. package/src/onboard/steps/escalation.ts +640 -0
  1212. package/src/onboard/steps/githubapp.ts +1414 -0
  1213. package/src/onboard/steps/golive.ts +577 -0
  1214. package/src/onboard/steps/index.ts +71 -0
  1215. package/src/onboard/steps/ingress.ts +907 -0
  1216. package/src/onboard/steps/inventory.ts +526 -0
  1217. package/src/onboard/steps/llmauth.ts +1095 -0
  1218. package/src/onboard/steps/memory.ts +1290 -0
  1219. package/src/onboard/steps/memorykeys.ts +85 -0
  1220. package/src/onboard/steps/preflight.ts +191 -0
  1221. package/src/onboard/steps/proof.ts +624 -0
  1222. package/src/onboard/steps/ssh.ts +377 -0
  1223. package/src/onboard/steps/topology.ts +337 -0
  1224. package/src/onboard/steps/transport.ts +665 -0
  1225. package/src/onboard/steps/verifyup.ts +448 -0
  1226. package/src/onboard/steps/vmdeploy.ts +442 -0
  1227. package/src/onboard/toml.ts +50 -0
  1228. package/src/opencli.ts +591 -0
  1229. package/src/openpr.ts +568 -0
  1230. package/src/openviking/client.ts +1131 -0
  1231. package/src/openviking/context.ts +263 -0
  1232. package/src/openviking/embedder.ts +516 -0
  1233. package/src/openviking/gapsink.ts +63 -0
  1234. package/src/openviking/health.ts +83 -0
  1235. package/src/openviking/index.ts +119 -0
  1236. package/src/openviking/lessonfind.ts +92 -0
  1237. package/src/openviking/probe.ts +129 -0
  1238. package/src/openviking/proc.ts +110 -0
  1239. package/src/openviking/provisionreport.ts +160 -0
  1240. package/src/openviking/reembed.ts +412 -0
  1241. package/src/openviking/relayout.ts +177 -0
  1242. package/src/openviking/sidecar-main.ts +38 -0
  1243. package/src/openviking/sidecar.ts +106 -0
  1244. package/src/openviking/store.ts +2025 -0
  1245. package/src/openviking/supervisor.ts +474 -0
  1246. package/src/openviking/types.ts +174 -0
  1247. package/src/operator-recovery.ts +237 -0
  1248. package/src/operatormessage.ts +52 -0
  1249. package/src/outcomes.ts +1670 -0
  1250. package/src/piauthcopy.ts +12 -0
  1251. package/src/picli.ts +49 -0
  1252. package/src/picwd.ts +25 -0
  1253. package/src/pilogin.ts +37 -0
  1254. package/src/pingpong.ts +1339 -0
  1255. package/src/posting-journal.ts +549 -0
  1256. package/src/posting-outbox.ts +802 -0
  1257. package/src/posting-receipt.ts +324 -0
  1258. package/src/posting.ts +603 -0
  1259. package/src/postops.ts +832 -0
  1260. package/src/pr-activity.ts +20 -0
  1261. package/src/pr-author.ts +6 -0
  1262. package/src/pr-conversation.ts +432 -0
  1263. package/src/pr-session-lifecycle.ts +631 -0
  1264. package/src/preflight.ts +391 -0
  1265. package/src/priorresolve.ts +343 -0
  1266. package/src/qcrbin.ts +186 -0
  1267. package/src/recheck.ts +1775 -0
  1268. package/src/reconcile.ts +1030 -0
  1269. package/src/recordedfindings.ts +27 -0
  1270. package/src/regression.ts +833 -0
  1271. package/src/replay.ts +816 -0
  1272. package/src/requiredpasses.ts +148 -0
  1273. package/src/resumecheck.ts +246 -0
  1274. package/src/reviewcli.ts +787 -0
  1275. package/src/reviewcontext.ts +35 -0
  1276. package/src/reviewdetach.ts +734 -0
  1277. package/src/reviewhistory.ts +427 -0
  1278. package/src/reviewhome.ts +36 -0
  1279. package/src/reviewmemory.ts +133 -0
  1280. package/src/reviewrendercli.ts +139 -0
  1281. package/src/round-work.ts +42 -0
  1282. package/src/runhost.ts +108 -0
  1283. package/src/scanauth.ts +36 -0
  1284. package/src/scanbox.ts +1081 -0
  1285. package/src/scancli.ts +1296 -0
  1286. package/src/scandriverlog.ts +32 -0
  1287. package/src/session-bridge.ts +139 -0
  1288. package/src/session-command-payload.ts +35 -0
  1289. package/src/session-command-supervisor.ts +1142 -0
  1290. package/src/sessionjsonl.ts +88 -0
  1291. package/src/sessions.ts +659 -0
  1292. package/src/setup/adapters.ts +335 -0
  1293. package/src/setup/baselines.ts +110 -0
  1294. package/src/setup/caserunner.ts +611 -0
  1295. package/src/setup/configcommit.ts +443 -0
  1296. package/src/setup/engine.ts +1001 -0
  1297. package/src/setup/facts.ts +627 -0
  1298. package/src/setup/findings.ts +1264 -0
  1299. package/src/setup/history.ts +443 -0
  1300. package/src/setup/interview.ts +243 -0
  1301. package/src/setup/ledger.ts +324 -0
  1302. package/src/setup/pins.ts +66 -0
  1303. package/src/setup/portrait.ts +635 -0
  1304. package/src/setup/presentation.ts +18 -0
  1305. package/src/setup/profile.ts +508 -0
  1306. package/src/setup/replay.ts +370 -0
  1307. package/src/setup/replaybuild.ts +392 -0
  1308. package/src/setup/replayrun.ts +1096 -0
  1309. package/src/setup/replaysource.ts +198 -0
  1310. package/src/setup/retune.ts +415 -0
  1311. package/src/setup/retunelog.ts +95 -0
  1312. package/src/setup/scan.ts +1033 -0
  1313. package/src/setup/scanbuild.ts +168 -0
  1314. package/src/setup/scanfacts.ts +107 -0
  1315. package/src/setup/scanlease.ts +297 -0
  1316. package/src/setup/scanreport.ts +373 -0
  1317. package/src/setup/scanrun.ts +2268 -0
  1318. package/src/setup/scantree.ts +259 -0
  1319. package/src/setup/stage2.ts +926 -0
  1320. package/src/setup/stage2request.ts +347 -0
  1321. package/src/setup/survey.ts +458 -0
  1322. package/src/setup/surveyrun.ts +758 -0
  1323. package/src/setup/textsniff.ts +95 -0
  1324. package/src/setup/trackersink.ts +433 -0
  1325. package/src/setup/triage.ts +768 -0
  1326. package/src/setup/tuning.ts +766 -0
  1327. package/src/setup/unitcut.ts +523 -0
  1328. package/src/singleflight.ts +86 -0
  1329. package/src/slack/announce.ts +911 -0
  1330. package/src/slack/api.ts +303 -0
  1331. package/src/slack/messages.ts +288 -0
  1332. package/src/slack/origin.ts +599 -0
  1333. package/src/slack/policy.ts +354 -0
  1334. package/src/slack/reply.ts +201 -0
  1335. package/src/slack/router.ts +285 -0
  1336. package/src/slack/socket.ts +384 -0
  1337. package/src/slack/types.ts +108 -0
  1338. package/src/sqlitehint.ts +32 -0
  1339. package/src/ssh-observation.ts +30 -0
  1340. package/src/state.ts +8243 -0
  1341. package/src/statemachine.ts +369 -0
  1342. package/src/stubs.ts +68 -0
  1343. package/src/takeover.ts +634 -0
  1344. package/src/takeoverpi.ts +293 -0
  1345. package/src/terminal-failure.ts +41 -0
  1346. package/src/thread-resolution-refusal.ts +2 -0
  1347. package/src/tmux.ts +153 -0
  1348. package/src/trackerid.ts +41 -0
  1349. package/src/transcriptindex.ts +665 -0
  1350. package/src/tui/actions.ts +484 -0
  1351. package/src/tui/alerts.ts +666 -0
  1352. package/src/tui/app.ts +1979 -0
  1353. package/src/tui/archiveops.ts +192 -0
  1354. package/src/tui/autofile.ts +233 -0
  1355. package/src/tui/board.ts +1432 -0
  1356. package/src/tui/candidates.ts +889 -0
  1357. package/src/tui/cellwidth.ts +148 -0
  1358. package/src/tui/changelog-store.ts +503 -0
  1359. package/src/tui/chord.ts +25 -0
  1360. package/src/tui/clipboard.ts +92 -0
  1361. package/src/tui/cmdbar.ts +296 -0
  1362. package/src/tui/companion.ts +1427 -0
  1363. package/src/tui/companionplan.ts +247 -0
  1364. package/src/tui/companiontab.ts +83 -0
  1365. package/src/tui/confighome.ts +155 -0
  1366. package/src/tui/connect.ts +68 -0
  1367. package/src/tui/deploy-ceremony.ts +104 -0
  1368. package/src/tui/deploy-drain.ts +129 -0
  1369. package/src/tui/deploy-process.ts +265 -0
  1370. package/src/tui/deploytab.ts +1523 -0
  1371. package/src/tui/design.ts +125 -0
  1372. package/src/tui/digesttab.ts +214 -0
  1373. package/src/tui/emptystate.ts +39 -0
  1374. package/src/tui/evidence.ts +999 -0
  1375. package/src/tui/feed.ts +604 -0
  1376. package/src/tui/feedbacktab.ts +1077 -0
  1377. package/src/tui/filters.ts +90 -0
  1378. package/src/tui/ghread.ts +321 -0
  1379. package/src/tui/historypull.ts +81 -0
  1380. package/src/tui/inboxpull.ts +236 -0
  1381. package/src/tui/index.ts +1565 -0
  1382. package/src/tui/issuesink.ts +238 -0
  1383. package/src/tui/jsonfile.ts +42 -0
  1384. package/src/tui/keys.ts +109 -0
  1385. package/src/tui/layout.ts +108 -0
  1386. package/src/tui/learning.ts +627 -0
  1387. package/src/tui/lessonswitch.ts +118 -0
  1388. package/src/tui/livecontrol.ts +228 -0
  1389. package/src/tui/memforward.ts +443 -0
  1390. package/src/tui/memincident.ts +363 -0
  1391. package/src/tui/memory.ts +620 -0
  1392. package/src/tui/memtab.ts +606 -0
  1393. package/src/tui/metricstab.ts +1177 -0
  1394. package/src/tui/model.ts +131 -0
  1395. package/src/tui/mouse.ts +98 -0
  1396. package/src/tui/msg.ts +268 -0
  1397. package/src/tui/nativecompanion.ts +417 -0
  1398. package/src/tui/openurl.ts +21 -0
  1399. package/src/tui/paint.ts +511 -0
  1400. package/src/tui/panes.ts +98 -0
  1401. package/src/tui/pipane.ts +219 -0
  1402. package/src/tui/poll-hooks.ts +12 -0
  1403. package/src/tui/poll.ts +147 -0
  1404. package/src/tui/proposals.ts +838 -0
  1405. package/src/tui/prpause.ts +150 -0
  1406. package/src/tui/reload.ts +436 -0
  1407. package/src/tui/remote.ts +413 -0
  1408. package/src/tui/rollover.ts +969 -0
  1409. package/src/tui/scantab.ts +1290 -0
  1410. package/src/tui/setupentry.ts +93 -0
  1411. package/src/tui/sidebar.ts +749 -0
  1412. package/src/tui/sshtriage.ts +510 -0
  1413. package/src/tui/startup.ts +231 -0
  1414. package/src/tui/tabs.ts +45 -0
  1415. package/src/tui/termmirror.ts +224 -0
  1416. package/src/tui/theme.ts +95 -0
  1417. package/src/tui/ticketstab.ts +310 -0
  1418. package/src/tui/tmuxsocket.ts +129 -0
  1419. package/src/tui/trackertickets.ts +84 -0
  1420. package/src/tui/unwedge.ts +286 -0
  1421. package/src/tui/viewer.ts +575 -0
  1422. package/src/tui/viewerinput.ts +173 -0
  1423. package/src/updatenotice.ts +178 -0
  1424. package/src/usage.ts +1154 -0
  1425. package/src/verdicts.ts +4689 -0
  1426. package/src/version.ts +80 -0
  1427. package/src/wakes.ts +476 -0
  1428. package/src/webhook.ts +942 -0
  1429. package/src/webhookheal.ts +276 -0
  1430. package/src/wire.ts +2153 -0
  1431. package/src/worker-session-host.ts +602 -0
  1432. package/src/workerbreaker.ts +156 -0
  1433. package/src/workercontrol.ts +104 -0
  1434. package/src/workerlease.ts +441 -0
  1435. package/src/workerliveness.ts +103 -0
  1436. package/src/workerlog.ts +79 -0
  1437. package/src/workerruntime.ts +30 -0
  1438. package/src/workersupervisor.ts +1538 -0
  1439. package/src/workerusage.ts +42 -0
  1440. package/src/workerworld.ts +427 -0
  1441. package/src/worktrees.ts +1138 -0
  1442. package/tests/fixtures/regression-cases.json +795 -0
  1443. package/tests/fixtures/seed-manifest.json +19 -0
@@ -0,0 +1,989 @@
1
+ // Lesson selection: which curated lessons and which past finding cases a
2
+ // round would carry — pure, deterministic, no I/O.
3
+ //
4
+ // The round's prefetch (src/lessonselect.ts) asks OpenViking two
5
+ // `/search/find`s under a hard budget (a find per plan row does not answer
6
+ // inside it): one inside `memories/experiences/` with a round-level query and
7
+ // a `limit` sized to cover the whole lesson corpus (`lessonFindLimit`, from the store's
8
+ // own count, bounded), and ONE for the main session inside
9
+ // `memories/finding-cases/`. Every row, the validator and every lens the
10
+ // session may add then filter that ONE answer for themselves. What comes back
11
+ // is a ranked list of hits by the ENGINE's score — semantic similarity, which
12
+ // knows nothing of lenses, paths or retirements; with the limit covering the
13
+ // corpus the score decides nothing at all. This module turns those hits into
14
+ // a selection with rules a person can read:
15
+ //
16
+ // FILTER (on the typed header — src/memory/lessons.ts `parseLesson`, the
17
+ // header only, so quoted prose in a body can never make a lesson eligible):
18
+ // * the hit is a file inside the area that was searched (never a folder
19
+ // blurb, never another area's entry the server let through);
20
+ // * never `#retired`, never a move's `#moved` stub, never a URI on the
21
+ // store's retired list, never a URI the operator SUPPRESSED (the kill
22
+ // switch, `commands/operator/` → state.db — src/lessonledger.ts);
23
+ // * a lesson (a typed header, or one of the legacy shapes the tolerant
24
+ // reader knows) whose polarity is known — a lesson nobody can tell is
25
+ // a "look for" or a "don't raise" is delivered to nobody;
26
+ // * the row's lens is in its `lens=` (a lesson naming no lens — the
27
+ // legacy conventions — is for every lens);
28
+ // * one of its `paths=` globs matches one of the row's files, when it
29
+ // names any;
30
+ // * created strictly before `as_of`, when a replay sets one (a temporal
31
+ // hold-out: a lesson the replayed PR's own outcome produced must not
32
+ // grade that PR). A lesson whose creation date cannot be read is not
33
+ // provably older, so it is out.
34
+ // RANK (deterministic — the engine's score only decided which hits came
35
+ // back, never their order here): pinned > a `paths=` glob hit > a `lens=`
36
+ // hit > evidence count > recency > URI.
37
+ // CAP per role (`SELECTION_CAPS`): items and an estimated token budget,
38
+ // greedy in rank order; EVERY lesson cut is listed with why.
39
+ //
40
+ // A CASE (src/cases.ts) is filtered on its own header: `#case kind=case`, not
41
+ // withdrawn, about a file this PR changes, from ANOTHER PR (the session has
42
+ // this PR's own history in its ledger), posted before `as_of`. Ranked by a
43
+ // shared lens > the replies it drew > recency > URI.
44
+ //
45
+ // Under `[memory] delivery = "shadow"` (the shipped value) the selection is
46
+ // only what the shadow ledger records; under `on` it is also what is
47
+ // delivered (src/memory/delivery.ts renders it) — the lenses a session may ADD
48
+ // included (one shared find, filtered per lens), and, for the recheck and the
49
+ // ping-pong wake, the repo facts for the paths they touch
50
+ // (`selectRepoFacts`).
51
+ import { globMatcherOrNothing } from "@quickchatai/pi-quickreview/src/glob.js";
52
+ import { canonicalLensIds } from "@quickchatai/pi-quickreview/src/lensids.js";
53
+ import { roundContextQuery } from "./context.js";
54
+ import { parseEventTags, parseHashTags } from "./eventtags.js";
55
+ import { CASES_AREA, EXPERIENCES_AREA, PINNED_AREA, isRetired } from "./layout.js";
56
+ import { parseLesson, type LessonKind, type ParsedLesson } from "./lessons.js";
57
+ import { VALIDATOR_LENS } from "@quickchatai/pi-quickreview/src/memoryport.js";
58
+
59
+ /** The validator's lens id — it has no task file and judges every finding
60
+ * (the delivery's, packages/pi-plugin/src/memoryport.ts). */
61
+ export { VALIDATOR_LENS };
62
+
63
+ /** What each role may carry: items and an ESTIMATED token budget. */
64
+ export const SELECTION_CAPS = Object.freeze({
65
+ /** One lens row's task file. */
66
+ row: Object.freeze({ items: 6, tokens: 1200 }),
67
+ /** The main session's "past reviews of these files". */
68
+ cases: Object.freeze({ items: 8, tokens: 2000 }),
69
+ /** The validator's lesson addendum. */
70
+ validator: Object.freeze({ items: 20, tokens: 2500 }),
71
+ });
72
+
73
+ export type SelectionCap = { readonly items: number; readonly tokens: number };
74
+
75
+ /** How many hits the main session's cases find asks for. The finding-case
76
+ * area is large (a case per answered finding) and the query names the PR's
77
+ * paths; the filter keeps only cases about those paths. */
78
+ export const FIND_LIMITS = Object.freeze({ cases: 40 });
79
+
80
+ /**
81
+ * The bounds of a lesson find's `limit`. One find inside `experiences/`
82
+ * serves every role of a round (and the recheck's repo facts), so it asks for
83
+ * the whole lesson corpus: the filters, the ranking and the caps all run
84
+ * here, and none of them reads the engine's score. `min` keeps a small
85
+ * corpus's find at the size a shared find has always asked for; `max`
86
+ * bounds the answer's size for a corpus that outgrows it — past it the
87
+ * round-level query's similarity decides which entries come back, recorded
88
+ * on the `lesson_selection` event (`corpus` > `limit`).
89
+ */
90
+ export const LESSON_FIND_LIMIT = Object.freeze({ min: 40, max: 200 });
91
+
92
+ /**
93
+ * The lesson find's `limit` for a corpus of `corpus` files in `experiences/`
94
+ * (the store's last sweep — `LessonEngine.corpusSize`): twice the count plus
95
+ * eight, within `LESSON_FIND_LIMIT`. The headroom is for what the engine
96
+ * returns that is not one lesson file each — the area's own directory record,
97
+ * an engine blurb, a file indexed more than once — all dropped by the
98
+ * filter, but each takes a place in the top K.
99
+ * An unknown corpus (no sweep yet) asks for the ceiling: coverage first, and
100
+ * the limit only sizes the answer — the query is embedded once either way.
101
+ */
102
+ export function lessonFindLimit(corpus: number | null | undefined): number {
103
+ if (corpus === null || corpus === undefined || !Number.isFinite(corpus) || corpus < 0)
104
+ return LESSON_FIND_LIMIT.max;
105
+ return Math.max(LESSON_FIND_LIMIT.min, Math.min(LESSON_FIND_LIMIT.max, 2 * Math.ceil(corpus) + 8));
106
+ }
107
+
108
+ /** Characters per token for the caps' estimate — the usual English ratio. */
109
+ export const CHARS_PER_TOKEN = 4;
110
+
111
+ export function estimateTokens(text: string): number {
112
+ return Math.max(1, Math.ceil(text.trim().length / CHARS_PER_TOKEN));
113
+ }
114
+
115
+ /** One hit of a `/search/find`, as the engine adapter hands it over. */
116
+ export interface FindHit {
117
+ uri: string;
118
+ score: number;
119
+ /** The entry text the engine returned (the abstract — the stored content
120
+ * itself in a deployment without a VLM). The header is its first line. */
121
+ text: string;
122
+ }
123
+
124
+ /** What one find produced, after the prefetch's budget. */
125
+ export type FindOutcome =
126
+ | { status: "ok"; hits: readonly FindHit[] }
127
+ | { status: "unreadable"; reason: string }
128
+ | { status: "timeout" };
129
+
130
+ /** `20260824T153000-…` / `20260824-eod-…` → `2026-08-24[T15:30:00]`; null when
131
+ * the file name carries no date. */
132
+ export function createdOfUri(uri: string): string | null {
133
+ const name = uri.slice(uri.lastIndexOf("/") + 1);
134
+ const m = /^(\d{4})(\d{2})(\d{2})(?:T(\d{2})(\d{2})(\d{2}))?/.exec(name);
135
+ if (!m) return null;
136
+ const day = `${m[1]}-${m[2]}-${m[3]}`;
137
+ return m[4] !== undefined ? `${day}T${m[4]}:${m[5]}:${m[6]}` : day;
138
+ }
139
+
140
+ /** Is `uri` a FILE directly addressable under `<root>/<area>/` (never a
141
+ * folder, never the engine's `.abstract.md`/`.overview.md` blurbs)? */
142
+ export function inArea(uri: string, root: string, area: string): boolean {
143
+ const prefix = `${root.replace(/\/+$/, "")}/${area}/`;
144
+ if (!uri.startsWith(prefix)) return false;
145
+ const rest = uri.slice(prefix.length);
146
+ const base = rest.slice(rest.lastIndexOf("/") + 1);
147
+ // `experiences/` holds files directly; a deeper path is another area
148
+ // (`preferences/pinned/` under `preferences/`) or something we never write.
149
+ if (rest.includes("/")) return false;
150
+ return base.endsWith(".md") && !base.startsWith(".");
151
+ }
152
+
153
+ /** A hit's engine score, or 0 when it is missing or not finite. */
154
+ function finiteScore(score: unknown): number {
155
+ return typeof score === "number" && Number.isFinite(score) ? score : 0;
156
+ }
157
+
158
+ /** The score as the ledger records it: three decimals. */
159
+ function recordedScore(score: number): number {
160
+ return Math.round(score * 1000) / 1000;
161
+ }
162
+
163
+ function cmp(a: string, b: string): number {
164
+ return a < b ? -1 : a > b ? 1 : 0;
165
+ }
166
+
167
+ /** Sort by URI and keep one hit per URI (the highest score), so the order the
168
+ * engine returned them in can never change what is selected. */
169
+ function dedupeHits(hits: readonly FindHit[]): { hits: FindHit[]; duplicates: number } {
170
+ const best = new Map<string, FindHit>();
171
+ let duplicates = 0;
172
+ for (const h of hits) {
173
+ if (typeof h?.uri !== "string" || h.uri === "") continue;
174
+ const prev = best.get(h.uri);
175
+ if (prev) {
176
+ duplicates += 1;
177
+ if ((h.score ?? 0) > (prev.score ?? 0)) best.set(h.uri, h);
178
+ } else best.set(h.uri, h);
179
+ }
180
+ return { hits: [...best.values()].sort((a, b) => cmp(a.uri, b.uri)), duplicates };
181
+ }
182
+
183
+ // ---- lessons ----------------------------------------------------------------
184
+
185
+ export type LessonDropReason =
186
+ | "out_of_area"
187
+ | "duplicate"
188
+ | "moved"
189
+ | "retired"
190
+ | "suppressed"
191
+ | "not_lesson"
192
+ | "kind_unknown"
193
+ | "lens"
194
+ | "paths"
195
+ | "as_of";
196
+
197
+ export interface LessonCandidate {
198
+ uri: string;
199
+ text: string;
200
+ score: number;
201
+ created: string | null;
202
+ lesson: ParsedLesson & { kind: LessonKind };
203
+ tokens: number;
204
+ pinned: boolean;
205
+ /** One of its `paths=` globs matched one of the files it was judged for. */
206
+ pathHit: boolean;
207
+ }
208
+
209
+ export interface LessonFilterContext {
210
+ /** The memories root URI (`viking://user/reviewer/memories`). */
211
+ root: string;
212
+ /** The lens the lessons are for; null — no lens precondition (the main
213
+ * session's repo facts). */
214
+ lens: string | null;
215
+ /** The files that lens reviews (the row's focus, else the PR's files). */
216
+ files: readonly string[];
217
+ retired: ReadonlySet<string>;
218
+ suppressed: ReadonlySet<string>;
219
+ /** `YYYY-MM-DD`: only lessons created strictly before it. */
220
+ asOf?: string | null;
221
+ }
222
+
223
+ export type RepoFactDropReason = "kind" | "no_paths";
224
+ export type DropReason = LessonDropReason | CaseDropReason | RepoFactDropReason;
225
+ export type DropCounts = Partial<Record<DropReason, number>>;
226
+
227
+ function bump(d: DropCounts, reason: DropReason, n = 1): void {
228
+ d[reason] = (d[reason] ?? 0) + n;
229
+ }
230
+
231
+ /** Retired or moved, by the store's list or by the entry's own header. */
232
+ function retiredState(uri: string, text: string, retired: ReadonlySet<string>): "moved" | "retired" | null {
233
+ const hash = parseHashTags(text.trim());
234
+ if (hash.includes("moved")) return "moved";
235
+ if (hash.includes("retired") || retired.has(uri)) return "retired";
236
+ return null;
237
+ }
238
+
239
+ function beforeAsOf(created: string | null, asOf: string | null | undefined): boolean {
240
+ if (!asOf) return true;
241
+ if (created === null) return false;
242
+ return created.slice(0, 10) < asOf.slice(0, 10);
243
+ }
244
+
245
+ /**
246
+ * The hits that may be selected for one lens, and how many were dropped for
247
+ * each reason. Pure; the order of `hits` does not matter.
248
+ */
249
+ export function filterLessonHits(
250
+ hits: readonly FindHit[],
251
+ ctx: LessonFilterContext,
252
+ ): { eligible: LessonCandidate[]; dropped: DropCounts } {
253
+ const dropped: DropCounts = {};
254
+ const { hits: unique, duplicates } = dedupeHits(hits);
255
+ if (duplicates > 0) bump(dropped, "duplicate", duplicates);
256
+ const eligible: LessonCandidate[] = [];
257
+ for (const h of unique) {
258
+ const text = typeof h.text === "string" ? h.text : "";
259
+ if (!inArea(h.uri, ctx.root, EXPERIENCES_AREA)) {
260
+ bump(dropped, "out_of_area");
261
+ continue;
262
+ }
263
+ const gone = retiredState(h.uri, text, ctx.retired);
264
+ if (gone) {
265
+ bump(dropped, gone);
266
+ continue;
267
+ }
268
+ if (ctx.suppressed.has(h.uri)) {
269
+ bump(dropped, "suppressed");
270
+ continue;
271
+ }
272
+ const lesson = parseLesson(text);
273
+ if (!lesson) {
274
+ bump(dropped, "not_lesson");
275
+ continue;
276
+ }
277
+ if (lesson.kind === null) {
278
+ bump(dropped, "kind_unknown");
279
+ continue;
280
+ }
281
+ if (ctx.lens !== null && lesson.lens.length > 0 && !lesson.lens.includes(ctx.lens)) {
282
+ bump(dropped, "lens");
283
+ continue;
284
+ }
285
+ const pathHit = pathHitOn(lesson, ctx.files);
286
+ if (lesson.paths.length > 0 && !pathHit) {
287
+ bump(dropped, "paths");
288
+ continue;
289
+ }
290
+ const created = createdOfUri(h.uri);
291
+ if (!beforeAsOf(created, ctx.asOf)) {
292
+ bump(dropped, "as_of");
293
+ continue;
294
+ }
295
+ eligible.push({
296
+ uri: h.uri,
297
+ text: text.trim(),
298
+ score: finiteScore(h.score),
299
+ created,
300
+ lesson: lesson as ParsedLesson & { kind: LessonKind },
301
+ tokens: estimateTokens(text),
302
+ pinned: h.uri.includes(`/memories/${PINNED_AREA}/`),
303
+ pathHit,
304
+ });
305
+ }
306
+ return { eligible, dropped };
307
+ }
308
+
309
+ /** Does the lesson's `paths=` precondition match any of `files`? A lesson
310
+ * with no paths is no hit; a glob list the compiler refuses matches nothing. */
311
+ function pathHitOn(lesson: ParsedLesson, files: readonly string[]): boolean {
312
+ return lesson.paths.length > 0 && files.some(globMatcherOrNothing(lesson.paths));
313
+ }
314
+
315
+ /** Ranking keys, most significant first; every key is "higher first" except
316
+ * the URI, the final tie-break. */
317
+ function lessonKey(c: LessonCandidate, lens: string): Array<number | string> {
318
+ return [
319
+ c.pinned ? 1 : 0,
320
+ c.pathHit ? 1 : 0,
321
+ c.lesson.lens.includes(lens) ? 1 : 0,
322
+ c.lesson.evidence.length,
323
+ c.created ?? "",
324
+ ];
325
+ }
326
+
327
+ function compareKeys(a: Array<number | string>, b: Array<number | string>): number {
328
+ for (let i = 0; i < a.length; i++) {
329
+ const x = a[i]!;
330
+ const y = b[i]!;
331
+ if (x === y) continue;
332
+ return x > y ? -1 : 1;
333
+ }
334
+ return 0;
335
+ }
336
+
337
+ /** Deterministic order: pinned > path-glob hit > lens hit > evidence count >
338
+ * recency > URI. The engine's score is not a key. */
339
+ export function rankLessons(cands: readonly LessonCandidate[], lens: string): LessonCandidate[] {
340
+ return [...cands].sort(
341
+ (a, b) => compareKeys(lessonKey(a, lens), lessonKey(b, lens)) || cmp(a.uri, b.uri),
342
+ );
343
+ }
344
+
345
+ export type CutReason = "items" | "tokens";
346
+ export interface SelectionCut {
347
+ uri: string;
348
+ reason: CutReason;
349
+ }
350
+
351
+ /** Greedy in rank order: an item past the item cap, or one that would take
352
+ * the role over its token budget, is CUT (and listed); a smaller one after
353
+ * it may still fit. */
354
+ export function capSelection<T extends { uri: string; tokens: number }>(
355
+ ranked: readonly T[],
356
+ cap: SelectionCap,
357
+ ): { selected: T[]; cuts: SelectionCut[] } {
358
+ const selected: T[] = [];
359
+ const cuts: SelectionCut[] = [];
360
+ let used = 0;
361
+ for (const c of ranked) {
362
+ if (selected.length >= cap.items) {
363
+ cuts.push({ uri: c.uri, reason: "items" });
364
+ continue;
365
+ }
366
+ if (used + c.tokens > cap.tokens) {
367
+ cuts.push({ uri: c.uri, reason: "tokens" });
368
+ continue;
369
+ }
370
+ selected.push(c);
371
+ used += c.tokens;
372
+ }
373
+ return { selected, cuts };
374
+ }
375
+
376
+ // ---- cases ------------------------------------------------------------------
377
+
378
+ export interface CaseHeader {
379
+ pr: number | null;
380
+ path: string | null;
381
+ lens: string[];
382
+ fate: string | null;
383
+ posted: string | null;
384
+ replies: number;
385
+ }
386
+
387
+ /** A case header value, decoded (src/cases.ts `tagValue` encodes `%`, the
388
+ * whitespace and control bytes as `%XX`, or wide code units as `%uXXXX`). */
389
+ function decodeTagValue(v: string): string {
390
+ return v.replace(
391
+ /%u([0-9A-Fa-f]{4})|%([0-9A-Fa-f]{2})/g,
392
+ (_m, wide: string | undefined, byte: string | undefined) =>
393
+ String.fromCharCode(parseInt(wide ?? byte!, 16)),
394
+ );
395
+ }
396
+
397
+ /** A finding case's header, or null when the text is not a live case (no
398
+ * `#case kind=case` header, or withdrawn/retired). Header only. */
399
+ export function parseCaseHeader(text: string): CaseHeader | null {
400
+ const t = text.trim();
401
+ const hash = parseHashTags(t);
402
+ if (!hash.includes("case") || hash.includes("retired") || hash.includes("moved")) return null;
403
+ const tags = parseEventTags(t);
404
+ if (tags["kind"] !== "case") return null;
405
+ const pr = tags["pr"] !== undefined && /^\d{1,9}$/.test(tags["pr"]) ? Number(tags["pr"]) : null;
406
+ const replies = tags["replies"] !== undefined && /^\d{1,6}$/.test(tags["replies"]) ? Number(tags["replies"]) : 0;
407
+ return {
408
+ pr,
409
+ path: tags["path"] !== undefined ? decodeTagValue(tags["path"]) : null,
410
+ lens: canonicalLensIds(tags["lens"] ?? ""),
411
+ fate: tags["fate"] ?? null,
412
+ posted: tags["posted"] ?? null,
413
+ replies,
414
+ };
415
+ }
416
+
417
+ export type CaseDropReason =
418
+ | "out_of_area"
419
+ | "duplicate"
420
+ | "retired"
421
+ | "suppressed"
422
+ | "not_case"
423
+ | "same_pr"
424
+ | "paths"
425
+ | "as_of";
426
+
427
+ export interface CaseCandidate {
428
+ uri: string;
429
+ text: string;
430
+ score: number;
431
+ header: CaseHeader;
432
+ tokens: number;
433
+ lensHit: boolean;
434
+ }
435
+
436
+ export interface CaseFilterContext {
437
+ root: string;
438
+ /** The PR under review: its own cases are its own history, not precedent. */
439
+ pr: number;
440
+ /** The PR's changed files — a case is about one of them, or it is out. */
441
+ files: readonly string[];
442
+ /** The round's planned lenses (a case raised by one of them ranks first). */
443
+ lenses: readonly string[];
444
+ retired: ReadonlySet<string>;
445
+ suppressed: ReadonlySet<string>;
446
+ asOf?: string | null;
447
+ }
448
+
449
+ export function filterCaseHits(
450
+ hits: readonly FindHit[],
451
+ ctx: CaseFilterContext,
452
+ ): { eligible: CaseCandidate[]; dropped: DropCounts } {
453
+ const dropped: DropCounts = {};
454
+ const { hits: unique, duplicates } = dedupeHits(hits);
455
+ if (duplicates > 0) bump(dropped, "duplicate", duplicates);
456
+ const files = new Set(ctx.files);
457
+ const eligible: CaseCandidate[] = [];
458
+ for (const h of unique) {
459
+ const text = typeof h.text === "string" ? h.text : "";
460
+ if (!inArea(h.uri, ctx.root, CASES_AREA)) {
461
+ bump(dropped, "out_of_area");
462
+ continue;
463
+ }
464
+ if (ctx.retired.has(h.uri) || isRetired(text.trim())) {
465
+ bump(dropped, "retired");
466
+ continue;
467
+ }
468
+ if (ctx.suppressed.has(h.uri)) {
469
+ bump(dropped, "suppressed");
470
+ continue;
471
+ }
472
+ const header = parseCaseHeader(text);
473
+ if (!header) {
474
+ bump(dropped, "not_case");
475
+ continue;
476
+ }
477
+ if (header.pr === ctx.pr) {
478
+ bump(dropped, "same_pr");
479
+ continue;
480
+ }
481
+ if (header.path === null || !files.has(header.path)) {
482
+ bump(dropped, "paths");
483
+ continue;
484
+ }
485
+ if (!beforeAsOf(header.posted, ctx.asOf)) {
486
+ bump(dropped, "as_of");
487
+ continue;
488
+ }
489
+ eligible.push({
490
+ uri: h.uri,
491
+ text: text.trim(),
492
+ score: finiteScore(h.score),
493
+ header,
494
+ tokens: estimateTokens(text),
495
+ lensHit: header.lens.some((l) => ctx.lenses.includes(l)),
496
+ });
497
+ }
498
+ return { eligible, dropped };
499
+ }
500
+
501
+ /** Deterministic: a shared lens > replies drawn > recency > URI. */
502
+ export function rankCases(cands: readonly CaseCandidate[]): CaseCandidate[] {
503
+ return [...cands].sort(
504
+ (a, b) =>
505
+ compareKeys(
506
+ [a.lensHit ? 1 : 0, a.header.replies, a.header.posted ?? ""],
507
+ [b.lensHit ? 1 : 0, b.header.replies, b.header.posted ?? ""],
508
+ ) || cmp(a.uri, b.uri),
509
+ );
510
+ }
511
+
512
+ // ---- the round ----------------------------------------------------------------
513
+
514
+ /** One row of the round's pass plan, as selection needs it. */
515
+ export interface SelectionRow {
516
+ /** Index into `pass_plan` (the task file's row). */
517
+ row: number;
518
+ lens: string;
519
+ agent: string;
520
+ /** Sweep rows: the files this row covers. */
521
+ focus?: readonly string[];
522
+ }
523
+
524
+ /** One find the prefetch asks. */
525
+ export interface PlannedFind {
526
+ key: string;
527
+ area: typeof EXPERIENCES_AREA | typeof CASES_AREA;
528
+ query: string;
529
+ limit: number;
530
+ }
531
+
532
+ export interface FindPlan {
533
+ finds: PlannedFind[];
534
+ /** Plan row → the find whose answer its lessons are filtered from.
535
+ * `planFinds` maps every row to the round's one lesson find (`lessonsKey`);
536
+ * `selectRound` takes any mapping, and records a row with no key as
537
+ * `find_cap` (a status `planFinds` never produces). */
538
+ rowKey: Map<number, string>;
539
+ /** The main session's cases find, when there is one. */
540
+ casesKey: string | null;
541
+ /** The find every lens the session may add filters — the round's lesson
542
+ * find — when the order offers any; null when it offers none. */
543
+ addableKey?: string | null;
544
+ /** The round's one lesson find: every discovery row, the
545
+ * validator and every addable lens filter its answer. Null when the round
546
+ * has neither a plan row nor a lens to add. */
547
+ lessonsKey?: string | null;
548
+ }
549
+
550
+ const QUERY_MAX_CHARS = 600;
551
+
552
+ /** A lens id as a query word: `pass-data-safety` → `data-safety`. */
553
+ function lensWord(lens: string): string {
554
+ return lens.replace(/^pass-/, "");
555
+ }
556
+
557
+ /**
558
+ * The query of the round's one lesson find: the PR title and the
559
+ * shape of its changed files (the round context query's own builder — the
560
+ * changed areas and extensions, a function of the file SET), then the
561
+ * planned lenses, sorted. With the find's limit covering the corpus the query
562
+ * only matters once the corpus outgrows `LESSON_FIND_LIMIT.max`.
563
+ */
564
+ export function roundLessonQuery(input: {
565
+ title: string;
566
+ files: readonly string[];
567
+ lenses: readonly string[];
568
+ }): string {
569
+ const base = roundContextQuery({ title: input.title, files: input.files.map((filename) => ({ filename })) });
570
+ const lenses = [...new Set(input.lenses.map(lensWord).filter((w) => w !== ""))].sort().join(" ");
571
+ return [base, lenses].filter((p) => p !== "").join(" — ").slice(0, QUERY_MAX_CHARS);
572
+ }
573
+
574
+ /** The main session's cases query: the title and the changed paths, sorted
575
+ * (a function of the file SET). */
576
+ export function casesQuery(input: { title: string; files: readonly string[] }): string {
577
+ const title = input.title.replace(/\s+/g, " ").trim();
578
+ const paths = [...new Set(input.files)].sort().slice(0, 12).join(" ");
579
+ return [title, paths].filter((p) => p !== "").join(" — ").slice(0, QUERY_MAX_CHARS);
580
+ }
581
+
582
+ function findKey(area: string, query: string): string {
583
+ return `${area}\u0000${query}`;
584
+ }
585
+
586
+ /**
587
+ * The round's finds — at most two: the main session's cases find
588
+ * (when the PR changes a file), then ONE lesson find inside `experiences/`
589
+ * that every discovery row, the validator and every lens the session may add
590
+ * share, its `limit` sized to cover the lesson corpus (`lessonFindLimit` of
591
+ * `corpus`, the store's count; the ceiling when unknown). Every per-row
592
+ * decision — lens, `paths=` globs, polarity, `as_of`, suppressed, retired,
593
+ * moved, caps, ranking — is `selectRound`'s, on that one answer: over an
594
+ * answer that holds the whole corpus, one shared find gives the same
595
+ * selection as a find per row (tests/lesson-selection.test.ts).
596
+ */
597
+ export function planFinds(input: {
598
+ title: string;
599
+ rows: readonly SelectionRow[];
600
+ prFiles: readonly string[];
601
+ /** The lenses the session may add this round (`addable_lenses`). */
602
+ addable?: readonly string[];
603
+ /** How many lesson files `experiences/` holds (the store's last sweep);
604
+ * null or absent — unknown. */
605
+ corpus?: number | null;
606
+ }): FindPlan {
607
+ const finds: PlannedFind[] = [];
608
+ let casesKey: string | null = null;
609
+ if (input.prFiles.length > 0) {
610
+ const query = casesQuery({ title: input.title, files: input.prFiles });
611
+ casesKey = findKey(CASES_AREA, query);
612
+ finds.push({ key: casesKey, area: CASES_AREA, query, limit: FIND_LIMITS.cases });
613
+ }
614
+ const addable = input.addable ?? [];
615
+ let lessonsKey: string | null = null;
616
+ if (input.rows.length > 0 || addable.length > 0) {
617
+ const query = roundLessonQuery({
618
+ title: input.title,
619
+ files: input.prFiles,
620
+ lenses: input.rows.map((r) => r.lens),
621
+ });
622
+ lessonsKey = findKey(EXPERIENCES_AREA, query);
623
+ finds.push({
624
+ key: lessonsKey,
625
+ area: EXPERIENCES_AREA,
626
+ query,
627
+ limit: lessonFindLimit(input.corpus),
628
+ });
629
+ }
630
+ const rowKey = new Map<number, string>();
631
+ if (lessonsKey !== null) for (const r of input.rows) rowKey.set(r.row, lessonsKey);
632
+ return {
633
+ finds,
634
+ rowKey,
635
+ casesKey,
636
+ addableKey: addable.length > 0 ? lessonsKey : null,
637
+ lessonsKey,
638
+ };
639
+ }
640
+
641
+ /** A lesson as the ledger records it — every field the shadow matcher and
642
+ * the report need, so neither ever reads memory. */
643
+ export interface SelectedLesson {
644
+ uri: string;
645
+ kind: LessonKind;
646
+ class: string | null;
647
+ lens: string[];
648
+ paths: string[];
649
+ evidence: number;
650
+ format: "typed" | "legacy";
651
+ tokens: number;
652
+ score: number;
653
+ created: string | null;
654
+ }
655
+
656
+ export interface SelectedCase {
657
+ uri: string;
658
+ pr: number | null;
659
+ path: string | null;
660
+ lens: string[];
661
+ fate: string | null;
662
+ replies: number;
663
+ tokens: number;
664
+ score: number;
665
+ }
666
+
667
+ /** `row` — a discovery plan row; `validator` — the validator's lessons;
668
+ * `addable` — a lens the session may add (its lessons file);
669
+ * `cases` — the main session's past reviews of these files. */
670
+ export type SelectionRole = "row" | "validator" | "addable" | "cases";
671
+ export type SelectionStatus = "ok" | "timeout" | "unreadable" | "find_cap";
672
+
673
+ export interface RoleSelection {
674
+ role: SelectionRole;
675
+ /** The plan row (`row`, `validator`); the lens's index in
676
+ * `addable_lenses` (`addable`); -1 for the main session's cases. */
677
+ row: number;
678
+ lens: string;
679
+ agent: string | null;
680
+ query: string | null;
681
+ status: SelectionStatus;
682
+ reason?: string;
683
+ lessons: SelectedLesson[];
684
+ cases: SelectedCase[];
685
+ cuts: SelectionCut[];
686
+ dropped: DropCounts;
687
+ }
688
+
689
+ function asSelected(c: LessonCandidate): SelectedLesson {
690
+ return {
691
+ uri: c.uri,
692
+ kind: c.lesson.kind,
693
+ class: c.lesson.class,
694
+ lens: [...c.lesson.lens],
695
+ paths: [...c.lesson.paths],
696
+ evidence: c.lesson.evidence.length,
697
+ format: c.lesson.format,
698
+ tokens: c.tokens,
699
+ score: recordedScore(c.score),
700
+ created: c.created,
701
+ };
702
+ }
703
+
704
+ function caseSelected(c: CaseCandidate): SelectedCase {
705
+ return {
706
+ uri: c.uri,
707
+ pr: c.header.pr,
708
+ path: c.header.path,
709
+ lens: [...c.header.lens],
710
+ fate: c.header.fate,
711
+ replies: c.header.replies,
712
+ tokens: c.tokens,
713
+ score: recordedScore(c.score),
714
+ };
715
+ }
716
+
717
+ export interface SelectRoundInput {
718
+ pr: number;
719
+ rows: readonly SelectionRow[];
720
+ prFiles: readonly string[];
721
+ root: string;
722
+ plan: FindPlan;
723
+ outcomes: ReadonlyMap<string, FindOutcome>;
724
+ retired: ReadonlySet<string>;
725
+ suppressed: ReadonlySet<string>;
726
+ asOf?: string | null;
727
+ caps?: { row: SelectionCap; cases: SelectionCap; validator: SelectionCap };
728
+ /** The lenses the session may add (`addable_lenses`): one
729
+ * `addable` record each, from the plan's shared addable find. */
730
+ addable?: readonly string[];
731
+ /** Filled with every SELECTED lesson's and case's text, by URI — what
732
+ * delivery renders. The records themselves stay text-free: they are
733
+ * what the ledger stores. */
734
+ texts?: Map<string, string>;
735
+ }
736
+
737
+ /**
738
+ * The round's selection, one record per role: every discovery row's lessons,
739
+ * the validator's (the dont-raise lessons any discovery row found eligible,
740
+ * and every lesson naming `pass-validate` its row's find returned), every
741
+ * lens the session may add (filtered per lens like a row over the PR's
742
+ * files), and the main session's cases. Under `planFinds` the rows, the
743
+ * validator and the addable lenses all read the round's one lesson find; the
744
+ * function itself takes any plan (each row's answer by its `rowKey`). Pure
745
+ * and deterministic: the same outcomes in any order give the same records.
746
+ */
747
+ export function selectRound(input: SelectRoundInput): RoleSelection[] {
748
+ const caps = input.caps ?? SELECTION_CAPS;
749
+ const out: RoleSelection[] = [];
750
+ const keepText = (c: { uri: string; text: string }): void => {
751
+ input.texts?.set(c.uri, c.text);
752
+ };
753
+ const query = (key: string | undefined | null): string | null =>
754
+ key ? (input.plan.finds.find((f) => f.key === key)?.query ?? null) : null;
755
+ const base = { retired: input.retired, suppressed: input.suppressed, asOf: input.asOf ?? null, root: input.root };
756
+ // Every dont-raise lesson some planned discovery row found eligible — the
757
+ // validator's candidates beside its own find's. An addable lens's do not
758
+ // join: an added lens may never run.
759
+ const dontRaise = new Map<string, LessonCandidate>();
760
+ let validatorRow: SelectionRow | null = null;
761
+ /** A discovery role's selection from its find's hits — planned rows and
762
+ * addable lenses alike: filtered for its lens and files, ranked, capped. A
763
+ * planned row's dont-raise lessons also feed the validator's pool. */
764
+ const selectDiscovery = (
765
+ rec: RoleSelection,
766
+ hits: readonly FindHit[],
767
+ files: readonly string[],
768
+ ): void => {
769
+ const { eligible, dropped } = filterLessonHits(hits, { ...base, lens: rec.lens, files });
770
+ rec.dropped = dropped;
771
+ if (rec.role === "row")
772
+ for (const c of eligible)
773
+ if (c.lesson.kind === "dont-raise" && !dontRaise.has(c.uri)) dontRaise.set(c.uri, c);
774
+ const { selected, cuts } = capSelection(rankLessons(eligible, rec.lens), caps.row);
775
+ rec.lessons = selected.map(asSelected);
776
+ selected.forEach(keepText);
777
+ rec.cuts = cuts;
778
+ };
779
+
780
+ for (const r of input.rows) {
781
+ if (r.lens === VALIDATOR_LENS) {
782
+ validatorRow ??= r;
783
+ continue;
784
+ }
785
+ const key = input.plan.rowKey.get(r.row);
786
+ const rec: RoleSelection = {
787
+ role: "row",
788
+ row: r.row,
789
+ lens: r.lens,
790
+ agent: r.agent,
791
+ query: query(key),
792
+ status: "ok",
793
+ lessons: [],
794
+ cases: [],
795
+ cuts: [],
796
+ dropped: {},
797
+ };
798
+ out.push(rec);
799
+ if (!key) {
800
+ rec.status = "find_cap";
801
+ continue;
802
+ }
803
+ const o = input.outcomes.get(key) ?? { status: "timeout" as const };
804
+ if (o.status !== "ok") {
805
+ rec.status = o.status;
806
+ if (o.status === "unreadable") rec.reason = o.reason;
807
+ continue;
808
+ }
809
+ selectDiscovery(rec, o.hits, r.focus && r.focus.length > 0 ? r.focus : input.prFiles);
810
+ }
811
+
812
+ if (validatorRow) {
813
+ const key = input.plan.rowKey.get(validatorRow.row);
814
+ const rec: RoleSelection = {
815
+ role: "validator",
816
+ row: validatorRow.row,
817
+ lens: VALIDATOR_LENS,
818
+ agent: validatorRow.agent,
819
+ query: query(key),
820
+ status: "ok",
821
+ lessons: [],
822
+ cases: [],
823
+ cuts: [],
824
+ dropped: {},
825
+ };
826
+ const pool = new Map(dontRaise);
827
+ if (!key) rec.status = "find_cap";
828
+ else {
829
+ const o = input.outcomes.get(key) ?? { status: "timeout" as const };
830
+ if (o.status !== "ok") {
831
+ // Its own find did not answer; the discovery rows' dont-raise lessons
832
+ // are still its candidates.
833
+ rec.status = o.status;
834
+ if (o.status === "unreadable") rec.reason = o.reason;
835
+ } else {
836
+ const { eligible, dropped } = filterLessonHits(o.hits, {
837
+ ...base,
838
+ lens: VALIDATOR_LENS,
839
+ files: input.prFiles,
840
+ });
841
+ rec.dropped = dropped;
842
+ for (const c of eligible)
843
+ if (c.lesson.lens.includes(VALIDATOR_LENS) || c.lesson.kind === "dont-raise")
844
+ if (!pool.has(c.uri)) pool.set(c.uri, c);
845
+ }
846
+ }
847
+ // Ranked against the whole PR: a path hit is a hit on any changed file.
848
+ const ranked = rankLessons(
849
+ [...pool.values()].map((c) => ({
850
+ ...c,
851
+ pathHit: pathHitOn(c.lesson, input.prFiles),
852
+ })),
853
+ VALIDATOR_LENS,
854
+ );
855
+ const { selected, cuts } = capSelection(ranked, caps.validator);
856
+ rec.lessons = selected.map(asSelected);
857
+ selected.forEach(keepText);
858
+ rec.cuts = cuts;
859
+ out.push(rec);
860
+ }
861
+
862
+ // The lenses the session may add: each filtered over the PR's files
863
+ // from the one shared find, ranked and capped like a row.
864
+ const addable = [...new Set(input.addable ?? [])];
865
+ if (addable.length > 0) {
866
+ const key = input.plan.addableKey ?? null;
867
+ const o: FindOutcome | null = key ? (input.outcomes.get(key) ?? { status: "timeout" }) : null;
868
+ addable.forEach((lens, i) => {
869
+ const rec: RoleSelection = {
870
+ role: "addable",
871
+ row: i,
872
+ lens,
873
+ agent: null,
874
+ query: query(key),
875
+ status: "ok",
876
+ lessons: [],
877
+ cases: [],
878
+ cuts: [],
879
+ dropped: {},
880
+ };
881
+ out.push(rec);
882
+ if (!o) {
883
+ rec.status = "find_cap";
884
+ return;
885
+ }
886
+ if (o.status !== "ok") {
887
+ rec.status = o.status;
888
+ if (o.status === "unreadable") rec.reason = o.reason;
889
+ return;
890
+ }
891
+ selectDiscovery(rec, o.hits, input.prFiles);
892
+ });
893
+ }
894
+
895
+ const casesKey = input.plan.casesKey;
896
+ const casesRec: RoleSelection = {
897
+ role: "cases",
898
+ row: -1,
899
+ lens: "",
900
+ agent: null,
901
+ query: query(casesKey),
902
+ status: "ok",
903
+ lessons: [],
904
+ cases: [],
905
+ cuts: [],
906
+ dropped: {},
907
+ };
908
+ if (casesKey) {
909
+ const o = input.outcomes.get(casesKey) ?? { status: "timeout" as const };
910
+ if (o.status !== "ok") {
911
+ casesRec.status = o.status;
912
+ if (o.status === "unreadable") casesRec.reason = o.reason;
913
+ } else {
914
+ const { eligible, dropped } = filterCaseHits(o.hits, {
915
+ ...base,
916
+ pr: input.pr,
917
+ files: input.prFiles,
918
+ lenses: input.rows.map((r) => r.lens),
919
+ });
920
+ casesRec.dropped = dropped;
921
+ const { selected, cuts } = capSelection(rankCases(eligible), caps.cases);
922
+ casesRec.cases = selected.map(caseSelected);
923
+ selected.forEach(keepText);
924
+ casesRec.cuts = cuts;
925
+ }
926
+ }
927
+ out.push(casesRec);
928
+ return out;
929
+ }
930
+
931
+ // ---- repo facts for the recheck and the ping-pong wake ----------------------
932
+
933
+ /** The query of a repo-fact find: the PR's title and the touched paths,
934
+ * sorted (a function of the path SET). */
935
+ export function repoFactsQuery(input: { title: string; paths: readonly string[] }): string {
936
+ return casesQuery({ title: input.title, files: input.paths });
937
+ }
938
+
939
+ /**
940
+ * The repo-fact lessons for the paths a recheck's delta or an author's reply
941
+ * touches: the same header filters as a row's (never retired,
942
+ * moved, suppressed, of unknown polarity, or created on/after `as_of`), no
943
+ * lens precondition (the main session reads them), and then only
944
+ * `kind=repo-fact` lessons whose `paths=` glob matches a TOUCHED path — a
945
+ * lesson naming no paths is for no path in particular, so it is not "for the
946
+ * touched paths" and is left out (`no_paths`). Ranked and capped like a row.
947
+ * Pure.
948
+ */
949
+ export function selectRepoFacts(
950
+ hits: readonly FindHit[],
951
+ ctx: Omit<LessonFilterContext, "lens">,
952
+ cap: SelectionCap = SELECTION_CAPS.row,
953
+ ): { selected: LessonCandidate[]; cuts: SelectionCut[]; dropped: DropCounts } {
954
+ const { eligible, dropped } = filterLessonHits(hits, { ...ctx, lens: null });
955
+ const facts: LessonCandidate[] = [];
956
+ for (const c of eligible) {
957
+ if (c.lesson.kind !== "repo-fact") bump(dropped, "kind");
958
+ else if (!c.pathHit) bump(dropped, "no_paths");
959
+ else facts.push(c);
960
+ }
961
+ const { selected, cuts } = capSelection(rankLessons(facts, ""), cap);
962
+ return { selected, cuts, dropped };
963
+ }
964
+
965
+ // ---- the engine port ---------------------------------------------------------
966
+
967
+ /**
968
+ * What the selector asks of the context engine — the port, so selection and
969
+ * its budget are testable over a fake engine and nothing above it knows HTTP
970
+ * (src/openviking/lessonfind.ts is the implementation). TOTAL: both methods
971
+ * resolve, a refusal is an answer (`ok: false`) and never a throw.
972
+ */
973
+ export interface LessonEngine {
974
+ /** The memories root URI the areas live under. */
975
+ root(): string;
976
+ /** One `/search/find` inside `<root>/<area>`. */
977
+ find(
978
+ area: string,
979
+ query: string,
980
+ opts: { limit: number; timeoutMs: number },
981
+ ): Promise<{ ok: true; hits: readonly FindHit[] } | { ok: false; reason: string }>;
982
+ /** The store's list of retired URIs (its last completed sweep). */
983
+ retiredUris(): Promise<readonly string[]>;
984
+ /** How many files `<root>/<area>/` holds by the store's last completed
985
+ * sweep — what sizes the lesson find's `limit`. Synchronous
986
+ * and I/O-free (it never waits for a sweep); null when no sweep has
987
+ * completed. Absent ⇒ unknown. */
988
+ corpusSize?(area: string): number | null;
989
+ }