@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,1060 @@
1
+ // Memory keys — mint, place, prove.
2
+ //
3
+ // A new operator gets working, CONFINED memory without ever learning what a
4
+ // memory key is: this step issues and places all three keys, and the one
5
+ // placement mistake that matters (the companion key landing where review
6
+ // sessions can read it) is a check, not a paragraph of prose.
7
+ //
8
+ // THE THREE KEYS AND WHERE EACH ONE MAY LIVE. This is the whole point of the
9
+ // step, and it is absolute (the companion boundary, docs/companion-memory-access.md):
10
+ //
11
+ // root the SERVER's own credential. ONLY <secrets>/openviking_root_key,
12
+ // 0600, on the daemon host. Never a client credential, never in the
13
+ // operator key file, never handed to a session or the companion.
14
+ // reviewer the one USER key the daemon and every review session hold.
15
+ // <secrets>/openviking_reviewer_key AND the operator key file.
16
+ // companion the companion's own USER key. ONLY the operator key file (0600).
17
+ // NEVER on the daemon side: review sessions run in that container,
18
+ // and a companion key they could read would defeat the confinement
19
+ // this whole design exists to enforce.
20
+ //
21
+ // The compose route mounts the WHOLE secrets dir into the container read-only,
22
+ // so the key file must never sit inside it. Its documented home is the
23
+ // operator home, outside every mounted dir; `resolveKeysFile` refuses any
24
+ // layout that would put it inside a dir the container mounts anyway (the
25
+ // secrets dir, the config home, the live config's directory, the checkout —
26
+ // `keysFileConfinement`), rather than writing a key into a mounted directory.
27
+ //
28
+ // IDEMPOTENT BY CONSTRUCTION. An existing key is left exactly alone: minting
29
+ // asks the server for the key a user ALREADY has instead of issuing a second
30
+ // one, and a local file that already holds a value is never overwritten. A
31
+ // rotation would orphan every copy already distributed — the daemon's secrets
32
+ // mount, the operator's key file — so nothing here rotates, ever. A local value
33
+ // that disagrees with the server is reported red, not "fixed".
34
+ //
35
+ // TWO PHASES, because the two halves need different things:
36
+ // A. the root key is minted and placed OFFLINE — it must be in the secrets
37
+ // dir BEFORE the daemon container boots, since the entrypoint renders it
38
+ // into ov.conf (no root key ⇒ the server degrades to auth_mode=dev and
39
+ // confinement is not enforced);
40
+ // B. the USER keys can only come from a RUNNING server (it mints them), so
41
+ // that half needs the stack up. Running this step before bring-up lands
42
+ // phase A and says plainly that phase B is waiting; re-run it after
43
+ // bring-up and it completes. The engine's resume re-verification is what
44
+ // makes that a normal flow rather than a special case.
45
+ //
46
+ // VERIFICATION IS THE EXISTING FOUR-CELL CONFINEMENT MATRIX
47
+ // (scripts/companion-memory-forward.mjs `runVerify`) — not a second proof.
48
+ // A FAILED row fails the step; an INCONCLUSIVE row also fails it. Inconclusive
49
+ // means the probe could not tell (a 404, a 5xx, a 200 carrying an error
50
+ // envelope), and "could not tell" has never been a pass for this matrix.
51
+ //
52
+ // DECLINING IS LEGAL AND LOUD. An operator who says no to memory setup gets the
53
+ // documented memory-less mode — rounds still run (context assembly resolves
54
+ // empty and never blocks or delays a round), the TUI's Memory tab paints its
55
+ // store row red, the EOD curator and the [feedback] sink have nowhere to write.
56
+ // The step records the choice, mints and places nothing, and writes exactly ONE
57
+ // thing: `[openviking] enabled = false` in config.toml — the daemon's word for
58
+ // "off". Without it the daemon cannot tell a declined install from
59
+ // a broken one: memory health reads a missing reviewer key as the credential
60
+ // failure it would be on an install that wanted memory, and wakes the overseer,
61
+ // paints the board and files a ticket for a choice. Configuring memory later
62
+ // switches it back on. It never wedges and never crashes.
63
+ import { createHash } from "node:crypto";
64
+ import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync, } from "node:fs";
65
+ import { homedir } from "node:os";
66
+ import { dirname, join, resolve, sep } from "node:path";
67
+ import { pathToFileURL } from "node:url";
68
+ import { OPENVIKING_DEFAULTS, parseConfig } from "../../config.js";
69
+ import { configHome, locateKeysFile, locateSecrets } from "../../install.js";
70
+ import { tuiMemoryBaseUrl } from "../../tui/memory.js";
71
+ import { shellQuote } from "../../tui/remote.js";
72
+ import { CHOICE_KEYS, MEMORY_CHOICE_IDS } from "../choices.js";
73
+ import { deliverConfigChange } from "./configdelivery.js";
74
+ import { configMountOf } from "./bringup.js";
75
+ import { MEMORY_SERVICE, interviewConfigPath, readTextOrNull, rootOf, writeAtomic, } from "./compose.js";
76
+ import { assertNoDryRunEdit, patchToml } from "./configfill.js";
77
+ import { readTomlKey } from "./ingress.js";
78
+ import { topologyOf } from "./topology.js";
79
+ import { remoteFactsFor, stackTransportFor } from "./transport.js";
80
+ export const MEMORY_STEP_ID = "memory";
81
+ /** Recorded choice: "configure" (default) | "declined". */
82
+ export const MEMORY_CHOICE_KEY = CHOICE_KEYS.memory;
83
+ export const MEMORY_RESTART_CHOICE_KEY = CHOICE_KEYS.memoryRestartOwed;
84
+ /** Private placement bookkeeping; verification follows the current locator. */
85
+ export const KEYS_FILE_CHOICE_KEY = "openviking_keys_file";
86
+ export const REVIEWER_USER = "reviewer";
87
+ export const COMPANION_USER = "companion";
88
+ /** Secret FILE NAMES — taken from the one config authority so this step cannot
89
+ * drift from the entrypoint, ansible and the secrets wizard. */
90
+ export const ROOT_KEY_FILE = OPENVIKING_DEFAULTS.root_key_file;
91
+ export const REVIEWER_KEY_FILE = OPENVIKING_DEFAULTS.reviewer_key_file;
92
+ /** The operator key file's three variables (docs/companion-memory-access.md).
93
+ * `OPENVIKING_API_KEY` is the companion extension's own identity. */
94
+ export const COMPANION_VARS = ["OPENVIKING_API_KEY", "OPENVIKING_COMPANION_KEY"];
95
+ export const REVIEWER_VAR = "OPENVIKING_REVIEWER_KEY";
96
+ /** Where the daemon container mounts the secrets dir, read-only — the same
97
+ * path on both routes (docker-compose.yml, the playbook's container task). */
98
+ export const CONTAINER_SECRETS_DIR = "/opt/quickreview/secrets";
99
+ // ---- path rules -------------------------------------------------------------
100
+ /** The install locator's answer: a set `[github] secrets_dir`
101
+ * first — exactly as the daemon's loader and the compose mount read it — then
102
+ * `$QC_SECRETS_DIR`, then `<config home>/secrets`. */
103
+ export function resolveSecretsDir(env, home, configured) {
104
+ return resolve(locateSecrets({ configured, override: env.QC_SECRETS_DIR, env: { ...env, HOME: home } }).path);
105
+ }
106
+ /** `[github] secrets_dir` as the live config.toml writes it; null when the
107
+ * file is not there yet (the step then resolves as an unset value would). */
108
+ function configuredSecretsDir(configPath) {
109
+ try {
110
+ return readTomlKey(readFileSync(configPath, "utf8"), "github", "secrets_dir");
111
+ }
112
+ catch {
113
+ return null;
114
+ }
115
+ }
116
+ /** The documented key-file location — the install locator's, the
117
+ * same one `keysFilePath` in the TUI and the forward read. */
118
+ export function documentedKeysFile(env, home) {
119
+ return resolve(locateKeysFile({ env: { ...env, HOME: home } }).path);
120
+ }
121
+ /** Is `file` inside `dir`? (A file IN the daemon-side secrets dir is readable by
122
+ * every review session on the compose route — the whole dir is bind-mounted.) */
123
+ export function isInside(dir, file) {
124
+ const d = resolve(dir).replace(new RegExp(`${sep}$`), "");
125
+ const f = resolve(file);
126
+ return f === d || f.startsWith(`${d}${sep}`);
127
+ }
128
+ /**
129
+ * Where the operator key file goes.
130
+ *
131
+ * The companion key lives in that file, so the file must not be inside the
132
+ * daemon-side secrets dir (`docker-compose.yml` mounts `$QCR_SECRETS_DIR`
133
+ * read-only at `/opt/quickreview/secrets`) nor inside the install's config home
134
+ * (mounted read-only too), or it would be one `cat` away from every review
135
+ * session. Its default home is the operator home, outside both. A
136
+ * layout that puts it inside either anyway — a pinned `QCR_OPENVIKING_KEYS`,
137
+ * or a secrets dir that contains the operator home — is refused rather than
138
+ * quietly moved: there is no other documented place to move it to.
139
+ */
140
+ export function resolveKeysFile(secretsDir, env, home, mounted = []) {
141
+ const pinned = (env.QCR_OPENVIKING_KEYS ?? "").trim() !== "";
142
+ const candidate = documentedKeysFile(env, home);
143
+ return keysFileConfinement(candidate, secretsDir, env, home, mounted, pinned);
144
+ }
145
+ /**
146
+ * Is a key file at `path` confined — outside EVERY directory the daemon
147
+ * container mounts? Those are the secrets dir, the install's config home,
148
+ * and whatever the caller adds: bring-up mounts the directory of
149
+ * the live config.toml (wherever `QCR_CONFIG` points, `configMountOf`) and the
150
+ * whole checkout (read-write, at /opt/quickreview/sandbox). A key file inside
151
+ * any of them is one `cat` away from every review session.
152
+ */
153
+ export function keysFileConfinement(path, secretsDir, env, home, mounted = [], pinned = true) {
154
+ const fix = pinned
155
+ ? "Point it at a path outside that directory and run this step again."
156
+ : "Point the secrets dir elsewhere, or set QCR_OPENVIKING_KEYS to a path outside it, and run this step again.";
157
+ const what = pinned ? "QCR_OPENVIKING_KEYS points" : `the key file's home ${path} sits`;
158
+ if (isInside(secretsDir, path)) {
159
+ return {
160
+ path,
161
+ unsafe: true,
162
+ note: `${what} inside the daemon-side secrets dir (${secretsDir}), which the container mounts read-only — ` +
163
+ `a review session could read the companion key there. ${fix}`,
164
+ };
165
+ }
166
+ const cfgHome = configHome({ ...env, HOME: home });
167
+ const places = [
168
+ [cfgHome, `the install's config home (${cfgHome}), which the container mounts read-only`],
169
+ ...mounted.map((dir) => [dir, `${dir}, which the daemon container mounts`]),
170
+ ];
171
+ for (const [dir, label] of places) {
172
+ if (isInside(dir, path)) {
173
+ return {
174
+ path,
175
+ unsafe: true,
176
+ note: `${what} inside ${label} — a review session could read the companion key there. ${fix}`,
177
+ };
178
+ }
179
+ }
180
+ return { path, unsafe: false, note: "" };
181
+ }
182
+ // ---- small file helpers (0600 everywhere) -----------------------------------
183
+ function writePrivate(path, content) {
184
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
185
+ const tmp = join(dirname(path), `.${path.split(sep).at(-1)}.tmp`);
186
+ writeFileSync(tmp, content, { mode: 0o600 });
187
+ chmodSync(tmp, 0o600);
188
+ renameSync(tmp, path);
189
+ chmodSync(path, 0o600);
190
+ }
191
+ /** A secret file's value, or "" (an unreadable secret is a degraded mode). */
192
+ export function readSecretFile(path) {
193
+ try {
194
+ return readFileSync(path, "utf8").trim();
195
+ }
196
+ catch {
197
+ return "";
198
+ }
199
+ }
200
+ /** Why a file that EXISTS could not be read (its errno code), or null when it
201
+ * is absent or readable. The readers above fold both into "empty" — right for
202
+ * reporting, wrong before a write: an unreadable key is not a missing one, and
203
+ * replacing it would rotate a key (or drop variables) we could not even see. */
204
+ export function unreadableReason(path) {
205
+ try {
206
+ readFileSync(path);
207
+ return null;
208
+ }
209
+ catch (err) {
210
+ const code = err.code;
211
+ return code === "ENOENT" ? null : (code ?? String(err));
212
+ }
213
+ }
214
+ function unreadableCheck(name, path, why) {
215
+ return {
216
+ name,
217
+ ok: false,
218
+ detail: `${path} exists but cannot be read (${why}) — left untouched: writing over it would rotate or drop keys that are ` +
219
+ "already in use. Fix its ownership/permissions and run this step again.",
220
+ };
221
+ }
222
+ /** `KEY=value` lines → map. Mirrors `readKeys` in the forward script. */
223
+ export function parseKeysFile(text) {
224
+ const out = {};
225
+ for (const line of text.split("\n")) {
226
+ const m = /^\s*(?:export\s+)?([A-Z0-9_]+)\s*=\s*(.*)$/.exec(line);
227
+ if (!m || m[1] === undefined || m[2] === undefined)
228
+ continue;
229
+ out[m[1]] = m[2].trim().replace(/^["']|["']$/g, "");
230
+ }
231
+ return out;
232
+ }
233
+ export function readKeysFile(path) {
234
+ try {
235
+ return parseKeysFile(readFileSync(path, "utf8"));
236
+ }
237
+ catch {
238
+ return {};
239
+ }
240
+ }
241
+ /** Render the key file, preserving any variables already in it that we do not
242
+ * own. Values already present are never replaced — that is the no-rotation rule
243
+ * at the file level. */
244
+ export function renderKeysFile(existing, next) {
245
+ const merged = { ...existing };
246
+ for (const [k, v] of Object.entries(next)) {
247
+ if (v && !merged[k])
248
+ merged[k] = v;
249
+ }
250
+ const head = [
251
+ "# OpenViking USER keys — the operator's copy (written by qcr onboard).",
252
+ "# BOTH user keys, and never a root or admin key: an admin key lists every",
253
+ "# user key in plaintext. The companion key must never reach the daemon-side",
254
+ "# secrets dir — review sessions run in that container.",
255
+ "# 0600. Read by the TUI, the companion container (--env-file) and",
256
+ "# scripts/companion-memory-forward.mjs.",
257
+ ];
258
+ const body = Object.entries(merged).map(([k, v]) => `${k}=${v}`);
259
+ return `${[...head, ...body].join("\n")}\n`;
260
+ }
261
+ /** Every file under `dir`, at any depth (the whole tree is bind-mounted),
262
+ * whose contents contain `value`. The companion-key negative assertion runs
263
+ * through this. A symlinked directory is not descended: its target is not
264
+ * part of the mount. */
265
+ export function filesContaining(dir, value) {
266
+ if (!value || !existsSync(dir))
267
+ return [];
268
+ const hits = [];
269
+ const walk = (at) => {
270
+ let names;
271
+ try {
272
+ names = readdirSync(at);
273
+ }
274
+ catch {
275
+ return;
276
+ }
277
+ for (const name of names) {
278
+ const path = join(at, name);
279
+ try {
280
+ if (lstatSync(path).isDirectory()) {
281
+ walk(path);
282
+ continue;
283
+ }
284
+ if (!statSync(path).isFile())
285
+ continue;
286
+ if (readFileSync(path, "utf8").includes(value))
287
+ hits.push(path);
288
+ }
289
+ catch {
290
+ /* unreadable file — cannot leak what we cannot read here either */
291
+ }
292
+ }
293
+ };
294
+ walk(dir);
295
+ return hits;
296
+ }
297
+ function modeOk(path) {
298
+ try {
299
+ return (statSync(path).mode & 0o077) === 0;
300
+ }
301
+ catch {
302
+ return false;
303
+ }
304
+ }
305
+ /** The two answers — the tool schema's enum, the guards and the refusal text
306
+ * all read this one list. */
307
+ export { MEMORY_CHOICE_IDS } from "../choices.js";
308
+ function isMemoryChoice(value) {
309
+ return MEMORY_CHOICE_IDS.includes(value);
310
+ }
311
+ /**
312
+ * Read a typed answer as a choice, or `null` when it is neither a yes nor a
313
+ * no. An empty answer is the [Y/n] prompt's default, "configure"; anything
314
+ * unrecognised is null, so the step refuses with the options rather than
315
+ * guessing — a guessed "configure" mints keys and turns memory on, and a
316
+ * guessed "declined" turns memory off. Each word must be whole: "need more
317
+ * information" is not a no.
318
+ */
319
+ export function normalizeMemoryChoice(answer) {
320
+ const text = (answer ?? "").trim();
321
+ if (text === "")
322
+ return "configure";
323
+ if (/^(n|no|nope|skip|declin(e|ed|ing)?|later|without)\b/i.test(text))
324
+ return "declined";
325
+ if (/^(y|yes|yep|yeah|sure|ok|okay|configure|set ?up)\b/i.test(text))
326
+ return "configure";
327
+ return null;
328
+ }
329
+ /** The refusal for an answer that is not a recognised choice. */
330
+ export function memoryChoiceOfferCheck(answer) {
331
+ return {
332
+ name: "choice",
333
+ ok: false,
334
+ detail: `"${answer.trim()}" is not a recognised answer — pick one of ${MEMORY_CHOICE_IDS.join(" | ")} and call this ` +
335
+ 'step again with it (choice: "<id>"): "configure" sets memory up, "declined" runs the reviewer memory-less.',
336
+ };
337
+ }
338
+ export const DECLINED_CHECKS = [
339
+ {
340
+ name: "memory",
341
+ ok: true,
342
+ detail: "memory setup DECLINED — running memory-less, which is a legal mode: rounds still run (context assembly resolves " +
343
+ "empty and never blocks or delays a round), the TUI's Memory tab paints its MEMORY STORE row red, and the EOD " +
344
+ "curator and the [feedback] sink have nowhere to write. No key was minted or placed. Re-run this step with " +
345
+ 'choice "configure" to set memory up later.',
346
+ },
347
+ ];
348
+ /** The check row that reports the daemon's on/off switch. */
349
+ export const MEMORY_SWITCH_CHECK = "memory-switch";
350
+ /**
351
+ * Tell the DAEMON the operator's answer: `[openviking] enabled =
352
+ * false` on a decline — its word for "off", under which memory health reports
353
+ * "not monitored" and raises nothing — and back to `true` when memory is
354
+ * configured over an earlier decline. Configuring never ADDS the key: an
355
+ * install that never said "off" stays exactly as it is. The patched text is
356
+ * parsed by the daemon's own loader before it is written, like every other
357
+ * wizard config write. Returns the row to report, or null when there is
358
+ * nothing to say (configuring an install that is already on).
359
+ */
360
+ function switchMemory(ctx, on) {
361
+ const path = interviewConfigPath(ctx);
362
+ const text = readTextOrNull(path);
363
+ if (text === null) {
364
+ return on
365
+ ? null
366
+ : {
367
+ name: MEMORY_SWITCH_CHECK,
368
+ ok: false,
369
+ detail: `${path} does not exist yet, so the daemon cannot be told memory is OFF — without that it reads the missing ` +
370
+ "reviewer key as a credential failure and wakes the overseer about it. Run the config_fill step, then this step again",
371
+ };
372
+ }
373
+ const current = readTomlKey(text, "openviking", "enabled");
374
+ if (on && current !== "false")
375
+ return null;
376
+ if (!on && current === "false") {
377
+ return {
378
+ name: MEMORY_SWITCH_CHECK,
379
+ ok: true,
380
+ detail: `[openviking] enabled = false already in ${path} — the daemon reports memory "not monitored" and raises no memory alert`,
381
+ };
382
+ }
383
+ const edits = [
384
+ { section: "openviking", key: "enabled", value: on ? "true" : "false" },
385
+ ];
386
+ assertNoDryRunEdit(edits);
387
+ const patched = patchToml(text, edits);
388
+ try {
389
+ parseConfig(patched);
390
+ }
391
+ catch (err) {
392
+ return {
393
+ name: MEMORY_SWITCH_CHECK,
394
+ ok: false,
395
+ detail: `[openviking] enabled = ${on ? "true" : "false"} would not load in ${path}: ${String(err)} — nothing was written`,
396
+ };
397
+ }
398
+ writeAtomic(path, patched);
399
+ return {
400
+ name: MEMORY_SWITCH_CHECK,
401
+ ok: true,
402
+ detail: on
403
+ ? `[openviking] enabled = true written to ${path} (it said false from an earlier decline) — ready for the daemon to reload`
404
+ : `[openviking] enabled = false written to ${path} — the daemon's word for "off": memory health reports "not monitored" ` +
405
+ "and raises no memory alert after the daemon reloads it",
406
+ };
407
+ }
408
+ /** Verify's half of the switch for a configured install: the daemon must not
409
+ * have been told memory is OFF since. */
410
+ function switchStillOn(ctx) {
411
+ const path = interviewConfigPath(ctx);
412
+ const text = readTextOrNull(path);
413
+ if (text === null || readTomlKey(text, "openviking", "enabled") !== "false")
414
+ return null;
415
+ return {
416
+ name: MEMORY_SWITCH_CHECK,
417
+ ok: false,
418
+ detail: `memory is configured, but ${path} says [openviking] enabled = false — the daemon runs memory-less whatever the ` +
419
+ 'keys prove. Run this step again with choice "configure" to switch it back on',
420
+ };
421
+ }
422
+ /** Verify's half of the switch: a declined install must still SAY off. */
423
+ function switchStillOff(ctx) {
424
+ const path = interviewConfigPath(ctx);
425
+ const text = readTextOrNull(path);
426
+ const current = text === null ? null : readTomlKey(text, "openviking", "enabled");
427
+ return current === "false"
428
+ ? { name: MEMORY_SWITCH_CHECK, ok: true, detail: `[openviking] enabled = false in ${path}` }
429
+ : {
430
+ name: MEMORY_SWITCH_CHECK,
431
+ ok: false,
432
+ detail: text === null
433
+ ? `${path} is not readable — the daemon cannot be told memory is OFF; run this step again`
434
+ : `memory was declined but ${path} does not say [openviking] enabled = false — the daemon will read the missing ` +
435
+ "reviewer key as a credential failure and wake the overseer; run this step again",
436
+ };
437
+ }
438
+ // ---- the step ---------------------------------------------------------------
439
+ function defaultLoaders(root) {
440
+ // Dynamic, by file URL, for the same reason src/tui/memforward.ts does it:
441
+ // both scripts are dependency-free ESM outside tsconfig's include, and a
442
+ // static import would either drag them into the build or fork their logic.
443
+ return {
444
+ provision: () => import(pathToFileURL(join(root, "scripts", "openviking-provision.mjs")).href),
445
+ matrix: () => import(pathToFileURL(join(root, "scripts", "companion-memory-forward.mjs")).href),
446
+ };
447
+ }
448
+ async function serverReady(fetchFn, base, provision) {
449
+ try {
450
+ const res = await fetchFn(`${base}/ready`, { signal: AbortSignal.timeout(10_000) });
451
+ let ok = res.status >= 200 && res.status < 300;
452
+ let detail = `HTTP ${res.status}`;
453
+ if (!ok) {
454
+ try {
455
+ const text = typeof res.text === "function" ? await res.text() : JSON.stringify(await res.json());
456
+ if (text.trim())
457
+ detail += `: ${text.trim().slice(0, 500)}`;
458
+ const embedding = provision.readyButEmbedding?.(JSON.parse(text));
459
+ if (embedding != null) {
460
+ ok = true;
461
+ detail += "; user provisioning can use the admin API despite the embedder failure";
462
+ }
463
+ }
464
+ catch {
465
+ /* The HTTP answer still establishes reachability. */
466
+ }
467
+ }
468
+ return { ok, detail, answering: true };
469
+ }
470
+ catch (err) {
471
+ return {
472
+ ok: false,
473
+ detail: err instanceof Error ? err.message : String(err),
474
+ answering: false,
475
+ };
476
+ }
477
+ }
478
+ function resolvePaths(opts, ctx) {
479
+ const env = opts.env ?? process.env;
480
+ const home = opts.home ?? homedir();
481
+ const secretsDir = opts.secretsDir
482
+ ? resolve(opts.secretsDir)
483
+ : resolveSecretsDir(env, home, configuredSecretsDir(ctx.adapters.paths.configPath));
484
+ const mounted = daemonMounts(ctx);
485
+ const keys = opts.keysFile
486
+ ? keysFileConfinement(resolve(opts.keysFile), secretsDir, env, home, mounted)
487
+ : resolveKeysFile(secretsDir, env, home, mounted);
488
+ // The endpoint is the memory forward's loopback listener on both routes —
489
+ // the engine is never published on a host port (docker-compose.yml, the
490
+ // playbook) — so this step reaches memory exactly where the TUI does.
491
+ const base = opts.base ?? ((env.QCR_OV_BASE ?? "").trim() || tuiMemoryBaseUrl(env));
492
+ const account = opts.account ?? ((env.QCR_OV_ADMIN_ACCOUNT ?? "").trim() || "default");
493
+ return { secretsDir, keys, base, account, env, home, mounted };
494
+ }
495
+ /** The host dirs bring-up mounts into the daemon container besides the
496
+ * secrets dir and the config home: the live config's directory
497
+ * (`configMountOf`) and the checkout. */
498
+ function daemonMounts(ctx) {
499
+ return [configMountOf(ctx.adapters.paths.configPath).dir, rootOf(ctx.adapters)];
500
+ }
501
+ /**
502
+ * The forward's own flags for THIS install: the alias, container and sudo the
503
+ * transport reads from config.toml ([tui] container / sudo_docker), on the
504
+ * laptop route the compose memory sidecar's container name (the engine runs
505
+ * there, not in the daemon). Rendered in full — the
506
+ * script's built-in defaults name the maintainers' own host, never yours —
507
+ * and `install` writes the same flags into the systemd unit.
508
+ */
509
+ export function forwardFlags(ctx) {
510
+ const facts = remoteFactsFor(ctx.adapters, ctx.choices);
511
+ const sudo = facts.sudo ? [] : ["--no-sudo"];
512
+ if (topologyOf(ctx.choices) === "vm") {
513
+ return [
514
+ "--ssh-host",
515
+ shellQuote(facts.alias || "<your-ssh-alias>"),
516
+ "--container",
517
+ shellQuote(facts.memoryContainer),
518
+ ...sudo,
519
+ ].join(" ");
520
+ }
521
+ // The memory sidecar's container NAME (stable across a recreate, unlike its
522
+ // id), resolved by the operator's shell from the repo root.
523
+ return [
524
+ "--local",
525
+ "--container",
526
+ `"$(${facts.sudo ? "sudo " : ""}docker compose ps --format '{{.Name}}' ${MEMORY_SERVICE})"`,
527
+ ...sudo,
528
+ ].join(" ");
529
+ }
530
+ /** Why nothing answered at `base`, and the one thing that makes it answer: the
531
+ * memory forward, in the mode this topology needs, with this install's own
532
+ * flags. The engine listens on its own container's loopback (the compose
533
+ * `memory` sidecar on the laptop route) and is never published. */
534
+ function serverUnreachableDetail(ctx, base, why) {
535
+ const root = shellQuote(rootOf(ctx.adapters));
536
+ const flags = forwardFlags(ctx);
537
+ const cmd = (sub) => `\`cd ${root} && node scripts/companion-memory-forward.mjs ${sub} ${flags}\``;
538
+ return (`no OpenViking answering at ${base} (${why}). The root key is in place, which is what the daemon needs at boot. ` +
539
+ "The memory engine listens only on its own container's loopback (the memory sidecar on the laptop route), so this machine reaches it through the memory " +
540
+ "forward: bring the stack up if it is not, then start the forward in another terminal, from the repo root — " +
541
+ `${cmd("run")} — or install it as the systemd unit with the same flags, ${cmd("install")}, or open \`qcr tui\`, which ` +
542
+ "starts one — and run this step again: the two user keys are minted and placed. Nothing is lost by waiting.");
543
+ }
544
+ /**
545
+ * The server route's daemon reads ITS copy of the reviewer key: the one a
546
+ * deploy shipped into the VM's secrets dir, and only `provision` ships secrets
547
+ * (`deploy.sh release` starts past those tasks). The operator copy proven here
548
+ * says nothing about it, so ask the container for the hash of its copy — a
549
+ * hash, never the key — and compare. null on the compose route, where the
550
+ * container mounts this machine's secrets dir itself.
551
+ */
552
+ async function daemonReviewerCopyCheck(ctx, localPath) {
553
+ if (topologyOf(ctx.choices) !== "vm")
554
+ return null;
555
+ const name = "reviewer-key-on-server";
556
+ const remotePath = `${CONTAINER_SECRETS_DIR}/${REVIEWER_KEY_FILE}`;
557
+ const ship = 'run the vm_deploy step with mode "provision" (`bash scripts/deploy.sh provision`) — only provision copies the ' +
558
+ "secrets dir to the server; a release never does — then run this step again";
559
+ let local;
560
+ try {
561
+ local = createHash("sha256").update(readFileSync(localPath)).digest("hex");
562
+ }
563
+ catch (err) {
564
+ return { name, ok: false, detail: `cannot read ${localPath} to compare: ${String(err)}` };
565
+ }
566
+ const r = await stackTransportFor(ctx).exec(["sha256sum", remotePath]);
567
+ const remote = /^([0-9a-f]{64})\b/.exec(r.stdout.trim())?.[1];
568
+ if (r.code === 0 && remote !== undefined) {
569
+ return remote === local
570
+ ? {
571
+ name,
572
+ ok: true,
573
+ detail: `the daemon on the server holds the same reviewer key as ${localPath}`,
574
+ }
575
+ : {
576
+ name,
577
+ ok: false,
578
+ detail: `the daemon on the server holds a DIFFERENT reviewer key than ${localPath} — it authenticates with a key the matrix never proved. Fix: ${ship}`,
579
+ };
580
+ }
581
+ const said = (r.stderr || r.stdout).trim().slice(0, 200) || `exit ${r.code}`;
582
+ return /no such file/i.test(said)
583
+ ? {
584
+ name,
585
+ ok: false,
586
+ detail: `the daemon on the server has no reviewer key yet (${remotePath}), so it runs memory-less. Fix: ${ship}`,
587
+ }
588
+ : {
589
+ name,
590
+ ok: false,
591
+ detail: `could not ask the server's daemon container for its reviewer key (${said}) — not proven either way; check the deploy step, then run this step again`,
592
+ };
593
+ }
594
+ /** Placement: root + reviewer daemon-side, both USER keys operator-side, the
595
+ * companion key operator-side ONLY. Returns one check per rule; writes nothing
596
+ * a rule forbids. */
597
+ export function placeKeys(args) {
598
+ const checks = [];
599
+ const { secretsDir, keysFile, rootKey, reviewerKey, companionKey } = args;
600
+ mkdirSync(secretsDir, { recursive: true, mode: 0o700 });
601
+ // --- daemon side: root + reviewer, and NOTHING else ---
602
+ for (const [name, file, value] of [
603
+ ["root", ROOT_KEY_FILE, rootKey],
604
+ ["reviewer", REVIEWER_KEY_FILE, reviewerKey],
605
+ ]) {
606
+ if (!value)
607
+ continue;
608
+ const path = join(secretsDir, file);
609
+ const existing = readSecretFile(path);
610
+ const unreadable = existing === "" ? unreadableReason(path) : null;
611
+ if (unreadable !== null) {
612
+ checks.push(unreadableCheck(`${name}-key-placed`, path, unreadable));
613
+ }
614
+ else if (existing === "") {
615
+ writePrivate(path, `${value}\n`);
616
+ checks.push({
617
+ name: `${name}-key-placed`,
618
+ ok: true,
619
+ detail: `${file} written 0600 in ${secretsDir}`,
620
+ });
621
+ }
622
+ else if (existing === value) {
623
+ if (!modeOk(path))
624
+ chmodSync(path, 0o600);
625
+ checks.push({
626
+ name: `${name}-key-placed`,
627
+ ok: true,
628
+ detail: `${file} already holds this key — left untouched (keys are never rotated)`,
629
+ });
630
+ }
631
+ else {
632
+ checks.push({
633
+ name: `${name}-key-placed`,
634
+ ok: false,
635
+ detail: `${path} holds a DIFFERENT ${name} key than the server has. Nothing was rotated: a rotation orphans every copy ` +
636
+ "already distributed. Restore the correct value, or remove that file and run this step again to adopt the server's key.",
637
+ });
638
+ }
639
+ }
640
+ // --- operator side: both USER keys, 0600, outside the secrets dir ---
641
+ if (isInside(secretsDir, keysFile)) {
642
+ checks.push({
643
+ name: "companion-key-confinement",
644
+ ok: false,
645
+ detail: `refusing to write the key file at ${keysFile}: it is inside the daemon-side secrets dir (${secretsDir}), which the ` +
646
+ "container mounts read-only — a review session could read the companion key. Point QCR_OPENVIKING_KEYS outside it.",
647
+ });
648
+ return checks;
649
+ }
650
+ const keysUnreadable = unreadableReason(keysFile);
651
+ if (keysUnreadable !== null) {
652
+ checks.push(unreadableCheck("key-file", keysFile, keysUnreadable));
653
+ return checks;
654
+ }
655
+ const existingKeys = readKeysFile(keysFile);
656
+ const next = {};
657
+ for (const v of COMPANION_VARS)
658
+ next[v] = companionKey;
659
+ next[REVIEWER_VAR] = reviewerKey;
660
+ const conflicts = Object.entries(next).filter(([k, v]) => v && existingKeys[k] && existingKeys[k] !== v);
661
+ writePrivate(keysFile, renderKeysFile(existingKeys, next));
662
+ const after = readKeysFile(keysFile);
663
+ const haveBoth = Boolean(after[COMPANION_VARS[0]] && after[REVIEWER_VAR]);
664
+ checks.push({
665
+ name: "key-file",
666
+ ok: haveBoth && conflicts.length === 0,
667
+ detail: conflicts.length > 0
668
+ ? `${keysFile} already defines ${conflicts.map(([k]) => k).join(", ")} with a different value — left as it was (never rotated). ` +
669
+ "Remove the stale line and run this step again to adopt the server's key."
670
+ : haveBoth
671
+ ? `${keysFile} holds both USER keys, 0600 (no root or admin key ever goes here)`
672
+ : `${keysFile} is missing ${[...COMPANION_VARS, REVIEWER_VAR].filter((v) => !after[v]).join(", ")}`,
673
+ });
674
+ // --- the negative assertion: the companion key is NOWHERE on the daemon side ---
675
+ const leaked = companionKey ? filesContaining(secretsDir, companionKey) : [];
676
+ checks.push({
677
+ name: "companion-key-confinement",
678
+ ok: leaked.length === 0,
679
+ detail: leaked.length === 0
680
+ ? `the companion key is not in any file under ${secretsDir} — review sessions run in that container and must never read it`
681
+ : `THE COMPANION KEY IS IN ${leaked.join(", ")} — remove those files: review sessions can read the secrets mount`,
682
+ });
683
+ return checks;
684
+ }
685
+ export function memoryStep(opts = {}) {
686
+ // A choice, or the answer that was not one (the step refuses with the options).
687
+ const askChoice = async (ctx) => {
688
+ const read = (answer) => normalizeMemoryChoice(answer) ?? { unrecognised: answer };
689
+ // The operator's answer through the tool call wins: it is how the pi
690
+ // wizard, which has no prompter, says yes or no, and how an earlier
691
+ // decline is reversed.
692
+ const given = ctx.input.choice;
693
+ if (isMemoryChoice(given))
694
+ return given;
695
+ if (typeof given === "string" && given.trim() !== "")
696
+ return read(given);
697
+ const recorded = ctx.choices[MEMORY_CHOICE_KEY];
698
+ if (isMemoryChoice(recorded))
699
+ return recorded;
700
+ const prompter = ctx.adapters.prompter;
701
+ if (!prompter)
702
+ return "configure";
703
+ let answer;
704
+ try {
705
+ answer = await prompter("Set up memory now? The reviewer remembers what it learned across PRs. Saying no is fine — it runs memory-less. [Y/n]");
706
+ }
707
+ catch {
708
+ return "configure";
709
+ }
710
+ return read(answer);
711
+ };
712
+ const loaders = (ctx) => {
713
+ const fallback = defaultLoaders(rootOf(ctx.adapters));
714
+ return {
715
+ provision: opts.loadProvision ?? fallback.provision,
716
+ matrix: opts.loadMatrix ?? fallback.matrix,
717
+ };
718
+ };
719
+ return {
720
+ id: MEMORY_STEP_ID,
721
+ title: "Memory: mint, place and confine the OpenViking keys",
722
+ explain: "Memory is what lets the reviewer remember what it learned about your repo. Three keys make it work, and where each " +
723
+ "one lives is a security boundary: the server's own root key stays on the daemon host, the reviewer key goes to the " +
724
+ "daemon and every review session, and the companion key goes only to your own machine — review sessions must never " +
725
+ "be able to read it. This step mints whatever does not exist yet (never re-issuing a key you already have), puts each " +
726
+ "one where it belongs, and then proves the confinement with the four-cell matrix. The root key is placed first because " +
727
+ "the daemon needs it at boot; the two user keys can only be minted by a running server, so if the stack is not up yet " +
728
+ "this step lands the root key, says so, and finishes when you re-run it after bring-up. Declining memory entirely is a " +
729
+ "supported answer — the reviewer then runs memory-less.",
730
+ order: 60,
731
+ parameters: {
732
+ type: "object",
733
+ properties: {
734
+ choice: {
735
+ type: "string",
736
+ enum: [...MEMORY_CHOICE_IDS],
737
+ description: 'The operator\'s answer: "configure" to set memory up, "declined" to run memory-less. Omit to keep the ' +
738
+ "recorded answer (configure when none is recorded).",
739
+ },
740
+ },
741
+ },
742
+ async run(ctx) {
743
+ let restartOwed = typeof ctx.choices[MEMORY_RESTART_CHOICE_KEY] === "boolean"
744
+ ? ctx.choices[MEMORY_RESTART_CHOICE_KEY] === true
745
+ : ctx.data.restart_owed === true;
746
+ const perform = async () => {
747
+ const choice = await askChoice(ctx);
748
+ if (typeof choice !== "string")
749
+ return { ok: false, checks: [memoryChoiceOfferCheck(choice.unrecognised)] };
750
+ ctx.recordChoice(CHOICE_KEYS.memory, choice);
751
+ const before = readTextOrNull(interviewConfigPath(ctx));
752
+ const switched = switchMemory(ctx, choice === "configure");
753
+ if (switched?.ok && before !== readTextOrNull(interviewConfigPath(ctx)))
754
+ restartOwed = true;
755
+ const switchChecks = switched ? [switched] : [];
756
+ const delivery = await deliverConfigChange(ctx, opts.transport, restartOwed, MEMORY_STEP_ID);
757
+ restartOwed = delivery.restartOwed;
758
+ switchChecks.push(...delivery.checks);
759
+ if (choice === "declined") {
760
+ const declined = [...DECLINED_CHECKS, ...switchChecks];
761
+ return { ok: declined.every((c) => c.ok), checks: declined, data: { declined: true } };
762
+ }
763
+ const { secretsDir, keys, base, account } = resolvePaths(opts, ctx);
764
+ // A failed switch-on stays in `checks` and turns the step red at the end;
765
+ // the keys are still worth placing.
766
+ const checks = [...switchChecks];
767
+ if (keys.unsafe) {
768
+ checks.push({ name: "key-file-location", ok: false, detail: keys.note });
769
+ return { ok: false, checks };
770
+ }
771
+ ctx.recordChoice(KEYS_FILE_CHOICE_KEY, keys.path);
772
+ // --- phase A: the root key (offline; needed before the daemon boots) ---
773
+ const rootPath = join(secretsDir, ROOT_KEY_FILE);
774
+ let rootKey = readSecretFile(rootPath);
775
+ const { provision, matrix } = loaders(ctx);
776
+ let prov;
777
+ try {
778
+ prov = await provision();
779
+ }
780
+ catch (err) {
781
+ checks.push({
782
+ name: "provisioning-machinery",
783
+ ok: false,
784
+ detail: `could not load scripts/openviking-provision.mjs: ${String(err)}`,
785
+ });
786
+ return { ok: false, checks };
787
+ }
788
+ const rootUnreadable = rootKey === "" ? unreadableReason(rootPath) : null;
789
+ if (rootUnreadable !== null) {
790
+ checks.push(unreadableCheck("root-key", rootPath, rootUnreadable));
791
+ return { ok: false, checks };
792
+ }
793
+ if (rootKey === "") {
794
+ rootKey = prov.mintRootKey();
795
+ mkdirSync(secretsDir, { recursive: true, mode: 0o700 });
796
+ writePrivate(rootPath, `${rootKey}\n`);
797
+ checks.push({
798
+ name: "root-key",
799
+ ok: true,
800
+ detail: `minted the server root key and wrote ${rootPath} (0600). It is the SERVER's credential: never a client's, never in the key file.`,
801
+ });
802
+ }
803
+ else {
804
+ checks.push({
805
+ name: "root-key",
806
+ ok: true,
807
+ detail: `${rootPath} already holds a root key — left untouched (nothing is ever rotated)`,
808
+ });
809
+ }
810
+ // --- phase B: the two USER keys (the server mints them) ---
811
+ const ready = await serverReady(ctx.adapters.fetch, base, prov);
812
+ if (!ready.ok) {
813
+ checks.push({
814
+ name: "memory-server",
815
+ ok: false,
816
+ detail: ready.answering
817
+ ? `OpenViking answers at ${base} but is not ready (${ready.detail}). Check the engine and embedder logs, then run this step again; the memory forward already reaches it.`
818
+ : serverUnreachableDetail(ctx, base, ready.detail),
819
+ });
820
+ return { ok: false, checks, data: { root_key_placed: true, keys_file: keys.path } };
821
+ }
822
+ const minted = await prov.mintUserKeys({
823
+ base,
824
+ account,
825
+ users: [REVIEWER_USER, COMPANION_USER],
826
+ rootKey,
827
+ fetchFn: ctx.adapters.fetch,
828
+ log: (line) => ctx.adapters.log?.(line),
829
+ });
830
+ const reviewerKey = minted.keys[REVIEWER_USER] ?? "";
831
+ const companionKey = minted.keys[COMPANION_USER] ?? "";
832
+ checks.push({
833
+ name: "user-keys",
834
+ ok: minted.ok && reviewerKey !== "" && companionKey !== "",
835
+ detail: minted.ok && reviewerKey && companionKey
836
+ ? `${minted.created.length > 0 ? `minted ${minted.created.join(", ")}` : "no user needed creating"}` +
837
+ `${minted.kept.length > 0 ? `; kept the existing key for ${minted.kept.join(", ")} (never rotated)` : ""}`
838
+ : `could not obtain a key for ${minted.missing.join(", ") || "every user"}${minted.detail ? ` (${minted.detail})` : ""} — ` +
839
+ "nothing was rotated. Check that the daemon restarted after the root key landed (the server reads it at boot, and " +
840
+ "without it runs auth_mode=dev), then run this step again.",
841
+ });
842
+ if (!reviewerKey || !companionKey)
843
+ return { ok: false, checks, data: { root_key_placed: true, keys_file: keys.path } };
844
+ checks.push(...placeKeys({ secretsDir, keysFile: keys.path, rootKey, reviewerKey, companionKey }));
845
+ if (!checks.every((c) => c.ok))
846
+ return { ok: false, checks, data: { root_key_placed: true, keys_file: keys.path } };
847
+ // --- the proof ---
848
+ checks.push(...(await matrixChecks(matrix, base, { companion: companionKey, reviewer: reviewerKey }, ctx, opts)));
849
+ // --- the daemon's own copy, where it is not this machine's file ---
850
+ const onServer = await daemonReviewerCopyCheck(ctx, join(secretsDir, REVIEWER_KEY_FILE));
851
+ if (onServer)
852
+ checks.push(onServer);
853
+ return {
854
+ ok: checks.every((c) => c.ok),
855
+ checks,
856
+ data: {
857
+ root_key_placed: true,
858
+ keys_file: keys.path,
859
+ users: [REVIEWER_USER, COMPANION_USER],
860
+ },
861
+ };
862
+ };
863
+ const report = await perform();
864
+ ctx.recordChoice(CHOICE_KEYS.memoryRestartOwed, restartOwed);
865
+ return { ...report, data: { ...report.data, restart_owed: restartOwed } };
866
+ },
867
+ async verify(ctx) {
868
+ // The recorded choice is authoritative: a run's data is merged into the
869
+ // step record, so an earlier decline's `declined` flag outlives a later
870
+ // configure. The flag counts only when no choice is recorded.
871
+ const delivery = (typeof ctx.choices[MEMORY_RESTART_CHOICE_KEY] === "boolean"
872
+ ? ctx.choices[MEMORY_RESTART_CHOICE_KEY] === true
873
+ : ctx.data.restart_owed === true)
874
+ ? [
875
+ {
876
+ name: "daemon-restart",
877
+ ok: false,
878
+ detail: "memory config is on disk but its daemon restart is still owed; run this step again",
879
+ },
880
+ ]
881
+ : [];
882
+ const recorded = ctx.choices[MEMORY_CHOICE_KEY];
883
+ if (recorded === "declined" || (recorded === undefined && ctx.data.declined === true)) {
884
+ const declined = [...DECLINED_CHECKS, switchStillOff(ctx), ...delivery];
885
+ return { ok: declined.every((c) => c.ok), checks: declined };
886
+ }
887
+ const { secretsDir, keys, base, env, home, mounted } = resolvePaths(opts, ctx);
888
+ // The file the TUI, the companion and the forward read NOW is the one
889
+ // that must hold the keys: a file this step wrote earlier, somewhere the
890
+ // locator no longer points, serves nobody. That earlier copy is still
891
+ // checked for confinement below — it holds the companion key.
892
+ const keysPath = keys.path;
893
+ const placedPath = typeof ctx.data.keys_file === "string" && resolve(ctx.data.keys_file) !== resolve(keysPath)
894
+ ? ctx.data.keys_file
895
+ : null;
896
+ // Confinement against the CURRENT mounts: the layout may have moved
897
+ // since this step placed the file (a new config location, a new pin).
898
+ const placed = placedPath !== null && existsSync(placedPath)
899
+ ? keysFileConfinement(placedPath, secretsDir, env, home, mounted)
900
+ : null;
901
+ const checks = [...delivery];
902
+ const switched = switchStillOn(ctx);
903
+ if (switched)
904
+ checks.push(switched);
905
+ const rootPath = join(secretsDir, ROOT_KEY_FILE);
906
+ const reviewerPath = join(secretsDir, REVIEWER_KEY_FILE);
907
+ for (const [name, path] of [
908
+ ["root-key", rootPath],
909
+ ["reviewer-key", reviewerPath],
910
+ ]) {
911
+ const value = readSecretFile(path);
912
+ checks.push({
913
+ name,
914
+ ok: value !== "" && modeOk(path),
915
+ detail: value === ""
916
+ ? `${path} is missing or empty — run this step to mint and place it`
917
+ : modeOk(path)
918
+ ? `${path} present, 0600`
919
+ : `${path} is readable by others — chmod 600 it`,
920
+ });
921
+ }
922
+ const fileKeys = readKeysFile(keysPath);
923
+ // Both companion spellings are written with the same key, and each has a
924
+ // reader (the companion extension takes OPENVIKING_API_KEY, the TUI the
925
+ // specific one first): proving one while the other disagrees proves a
926
+ // key one of them never sends.
927
+ const companionValues = [...new Set(COMPANION_VARS.map((v) => fileKeys[v] ?? ""))];
928
+ const companionSplit = companionValues.length > 1;
929
+ const companionKey = companionSplit ? "" : (companionValues[0] ?? "");
930
+ const reviewerKey = fileKeys[REVIEWER_VAR] ?? "";
931
+ checks.push({
932
+ name: "key-file",
933
+ ok: companionKey !== "" && reviewerKey !== "" && modeOk(keysPath),
934
+ detail: companionSplit
935
+ ? `${keysPath} defines ${COMPANION_VARS.join(" and ")} with different values (or only one of them) — both must hold ` +
936
+ "the companion key. Remove the stale line and run this step again to adopt the server's key"
937
+ : companionKey === "" || reviewerKey === ""
938
+ ? `${keysPath} must define ${COMPANION_VARS.join("/")} and ${REVIEWER_VAR} — run this step to write them`
939
+ : modeOk(keysPath)
940
+ ? `${keysPath} holds both USER keys, 0600`
941
+ : `${keysPath} is readable by others — chmod 600 it`,
942
+ });
943
+ // The matrix proves the operator copy of the reviewer key; the daemon
944
+ // reads its own copy from the secrets dir. Only when the two agree does
945
+ // that proof cover the key the daemon and its sessions actually hold.
946
+ const daemonReviewerKey = readSecretFile(reviewerPath);
947
+ if (daemonReviewerKey !== "" && reviewerKey !== "") {
948
+ const same = daemonReviewerKey === reviewerKey;
949
+ checks.push({
950
+ name: "reviewer-key-match",
951
+ ok: same,
952
+ detail: same
953
+ ? `${reviewerPath} holds the same reviewer key as ${keysPath}`
954
+ : `${reviewerPath} holds a DIFFERENT reviewer key than ${REVIEWER_VAR} in ${keysPath} — the daemon would ` +
955
+ "authenticate with a key the matrix never proved. Nothing is rotated: restore the correct value, or remove " +
956
+ "the stale copy and run this step again to adopt the server's key.",
957
+ });
958
+ }
959
+ const leaked = [
960
+ ...companionValues.flatMap((v) => (v ? filesContaining(secretsDir, v) : [])),
961
+ ...[keysPath, ...(placedPath !== null ? [placedPath] : [])].filter((p) => isInside(secretsDir, p)),
962
+ ];
963
+ // The file the locator names now, then an earlier placement still on
964
+ // disk (their secrets-dir cases are already in `leaked`).
965
+ const misplaced = keys.unsafe && !isInside(secretsDir, keysPath)
966
+ ? keys
967
+ : placed?.unsafe && placedPath !== null && !isInside(secretsDir, placedPath)
968
+ ? placed
969
+ : undefined;
970
+ checks.push({
971
+ name: "companion-key-confinement",
972
+ ok: leaked.length === 0 && misplaced === undefined,
973
+ detail: leaked.length > 0
974
+ ? `the companion key is reachable from the daemon-side secrets dir (${leaked.join(", ")}) — remove it and re-run this step`
975
+ : misplaced !== undefined
976
+ ? `the key file ${misplaced.path} is no longer confined: ${misplaced.note}`
977
+ : `no companion key under ${secretsDir}, and the key file sits outside every directory the daemon container mounts`,
978
+ });
979
+ if (!companionKey || !reviewerKey) {
980
+ checks.push({
981
+ name: "confinement-matrix",
982
+ ok: false,
983
+ detail: "not run: both USER keys are needed to probe the four cells",
984
+ });
985
+ return { ok: false, checks };
986
+ }
987
+ const { matrix } = loaders(ctx);
988
+ checks.push(...(await matrixChecks(matrix, base, { companion: companionKey, reviewer: reviewerKey }, ctx, opts)));
989
+ const onServer = await daemonReviewerCopyCheck(ctx, reviewerPath);
990
+ if (onServer)
991
+ checks.push(onServer);
992
+ return { ok: checks.every((c) => c.ok), checks };
993
+ },
994
+ };
995
+ }
996
+ /**
997
+ * The four-cell confinement matrix as onboarding checks.
998
+ *
999
+ * One check per row plus a summary. A FAILED row is a boundary violation; an
1000
+ * INCONCLUSIVE row is NOT a pass — it means the probe could not tell (a 404, a
1001
+ * 5xx, a 200 carrying an error envelope), and the guidance says exactly that.
1002
+ */
1003
+ async function matrixChecks(load, base, keys, ctx, opts) {
1004
+ let mod;
1005
+ try {
1006
+ mod = await load();
1007
+ }
1008
+ catch (err) {
1009
+ return [
1010
+ {
1011
+ name: "confinement-matrix",
1012
+ ok: false,
1013
+ detail: `could not load scripts/companion-memory-forward.mjs: ${String(err)}`,
1014
+ },
1015
+ ];
1016
+ }
1017
+ let report;
1018
+ try {
1019
+ report = await mod.runVerify({
1020
+ base,
1021
+ keys,
1022
+ env: opts.env ?? process.env,
1023
+ fetchFn: ctx.adapters.fetch,
1024
+ write: false,
1025
+ log: () => { },
1026
+ });
1027
+ }
1028
+ catch (err) {
1029
+ return [
1030
+ {
1031
+ name: "confinement-matrix",
1032
+ ok: false,
1033
+ detail: `the confinement matrix could not run: ${String(err)}`,
1034
+ },
1035
+ ];
1036
+ }
1037
+ const checks = report.rows.map((row) => ({
1038
+ name: `matrix:${row.who}-key→${row.ns}`,
1039
+ ok: row.verdict === "PASS",
1040
+ detail: row.verdict === "PASS"
1041
+ ? `${row.want} — ${row.why}`
1042
+ : row.verdict === "INCONCLUSIVE"
1043
+ ? `INCONCLUSIVE (${row.detail}): the probe could not tell reach from refusal, which is NEVER a pass. ` +
1044
+ "Usually the request shape does not match this server — see docs/companion-memory-access.md " +
1045
+ "(QCR_OV_READ_PATH / QCR_OV_READ_URI / QCR_OV_WRITE_PATH) — or the memory forward is not up."
1046
+ : `FAILED: expected ${row.want}, got ${row.observed} (${row.detail}). ${row.why}`,
1047
+ }));
1048
+ checks.push({
1049
+ name: "confinement-matrix",
1050
+ ok: report.failed === 0 && report.unclear === 0 && report.rows.length > 0,
1051
+ detail: report.rows.length === 0
1052
+ ? "the matrix produced no rows — it did not run"
1053
+ : `${report.rows.length - report.failed - report.unclear} pass, ${report.failed} fail, ${report.unclear} inconclusive` +
1054
+ (report.failed === 0 && report.unclear === 0
1055
+ ? " (run `node scripts/companion-memory-forward.mjs verify --write` for the write half)"
1056
+ : " — an inconclusive cell is not a pass"),
1057
+ });
1058
+ return checks;
1059
+ }
1060
+ //# sourceMappingURL=memory.js.map