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,608 @@
1
+ /**
2
+ * spa-rescue-bridge.ts
3
+ * ============================================================================
4
+ * ADDITIVE bridge that closes the one self-documented gap in the canonical
5
+ * stack: `structured-source-adapter.ts`'s `rescueSpaPayload()` requires the
6
+ * raw HTML to arrive via `Error.cause`, but `retrieval-policy-augments.ts`'s
7
+ * `withChallengeGate()` throws a plain `Error(message)` with no `.cause`.
8
+ * As documented by the canonical author: "This is a known limitation,
9
+ * documented, not a silent bug." This file closes it without touching either
10
+ * canonical file.
11
+ *
12
+ * WHAT THIS DOES:
13
+ * Wraps a base reader with:
14
+ * 1. Content classification: distinguish TRUE bot-challenges (Turnstile,
15
+ * CAPTCHA, WAF block pages — hard failures that must propagate so the
16
+ * circuit breaker in retrieval-control-plane.ts responds correctly)
17
+ * from SOFT SPA shells / thin-content pages (safe to rescue).
18
+ * 2. On a soft failure, attaches the raw HTML as `Error.cause` in the
19
+ * exact shape `structured-source-adapter.ts`'s `wrappedStructuredChallengeReader`
20
+ * already expects (a string > 200 chars), then re-throws so the
21
+ * existing canonical rescue logic activates unmodified.
22
+ * 3. On a hard failure (real challenge), re-throws with NO cause,
23
+ * preserving the canonical circuit-breaker/challenge-gate semantics
24
+ * exactly as designed — this is the safety-critical distinction.
25
+ *
26
+ * WHAT THIS EXPLICITLY DOES NOT DO (red-teamed and rejected this session):
27
+ * - Does NOT attempt any new transport lane, proxy, or CORS bypass.
28
+ * - Does NOT modify retrieval-policy-augments.ts's detectChallenge/
29
+ * withChallengeGate or structured-source-adapter.ts's rescue functions.
30
+ *
31
+ * ADDITIVE ONLY. Zero new npm deps. Browser-only, keyless.
32
+ * NOT EXECUTED in this environment.
33
+ * ============================================================================ */
34
+
35
+ import type { ScheduleContext, RetrievalPolicy, CrawlPayload } from "./retrieval-control-plane";
36
+ import { detectPageBlock } from "./retrieval-policy-augments";
37
+
38
+ // Adapter around detectPageBlock to provide standard isChallenge/isSpaShell properties
39
+ export function detectChallenge(html: string): {
40
+ isChallenge: boolean;
41
+ isSpaShell: boolean;
42
+ markers: string[];
43
+ } {
44
+ const d = detectPageBlock(html);
45
+ return {
46
+ isChallenge: d.blocked,
47
+ isSpaShell: d.softShell,
48
+ markers: d.markers,
49
+ };
50
+ }
51
+
52
+ // ═══════════════════════════════════════════════════════════════════════════
53
+ // SOFT vs HARD FAILURE CLASSIFICATION
54
+ // ═══════════════════════════════════════════════════════════════════════════
55
+
56
+ /**
57
+ * A "soft" failure is one where detectChallenge() found NO true challenge
58
+ * markers (Turnstile/CAPTCHA/WAF text) but the content was still rejected —
59
+ * i.e. it was thin, an SPA shell, or low-text-ratio. These are the ONLY
60
+ * cases eligible for rescue. A true isChallenge=true case is a real bot
61
+ * block and MUST propagate unmodified so the circuit breaker in
62
+ * retrieval-control-plane.ts opens correctly for that host.
63
+ */
64
+ export function isSoftFailure(html: string): boolean {
65
+ const d = detectChallenge(html);
66
+ return !d.isChallenge && (d.isSpaShell || d.markers.length > 0);
67
+ }
68
+
69
+ // ═══════════════════════════════════════════════════════════════════════════
70
+ // PUBLIC API
71
+ // ═══════════════════════════════════════════════════════════════════════════
72
+
73
+ /**
74
+ * withSpaRescueCause — wraps a base reader (the one you'd normally pass to
75
+ * canonical `withChallengeGate()`) so that when the underlying fetch succeeds
76
+ * in getting bytes but the CONTENT is a soft SPA shell / thin page (not a
77
+ * true bot-challenge), the raw HTML is captured and attached to the thrown
78
+ * error's `.cause` in the exact shape `structured-source-adapter.ts`'s
79
+ * `wrappedStructuredChallengeReader` already expects.
80
+ */
81
+ export function withSpaRescueCause<T>(
82
+ reader: (url: string, ctx: ScheduleContext, policy: RetrievalPolicy) => Promise<CrawlPayload<T>>,
83
+ ): (url: string, ctx: ScheduleContext, policy: RetrievalPolicy) => Promise<CrawlPayload<T>> {
84
+ return async (url, ctx, policy) => {
85
+ try {
86
+ const payload = await reader(url, ctx, policy);
87
+ return payload;
88
+ } catch (e) {
89
+ const err = e instanceof Error ? e : new Error(String(e));
90
+ const existingCause = (err as { cause?: unknown }).cause;
91
+ if (typeof existingCause === "string" && existingCause.length > 200) {
92
+ if (isSoftFailure(existingCause)) {
93
+ throw err;
94
+ }
95
+ const stripped = new Error(err.message);
96
+ throw stripped;
97
+ }
98
+ throw err;
99
+ }
100
+ };
101
+ }
102
+
103
+ /**
104
+ * withSpaRescueFromRawResponse — the PRIMARY, fully-functional rescue path.
105
+ * Use this INSTEAD of `withChallengeGate` (not layered on top of it) when
106
+ * you construct your own base reader, because it has access to the raw
107
+ * fetched text BEFORE any challenge-gate throws away that context.
108
+ */
109
+ export function withSpaRescueFromRawResponse<T>(
110
+ rawReader: (url: string, ctx: ScheduleContext, policy: RetrievalPolicy) => Promise<CrawlPayload<T>>,
111
+ ): (url: string, ctx: ScheduleContext, policy: RetrievalPolicy) => Promise<CrawlPayload<T>> {
112
+ return async (url, ctx, policy) => {
113
+ const payload = await rawReader(url, ctx, policy);
114
+ const html = payload.text ?? "";
115
+ const classification = detectChallenge(html);
116
+
117
+ if (classification.isChallenge) {
118
+ throw new Error(`challenge_detected:${classification.markers[0] ?? "unknown"}`);
119
+ }
120
+
121
+ if (classification.isSpaShell || html.trim().length < 80) {
122
+ const err = new Error(
123
+ classification.isSpaShell ? "spa_shell_detected" : "thin_content_detected",
124
+ );
125
+ if (html.length > 200) {
126
+ (err as { cause?: unknown }).cause = html;
127
+ }
128
+ throw err;
129
+ }
130
+
131
+ return payload;
132
+ };
133
+ }
134
+
135
+ // ═══════════════════════════════════════════════════════════════════════════
136
+ // DIAGNOSTICS
137
+ // ═══════════════════════════════════════════════════════════════════════════
138
+
139
+ export async function runSpaRescueBridgeDiagnostics(): Promise<{
140
+ ok: boolean;
141
+ checks: Array<{
142
+ id: string;
143
+ passed: boolean;
144
+ detail: string;
145
+ }>;
146
+ }> {
147
+ const checks: Array<{
148
+ id: string;
149
+ passed: boolean;
150
+ detail: string;
151
+ }> = [];
152
+
153
+ const add = (
154
+ id: string,
155
+ passed: boolean,
156
+ detail: string,
157
+ ): void => {
158
+ checks.push({ id, passed, detail });
159
+ };
160
+
161
+ const mockController = new AbortController();
162
+
163
+ const mockCtx = {
164
+ attempt: 1,
165
+ host: "example.com",
166
+ hostLimit: 1,
167
+ signal: mockController.signal,
168
+ } as ScheduleContext;
169
+
170
+ const mockPolicy = {
171
+ policyVersion: "diagnostic",
172
+ extractionVersion: "diagnostic",
173
+ maxBytes: 2_000_000,
174
+ freshnessMs: 0,
175
+ requiredLaneClasses: 1,
176
+ cacheMode: "off",
177
+ robotsMode: "off",
178
+ scope: "seed-origins",
179
+ allowHostedRenderer: true,
180
+ allowPublicRelays: true,
181
+ allowArchive: true,
182
+ } as RetrievalPolicy;
183
+
184
+ // 1. Clean content passes through unchanged.
185
+ {
186
+ const wrapped =
187
+ withSpaRescueFromRawResponse<string>(
188
+ async () => ({
189
+ value: "ok",
190
+ text:
191
+ "<article><p>" +
192
+ "Normal readable article content spanning several sentences. ".repeat(
193
+ 10,
194
+ ) +
195
+ "</p></article>",
196
+ contentType: "text/html",
197
+ canonicalUrl:
198
+ "https://example.com/article",
199
+ bytesRead: 640,
200
+ }),
201
+ );
202
+
203
+ try {
204
+ const result = await wrapped(
205
+ "https://example.com/article",
206
+ mockCtx,
207
+ mockPolicy,
208
+ );
209
+
210
+ add(
211
+ "clean-content-passes",
212
+ result.value === "ok",
213
+ `value=${String(result.value)}`,
214
+ );
215
+ } catch (error) {
216
+ add(
217
+ "clean-content-passes",
218
+ false,
219
+ error instanceof Error
220
+ ? error.message
221
+ : "unexpected rejection",
222
+ );
223
+ }
224
+ }
225
+
226
+ // 2. SPA shell throws with the original HTML as Error.cause.
227
+ {
228
+ const spaHtml =
229
+ '<html><head><meta property="og:title" content="SPA article"></head>' +
230
+ '<body><div id="__next"></div><script src="/app.js"></script></body></html>' +
231
+ "x".repeat(240);
232
+
233
+ const wrapped =
234
+ withSpaRescueFromRawResponse<string>(
235
+ async () => ({
236
+ value: "spa",
237
+ text: spaHtml,
238
+ contentType: "text/html",
239
+ canonicalUrl:
240
+ "https://spa.example.com/article",
241
+ bytesRead: spaHtml.length,
242
+ }),
243
+ );
244
+
245
+ try {
246
+ await wrapped(
247
+ "https://spa.example.com/article",
248
+ mockCtx,
249
+ mockPolicy,
250
+ );
251
+
252
+ add(
253
+ "spa-shell-throws-with-cause",
254
+ false,
255
+ "did not throw",
256
+ );
257
+ } catch (error) {
258
+ const cause = (
259
+ error as { cause?: unknown }
260
+ ).cause;
261
+
262
+ add(
263
+ "spa-shell-throws-with-cause",
264
+ typeof cause === "string" &&
265
+ cause === spaHtml &&
266
+ cause.includes("__next"),
267
+ `causeType=${typeof cause} causeLength=${
268
+ typeof cause === "string"
269
+ ? cause.length
270
+ : 0
271
+ }`,
272
+ );
273
+ }
274
+ }
275
+
276
+ // 3. A genuine WAF/challenge response must not expose rescue data.
277
+ {
278
+ const challengeHtml =
279
+ "<html><body>" +
280
+ '<div class="cf-challenge">' +
281
+ "Checking your browser. Turnstile verification required." +
282
+ "</div>" +
283
+ "</body></html>";
284
+
285
+ const wrapped =
286
+ withSpaRescueFromRawResponse<string>(
287
+ async () => ({
288
+ value: "blocked",
289
+ text: challengeHtml,
290
+ contentType: "text/html",
291
+ canonicalUrl:
292
+ "https://blocked.example.com/article",
293
+ bytesRead: challengeHtml.length,
294
+ }),
295
+ );
296
+
297
+ try {
298
+ await wrapped(
299
+ "https://blocked.example.com/article",
300
+ mockCtx,
301
+ mockPolicy,
302
+ );
303
+
304
+ add(
305
+ "hard-challenge-throws-without-cause",
306
+ false,
307
+ "did not throw",
308
+ );
309
+ } catch (error) {
310
+ const cause = (
311
+ error as { cause?: unknown }
312
+ ).cause;
313
+
314
+ const message =
315
+ error instanceof Error
316
+ ? error.message
317
+ : String(error);
318
+
319
+ add(
320
+ "hard-challenge-throws-without-cause",
321
+ cause === undefined &&
322
+ message.startsWith(
323
+ "challenge_detected:",
324
+ ),
325
+ `causePresent=${
326
+ cause !== undefined
327
+ } message=${message}`,
328
+ );
329
+ }
330
+ }
331
+
332
+ // 4. Very short content contains nothing useful to salvage.
333
+ {
334
+ const wrapped =
335
+ withSpaRescueFromRawResponse<string>(
336
+ async () => ({
337
+ value: "thin",
338
+ text: "x".repeat(50),
339
+ contentType: "text/html",
340
+ canonicalUrl:
341
+ "https://thin.example.com/article",
342
+ bytesRead: 50,
343
+ }),
344
+ );
345
+
346
+ try {
347
+ await wrapped(
348
+ "https://thin.example.com/article",
349
+ mockCtx,
350
+ mockPolicy,
351
+ );
352
+
353
+ add(
354
+ "thin-content-too-short-no-cause",
355
+ false,
356
+ "did not throw",
357
+ );
358
+ } catch (error) {
359
+ const cause = (
360
+ error as { cause?: unknown }
361
+ ).cause;
362
+
363
+ const message =
364
+ error instanceof Error
365
+ ? error.message
366
+ : String(error);
367
+
368
+ add(
369
+ "thin-content-too-short-no-cause",
370
+ cause === undefined &&
371
+ message === "thin_content_detected",
372
+ `causePresent=${
373
+ cause !== undefined
374
+ } message=${message}`,
375
+ );
376
+ }
377
+ }
378
+
379
+ // 5. Empty response also has no salvageable cause.
380
+ {
381
+ const wrapped =
382
+ withSpaRescueFromRawResponse<string>(
383
+ async () => ({
384
+ value: "empty",
385
+ text: "",
386
+ contentType: "text/html",
387
+ canonicalUrl:
388
+ "https://empty.example.com/article",
389
+ bytesRead: 0,
390
+ }),
391
+ );
392
+
393
+ try {
394
+ await wrapped(
395
+ "https://empty.example.com/article",
396
+ mockCtx,
397
+ mockPolicy,
398
+ );
399
+
400
+ add(
401
+ "empty-html-no-cause",
402
+ false,
403
+ "did not throw",
404
+ );
405
+ } catch (error) {
406
+ const cause = (
407
+ error as { cause?: unknown }
408
+ ).cause;
409
+
410
+ add(
411
+ "empty-html-no-cause",
412
+ cause === undefined,
413
+ `causePresent=${cause !== undefined}`,
414
+ );
415
+ }
416
+ }
417
+
418
+ // 6. Plain failures are not converted into fabricated rescue payloads.
419
+ {
420
+ const wrapped =
421
+ withSpaRescueCause<string>(
422
+ async () => {
423
+ throw new Error(
424
+ "some_generic_failure",
425
+ );
426
+ },
427
+ );
428
+
429
+ try {
430
+ await wrapped(
431
+ "https://generic.example.com/article",
432
+ mockCtx,
433
+ mockPolicy,
434
+ );
435
+
436
+ add(
437
+ "no-cause-rethrows-unchanged",
438
+ false,
439
+ "did not throw",
440
+ );
441
+ } catch (error) {
442
+ const cause = (
443
+ error as { cause?: unknown }
444
+ ).cause;
445
+
446
+ const message =
447
+ error instanceof Error
448
+ ? error.message
449
+ : String(error);
450
+
451
+ add(
452
+ "no-cause-rethrows-unchanged",
453
+ message === "some_generic_failure" &&
454
+ cause === undefined,
455
+ `message=${message} causePresent=${
456
+ cause !== undefined
457
+ }`,
458
+ );
459
+ }
460
+ }
461
+
462
+ // 7. A pre-existing, valid SPA rescue cause is preserved exactly.
463
+ {
464
+ const softHtml =
465
+ '<html><body><div id="__next"></div>' +
466
+ "y".repeat(240) +
467
+ "</body></html>";
468
+
469
+ const wrapped =
470
+ withSpaRescueCause<string>(
471
+ async () => {
472
+ const error = new Error(
473
+ "spa_shell_detected",
474
+ );
475
+
476
+ (
477
+ error as {
478
+ cause?: unknown;
479
+ }
480
+ ).cause = softHtml;
481
+
482
+ throw error;
483
+ },
484
+ );
485
+
486
+ try {
487
+ await wrapped(
488
+ "https://soft.example.com/article",
489
+ mockCtx,
490
+ mockPolicy,
491
+ );
492
+
493
+ add(
494
+ "soft-cause-propagated",
495
+ false,
496
+ "did not throw",
497
+ );
498
+ } catch (error) {
499
+ const cause = (
500
+ error as { cause?: unknown }
501
+ ).cause;
502
+
503
+ add(
504
+ "soft-cause-propagated",
505
+ cause === softHtml,
506
+ `causeMatches=${cause === softHtml}`,
507
+ );
508
+ }
509
+ }
510
+
511
+ // 8. A mistakenly attached challenge page must have its cause stripped.
512
+ {
513
+ const hardHtml =
514
+ '<html><body><div class="cf-challenge">' +
515
+ "Checking your browser. Turnstile verification required." +
516
+ "</div>" +
517
+ "z".repeat(180) +
518
+ "</body></html>";
519
+
520
+ const wrapped =
521
+ withSpaRescueCause<string>(
522
+ async () => {
523
+ const error = new Error(
524
+ "mislabeled_soft_failure",
525
+ );
526
+
527
+ (
528
+ error as {
529
+ cause?: unknown;
530
+ }
531
+ ).cause = hardHtml;
532
+
533
+ throw error;
534
+ },
535
+ );
536
+
537
+ try {
538
+ await wrapped(
539
+ "https://hard.example.com/article",
540
+ mockCtx,
541
+ mockPolicy,
542
+ );
543
+
544
+ add(
545
+ "hard-cause-stripped",
546
+ false,
547
+ "did not throw",
548
+ );
549
+ } catch (error) {
550
+ const cause = (
551
+ error as { cause?: unknown }
552
+ ).cause;
553
+
554
+ add(
555
+ "hard-cause-stripped",
556
+ cause === undefined,
557
+ cause === undefined
558
+ ? "cause stripped"
559
+ : "hard challenge cause leaked",
560
+ );
561
+ }
562
+ }
563
+
564
+ // 9. Non-Error thrown values are normalized without inventing data.
565
+ {
566
+ const wrapped =
567
+ withSpaRescueCause<string>(
568
+ async () => {
569
+ throw "raw_string_failure";
570
+ },
571
+ );
572
+
573
+ try {
574
+ await wrapped(
575
+ "https://nonerror.example.com/article",
576
+ mockCtx,
577
+ mockPolicy,
578
+ );
579
+
580
+ add(
581
+ "non-error-normalized",
582
+ false,
583
+ "did not throw",
584
+ );
585
+ } catch (error) {
586
+ add(
587
+ "non-error-normalized",
588
+ error instanceof Error &&
589
+ error.message ===
590
+ "raw_string_failure",
591
+ `isError=${
592
+ error instanceof Error
593
+ } message=${
594
+ error instanceof Error
595
+ ? error.message
596
+ : String(error)
597
+ }`,
598
+ );
599
+ }
600
+ }
601
+
602
+ return {
603
+ ok: checks.every(
604
+ (check) => check.passed,
605
+ ),
606
+ checks,
607
+ };
608
+ }