2sagaco48 1.0.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 (365) hide show
  1. package/diagnostics.mjs +141 -0
  2. package/dist/compute.worker-j5ahIpF-.js +1 -0
  3. package/dist/graph.worker-DG6iGCB9.js +1 -0
  4. package/dist/index.html +2314 -0
  5. package/flatten-guide.md +248 -0
  6. package/index.html +12 -0
  7. package/package.json +38 -0
  8. package/src/App.orig.tsx +204 -0
  9. package/src/App.orig1.tsx +27 -0
  10. package/src/App.orig2.tsx +25 -0
  11. package/src/App.tsx +3 -0
  12. package/src/BaseApp.tsx +18 -0
  13. package/src/INTEGRATION_LEDGER.md +22 -0
  14. package/src/PERSIST_CANARY.orig.txt +1 -0
  15. package/src/PERSIST_CANARY.txt +1 -0
  16. package/src/REGRESSION_LEDGER.md +651 -0
  17. package/src/TEMPLATE_PIPELINE_AUDIT.md +208 -0
  18. package/src/WILLIAMS_PERSONA_GUIDE.md +62 -0
  19. package/src/chat/VeritasChat.tsx +69 -0
  20. package/src/chat/synthesis.ts +31 -0
  21. package/src/chat/tier.ts +45 -0
  22. package/src/components/AdaptersPage.orig.tsx +99 -0
  23. package/src/components/AdaptersPage.tsx +3 -0
  24. package/src/components/AdversarialPanel.tsx +136 -0
  25. package/src/components/AnchorBaselinePanel.tsx +75 -0
  26. package/src/components/AnswerPanel.tsx +60 -0
  27. package/src/components/ArtifactPanel.tsx +43 -0
  28. package/src/components/ChatApp.orig.tsx +1582 -0
  29. package/src/components/ChatApp.orig1.tsx +722 -0
  30. package/src/components/ChatApp.tsx +95 -0
  31. package/src/components/ChatAugmentPanels.tsx +73 -0
  32. package/src/components/CitationLedgerPanel.tsx +313 -0
  33. package/src/components/ComputeSandboxPanel.tsx +130 -0
  34. package/src/components/ConfigPanel.tsx +110 -0
  35. package/src/components/ControlPlanePage.tsx +195 -0
  36. package/src/components/CreativeTreeLifePage.tsx +234 -0
  37. package/src/components/CreativeTreeOfLifePanel.tsx +149 -0
  38. package/src/components/DebugTracePanel.tsx +137 -0
  39. package/src/components/DeepReasoningTrace.tsx +48 -0
  40. package/src/components/EntitySheetPanel.tsx +51 -0
  41. package/src/components/FailureModesPanel.tsx +104 -0
  42. package/src/components/GBSDashboard.tsx +239 -0
  43. package/src/components/GraphView.tsx +116 -0
  44. package/src/components/HUD.tsx +125 -0
  45. package/src/components/HypothesisPanel.tsx +67 -0
  46. package/src/components/InnovationGenomeEngine.tsx +792 -0
  47. package/src/components/InnovationPersonaGuide.tsx +348 -0
  48. package/src/components/InnovationPersonaPanel.tsx +289 -0
  49. package/src/components/LiveResourceHUD.tsx +109 -0
  50. package/src/components/LongWriterPanel.tsx +112 -0
  51. package/src/components/MainPipelineV10Bridge.tsx +72 -0
  52. package/src/components/MarkdownLite.tsx +63 -0
  53. package/src/components/MemoryInspector.tsx +38 -0
  54. package/src/components/MemoryMonitor.tsx +52 -0
  55. package/src/components/MemoryStressPanel.tsx +176 -0
  56. package/src/components/ModulesPage.tsx +171 -0
  57. package/src/components/PipelineDebugConsole.orig.tsx +1856 -0
  58. package/src/components/PipelineDebugConsole.tsx +3 -0
  59. package/src/components/PreFlightHUD.tsx +67 -0
  60. package/src/components/PrismaFetchTracePanel.tsx +87 -0
  61. package/src/components/ReportOSPanel.tsx +165 -0
  62. package/src/components/ResourceEstimatorPage.tsx +327 -0
  63. package/src/components/RichText.tsx +181 -0
  64. package/src/components/SagaOsPanel.tsx +605 -0
  65. package/src/components/SagaOsReference.tsx +421 -0
  66. package/src/components/SagaOsV2Panel.tsx +594 -0
  67. package/src/components/SagaStyleTab.tsx +382 -0
  68. package/src/components/SageBlueprintPanel.tsx +416 -0
  69. package/src/components/SharedChatInput.tsx +77 -0
  70. package/src/components/StatFinancePanel.tsx +190 -0
  71. package/src/components/StylePersonaPanel.tsx +128 -0
  72. package/src/components/TemplatesPage.tsx +300 -0
  73. package/src/components/TestPanel.tsx +63 -0
  74. package/src/components/TraceLog.tsx +89 -0
  75. package/src/components/V15CalibrationAugment.tsx +1134 -0
  76. package/src/components/V15CalibrationDialog.tsx +1871 -0
  77. package/src/components/V15Overlay.orig.tsx +120 -0
  78. package/src/components/V15Overlay.tsx +4 -0
  79. package/src/components/V15OverlayWrapper.tsx +362 -0
  80. package/src/components/V15Toggle.tsx +34 -0
  81. package/src/console/DiagnosticRecoveryPanel.tsx +358 -0
  82. package/src/console/EngineeringConsole.tsx +103 -0
  83. package/src/console/FictionSystemPanels.tsx +882 -0
  84. package/src/console/InspectorPanels.tsx +254 -0
  85. package/src/console/ManuscriptGraderPanel.tsx +182 -0
  86. package/src/console/RecursiveReviserPanel.tsx +245 -0
  87. package/src/console/SeedControlPanel.tsx +135 -0
  88. package/src/console/StoryControllerPanel.tsx +443 -0
  89. package/src/console/engineBridge.ts +258 -0
  90. package/src/console/gemini.ts +106 -0
  91. package/src/console/grading.ts +250 -0
  92. package/src/console/util.ts +45 -0
  93. package/src/fiction/continuity.ts +372 -0
  94. package/src/fiction/crash-protection.ts +111 -0
  95. package/src/fiction/diagnostics.ts +208 -0
  96. package/src/fiction/diff.ts +74 -0
  97. package/src/fiction/entity-state-machine.ts +214 -0
  98. package/src/fiction/nive-engine.ts +404 -0
  99. package/src/fiction/pipeline-selftest.ts +132 -0
  100. package/src/fiction/seed-control.ts +193 -0
  101. package/src/fiction/story-engine.ts +326 -0
  102. package/src/fiction/types.ts +68 -0
  103. package/src/flatten-guide.md +379 -0
  104. package/src/index.css +14 -0
  105. package/src/index.orig.css +13 -0
  106. package/src/lib/academic-sources.base.ts +188 -0
  107. package/src/lib/academic-sources.orig.ts +28 -0
  108. package/src/lib/academic-sources.ts +10 -0
  109. package/src/lib/advanced-math.ts +119 -0
  110. package/src/lib/adversarial-engine.base.ts +409 -0
  111. package/src/lib/adversarial-engine.ts +82 -0
  112. package/src/lib/ai-revision.ts +623 -0
  113. package/src/lib/app-state.tsx +426 -0
  114. package/src/lib/artifact-registry.ts +97 -0
  115. package/src/lib/artifacts.ts +180 -0
  116. package/src/lib/atlas-dr.ts +167 -0
  117. package/src/lib/browser-mtls.ts +127 -0
  118. package/src/lib/browser-queue.ts +221 -0
  119. package/src/lib/browser-search-scraper.base.ts +382 -0
  120. package/src/lib/browser-search-scraper.orig.ts +90 -0
  121. package/src/lib/browser-search-scraper.ts +10 -0
  122. package/src/lib/calc-interceptor.ts +82 -0
  123. package/src/lib/citation-lane-tap.ts +78 -0
  124. package/src/lib/citation-ledger-store.ts +369 -0
  125. package/src/lib/citation-ledger.ts +203 -0
  126. package/src/lib/compute-sandbox.ts +215 -0
  127. package/src/lib/compute.worker.ts +153 -0
  128. package/src/lib/connectors/gemini.ts +120 -0
  129. package/src/lib/connectors/jina.ts +233 -0
  130. package/src/lib/connectors/marketdata.ts +51 -0
  131. package/src/lib/connectors/prismafetch.base.ts +175 -0
  132. package/src/lib/connectors/prismafetch.ts +1 -0
  133. package/src/lib/connectors/serpapi.ts +65 -0
  134. package/src/lib/connectors/wikidata.ts +44 -0
  135. package/src/lib/constraints.ts +331 -0
  136. package/src/lib/continuation-detector.base.ts +153 -0
  137. package/src/lib/continuation-detector.ts +48 -0
  138. package/src/lib/contradraft.ts +168 -0
  139. package/src/lib/cors-proxy.ts +120 -0
  140. package/src/lib/coverage.ts +81 -0
  141. package/src/lib/debug/architecture-prescription.ts +556 -0
  142. package/src/lib/debug/covea-repair.ts +543 -0
  143. package/src/lib/debug/helios-ground.ts +319 -0
  144. package/src/lib/debug/intent-decomposer.ts +281 -0
  145. package/src/lib/debug/intent-lattice.ts +349 -0
  146. package/src/lib/debug/pipeline-diagnosis.ts +1149 -0
  147. package/src/lib/debug/pipeline-trace-bus.ts +424 -0
  148. package/src/lib/debug/prompt-forge.ts +678 -0
  149. package/src/lib/debug/repair-sites.ts +513 -0
  150. package/src/lib/debug/research-phase.ts +266 -0
  151. package/src/lib/debug/retrieval-context.ts +76 -0
  152. package/src/lib/debug/retrieval-hardener.ts +142 -0
  153. package/src/lib/debug/scraper-debug-runner.ts +576 -0
  154. package/src/lib/debug/scraper-forensics.ts +418 -0
  155. package/src/lib/debug/scraper-lane-roadmap.ts +136 -0
  156. package/src/lib/debug/self-test.ts +415 -0
  157. package/src/lib/debug/step-attribution.ts +211 -0
  158. package/src/lib/debug/template-rubric.ts +301 -0
  159. package/src/lib/debug/unified-innovation.ts +126 -0
  160. package/src/lib/debug/veritas-hybrid-scraper.ts +335 -0
  161. package/src/lib/defense-registry.ts +104 -0
  162. package/src/lib/defenses.ts +162 -0
  163. package/src/lib/deterministic-citation-ledger.ts +174 -0
  164. package/src/lib/elo-registry.base.ts +117 -0
  165. package/src/lib/elo-registry.ts +1 -0
  166. package/src/lib/entity-resolver.ts +291 -0
  167. package/src/lib/failure-modes.ts +267 -0
  168. package/src/lib/feature-registry.ts +69 -0
  169. package/src/lib/flaw-registry.ts +143 -0
  170. package/src/lib/flaws/_template.ts +52 -0
  171. package/src/lib/flaws/builtins.ts +63 -0
  172. package/src/lib/flaws/finance.ts +169 -0
  173. package/src/lib/flaws/fixers.ts +10 -0
  174. package/src/lib/flaws/index.ts +32 -0
  175. package/src/lib/flaws/legal.ts +157 -0
  176. package/src/lib/flaws/medical.ts +188 -0
  177. package/src/lib/flaws/original-defenses-pack.ts +81 -0
  178. package/src/lib/flaws/sample-declarative-pack.json +38 -0
  179. package/src/lib/flaws/selftest.ts +201 -0
  180. package/src/lib/flaws/software-extended.ts +125 -0
  181. package/src/lib/flaws/software-rn-webgl.ts +182 -0
  182. package/src/lib/flaws/statistics-advanced.ts +46 -0
  183. package/src/lib/flaws/statistics.ts +61 -0
  184. package/src/lib/gbse/config.ts +20 -0
  185. package/src/lib/gbse/engine.ts +226 -0
  186. package/src/lib/gbse/graph.ts +118 -0
  187. package/src/lib/gbse/graph.worker.ts +21 -0
  188. package/src/lib/gbse/tests.ts +117 -0
  189. package/src/lib/gbse/tiers.ts +65 -0
  190. package/src/lib/gbse/types.ts +94 -0
  191. package/src/lib/innovation-genome-engine-v2.orig.ts +1001 -0
  192. package/src/lib/innovation-genome-engine-v2.ts +3 -0
  193. package/src/lib/innovation-genome-engine.orig.ts +330 -0
  194. package/src/lib/innovation-genome-engine.ts +3 -0
  195. package/src/lib/innovation-genome-v10.orig.ts +314 -0
  196. package/src/lib/innovation-genome-v10.ts +2 -0
  197. package/src/lib/innovation-genome-v3.orig.ts +2015 -0
  198. package/src/lib/innovation-genome-v3.ts +2 -0
  199. package/src/lib/innovation-genome-v4.orig.ts +1959 -0
  200. package/src/lib/innovation-genome-v4.ts +2 -0
  201. package/src/lib/innovation-genome-v5.orig.ts +1210 -0
  202. package/src/lib/innovation-genome-v5.ts +2 -0
  203. package/src/lib/innovation-genome-v7.orig.ts +2549 -0
  204. package/src/lib/innovation-genome-v7.ts +2 -0
  205. package/src/lib/innovation-genome-v8.orig.ts +1485 -0
  206. package/src/lib/innovation-genome-v8.ts +2 -0
  207. package/src/lib/innovation-genome-v9.orig.ts +643 -0
  208. package/src/lib/innovation-genome-v9.ts +2 -0
  209. package/src/lib/jina.base.ts +293 -0
  210. package/src/lib/jina.ts +1 -0
  211. package/src/lib/live-telemetry.ts +61 -0
  212. package/src/lib/longwriter.ts +84 -0
  213. package/src/lib/manuscript-grade-v2.ts +298 -0
  214. package/src/lib/memory-governor.ts +173 -0
  215. package/src/lib/memory-stress-tests.ts +248 -0
  216. package/src/lib/model-intelligence.ts +48 -0
  217. package/src/lib/model-rotator.ts +75 -0
  218. package/src/lib/models.orig.ts +513 -0
  219. package/src/lib/models.ts +151 -0
  220. package/src/lib/n-deep.base.ts +592 -0
  221. package/src/lib/n-deep.ts +51 -0
  222. package/src/lib/nih-simulator.ts +56 -0
  223. package/src/lib/nih-vulnerability-fixes.ts +460 -0
  224. package/src/lib/omega-templates.base.ts +294 -0
  225. package/src/lib/omega-templates.ts +225 -0
  226. package/src/lib/omni-nexus.ts +64 -0
  227. package/src/lib/oracle-adapters.ts +67 -0
  228. package/src/lib/oracle-registry.ts +163 -0
  229. package/src/lib/orchestrator.ts +357 -0
  230. package/src/lib/output-boundary.ts +235 -0
  231. package/src/lib/overrides/vite-native-chaos-harness.ts +154 -0
  232. package/src/lib/overrides/vite-native-contract-plane.ts +245 -0
  233. package/src/lib/overrides/vite-native-doctor-plane.ts +208 -0
  234. package/src/lib/overrides/vite-native-knowledge-store.ts +267 -0
  235. package/src/lib/overrides/vite-native-policy-plane.ts +190 -0
  236. package/src/lib/overrides/vite-native-replay-plane.ts +197 -0
  237. package/src/lib/overrides/vite-native-runtime-plane.ts +106 -0
  238. package/src/lib/overrides/vite-native-scraper.ts +848 -0
  239. package/src/lib/overrides/vite-native-selftest-functional.ts +217 -0
  240. package/src/lib/overrides/vite-native-selftest.ts +183 -0
  241. package/src/lib/overrides/vite-native-snapshot-plane.ts +123 -0
  242. package/src/lib/philosophy-toolkit.ts +75 -0
  243. package/src/lib/pipeline.orig.ts +659 -0
  244. package/src/lib/pipeline.ts +42 -0
  245. package/src/lib/precache.ts +128 -0
  246. package/src/lib/py-sandbox.ts +205 -0
  247. package/src/lib/quality-score.ts +96 -0
  248. package/src/lib/quant-engine.ts +231 -0
  249. package/src/lib/quant-lib.ts +80 -0
  250. package/src/lib/reportos.ts +175 -0
  251. package/src/lib/research-os.ts +306 -0
  252. package/src/lib/resource-estimator.ts +114 -0
  253. package/src/lib/rpm-governor.ts +93 -0
  254. package/src/lib/runtime-estimator.ts +135 -0
  255. package/src/lib/sage/empty-space-v6.ts +560 -0
  256. package/src/lib/sage/empty-space-v7.ts +222 -0
  257. package/src/lib/sage/empty-space.ts +733 -0
  258. package/src/lib/sage/engine.ts +786 -0
  259. package/src/lib/sage/index.ts +17 -0
  260. package/src/lib/sage/judge.ts +246 -0
  261. package/src/lib/sage/prng.ts +53 -0
  262. package/src/lib/sage/reality-grounding.ts +380 -0
  263. package/src/lib/sage/repetition.ts +151 -0
  264. package/src/lib/sage/saga-os-v2-engines.ts +1870 -0
  265. package/src/lib/sage/saga-os-v2.ts +274 -0
  266. package/src/lib/sage/saga-os-v3-core.ts +1491 -0
  267. package/src/lib/sage/saga-os-v3-release.ts +739 -0
  268. package/src/lib/sage/saga-os-v4-aureate.ts +1161 -0
  269. package/src/lib/sage/saga-os-v4.ts +212 -0
  270. package/src/lib/sage/saga-os-v5.ts +205 -0
  271. package/src/lib/sage/saga-os-v6.ts +346 -0
  272. package/src/lib/sage/saga-os-v7.ts +314 -0
  273. package/src/lib/sage/saga-os-v8.ts +505 -0
  274. package/src/lib/sage/saga-os.ts +329 -0
  275. package/src/lib/sage/taxonomy.ts +403 -0
  276. package/src/lib/sage/unified-roll.ts +524 -0
  277. package/src/lib/sage/worked-sketches.ts +44 -0
  278. package/src/lib/sage.ts +166 -0
  279. package/src/lib/scraper-debug-bus.ts +53 -0
  280. package/src/lib/scraper-enhanced.orig.ts +153 -0
  281. package/src/lib/scraper-enhanced.ts +10 -0
  282. package/src/lib/scraper-hardener.base.orig.ts +155 -0
  283. package/src/lib/scraper-hardener.base.ts +317 -0
  284. package/src/lib/scraper-hardener.ts +1 -0
  285. package/src/lib/scraper-palisade/palisade-adjudicator.orig.ts +419 -0
  286. package/src/lib/scraper-palisade/palisade-adjudicator.ts +13 -0
  287. package/src/lib/scraper-vnext/arbiter-omega.orig.ts +688 -0
  288. package/src/lib/scraper-vnext/arbiter-omega.ts +13 -0
  289. package/src/lib/scraper-vnext/canonical-portfolio-augments.ts +479 -0
  290. package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.orig.ts +1529 -0
  291. package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.ts +13 -0
  292. package/src/lib/scraper-vnext/conclave-omega.ts +1830 -0
  293. package/src/lib/scraper-vnext/content-extractor-v2.ts +226 -0
  294. package/src/lib/scraper-vnext/diagnostics-suite.ts +36 -0
  295. package/src/lib/scraper-vnext/epistemic-packer.ts +97 -0
  296. package/src/lib/scraper-vnext/fusion-v2.ts +65 -0
  297. package/src/lib/scraper-vnext/hydra-reader.orig.ts +1216 -0
  298. package/src/lib/scraper-vnext/hydra-reader.ts +13 -0
  299. package/src/lib/scraper-vnext/native-scraper-browser-vnext.orig.ts +91 -0
  300. package/src/lib/scraper-vnext/native-scraper-browser-vnext.ts +13 -0
  301. package/src/lib/scraper-vnext/nexus-consensus.orig.ts +905 -0
  302. package/src/lib/scraper-vnext/nexus-consensus.ts +13 -0
  303. package/src/lib/scraper-vnext/portfolio-consensus-adjudicator.ts +804 -0
  304. package/src/lib/scraper-vnext/portfolio-consensus-memory.ts +377 -0
  305. package/src/lib/scraper-vnext/portfolio-terminal-governor.ts +548 -0
  306. package/src/lib/scraper-vnext/query-strategist.orig.ts +224 -0
  307. package/src/lib/scraper-vnext/query-strategist.ts +423 -0
  308. package/src/lib/scraper-vnext/retrieval-accelerator.ts +708 -0
  309. package/src/lib/scraper-vnext/retrieval-audit-augments.ts +477 -0
  310. package/src/lib/scraper-vnext/retrieval-control-plane.ts +904 -0
  311. package/src/lib/scraper-vnext/retrieval-policy-augments.ts +358 -0
  312. package/src/lib/scraper-vnext/safe-fetch-v2.ts +157 -0
  313. package/src/lib/scraper-vnext/sentinel-omega.ts +56 -0
  314. package/src/lib/scraper-vnext/sentinel-orchestrator.ts +69 -0
  315. package/src/lib/scraper-vnext/sibyl-oracle.orig.ts +413 -0
  316. package/src/lib/scraper-vnext/sibyl-oracle.ts +13 -0
  317. package/src/lib/scraper-vnext/smart-read-v2.ts +55 -0
  318. package/src/lib/scraper-vnext/spa-rescue-bridge.ts +608 -0
  319. package/src/lib/scraper-vnext/strata-engine.orig.ts +2666 -0
  320. package/src/lib/scraper-vnext/strata-engine.ts +13 -0
  321. package/src/lib/scraper-vnext/structured-source-adapter.orig.ts +369 -0
  322. package/src/lib/scraper-vnext/structured-source-adapter.ts +34 -0
  323. package/src/lib/scraper-vnext/terminal-complete.ts +224 -0
  324. package/src/lib/scraper-vnext/terminal-final.ts +277 -0
  325. package/src/lib/scraper-vnext/terminal-saturation.ts +345 -0
  326. package/src/lib/scraper-vnext/terminal-wire.ts +425 -0
  327. package/src/lib/scraper-vnext/vanguard-titanium.orig.ts +467 -0
  328. package/src/lib/scraper-vnext/vanguard-titanium.ts +17 -0
  329. package/src/lib/search-cache.ts +138 -0
  330. package/src/lib/sloop-runner.base.ts +223 -0
  331. package/src/lib/sloop-runner.ts +104 -0
  332. package/src/lib/sloop.ts +114 -0
  333. package/src/lib/small-model-adapters.ts +82 -0
  334. package/src/lib/sscp.ts +86 -0
  335. package/src/lib/system-map.ts +54 -0
  336. package/src/lib/uni-node.ts +86 -0
  337. package/src/lib/universal-rigor-guard.ts +433 -0
  338. package/src/lib/v15-gate-testbed.ts +274 -0
  339. package/src/lib/v15-gemini.base.ts +89 -0
  340. package/src/lib/v15-gemini.ts +1 -0
  341. package/src/lib/v15-grounding.orig.ts +241 -0
  342. package/src/lib/v15-grounding.ts +79 -0
  343. package/src/lib/v15-pipeline.base.ts +769 -0
  344. package/src/lib/v15-pipeline.orig.ts +1154 -0
  345. package/src/lib/v15-pipeline.ts +674 -0
  346. package/src/lib/v15-questions.ts +64 -0
  347. package/src/lib/v15-rate-limiter.orig.ts +91 -0
  348. package/src/lib/v15-rate-limiter.ts +48 -0
  349. package/src/lib/v15-state.base.ts +87 -0
  350. package/src/lib/v15-state.ts +28 -0
  351. package/src/lib/visual-table-generator.tsx +207 -0
  352. package/src/lib/wasm-runtime.ts +133 -0
  353. package/src/lib/williams-persona-guide.ts +265 -0
  354. package/src/lib/williams-style.base.ts +464 -0
  355. package/src/lib/williams-style.ts +59 -0
  356. package/src/lib/worker-pool.ts +96 -0
  357. package/src/lib/writing-tiers.ts +125 -0
  358. package/src/main.orig.tsx +10 -0
  359. package/src/main.tsx +10 -0
  360. package/src/utils/cn.orig.ts +6 -0
  361. package/src/utils/cn.ts +6 -0
  362. package/src/vite-env.d.ts +1 -0
  363. package/tsconfig.json +31 -0
  364. package/unify.mjs +537 -0
  365. package/vite.config.ts +18 -0
@@ -0,0 +1,208 @@
1
+ /**
2
+ * vite-native-doctor-plane.ts — L4: Aggregated Health & Remediation
3
+ * Dynamically imports all planes to avoid circular dependencies.
4
+ * Zero-dependency: node:* only.
5
+ */
6
+ async function optionalImport(specifier: string): Promise<{ ok: boolean; mod?: any; error?: string }> {
7
+ try {
8
+ const mod = await import(specifier);
9
+ return { ok: true, mod };
10
+ } catch (e: any) {
11
+ return { ok: false, error: e?.message ?? 'Import failed' };
12
+ }
13
+ }
14
+
15
+ export type HealthStatus = 'green' | 'yellow' | 'red';
16
+
17
+ export interface DoctorSection {
18
+ available: boolean;
19
+ error?: string;
20
+ data?: Record<string, unknown>;
21
+ }
22
+
23
+ export interface DoctorReport {
24
+ status: HealthStatus;
25
+ ts: number;
26
+ pressure: string;
27
+ criticalFailed: number;
28
+ highFailed: number;
29
+ indexConsistent: boolean;
30
+ recommendations: string[];
31
+ sections: {
32
+ runtime: DoctorSection;
33
+ policy: DoctorSection;
34
+ knowledge: DoctorSection;
35
+ contract: DoctorSection;
36
+ snapshot: DoctorSection;
37
+ selftest?: DoctorSection;
38
+ };
39
+ }
40
+
41
+ function pickStatus(opts: {
42
+ criticalFailed: number;
43
+ pressure: string;
44
+ indexConsistent: boolean;
45
+ highFailed: number;
46
+ }): HealthStatus {
47
+ if (opts.criticalFailed > 0 || opts.pressure === 'hot') return 'red';
48
+ if (!opts.indexConsistent || opts.highFailed > 0 || opts.pressure === 'warm') return 'yellow';
49
+ return 'green';
50
+ }
51
+
52
+ export async function buildDoctorReport(opts: { deep?: boolean } = {}): Promise<DoctorReport> {
53
+ const ts = Date.now();
54
+ const recommendations: string[] = [];
55
+ let criticalFailed = 0;
56
+ let highFailed = 0;
57
+ let pressure = 'ok';
58
+ let indexConsistent = true;
59
+
60
+ // ── Runtime section ────────────────────────────────────────────────────
61
+ // Hand-trace: if getRuntimeStats() throws an Error:
62
+ // sections.runtime = { available: true, error: 'Error message string', data: {} }
63
+ // criticalFailed is NOT incremented (runtime errors are not critical failures)
64
+ const runtimeSection: DoctorSection = { available: true };
65
+ const runtimeImport = await optionalImport('./vite-native-runtime-plane.js');
66
+ if (!runtimeImport.ok) {
67
+ runtimeSection.available = true;
68
+ runtimeSection.error = runtimeImport.error;
69
+ criticalFailed++;
70
+ } else {
71
+ try {
72
+ const stats = runtimeImport.mod.getRuntimeStats();
73
+ pressure = stats.pressure;
74
+ runtimeSection.data = stats;
75
+ } catch (e: any) {
76
+ runtimeSection.error = e?.message ?? 'getRuntimeStats failed';
77
+ runtimeSection.data = {};
78
+ }
79
+ }
80
+
81
+ // ── Policy section ─────────────────────────────────────────────────────
82
+ const policySection: DoctorSection = { available: true };
83
+ const policyImport = await optionalImport('./vite-native-policy-plane.js');
84
+ if (!policyImport.ok) {
85
+ policySection.available = true;
86
+ policySection.error = policyImport.error;
87
+ criticalFailed++;
88
+ } else {
89
+ try {
90
+ const policy = policyImport.mod.evaluatePolicy({ pressure });
91
+ policySection.data = policy;
92
+ } catch (e: any) {
93
+ policySection.error = e?.message ?? 'evaluatePolicy failed';
94
+ highFailed++;
95
+ }
96
+ }
97
+
98
+ // ── Knowledge section ──────────────────────────────────────────────────
99
+ const knowledgeSection: DoctorSection = { available: true };
100
+ const knowledgeImport = await optionalImport('./vite-native-knowledge-store.js');
101
+ if (!knowledgeImport.ok) {
102
+ knowledgeSection.available = true;
103
+ knowledgeSection.error = knowledgeImport.error;
104
+ criticalFailed++;
105
+ } else {
106
+ try {
107
+ const stats = knowledgeImport.mod.getKnowledgeStats();
108
+ knowledgeSection.data = stats;
109
+ // Check FTS index consistency
110
+ if (stats.totalRecords > 0 && !stats.available) {
111
+ indexConsistent = false;
112
+ recommendations.push('Run /api/native-knowledge/repair-index to heal FTS drift.');
113
+ }
114
+ } catch (e: any) {
115
+ knowledgeSection.error = e?.message ?? 'getKnowledgeStats failed';
116
+ highFailed++;
117
+ }
118
+ }
119
+
120
+ // ── Contract section ───────────────────────────────────────────────────
121
+ const contractSection: DoctorSection = { available: true };
122
+ const contractImport = await optionalImport('./vite-native-contract-plane.js');
123
+ if (!contractImport.ok) {
124
+ contractSection.available = true;
125
+ contractSection.error = contractImport.error;
126
+ highFailed++;
127
+ } else {
128
+ try {
129
+ const result = contractImport.mod.contractSelfTest();
130
+ contractSection.data = result;
131
+ if (!result.passed) highFailed++;
132
+ } catch (e: any) {
133
+ contractSection.error = e?.message ?? 'contractSelfTest failed';
134
+ highFailed++;
135
+ }
136
+ }
137
+
138
+ // ── Snapshot section ───────────────────────────────────────────────────
139
+ const snapshotSection: DoctorSection = { available: true };
140
+ const snapshotImport = await optionalImport('./vite-native-snapshot-plane.js');
141
+ if (!snapshotImport.ok) {
142
+ snapshotSection.available = true;
143
+ snapshotSection.error = snapshotImport.error;
144
+ } else {
145
+ try {
146
+ const manifest = await snapshotImport.mod.getSnapshotManifest();
147
+ snapshotSection.data = manifest;
148
+ // Maintenance recommendation: >32MB reclaimable space
149
+ if (manifest.sizeBytes > 32 * 1024 * 1024) {
150
+ recommendations.push('Run /api/native-maintenance/run to reclaim SQLite space.');
151
+ }
152
+ } catch (e: any) {
153
+ snapshotSection.error = e?.message ?? 'getSnapshotManifest failed';
154
+ }
155
+ }
156
+
157
+ // ── Optional deep self-test ────────────────────────────────────────────
158
+ let selftestSection: DoctorSection | undefined;
159
+ if (opts.deep) {
160
+ selftestSection = { available: true };
161
+ const stImport = await optionalImport('./vite-native-selftest.js');
162
+ if (!stImport.ok) {
163
+ selftestSection.available = true;
164
+ selftestSection.error = stImport.error;
165
+ criticalFailed++;
166
+ } else {
167
+ try {
168
+ const result = stImport.mod.runStaticSelfTest();
169
+ selftestSection.data = result;
170
+ if (!result.passed) {
171
+ highFailed += result.failures?.length ?? 1;
172
+ // Trigger policy remediation for known failures
173
+ if (policyImport.ok) {
174
+ policyImport.mod.applySelfTestRemediation(result);
175
+ }
176
+ }
177
+ } catch (e: any) {
178
+ selftestSection.error = e?.message ?? 'Static self-test failed';
179
+ criticalFailed++;
180
+ }
181
+ }
182
+ }
183
+
184
+ // Add index inconsistency recommendation
185
+ if (!indexConsistent) {
186
+ recommendations.push('Run /api/native-knowledge/repair-index to heal FTS drift.');
187
+ }
188
+
189
+ const status = pickStatus({ criticalFailed, pressure, indexConsistent, highFailed });
190
+
191
+ return {
192
+ status,
193
+ ts,
194
+ pressure,
195
+ criticalFailed,
196
+ highFailed,
197
+ indexConsistent,
198
+ recommendations: [...new Set(recommendations)],
199
+ sections: {
200
+ runtime: runtimeSection,
201
+ policy: policySection,
202
+ knowledge: knowledgeSection,
203
+ contract: contractSection,
204
+ snapshot: snapshotSection,
205
+ ...(selftestSection && { selftest: selftestSection }),
206
+ },
207
+ };
208
+ }
@@ -0,0 +1,267 @@
1
+ /**
2
+ * vite-native-knowledge-store.ts — L1: Persistence & Vector/Lexical Math
3
+ * Zero-dependency SQLite storage for scraped content, RAG chunks, and Merkle-lite audit logs.
4
+ * All imports are from node:* only.
5
+ */
6
+ import { createHash } from 'node:crypto';
7
+ import { existsSync, mkdirSync } from 'node:fs';
8
+ import { createRequire } from 'node:module';
9
+ import { join, dirname } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+
15
+ // ── Ghost Load Pattern: avoids Rollup static analysis crash ──────────────
16
+ let DatabaseSync: any = null;
17
+ let dbAvailable = false;
18
+ try {
19
+ const anyProc: any = globalThis.process as any;
20
+ if (anyProc && typeof anyProc.getBuiltinModule === 'function') {
21
+ const mod = anyProc.getBuiltinModule('node:sqlite');
22
+ if (mod?.DatabaseSync) { DatabaseSync = mod.DatabaseSync; dbAvailable = true; }
23
+ }
24
+ } catch {}
25
+ if (!dbAvailable) {
26
+ try {
27
+ const req = createRequire(import.meta.url);
28
+ ({ DatabaseSync } = req('node:sqlite'));
29
+ dbAvailable = !!DatabaseSync;
30
+ } catch { dbAvailable = false; }
31
+ }
32
+
33
+ const AUDIT_DIR = join(__dirname, '..', '..', '..', 'src', 'audit');
34
+ const DB_PATH = join(AUDIT_DIR, 'knowledge.db');
35
+
36
+ let db: any = null;
37
+
38
+ function ensureDb(): boolean {
39
+ if (db) return true;
40
+ if (!dbAvailable) return false;
41
+ try {
42
+ if (!existsSync(AUDIT_DIR)) mkdirSync(AUDIT_DIR, { recursive: true });
43
+ db = new DatabaseSync(DB_PATH);
44
+ // Exact pragmas — MUST execute immediately after open
45
+ db.exec('PRAGMA journal_mode = WAL;');
46
+ db.exec('PRAGMA synchronous = NORMAL;');
47
+ db.exec('PRAGMA busy_timeout = 3000;');
48
+ initSchema();
49
+ return true;
50
+ } catch (e: any) {
51
+ console.warn('[knowledge-store] DB init failed:', e?.message);
52
+ return false;
53
+ }
54
+ }
55
+
56
+ function initSchema(): void {
57
+ db.exec(`
58
+ CREATE TABLE IF NOT EXISTS knowledge (
59
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
60
+ kind TEXT NOT NULL,
61
+ ref TEXT NOT NULL,
62
+ summary TEXT NOT NULL,
63
+ ts INTEGER NOT NULL,
64
+ refHash TEXT NOT NULL,
65
+ simHash TEXT NOT NULL
66
+ );
67
+ CREATE VIRTUAL TABLE IF NOT EXISTS knowledge_fts
68
+ USING fts5(summary, content='knowledge', content_rowid='id');
69
+ `);
70
+ // Exact FTS5 triggers — must NOT deviate
71
+ db.exec(`
72
+ CREATE TRIGGER IF NOT EXISTS tbl_ai AFTER INSERT ON knowledge BEGIN
73
+ INSERT INTO knowledge_fts(rowid, summary) VALUES (new.id, new.summary);
74
+ END;
75
+ CREATE TRIGGER IF NOT EXISTS tbl_ad AFTER DELETE ON knowledge BEGIN
76
+ INSERT INTO knowledge_fts(knowledge_fts, rowid, summary) VALUES('delete', old.id, old.summary);
77
+ END;
78
+ CREATE TRIGGER IF NOT EXISTS tbl_au AFTER UPDATE ON knowledge BEGIN
79
+ INSERT INTO knowledge_fts(knowledge_fts, rowid, summary) VALUES('delete', old.id, old.summary);
80
+ INSERT INTO knowledge_fts(rowid, summary) VALUES (new.id, new.summary);
81
+ END;
82
+ `);
83
+ db.exec(`
84
+ CREATE TABLE IF NOT EXISTS audit_log (
85
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
86
+ kind TEXT NOT NULL,
87
+ ref TEXT NOT NULL,
88
+ merkleHash TEXT NOT NULL,
89
+ ts INTEGER NOT NULL
90
+ );
91
+ `);
92
+ }
93
+
94
+ // ── 64-bit SimHash using BigInt — NO Number bitwise ops allowed ──────────
95
+ // Hand-trace: "hello world"
96
+ // toks = ["hello","world"]
97
+ // For "hello": sha256 -> 32 bytes; use first 8 bytes as BigInt
98
+ // bits = byte[0]<<56 | byte[1]<<48 | ... | byte[7]<<0 (using BigInt shifts)
99
+ // For each bit position b in 0..63: v[b] += ((bits >> BigInt(b)) & 1n) === 1n ? 1 : -1
100
+ // After all tokens, fp: for b in 0..63 if v[b]>0 then fp |= 1n<<BigInt(b)
101
+ // Return fp.toString(16).padStart(16,'0')
102
+ export function computeSimHash64(text: string): string {
103
+ const toks = text.toLowerCase().match(/[a-z0-9]+/g) || [];
104
+ const v = new Array(64).fill(0);
105
+ for (const tok of toks) {
106
+ const hashBuffer = createHash('sha256').update(tok, 'utf8').digest();
107
+ // Construct 64-bit BigInt from first 8 bytes — strictly BigInt arithmetic
108
+ let bits = 0n;
109
+ for (let i = 0; i < 8; i++) bits = (bits << 8n) | BigInt(hashBuffer[i]);
110
+ // Project onto 64-dimensional vector
111
+ for (let b = 0; b < 64; b++) v[b] += ((bits >> BigInt(b)) & 1n) === 1n ? 1 : -1;
112
+ }
113
+ // Collapse vector to fingerprint — MUST use BigInt, not Number bitwise
114
+ let fp = 0n;
115
+ for (let b = 0; b < 64; b++) if (v[b] > 0) fp |= (1n << BigInt(b));
116
+ return fp.toString(16).padStart(16, '0');
117
+ }
118
+
119
+ export function hammingDistance64(a: string, b: string): number {
120
+ let diff = BigInt(`0x${a}`) ^ BigInt(`0x${b}`);
121
+ let dist = 0;
122
+ while (diff > 0n) { dist += Number(diff & 1n); diff >>= 1n; }
123
+ return dist;
124
+ }
125
+
126
+ // ── Secret redaction before any data hits disk ───────────────────────────
127
+ export function redactSecrets(text: string): string {
128
+ // AWS keys
129
+ let r = text.replace(/AKIA[0-9A-Z]{16}/g, '[REDACTED_AWS_KEY]');
130
+ // GitHub PATs
131
+ r = r.replace(/ghp_[A-Za-z0-9]{36}/g, '[REDACTED_GH_PAT]');
132
+ r = r.replace(/github_pat_[A-Za-z0-9_]{82}/g, '[REDACTED_GH_PAT]');
133
+ // Generic secrets — bearer tokens, API keys in headers
134
+ r = r.replace(/Bearer\s+[A-Za-z0-9._\-]{20,}/gi, 'Bearer [REDACTED]');
135
+ r = r.replace(/api[_-]?key["\s:=]+[A-Za-z0-9_\-]{20,}/gi, 'api_key=[REDACTED]');
136
+ return r;
137
+ }
138
+
139
+ // ── Prompt injection scanner ──────────────────────────────────────────────
140
+ export function scanForInjection(text: string): boolean {
141
+ const lower = text.toLowerCase();
142
+ const injectionPatterns = [
143
+ 'ignore previous instructions',
144
+ 'ignore all instructions',
145
+ 'system prompt:',
146
+ 'new instruction:',
147
+ 'prompt injection',
148
+ '</system>',
149
+ '<|im_start|>',
150
+ 'jailbreak',
151
+ 'dan mode',
152
+ ];
153
+ return injectionPatterns.some(p => lower.includes(p));
154
+ }
155
+
156
+ // ── Core storage API ─────────────────────────────────────────────────────
157
+ export interface KnowledgeRecord {
158
+ id?: number;
159
+ kind: string;
160
+ ref: string;
161
+ summary: string;
162
+ ts: number;
163
+ refHash: string;
164
+ simHash: string;
165
+ }
166
+
167
+ export function recordKnowledge(kind: string, ref: string, rawSummary: string): { id: number } | null {
168
+ if (!ensureDb()) return null;
169
+ // Redact secrets before writing
170
+ const summary = redactSecrets(rawSummary).slice(0, 4000);
171
+ // Block injection attempts
172
+ if (scanForInjection(summary)) {
173
+ console.warn('[knowledge-store] Injection attempt detected in summary, blocking.');
174
+ return null;
175
+ }
176
+ const ts = Date.now();
177
+ const refHash = createHash('sha256').update(ref, 'utf8').digest('hex');
178
+ const simHash = computeSimHash64(summary);
179
+ try {
180
+ const stmt = db.prepare(`
181
+ INSERT INTO knowledge (kind, ref, summary, ts, refHash, simHash)
182
+ VALUES (?, ?, ?, ?, ?, ?)
183
+ `);
184
+ const result = stmt.run(kind, ref, summary, ts, refHash, simHash);
185
+ return { id: Number(result.lastInsertRowid) };
186
+ } catch (e: any) {
187
+ console.warn('[knowledge-store] recordKnowledge failed:', e?.message);
188
+ return null;
189
+ }
190
+ }
191
+
192
+ export function searchKnowledge(query: string, limit = 10): KnowledgeRecord[] {
193
+ if (!ensureDb()) return [];
194
+ try {
195
+ const stmt = db.prepare(`
196
+ SELECT k.* FROM knowledge k
197
+ JOIN knowledge_fts f ON f.rowid = k.id
198
+ WHERE knowledge_fts MATCH ?
199
+ ORDER BY rank
200
+ LIMIT ?
201
+ `);
202
+ return stmt.all(query, limit) as KnowledgeRecord[];
203
+ } catch {
204
+ // Fallback to LIKE if FTS fails
205
+ try {
206
+ const stmt = db.prepare(`SELECT * FROM knowledge WHERE summary LIKE ? LIMIT ?`);
207
+ return stmt.all(`%${query}%`, limit) as KnowledgeRecord[];
208
+ } catch { return []; }
209
+ }
210
+ }
211
+
212
+ export function getKnowledgeById(id: number): KnowledgeRecord | null {
213
+ if (!ensureDb()) return null;
214
+ try {
215
+ const stmt = db.prepare(`SELECT * FROM knowledge WHERE id = ?`);
216
+ return (stmt.get(id) as KnowledgeRecord) || null;
217
+ } catch { return null; }
218
+ }
219
+
220
+ export function deleteKnowledge(id: number): boolean {
221
+ if (!ensureDb()) return false;
222
+ try {
223
+ const stmt = db.prepare(`DELETE FROM knowledge WHERE id = ?`);
224
+ stmt.run(id);
225
+ return true;
226
+ } catch { return false; }
227
+ }
228
+
229
+ export function repairKnowledgeFts(): boolean {
230
+ if (!ensureDb()) return false;
231
+ try {
232
+ db.exec(`INSERT INTO knowledge_fts(knowledge_fts) VALUES('rebuild')`);
233
+ return true;
234
+ } catch { return false; }
235
+ }
236
+
237
+ // ── Autophagy: purge ghost files (refs no longer on disk) ────────────────
238
+ export function purgeGhostFiles(): number {
239
+ if (!ensureDb()) return 0;
240
+ try {
241
+ const rows = db.prepare(`SELECT id, ref FROM knowledge WHERE kind = 'file'`).all() as Array<{id:number, ref:string}>;
242
+ let purged = 0;
243
+ for (const row of rows) {
244
+ if (!existsSync(row.ref)) {
245
+ db.prepare(`DELETE FROM knowledge WHERE id = ?`).run(row.id);
246
+ purged++;
247
+ }
248
+ }
249
+ return purged;
250
+ } catch { return 0; }
251
+ }
252
+
253
+ // ── Stats ─────────────────────────────────────────────────────────────────
254
+ export function getKnowledgeStats(): { totalRecords: number; kinds: Record<string, number>; dbPath: string; available: boolean } {
255
+ if (!ensureDb()) return { totalRecords: 0, kinds: {}, dbPath: DB_PATH, available: false };
256
+ try {
257
+ const total = (db.prepare(`SELECT COUNT(*) as c FROM knowledge`).get() as any)?.c ?? 0;
258
+ const kindRows = db.prepare(`SELECT kind, COUNT(*) as c FROM knowledge GROUP BY kind`).all() as Array<{kind:string,c:number}>;
259
+ const kinds: Record<string, number> = {};
260
+ for (const r of kindRows) kinds[r.kind] = r.c;
261
+ return { totalRecords: total, kinds, dbPath: DB_PATH, available: true };
262
+ } catch { return { totalRecords: 0, kinds: {}, dbPath: DB_PATH, available: false }; }
263
+ }
264
+
265
+ export function getDb(): any { ensureDb(); return db; }
266
+ export function getDbPath(): string { return DB_PATH; }
267
+ export function isDbAvailable(): boolean { return dbAvailable && !!db; }
@@ -0,0 +1,190 @@
1
+ /**
2
+ * vite-native-policy-plane.ts — L2: Dynamic Feature Flags & Overrides
3
+ * Dynamic feature flagging backed by SQLite, allowing runtime degradation.
4
+ * Zero-dependency: node:* only.
5
+ */
6
+ import { createRequire } from 'node:module';
7
+ import { existsSync, mkdirSync } from 'node:fs';
8
+ import { join, dirname } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+
14
+ // Ghost load for SQLite
15
+ let DatabaseSync: any = null;
16
+ let dbAvailable = false;
17
+ try {
18
+ const anyProc: any = globalThis.process as any;
19
+ if (anyProc && typeof anyProc.getBuiltinModule === 'function') {
20
+ const mod = anyProc.getBuiltinModule('node:sqlite');
21
+ if (mod?.DatabaseSync) { DatabaseSync = mod.DatabaseSync; dbAvailable = true; }
22
+ }
23
+ } catch {}
24
+ if (!dbAvailable) {
25
+ try {
26
+ const req = createRequire(import.meta.url);
27
+ ({ DatabaseSync } = req('node:sqlite'));
28
+ dbAvailable = !!DatabaseSync;
29
+ } catch { dbAvailable = false; }
30
+ }
31
+
32
+ const AUDIT_DIR = join(__dirname, '..', '..', '..', 'src', 'audit');
33
+ const DB_PATH = join(AUDIT_DIR, 'knowledge.db');
34
+
35
+ let db: any = null;
36
+
37
+ function ensureDb(): boolean {
38
+ if (db) return true;
39
+ if (!dbAvailable) return false;
40
+ try {
41
+ if (!existsSync(AUDIT_DIR)) mkdirSync(AUDIT_DIR, { recursive: true });
42
+ db = new DatabaseSync(DB_PATH);
43
+ db.exec('PRAGMA journal_mode = WAL;');
44
+ db.exec('PRAGMA synchronous = NORMAL;');
45
+ db.exec('PRAGMA busy_timeout = 3000;');
46
+ db.exec(`
47
+ CREATE TABLE IF NOT EXISTS policy_flags (
48
+ name TEXT PRIMARY KEY,
49
+ valueJson TEXT NOT NULL,
50
+ ts INTEGER NOT NULL
51
+ );
52
+ `);
53
+ return true;
54
+ } catch (e: any) {
55
+ console.warn('[policy-plane] DB init failed:', e?.message);
56
+ return false;
57
+ }
58
+ }
59
+
60
+ export interface PolicyState {
61
+ useDdg: boolean;
62
+ useBing: boolean;
63
+ useYahoo: boolean;
64
+ useMojeek: boolean;
65
+ enableSSE: boolean;
66
+ enablePrefetch: boolean;
67
+ enableAutoRag: boolean;
68
+ enableRateLimit: boolean;
69
+ enableCircuitBreaker: boolean;
70
+ maxResultsPerEngine: number;
71
+ searchTimeoutMs: number;
72
+ }
73
+
74
+ export const DEFAULT_POLICY: PolicyState = {
75
+ useDdg: true,
76
+ useBing: true,
77
+ useYahoo: true,
78
+ useMojeek: true,
79
+ enableSSE: true,
80
+ enablePrefetch: true,
81
+ enableAutoRag: true,
82
+ enableRateLimit: true,
83
+ enableCircuitBreaker: true,
84
+ maxResultsPerEngine: 5,
85
+ searchTimeoutMs: 8000,
86
+ };
87
+
88
+ export function getPolicyOverrides(): Partial<PolicyState> {
89
+ if (!ensureDb()) return {};
90
+ try {
91
+ const rows = db.prepare(`SELECT name, valueJson FROM policy_flags`).all() as Array<{name: string; valueJson: string}>;
92
+ const result: Partial<PolicyState> = {};
93
+ for (const row of rows) {
94
+ try {
95
+ // Wrap JSON.parse — corrupted rows must be ignored, not thrown
96
+ const val = JSON.parse(row.valueJson);
97
+ (result as any)[row.name] = val;
98
+ } catch {
99
+ // Silently ignore corrupted DB rows
100
+ }
101
+ }
102
+ return result;
103
+ } catch { return {}; }
104
+ }
105
+
106
+ // UPSERT implementation for SQLite
107
+ export function setPolicyOverride(name: keyof PolicyState | string, value: unknown): boolean {
108
+ if (!ensureDb()) return false;
109
+ try {
110
+ // Hand-trace: calling twice with same name — second call hits ON CONFLICT
111
+ // First: INSERT succeeds, row created with name, valueJson, ts
112
+ // Second: INSERT fails ON CONFLICT(name), DO UPDATE SET fires instead
113
+ // Both calls result in the same row with updated valueJson and ts
114
+ const stmt = db.prepare(`
115
+ INSERT INTO policy_flags (name, valueJson, ts)
116
+ VALUES (?, ?, ?)
117
+ ON CONFLICT(name) DO UPDATE SET valueJson = excluded.valueJson, ts = excluded.ts
118
+ `);
119
+ stmt.run(name, JSON.stringify(value), Date.now());
120
+ return true;
121
+ } catch { return false; }
122
+ }
123
+
124
+ export function deletePolicyOverride(name: string): boolean {
125
+ if (!ensureDb()) return false;
126
+ try {
127
+ db.prepare(`DELETE FROM policy_flags WHERE name = ?`).run(name);
128
+ return true;
129
+ } catch { return false; }
130
+ }
131
+
132
+ // ── Policy Evaluation ─────────────────────────────────────────────────────
133
+ // Hand-trace: DB override sets enablePrefetch = true, but ctx.pressure = 'hot'
134
+ // Step 1: merged = {...DEFAULT_POLICY, ...overrides} => enablePrefetch = true
135
+ // Step 2: pressure === 'hot' => forcefully set enablePrefetch = false, enableSSE = false, enableAutoRag = false
136
+ // Final value of enablePrefetch = FALSE (hot pressure wins, ignores DB override)
137
+ export function evaluatePolicy(ctx: { pressure: 'ok' | 'warm' | 'hot' }): PolicyState {
138
+ const overrides = getPolicyOverrides();
139
+ const merged: PolicyState = { ...DEFAULT_POLICY, ...overrides };
140
+
141
+ // Hot pressure: force shed non-critical features — DB overrides are IGNORED
142
+ if (ctx.pressure === 'hot') {
143
+ merged.enablePrefetch = false;
144
+ merged.enableSSE = false;
145
+ merged.enableAutoRag = false;
146
+ }
147
+
148
+ // Total engine blackout prevention: force useDdg if all four engines disabled
149
+ if (!merged.useDdg && !merged.useBing && !merged.useYahoo && !merged.useMojeek) {
150
+ merged.useDdg = true;
151
+ }
152
+
153
+ return merged;
154
+ }
155
+
156
+ // ── Self-test remediation ─────────────────────────────────────────────────
157
+ export interface SelfTestResult {
158
+ passed: boolean;
159
+ failures: string[];
160
+ }
161
+
162
+ export function applySelfTestRemediation(result: SelfTestResult): void {
163
+ for (const failure of result.failures) {
164
+ if (failure.includes('parser.bing.href.capture')) {
165
+ console.warn('[policy-plane] Bing parser failure detected — disabling Bing engine');
166
+ setPolicyOverride('useBing', false);
167
+ }
168
+ if (failure.includes('parser.ddg.href.capture')) {
169
+ console.warn('[policy-plane] DDG parser failure detected — disabling DDG engine');
170
+ setPolicyOverride('useDdg', false);
171
+ }
172
+ if (failure.includes('parser.yahoo.href.capture')) {
173
+ setPolicyOverride('useYahoo', false);
174
+ }
175
+ if (failure.includes('parser.mojeek.href.capture')) {
176
+ setPolicyOverride('useMojeek', false);
177
+ }
178
+ }
179
+ }
180
+
181
+ export function getAllPolicyFlags(): Array<{ name: string; value: unknown; ts: number }> {
182
+ if (!ensureDb()) return [];
183
+ try {
184
+ const rows = db.prepare(`SELECT name, valueJson, ts FROM policy_flags ORDER BY name`).all() as Array<{name:string;valueJson:string;ts:number}>;
185
+ return rows.map(r => {
186
+ try { return { name: r.name, value: JSON.parse(r.valueJson), ts: r.ts }; }
187
+ catch { return { name: r.name, value: null, ts: r.ts }; }
188
+ });
189
+ } catch { return []; }
190
+ }