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.
- package/diagnostics.mjs +141 -0
- package/dist/compute.worker-j5ahIpF-.js +1 -0
- package/dist/graph.worker-DG6iGCB9.js +1 -0
- package/dist/index.html +2314 -0
- package/flatten-guide.md +248 -0
- package/index.html +12 -0
- package/package.json +38 -0
- package/src/App.orig.tsx +204 -0
- package/src/App.orig1.tsx +27 -0
- package/src/App.orig2.tsx +25 -0
- package/src/App.tsx +3 -0
- package/src/BaseApp.tsx +18 -0
- package/src/INTEGRATION_LEDGER.md +22 -0
- package/src/PERSIST_CANARY.orig.txt +1 -0
- package/src/PERSIST_CANARY.txt +1 -0
- package/src/REGRESSION_LEDGER.md +651 -0
- package/src/TEMPLATE_PIPELINE_AUDIT.md +208 -0
- package/src/WILLIAMS_PERSONA_GUIDE.md +62 -0
- package/src/chat/VeritasChat.tsx +69 -0
- package/src/chat/synthesis.ts +31 -0
- package/src/chat/tier.ts +45 -0
- package/src/components/AdaptersPage.orig.tsx +99 -0
- package/src/components/AdaptersPage.tsx +3 -0
- package/src/components/AdversarialPanel.tsx +136 -0
- package/src/components/AnchorBaselinePanel.tsx +75 -0
- package/src/components/AnswerPanel.tsx +60 -0
- package/src/components/ArtifactPanel.tsx +43 -0
- package/src/components/ChatApp.orig.tsx +1582 -0
- package/src/components/ChatApp.orig1.tsx +722 -0
- package/src/components/ChatApp.tsx +95 -0
- package/src/components/ChatAugmentPanels.tsx +73 -0
- package/src/components/CitationLedgerPanel.tsx +313 -0
- package/src/components/ComputeSandboxPanel.tsx +130 -0
- package/src/components/ConfigPanel.tsx +110 -0
- package/src/components/ControlPlanePage.tsx +195 -0
- package/src/components/CreativeTreeLifePage.tsx +234 -0
- package/src/components/CreativeTreeOfLifePanel.tsx +149 -0
- package/src/components/DebugTracePanel.tsx +137 -0
- package/src/components/DeepReasoningTrace.tsx +48 -0
- package/src/components/EntitySheetPanel.tsx +51 -0
- package/src/components/FailureModesPanel.tsx +104 -0
- package/src/components/GBSDashboard.tsx +239 -0
- package/src/components/GraphView.tsx +116 -0
- package/src/components/HUD.tsx +125 -0
- package/src/components/HypothesisPanel.tsx +67 -0
- package/src/components/InnovationGenomeEngine.tsx +792 -0
- package/src/components/InnovationPersonaGuide.tsx +348 -0
- package/src/components/InnovationPersonaPanel.tsx +289 -0
- package/src/components/LiveResourceHUD.tsx +109 -0
- package/src/components/LongWriterPanel.tsx +112 -0
- package/src/components/MainPipelineV10Bridge.tsx +72 -0
- package/src/components/MarkdownLite.tsx +63 -0
- package/src/components/MemoryInspector.tsx +38 -0
- package/src/components/MemoryMonitor.tsx +52 -0
- package/src/components/MemoryStressPanel.tsx +176 -0
- package/src/components/ModulesPage.tsx +171 -0
- package/src/components/PipelineDebugConsole.orig.tsx +1856 -0
- package/src/components/PipelineDebugConsole.tsx +3 -0
- package/src/components/PreFlightHUD.tsx +67 -0
- package/src/components/PrismaFetchTracePanel.tsx +87 -0
- package/src/components/ReportOSPanel.tsx +165 -0
- package/src/components/ResourceEstimatorPage.tsx +327 -0
- package/src/components/RichText.tsx +181 -0
- package/src/components/SagaOsPanel.tsx +605 -0
- package/src/components/SagaOsReference.tsx +421 -0
- package/src/components/SagaOsV2Panel.tsx +594 -0
- package/src/components/SagaStyleTab.tsx +382 -0
- package/src/components/SageBlueprintPanel.tsx +416 -0
- package/src/components/SharedChatInput.tsx +77 -0
- package/src/components/StatFinancePanel.tsx +190 -0
- package/src/components/StylePersonaPanel.tsx +128 -0
- package/src/components/TemplatesPage.tsx +300 -0
- package/src/components/TestPanel.tsx +63 -0
- package/src/components/TraceLog.tsx +89 -0
- package/src/components/V15CalibrationAugment.tsx +1134 -0
- package/src/components/V15CalibrationDialog.tsx +1871 -0
- package/src/components/V15Overlay.orig.tsx +120 -0
- package/src/components/V15Overlay.tsx +4 -0
- package/src/components/V15OverlayWrapper.tsx +362 -0
- package/src/components/V15Toggle.tsx +34 -0
- package/src/console/DiagnosticRecoveryPanel.tsx +358 -0
- package/src/console/EngineeringConsole.tsx +103 -0
- package/src/console/FictionSystemPanels.tsx +882 -0
- package/src/console/InspectorPanels.tsx +254 -0
- package/src/console/ManuscriptGraderPanel.tsx +182 -0
- package/src/console/RecursiveReviserPanel.tsx +245 -0
- package/src/console/SeedControlPanel.tsx +135 -0
- package/src/console/StoryControllerPanel.tsx +443 -0
- package/src/console/engineBridge.ts +258 -0
- package/src/console/gemini.ts +106 -0
- package/src/console/grading.ts +250 -0
- package/src/console/util.ts +45 -0
- package/src/fiction/continuity.ts +372 -0
- package/src/fiction/crash-protection.ts +111 -0
- package/src/fiction/diagnostics.ts +208 -0
- package/src/fiction/diff.ts +74 -0
- package/src/fiction/entity-state-machine.ts +214 -0
- package/src/fiction/nive-engine.ts +404 -0
- package/src/fiction/pipeline-selftest.ts +132 -0
- package/src/fiction/seed-control.ts +193 -0
- package/src/fiction/story-engine.ts +326 -0
- package/src/fiction/types.ts +68 -0
- package/src/flatten-guide.md +379 -0
- package/src/index.css +14 -0
- package/src/index.orig.css +13 -0
- package/src/lib/academic-sources.base.ts +188 -0
- package/src/lib/academic-sources.orig.ts +28 -0
- package/src/lib/academic-sources.ts +10 -0
- package/src/lib/advanced-math.ts +119 -0
- package/src/lib/adversarial-engine.base.ts +409 -0
- package/src/lib/adversarial-engine.ts +82 -0
- package/src/lib/ai-revision.ts +623 -0
- package/src/lib/app-state.tsx +426 -0
- package/src/lib/artifact-registry.ts +97 -0
- package/src/lib/artifacts.ts +180 -0
- package/src/lib/atlas-dr.ts +167 -0
- package/src/lib/browser-mtls.ts +127 -0
- package/src/lib/browser-queue.ts +221 -0
- package/src/lib/browser-search-scraper.base.ts +382 -0
- package/src/lib/browser-search-scraper.orig.ts +90 -0
- package/src/lib/browser-search-scraper.ts +10 -0
- package/src/lib/calc-interceptor.ts +82 -0
- package/src/lib/citation-lane-tap.ts +78 -0
- package/src/lib/citation-ledger-store.ts +369 -0
- package/src/lib/citation-ledger.ts +203 -0
- package/src/lib/compute-sandbox.ts +215 -0
- package/src/lib/compute.worker.ts +153 -0
- package/src/lib/connectors/gemini.ts +120 -0
- package/src/lib/connectors/jina.ts +233 -0
- package/src/lib/connectors/marketdata.ts +51 -0
- package/src/lib/connectors/prismafetch.base.ts +175 -0
- package/src/lib/connectors/prismafetch.ts +1 -0
- package/src/lib/connectors/serpapi.ts +65 -0
- package/src/lib/connectors/wikidata.ts +44 -0
- package/src/lib/constraints.ts +331 -0
- package/src/lib/continuation-detector.base.ts +153 -0
- package/src/lib/continuation-detector.ts +48 -0
- package/src/lib/contradraft.ts +168 -0
- package/src/lib/cors-proxy.ts +120 -0
- package/src/lib/coverage.ts +81 -0
- package/src/lib/debug/architecture-prescription.ts +556 -0
- package/src/lib/debug/covea-repair.ts +543 -0
- package/src/lib/debug/helios-ground.ts +319 -0
- package/src/lib/debug/intent-decomposer.ts +281 -0
- package/src/lib/debug/intent-lattice.ts +349 -0
- package/src/lib/debug/pipeline-diagnosis.ts +1149 -0
- package/src/lib/debug/pipeline-trace-bus.ts +424 -0
- package/src/lib/debug/prompt-forge.ts +678 -0
- package/src/lib/debug/repair-sites.ts +513 -0
- package/src/lib/debug/research-phase.ts +266 -0
- package/src/lib/debug/retrieval-context.ts +76 -0
- package/src/lib/debug/retrieval-hardener.ts +142 -0
- package/src/lib/debug/scraper-debug-runner.ts +576 -0
- package/src/lib/debug/scraper-forensics.ts +418 -0
- package/src/lib/debug/scraper-lane-roadmap.ts +136 -0
- package/src/lib/debug/self-test.ts +415 -0
- package/src/lib/debug/step-attribution.ts +211 -0
- package/src/lib/debug/template-rubric.ts +301 -0
- package/src/lib/debug/unified-innovation.ts +126 -0
- package/src/lib/debug/veritas-hybrid-scraper.ts +335 -0
- package/src/lib/defense-registry.ts +104 -0
- package/src/lib/defenses.ts +162 -0
- package/src/lib/deterministic-citation-ledger.ts +174 -0
- package/src/lib/elo-registry.base.ts +117 -0
- package/src/lib/elo-registry.ts +1 -0
- package/src/lib/entity-resolver.ts +291 -0
- package/src/lib/failure-modes.ts +267 -0
- package/src/lib/feature-registry.ts +69 -0
- package/src/lib/flaw-registry.ts +143 -0
- package/src/lib/flaws/_template.ts +52 -0
- package/src/lib/flaws/builtins.ts +63 -0
- package/src/lib/flaws/finance.ts +169 -0
- package/src/lib/flaws/fixers.ts +10 -0
- package/src/lib/flaws/index.ts +32 -0
- package/src/lib/flaws/legal.ts +157 -0
- package/src/lib/flaws/medical.ts +188 -0
- package/src/lib/flaws/original-defenses-pack.ts +81 -0
- package/src/lib/flaws/sample-declarative-pack.json +38 -0
- package/src/lib/flaws/selftest.ts +201 -0
- package/src/lib/flaws/software-extended.ts +125 -0
- package/src/lib/flaws/software-rn-webgl.ts +182 -0
- package/src/lib/flaws/statistics-advanced.ts +46 -0
- package/src/lib/flaws/statistics.ts +61 -0
- package/src/lib/gbse/config.ts +20 -0
- package/src/lib/gbse/engine.ts +226 -0
- package/src/lib/gbse/graph.ts +118 -0
- package/src/lib/gbse/graph.worker.ts +21 -0
- package/src/lib/gbse/tests.ts +117 -0
- package/src/lib/gbse/tiers.ts +65 -0
- package/src/lib/gbse/types.ts +94 -0
- package/src/lib/innovation-genome-engine-v2.orig.ts +1001 -0
- package/src/lib/innovation-genome-engine-v2.ts +3 -0
- package/src/lib/innovation-genome-engine.orig.ts +330 -0
- package/src/lib/innovation-genome-engine.ts +3 -0
- package/src/lib/innovation-genome-v10.orig.ts +314 -0
- package/src/lib/innovation-genome-v10.ts +2 -0
- package/src/lib/innovation-genome-v3.orig.ts +2015 -0
- package/src/lib/innovation-genome-v3.ts +2 -0
- package/src/lib/innovation-genome-v4.orig.ts +1959 -0
- package/src/lib/innovation-genome-v4.ts +2 -0
- package/src/lib/innovation-genome-v5.orig.ts +1210 -0
- package/src/lib/innovation-genome-v5.ts +2 -0
- package/src/lib/innovation-genome-v7.orig.ts +2549 -0
- package/src/lib/innovation-genome-v7.ts +2 -0
- package/src/lib/innovation-genome-v8.orig.ts +1485 -0
- package/src/lib/innovation-genome-v8.ts +2 -0
- package/src/lib/innovation-genome-v9.orig.ts +643 -0
- package/src/lib/innovation-genome-v9.ts +2 -0
- package/src/lib/jina.base.ts +293 -0
- package/src/lib/jina.ts +1 -0
- package/src/lib/live-telemetry.ts +61 -0
- package/src/lib/longwriter.ts +84 -0
- package/src/lib/manuscript-grade-v2.ts +298 -0
- package/src/lib/memory-governor.ts +173 -0
- package/src/lib/memory-stress-tests.ts +248 -0
- package/src/lib/model-intelligence.ts +48 -0
- package/src/lib/model-rotator.ts +75 -0
- package/src/lib/models.orig.ts +513 -0
- package/src/lib/models.ts +151 -0
- package/src/lib/n-deep.base.ts +592 -0
- package/src/lib/n-deep.ts +51 -0
- package/src/lib/nih-simulator.ts +56 -0
- package/src/lib/nih-vulnerability-fixes.ts +460 -0
- package/src/lib/omega-templates.base.ts +294 -0
- package/src/lib/omega-templates.ts +225 -0
- package/src/lib/omni-nexus.ts +64 -0
- package/src/lib/oracle-adapters.ts +67 -0
- package/src/lib/oracle-registry.ts +163 -0
- package/src/lib/orchestrator.ts +357 -0
- package/src/lib/output-boundary.ts +235 -0
- package/src/lib/overrides/vite-native-chaos-harness.ts +154 -0
- package/src/lib/overrides/vite-native-contract-plane.ts +245 -0
- package/src/lib/overrides/vite-native-doctor-plane.ts +208 -0
- package/src/lib/overrides/vite-native-knowledge-store.ts +267 -0
- package/src/lib/overrides/vite-native-policy-plane.ts +190 -0
- package/src/lib/overrides/vite-native-replay-plane.ts +197 -0
- package/src/lib/overrides/vite-native-runtime-plane.ts +106 -0
- package/src/lib/overrides/vite-native-scraper.ts +848 -0
- package/src/lib/overrides/vite-native-selftest-functional.ts +217 -0
- package/src/lib/overrides/vite-native-selftest.ts +183 -0
- package/src/lib/overrides/vite-native-snapshot-plane.ts +123 -0
- package/src/lib/philosophy-toolkit.ts +75 -0
- package/src/lib/pipeline.orig.ts +659 -0
- package/src/lib/pipeline.ts +42 -0
- package/src/lib/precache.ts +128 -0
- package/src/lib/py-sandbox.ts +205 -0
- package/src/lib/quality-score.ts +96 -0
- package/src/lib/quant-engine.ts +231 -0
- package/src/lib/quant-lib.ts +80 -0
- package/src/lib/reportos.ts +175 -0
- package/src/lib/research-os.ts +306 -0
- package/src/lib/resource-estimator.ts +114 -0
- package/src/lib/rpm-governor.ts +93 -0
- package/src/lib/runtime-estimator.ts +135 -0
- package/src/lib/sage/empty-space-v6.ts +560 -0
- package/src/lib/sage/empty-space-v7.ts +222 -0
- package/src/lib/sage/empty-space.ts +733 -0
- package/src/lib/sage/engine.ts +786 -0
- package/src/lib/sage/index.ts +17 -0
- package/src/lib/sage/judge.ts +246 -0
- package/src/lib/sage/prng.ts +53 -0
- package/src/lib/sage/reality-grounding.ts +380 -0
- package/src/lib/sage/repetition.ts +151 -0
- package/src/lib/sage/saga-os-v2-engines.ts +1870 -0
- package/src/lib/sage/saga-os-v2.ts +274 -0
- package/src/lib/sage/saga-os-v3-core.ts +1491 -0
- package/src/lib/sage/saga-os-v3-release.ts +739 -0
- package/src/lib/sage/saga-os-v4-aureate.ts +1161 -0
- package/src/lib/sage/saga-os-v4.ts +212 -0
- package/src/lib/sage/saga-os-v5.ts +205 -0
- package/src/lib/sage/saga-os-v6.ts +346 -0
- package/src/lib/sage/saga-os-v7.ts +314 -0
- package/src/lib/sage/saga-os-v8.ts +505 -0
- package/src/lib/sage/saga-os.ts +329 -0
- package/src/lib/sage/taxonomy.ts +403 -0
- package/src/lib/sage/unified-roll.ts +524 -0
- package/src/lib/sage/worked-sketches.ts +44 -0
- package/src/lib/sage.ts +166 -0
- package/src/lib/scraper-debug-bus.ts +53 -0
- package/src/lib/scraper-enhanced.orig.ts +153 -0
- package/src/lib/scraper-enhanced.ts +10 -0
- package/src/lib/scraper-hardener.base.orig.ts +155 -0
- package/src/lib/scraper-hardener.base.ts +317 -0
- package/src/lib/scraper-hardener.ts +1 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.orig.ts +419 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.ts +13 -0
- package/src/lib/scraper-vnext/arbiter-omega.orig.ts +688 -0
- package/src/lib/scraper-vnext/arbiter-omega.ts +13 -0
- package/src/lib/scraper-vnext/canonical-portfolio-augments.ts +479 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.orig.ts +1529 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.ts +13 -0
- package/src/lib/scraper-vnext/conclave-omega.ts +1830 -0
- package/src/lib/scraper-vnext/content-extractor-v2.ts +226 -0
- package/src/lib/scraper-vnext/diagnostics-suite.ts +36 -0
- package/src/lib/scraper-vnext/epistemic-packer.ts +97 -0
- package/src/lib/scraper-vnext/fusion-v2.ts +65 -0
- package/src/lib/scraper-vnext/hydra-reader.orig.ts +1216 -0
- package/src/lib/scraper-vnext/hydra-reader.ts +13 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.orig.ts +91 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.ts +13 -0
- package/src/lib/scraper-vnext/nexus-consensus.orig.ts +905 -0
- package/src/lib/scraper-vnext/nexus-consensus.ts +13 -0
- package/src/lib/scraper-vnext/portfolio-consensus-adjudicator.ts +804 -0
- package/src/lib/scraper-vnext/portfolio-consensus-memory.ts +377 -0
- package/src/lib/scraper-vnext/portfolio-terminal-governor.ts +548 -0
- package/src/lib/scraper-vnext/query-strategist.orig.ts +224 -0
- package/src/lib/scraper-vnext/query-strategist.ts +423 -0
- package/src/lib/scraper-vnext/retrieval-accelerator.ts +708 -0
- package/src/lib/scraper-vnext/retrieval-audit-augments.ts +477 -0
- package/src/lib/scraper-vnext/retrieval-control-plane.ts +904 -0
- package/src/lib/scraper-vnext/retrieval-policy-augments.ts +358 -0
- package/src/lib/scraper-vnext/safe-fetch-v2.ts +157 -0
- package/src/lib/scraper-vnext/sentinel-omega.ts +56 -0
- package/src/lib/scraper-vnext/sentinel-orchestrator.ts +69 -0
- package/src/lib/scraper-vnext/sibyl-oracle.orig.ts +413 -0
- package/src/lib/scraper-vnext/sibyl-oracle.ts +13 -0
- package/src/lib/scraper-vnext/smart-read-v2.ts +55 -0
- package/src/lib/scraper-vnext/spa-rescue-bridge.ts +608 -0
- package/src/lib/scraper-vnext/strata-engine.orig.ts +2666 -0
- package/src/lib/scraper-vnext/strata-engine.ts +13 -0
- package/src/lib/scraper-vnext/structured-source-adapter.orig.ts +369 -0
- package/src/lib/scraper-vnext/structured-source-adapter.ts +34 -0
- package/src/lib/scraper-vnext/terminal-complete.ts +224 -0
- package/src/lib/scraper-vnext/terminal-final.ts +277 -0
- package/src/lib/scraper-vnext/terminal-saturation.ts +345 -0
- package/src/lib/scraper-vnext/terminal-wire.ts +425 -0
- package/src/lib/scraper-vnext/vanguard-titanium.orig.ts +467 -0
- package/src/lib/scraper-vnext/vanguard-titanium.ts +17 -0
- package/src/lib/search-cache.ts +138 -0
- package/src/lib/sloop-runner.base.ts +223 -0
- package/src/lib/sloop-runner.ts +104 -0
- package/src/lib/sloop.ts +114 -0
- package/src/lib/small-model-adapters.ts +82 -0
- package/src/lib/sscp.ts +86 -0
- package/src/lib/system-map.ts +54 -0
- package/src/lib/uni-node.ts +86 -0
- package/src/lib/universal-rigor-guard.ts +433 -0
- package/src/lib/v15-gate-testbed.ts +274 -0
- package/src/lib/v15-gemini.base.ts +89 -0
- package/src/lib/v15-gemini.ts +1 -0
- package/src/lib/v15-grounding.orig.ts +241 -0
- package/src/lib/v15-grounding.ts +79 -0
- package/src/lib/v15-pipeline.base.ts +769 -0
- package/src/lib/v15-pipeline.orig.ts +1154 -0
- package/src/lib/v15-pipeline.ts +674 -0
- package/src/lib/v15-questions.ts +64 -0
- package/src/lib/v15-rate-limiter.orig.ts +91 -0
- package/src/lib/v15-rate-limiter.ts +48 -0
- package/src/lib/v15-state.base.ts +87 -0
- package/src/lib/v15-state.ts +28 -0
- package/src/lib/visual-table-generator.tsx +207 -0
- package/src/lib/wasm-runtime.ts +133 -0
- package/src/lib/williams-persona-guide.ts +265 -0
- package/src/lib/williams-style.base.ts +464 -0
- package/src/lib/williams-style.ts +59 -0
- package/src/lib/worker-pool.ts +96 -0
- package/src/lib/writing-tiers.ts +125 -0
- package/src/main.orig.tsx +10 -0
- package/src/main.tsx +10 -0
- package/src/utils/cn.orig.ts +6 -0
- package/src/utils/cn.ts +6 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +31 -0
- package/unify.mjs +537 -0
- package/vite.config.ts +18 -0
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIDECAR SEAM — Type B (Complex Override). See flatten-guide.md §2, §8, §9.
|
|
3
|
+
* ===========================================================================
|
|
4
|
+
* TURN-4 REWRITE — additive, minimum-diff, non-destructive.
|
|
5
|
+
*
|
|
6
|
+
* The turn-2 version instrumented `onProgress` into the trace bus. Turn 4
|
|
7
|
+
* adds four architectural gates while preserving every existing behaviour:
|
|
8
|
+
*
|
|
9
|
+
* G1 DUAL scraper-debug-bus subscription (workspace shim path AND direct
|
|
10
|
+
* package path) with a listener dedup — defense against Vite module-
|
|
11
|
+
* duplication edge cases.
|
|
12
|
+
* G2 Genome v1 + v2 injection (the package's `v15-pipeline.ts` already
|
|
13
|
+
* injects v10 via `_VERITAS_V10_DISCOVERY`; we append the v1 base
|
|
14
|
+
* genome directive and the v2 extended-persona directive verbatim,
|
|
15
|
+
* no truncation, so all three genome layers steer the run).
|
|
16
|
+
* G3 Numeric-question profile-mutation — force compute-relevant flags on
|
|
17
|
+
* when the question is numeric AND the profile did not set them.
|
|
18
|
+
* G4 POST-COMPLETION COVEA REPAIR PASS — targeted CoVe + adversarial
|
|
19
|
+
* repair invoked ONLY when the standard pipeline surfaces failures
|
|
20
|
+
* and did not repair them (the exact observed failure mode).
|
|
21
|
+
*
|
|
22
|
+
* NON-INTERCEPTABLE by design (documented in flatten-guide §9):
|
|
23
|
+
* `runV15OnQuestion` internally calls `groundQuestion` with RELATIVE
|
|
24
|
+
* specifier, so wrapping this seam cannot intercept retrieval. COVEA runs
|
|
25
|
+
* AFTER the pipeline completes and therefore observes the retrieval trace,
|
|
26
|
+
* never re-runs it.
|
|
27
|
+
*
|
|
28
|
+
* FAIL-OPEN: every added path is try/catch-wrapped. Telemetry and repair
|
|
29
|
+
* never break a real pipeline run.
|
|
30
|
+
* ===========================================================================
|
|
31
|
+
*/
|
|
32
|
+
export * from "./v15-pipeline.orig";
|
|
33
|
+
|
|
34
|
+
import {
|
|
35
|
+
runV15OnQuestion as packageRunV15,
|
|
36
|
+
runBaselineOnQuestion as packageRunBaseline,
|
|
37
|
+
} from "./v15-pipeline.orig";
|
|
38
|
+
import { subscribeScraperDebug as subscribeScraperDebugPkg } from '@/lib/scraper-debug-bus';
|
|
39
|
+
// G1: workspace-shim path as second subscription source. If the workspace
|
|
40
|
+
// shim and the direct package path resolve to the same module, the second
|
|
41
|
+
// subscribe() call is a no-op duplicate that our listener dedup absorbs. If
|
|
42
|
+
// they resolve to two module instances (rare, Vite edge case), we capture
|
|
43
|
+
// events from BOTH.
|
|
44
|
+
import { subscribeScraperDebug as subscribeScraperDebugShim } from "@/lib/scraper-debug-bus";
|
|
45
|
+
import {
|
|
46
|
+
startRun,
|
|
47
|
+
finishRun,
|
|
48
|
+
pushEvent,
|
|
49
|
+
attachScraperLine,
|
|
50
|
+
attachGenome,
|
|
51
|
+
attachResearch,
|
|
52
|
+
attachCovea,
|
|
53
|
+
classifyProgress,
|
|
54
|
+
} from "@/lib/debug/pipeline-trace-bus";
|
|
55
|
+
import { loadTemplateRubric } from "@/lib/debug/template-rubric";
|
|
56
|
+
import { runCoveaRepair } from "@/lib/debug/covea-repair";
|
|
57
|
+
import { isPlaceholderUrl } from "@/lib/debug/scraper-forensics";
|
|
58
|
+
import {
|
|
59
|
+
buildLatticeQueries,
|
|
60
|
+
enrichLatticeWithLlm,
|
|
61
|
+
renderLatticeDirective,
|
|
62
|
+
type IntentLattice,
|
|
63
|
+
} from "@/lib/debug/intent-lattice";
|
|
64
|
+
import { geminiGenerate } from '@/lib/v15-gemini';
|
|
65
|
+
import { clearRetrievalContext, registerRetrievalContext } from "@/lib/debug/retrieval-context";
|
|
66
|
+
import { buildUnifiedInnovationPlan, type UnifiedInnovationPlan } from "@/lib/debug/unified-innovation";
|
|
67
|
+
import { runPrewritingResearch, type ResearchPhaseResult } from "@/lib/debug/research-phase";
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Template → ordered section titles, used as the lattice's section vector.
|
|
71
|
+
* Falls back to a single "general" section for non-OMEGA templates so HDIG
|
|
72
|
+
* and adv-repair still receive decomposed queries.
|
|
73
|
+
*/
|
|
74
|
+
function latticeSectionsFor(templateId: string | undefined): string[] {
|
|
75
|
+
if (!templateId) return ["general"];
|
|
76
|
+
const rubric = loadTemplateRubric(templateId, null, null);
|
|
77
|
+
const titles = rubric?.sections.map((s) => s.title) ?? [];
|
|
78
|
+
return titles.length ? titles : ["general"];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* G7: build the Intent Facet Lattice from the UNTRUNCATED prompt and splice
|
|
83
|
+
* its directive into the question envelope. Deterministic floor always
|
|
84
|
+
* applies; the LLM enrichment layer can only ADD facets and fails safe.
|
|
85
|
+
*/
|
|
86
|
+
async function injectIntentLattice(
|
|
87
|
+
opts: Record<string, any>,
|
|
88
|
+
runId: string,
|
|
89
|
+
trueQuestion: string
|
|
90
|
+
): Promise<void> {
|
|
91
|
+
try {
|
|
92
|
+
if (String(opts.question ?? "").includes("RETRIEVAL INTENT LATTICE")) return; // idempotent
|
|
93
|
+
const sections = latticeSectionsFor(opts.profile?.templateId);
|
|
94
|
+
let lattice: IntentLattice = buildLatticeQueries(trueQuestion, sections);
|
|
95
|
+
|
|
96
|
+
const apiKey = String(opts.apiKey ?? "");
|
|
97
|
+
if (apiKey && opts.profile?.webSearch !== false) {
|
|
98
|
+
try {
|
|
99
|
+
const enriched = await enrichLatticeWithLlm(lattice, (p) =>
|
|
100
|
+
geminiGenerate({ apiKey, model: "gemini-2.0-flash-lite", prompt: p, maxOutputTokens: 600 })
|
|
101
|
+
.then((r: any) => ({ ok: !!(r?.text ?? r?.output), text: String(r?.text ?? r?.output ?? ""), error: r?.error }))
|
|
102
|
+
.catch((e: unknown) => ({ ok: false, text: "", error: e instanceof Error ? e.message : String(e) }))
|
|
103
|
+
);
|
|
104
|
+
if (enriched.ok) lattice = enriched.lattice;
|
|
105
|
+
pushEvent(runId, "system", "init",
|
|
106
|
+
`G7 Intent Facet Lattice · ${lattice.facets.length} facets · ${lattice.queries.length} per-section queries · llmEnriched=${lattice.llmEnriched}` +
|
|
107
|
+
(enriched.ok ? "" : ` (LLM enrich failed: ${enriched.error}; deterministic floor retained)`)
|
|
108
|
+
);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
pushEvent(runId, "system", "init",
|
|
111
|
+
`G7 Intent Facet Lattice · ${lattice.facets.length} facets · ${lattice.queries.length} per-section queries · enrichment threw: ${e instanceof Error ? e.message : String(e)} (deterministic floor retained)`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
pushEvent(runId, "system", "init",
|
|
116
|
+
`G7 Intent Facet Lattice · ${lattice.facets.length} facets · ${lattice.queries.length} per-section queries · deterministic-only`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Order: true question first (never truncated), then the lattice directive
|
|
121
|
+
// so the draft path's grounding sees decomposed queries.
|
|
122
|
+
opts.question = [trueQuestion, renderLatticeDirective(lattice)].filter(Boolean).join("\n\n");
|
|
123
|
+
opts.intentLattice = lattice;
|
|
124
|
+
registerRetrievalContext(runId, trueQuestion, lattice);
|
|
125
|
+
} catch {
|
|
126
|
+
/* fail-open — raw question still works without the lattice */
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ── G1: dual scraper bridge with per-message dedup ─────────────────────────
|
|
131
|
+
let scraperBridgeInstalled = false;
|
|
132
|
+
/** Small ring of (lane|message|~timestamp) so a duplicate emit from two module
|
|
133
|
+
* instances or double-subscription does not fire the listener twice. */
|
|
134
|
+
const recentBridgeKeys = new Set<string>();
|
|
135
|
+
const RECENT_MAX = 500;
|
|
136
|
+
function seenRecently(key: string): boolean {
|
|
137
|
+
if (recentBridgeKeys.has(key)) return true;
|
|
138
|
+
recentBridgeKeys.add(key);
|
|
139
|
+
if (recentBridgeKeys.size > RECENT_MAX) {
|
|
140
|
+
// Trim oldest ~half
|
|
141
|
+
const arr = Array.from(recentBridgeKeys);
|
|
142
|
+
recentBridgeKeys.clear();
|
|
143
|
+
for (const k of arr.slice(-Math.floor(RECENT_MAX / 2))) recentBridgeKeys.add(k);
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
function installScraperBridge(): void {
|
|
148
|
+
if (scraperBridgeInstalled) return;
|
|
149
|
+
scraperBridgeInstalled = true;
|
|
150
|
+
const relay = (line: { lane: string; message: string }) => {
|
|
151
|
+
const bucket = Math.floor(Date.now() / 250); // 250ms bucket for dedup key
|
|
152
|
+
const key = `${line.lane}|${line.message}|${bucket}`;
|
|
153
|
+
if (seenRecently(key)) return;
|
|
154
|
+
try {
|
|
155
|
+
attachScraperLine(line.lane, line.message);
|
|
156
|
+
} catch {
|
|
157
|
+
/* fail-open */
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
try {
|
|
161
|
+
subscribeScraperDebugPkg(relay);
|
|
162
|
+
} catch {
|
|
163
|
+
/* subscription unavailable via package path */
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
subscribeScraperDebugShim(relay);
|
|
167
|
+
} catch {
|
|
168
|
+
/* subscription unavailable via shim path */
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ── Progress tee ───────────────────────────────────────────────────────────
|
|
173
|
+
function teeProgress(
|
|
174
|
+
runId: string,
|
|
175
|
+
original: ((s: string) => void) | undefined
|
|
176
|
+
): (s: string) => void {
|
|
177
|
+
return (s: string) => {
|
|
178
|
+
try {
|
|
179
|
+
original?.(s);
|
|
180
|
+
} catch {
|
|
181
|
+
/* caller's handler threw; not our concern */
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
pushEvent(runId, "progress", classifyProgress(s), s);
|
|
185
|
+
} catch {
|
|
186
|
+
/* fail-open */
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ── G2: one base genome plus v2 expansion; never independent genomes ───────
|
|
192
|
+
function injectGenomeAndResearch(
|
|
193
|
+
opts: Record<string, any>,
|
|
194
|
+
runId: string,
|
|
195
|
+
trueQuestion: string,
|
|
196
|
+
unified: UnifiedInnovationPlan,
|
|
197
|
+
research: ResearchPhaseResult | null,
|
|
198
|
+
): void {
|
|
199
|
+
try {
|
|
200
|
+
attachGenome(runId, unified);
|
|
201
|
+
const existing = String(opts.question ?? trueQuestion);
|
|
202
|
+
opts.question = [
|
|
203
|
+
existing,
|
|
204
|
+
unified.directive,
|
|
205
|
+
research?.dossier ?? "## PREWRITING RESEARCH DOSSIER\n[EVIDENCE_STARVED] Research phase unavailable; report writer must preserve gaps.",
|
|
206
|
+
research?.evidenceBlock ?? "",
|
|
207
|
+
].join("\n\n");
|
|
208
|
+
opts.unifiedInnovation = unified;
|
|
209
|
+
opts.prewritingResearch = research;
|
|
210
|
+
pushEvent(
|
|
211
|
+
runId,
|
|
212
|
+
"system",
|
|
213
|
+
"genome",
|
|
214
|
+
`Unified genome v1+v2 expansion injected — seed=${unified.seed} domain=${unified.domain} path=${unified.expansion.path.name}; path symbols expanded to full words`
|
|
215
|
+
);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
pushEvent(runId, "system", "error", `unified genome/research injection failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async function preparePrewritingResearch(
|
|
222
|
+
opts: Record<string, any>,
|
|
223
|
+
runId: string,
|
|
224
|
+
question: string,
|
|
225
|
+
unified: UnifiedInnovationPlan,
|
|
226
|
+
): Promise<ResearchPhaseResult | null> {
|
|
227
|
+
if (opts.profile?.prewritingResearch === false) {
|
|
228
|
+
pushEvent(runId, "system", "grounding", "Prewriting research explicitly disabled by profile.prewritingResearch=false");
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
const apiKey = String(opts.apiKey ?? "");
|
|
232
|
+
try {
|
|
233
|
+
pushEvent(runId, "system", "grounding", "Prewriting research started — independent search strategist before report writer");
|
|
234
|
+
const result = await runPrewritingResearch({
|
|
235
|
+
question,
|
|
236
|
+
personaSeed: Number(opts.personaSeed ?? opts.profile?.personaSeed ?? unified.seed),
|
|
237
|
+
risk: opts.profile?.risk ?? "medium",
|
|
238
|
+
maxQueries: Number(opts.profile?.researchQueries ?? 8),
|
|
239
|
+
generateQueries: apiKey
|
|
240
|
+
? (prompt) => geminiGenerate({ apiKey, model: "gemini-2.0-flash-lite", prompt, maxOutputTokens: 1400 })
|
|
241
|
+
.then((r: any) => ({ ok: !!(r?.text ?? r?.output), text: String(r?.text ?? r?.output ?? ""), error: r?.error }))
|
|
242
|
+
.catch((e: unknown) => ({ ok: false, text: "", error: e instanceof Error ? e.message : String(e) }))
|
|
243
|
+
: undefined,
|
|
244
|
+
onProgress: (m) => pushEvent(runId, "progress", "grounding", m),
|
|
245
|
+
});
|
|
246
|
+
attachResearch(runId, result);
|
|
247
|
+
pushEvent(runId, "system", "grounding", `Prewriting research complete — ${result.queries.length} queries, ${result.sources.length} URL-backed sources, status=${result.status}`);
|
|
248
|
+
return result;
|
|
249
|
+
} catch (e) {
|
|
250
|
+
pushEvent(runId, "system", "error", `Prewriting research failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ── G3: numeric-question profile mutation (deterministic route) ────────────
|
|
256
|
+
const NUMERIC_QUESTION_RE = /\b(calculate|estimate|npv|irr|percent|ratio|market size|tam|sam|som|forecast|projection|multiple|revenue|margin|cost)\b/i;
|
|
257
|
+
function mutateProfileForNumericQuestion(opts: Record<string, any>, runId: string): void {
|
|
258
|
+
if (!opts?.question || !NUMERIC_QUESTION_RE.test(String(opts.question))) return;
|
|
259
|
+
const p = (opts.profile = opts.profile ?? {});
|
|
260
|
+
const before = { computeSandbox: !!p.computeSandbox, webSearch: !!p.webSearch };
|
|
261
|
+
if (p.computeSandbox !== true) p.computeSandbox = true;
|
|
262
|
+
if (p.webSearch !== true) p.webSearch = true; // grounding is a prerequisite for numeric sourcing
|
|
263
|
+
const after = { computeSandbox: p.computeSandbox, webSearch: p.webSearch };
|
|
264
|
+
if (before.computeSandbox !== after.computeSandbox || before.webSearch !== after.webSearch) {
|
|
265
|
+
pushEvent(runId, "system", "init", `numeric-question detected → forced profile.computeSandbox=${after.computeSandbox}, profile.webSearch=${after.webSearch}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ── Pure text primitives (exported for self-test / architecture audit) ─────
|
|
270
|
+
|
|
271
|
+
/** All distinct numeric citation ids referenced by the text, incl. grouped tags. */
|
|
272
|
+
export function extractCitationIds(text: string): number[] {
|
|
273
|
+
const ids = new Set<number>();
|
|
274
|
+
for (const m of text.matchAll(/\[S?(\d{1,3})(?:\s*,\s*S?(\d{1,3}))*\]/gi)) {
|
|
275
|
+
for (const n of m[0].matchAll(/(\d{1,3})/g)) ids.add(Number(n[1]));
|
|
276
|
+
}
|
|
277
|
+
return [...ids].sort((a, b) => a - b);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** CSS-reset / chrome blobs that the retriever admitted as "sources". */
|
|
281
|
+
export function looksLikeBoilerplate(text: string): boolean {
|
|
282
|
+
const s = String(text ?? "").toLowerCase();
|
|
283
|
+
if (s.trim().length === 0) return true;
|
|
284
|
+
return /table,\s*caption,\s*tbody/.test(s)
|
|
285
|
+
|| /--font-inter|font-family:\s*var\(--font/.test(s)
|
|
286
|
+
|| /margin:\s*0;padding:\s*0;border:\s*0/.test(s);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** Sentence that stops mid-clause on a connector — the truncation gate. */
|
|
290
|
+
export function endsOnDanglingConnector(text: string): boolean {
|
|
291
|
+
return /[a-z]\s+(and|but|or|which|that|because|however|so|thereby|although|by)\s*[.!]?\s*$/i.test(String(text ?? "").trim());
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* G5 (pure): insert a stub for every template section absent from `text`.
|
|
296
|
+
* Insertion-only — never rewrites or reorders existing prose. Idempotent:
|
|
297
|
+
* an already-inserted stub counts as present on a second pass.
|
|
298
|
+
*/
|
|
299
|
+
export function insertMissingSectionStubs(
|
|
300
|
+
text: string,
|
|
301
|
+
templateId?: string,
|
|
302
|
+
styleOverride?: string | null,
|
|
303
|
+
williamsPersona?: string | null
|
|
304
|
+
): { text: string; inserted: string[] } {
|
|
305
|
+
if (!text || !templateId) return { text, inserted: [] };
|
|
306
|
+
const rubric = loadTemplateRubric(templateId, styleOverride ?? null, williamsPersona ?? null);
|
|
307
|
+
if (!rubric) return { text, inserted: [] };
|
|
308
|
+
|
|
309
|
+
const missing: Array<{ title: string; hint: string }> = [];
|
|
310
|
+
for (const sec of rubric.sections) {
|
|
311
|
+
const rx = new RegExp(`##\\s*(?:§\\d+\\s*)?${sec.title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i");
|
|
312
|
+
if (!rx.test(text)) missing.push({ title: sec.title, hint: sec.purpose || "(open item)" });
|
|
313
|
+
}
|
|
314
|
+
if (missing.length === 0) return { text, inserted: [] };
|
|
315
|
+
|
|
316
|
+
const stubs = missing
|
|
317
|
+
.map((s) => `\n\n## ${s.title}\n\n[MISSING SECTION — please supply]\nRequired by template ${templateId}. ${s.hint}\n`)
|
|
318
|
+
.join("");
|
|
319
|
+
|
|
320
|
+
// Insert stubs before References if present, otherwise append.
|
|
321
|
+
const refsIdx = text.search(/##\s*references/i);
|
|
322
|
+
const patched = refsIdx >= 0 ? text.slice(0, refsIdx) + stubs + text.slice(refsIdx) : text + stubs;
|
|
323
|
+
return { text: patched, inserted: missing.map((s) => s.title) };
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Annotate sections whose grounding returned zero URL-backed sources so the
|
|
328
|
+
* reader sees an explicit evidence gap instead of confident unsourced prose.
|
|
329
|
+
* Pure; insertion-only.
|
|
330
|
+
*/
|
|
331
|
+
export function annotateEvidenceStarvedSections(
|
|
332
|
+
text: string,
|
|
333
|
+
starvedSections: string[]
|
|
334
|
+
): { text: string; annotated: string[] } {
|
|
335
|
+
if (!text || starvedSections.length === 0) return { text, annotated: [] };
|
|
336
|
+
const annotated: string[] = [];
|
|
337
|
+
let out = text;
|
|
338
|
+
for (const section of starvedSections) {
|
|
339
|
+
const esc = section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
340
|
+
const rx = new RegExp(`(##\\s*(?:§\\d+\\s*)?${esc}[^\\n]*\\n)`, "i");
|
|
341
|
+
if (!rx.test(out)) continue;
|
|
342
|
+
if (new RegExp(`${esc}[^\\n]*\\n+\\[EVIDENCE_STARVED`, "i").test(out)) continue; // idempotent
|
|
343
|
+
out = out.replace(rx, `$1\n[EVIDENCE_STARVED] Retrieval returned no URL-backed source for this section. Claims here are unsourced; supply evidence or downgrade to an explicit open item.\n`);
|
|
344
|
+
annotated.push(section);
|
|
345
|
+
}
|
|
346
|
+
return { text: out, annotated };
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* G6 (pure): deterministic rubric floor. NEVER a judge score — reported
|
|
351
|
+
* alongside it. Inputs are already-measured ratios so the function is
|
|
352
|
+
* trivially testable and has no I/O.
|
|
353
|
+
*/
|
|
354
|
+
export function computeDeterministicFloor(m: {
|
|
355
|
+
templateCoverage: number; // 0..1
|
|
356
|
+
citationTrustRatio: number; // 0..1
|
|
357
|
+
placeholderDensity: number; // placeholders / word
|
|
358
|
+
placeholderUrlRatio: number;// 0..1
|
|
359
|
+
truncated: boolean;
|
|
360
|
+
}): number {
|
|
361
|
+
const floor = Math.max(1, Math.min(9.5,
|
|
362
|
+
m.templateCoverage * 3.0 +
|
|
363
|
+
m.citationTrustRatio * 2.5 +
|
|
364
|
+
(1 - Math.min(1, m.placeholderDensity * 50)) * 1.5 +
|
|
365
|
+
(1 - m.placeholderUrlRatio) * 1.5 +
|
|
366
|
+
(m.truncated ? 0 : 1.0)
|
|
367
|
+
));
|
|
368
|
+
return Number(floor.toFixed(2));
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ── G5 wrapper: apply the pure stub inserter to a live outcome ─────────────
|
|
372
|
+
function applyMissingSectionStubs(outcome: any, runId: string | null): void {
|
|
373
|
+
const draft: string = outcome?.fixed || outcome?.draft || "";
|
|
374
|
+
const settings = outcome?.runSettings ?? {};
|
|
375
|
+
const { text, inserted } = insertMissingSectionStubs(
|
|
376
|
+
draft, settings.templateId, settings.styleOverride, settings.williamsPersona
|
|
377
|
+
);
|
|
378
|
+
if (inserted.length === 0) return;
|
|
379
|
+
outcome.fixed = text;
|
|
380
|
+
outcome.insertedSectionStubs = inserted;
|
|
381
|
+
if (runId) {
|
|
382
|
+
pushEvent(runId, "system", "covea",
|
|
383
|
+
`G5: inserted ${inserted.length} missing-section stub(s): ${inserted.join(", ")}`
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// ── G6 wrapper: measure the live outcome, then call the pure floor fn ──────
|
|
389
|
+
function applyDeterministicFloor(outcome: any, runId: string | null): void {
|
|
390
|
+
if (outcome?.judgeScore != null) return; // judge succeeded — do not override
|
|
391
|
+
const excluded = outcome?.judgeExcluded;
|
|
392
|
+
if (!Array.isArray(excluded) || excluded.length === 0) return;
|
|
393
|
+
|
|
394
|
+
const draft: string = outcome?.fixed || outcome?.draft || "";
|
|
395
|
+
if (!draft) return;
|
|
396
|
+
|
|
397
|
+
// Template coverage
|
|
398
|
+
const settings = outcome?.runSettings ?? {};
|
|
399
|
+
const rubric = loadTemplateRubric(settings.templateId, settings.styleOverride, settings.williamsPersona);
|
|
400
|
+
let templateCov = 1;
|
|
401
|
+
if (rubric && rubric.sections.length > 0) {
|
|
402
|
+
const present = rubric.sections.filter((s) =>
|
|
403
|
+
new RegExp(`##\\s*(?:§\\d+\\s*)?${s.title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i").test(draft)
|
|
404
|
+
).length;
|
|
405
|
+
templateCov = present / rubric.sections.length;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Citation trust ratio
|
|
409
|
+
const audit = outcome?.citationAudit;
|
|
410
|
+
let trustRatio = 1;
|
|
411
|
+
if (audit?.totalCitations > 0) {
|
|
412
|
+
trustRatio = (audit.trustedCount ?? 0) / audit.totalCitations;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Placeholder density
|
|
416
|
+
const placeholders = (draft.match(/\[(DATA GAP|ASSUMPTION|TBD|PROPOSED)\]/gi) ?? []).length;
|
|
417
|
+
const words = Math.max(1, draft.split(/\s+/).length);
|
|
418
|
+
const placeholderDensity = placeholders / words;
|
|
419
|
+
|
|
420
|
+
// Placeholder URL ratio
|
|
421
|
+
const entries = audit?.entries as Array<{ url?: string }> | undefined;
|
|
422
|
+
let placeholderUrlRatio = 0;
|
|
423
|
+
if (Array.isArray(entries) && entries.length > 0) {
|
|
424
|
+
placeholderUrlRatio = entries.filter((e) => isPlaceholderUrl(e.url)).length / entries.length;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Truncation
|
|
428
|
+
const truncated = endsOnDanglingConnector(draft);
|
|
429
|
+
|
|
430
|
+
// Delegate the arithmetic to the pure, self-tested core.
|
|
431
|
+
const floor = computeDeterministicFloor({
|
|
432
|
+
templateCoverage: templateCov,
|
|
433
|
+
citationTrustRatio: trustRatio,
|
|
434
|
+
placeholderDensity,
|
|
435
|
+
placeholderUrlRatio,
|
|
436
|
+
truncated,
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// NEVER write into judgeScore — it must stay null per contract.
|
|
440
|
+
outcome.deterministicFloor = floor;
|
|
441
|
+
if (runId) {
|
|
442
|
+
pushEvent(runId, "system", "judge",
|
|
443
|
+
`G6: deterministicFloor=${floor.toFixed(2)} (templateCov=${(templateCov * 100).toFixed(0)}% trustRatio=${(trustRatio * 100).toFixed(0)}% placeholders=${placeholders} placeholderUrls=${(placeholderUrlRatio * 100).toFixed(0)}% truncated=${truncated}). judgeScore remains null — all ${excluded.length} judge(s) excluded.`
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// ── G4: post-completion COVEA repair (targeted, non-destructive) ───────────
|
|
449
|
+
async function maybeRunCoveaRepair(
|
|
450
|
+
runId: string,
|
|
451
|
+
apiKey: string,
|
|
452
|
+
question: string,
|
|
453
|
+
outcome: any
|
|
454
|
+
): Promise<void> {
|
|
455
|
+
try {
|
|
456
|
+
const cove = outcome?.coveReport;
|
|
457
|
+
// adversarialPreview is inspected via outcome.issues below; kept off the top-level to avoid dead vars.
|
|
458
|
+
const draft: string = outcome?.fixed || outcome?.draft || "";
|
|
459
|
+
if (!draft) return;
|
|
460
|
+
|
|
461
|
+
const coveFailures =
|
|
462
|
+
Array.isArray(cove?.questions)
|
|
463
|
+
? cove.questions.filter((q: any) => !q.consistent).map((q: any) => ({
|
|
464
|
+
question: String(q.question ?? ""),
|
|
465
|
+
expectedAnswer: String(q.expectedAnswer ?? ""),
|
|
466
|
+
verifiedAnswer: String(q.verifiedAnswer ?? ""),
|
|
467
|
+
}))
|
|
468
|
+
: [];
|
|
469
|
+
|
|
470
|
+
// Adversarial defects: prefer structured issues, fall back to preview categories.
|
|
471
|
+
const issues = Array.isArray(outcome?.issues) ? outcome.issues : [];
|
|
472
|
+
const advDefects = issues
|
|
473
|
+
.filter((i: any) => /adv|adversarial|red_team|red-team/i.test(String(i?.code ?? "")) || String(i?.severity ?? "") === "critical")
|
|
474
|
+
.map((i: any) => ({
|
|
475
|
+
code: String(i?.code ?? "ADV"),
|
|
476
|
+
severity: String(i?.severity ?? "critical"),
|
|
477
|
+
message: String(i?.message ?? i?.remediation ?? ""),
|
|
478
|
+
}));
|
|
479
|
+
|
|
480
|
+
const audit = outcome?.citationAudit;
|
|
481
|
+
const hasCitationWork = Array.isArray(audit?.entries) && audit.entries.some((e: any) => !/^https?:\/\//i.test(String(e?.url ?? "")))
|
|
482
|
+
|| Array.isArray(audit?.auditResults) && audit.auditResults.some((r: any) => r?.trusted === false || r?.found === false);
|
|
483
|
+
const hasPlaceholderWork = /\[(DATA GAP|ASSUMPTION|TBD|PROPOSED)\]/i.test(draft);
|
|
484
|
+
|
|
485
|
+
// If neither source has any failure to repair, skip cleanly. Citation and
|
|
486
|
+
// placeholder containment are deterministic and do not require an API key.
|
|
487
|
+
if (coveFailures.length === 0 && advDefects.length === 0 && !hasCitationWork && !hasPlaceholderWork) {
|
|
488
|
+
pushEvent(runId, "system", "covea", "COVEA skipped — no CoVe/adversarial/citation/placeholder failures reported by pipeline");
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Extract innovation context and research evidence from the outcome
|
|
493
|
+
// so COVEA repairs stay in-voice and can cite real prewriting sources.
|
|
494
|
+
const innovationCtx = (outcome?.unifiedInnovation as any)?.directive as string | undefined;
|
|
495
|
+
const researchEv = (outcome?.prewritingResearch as any)?.evidenceBlock as string | undefined;
|
|
496
|
+
pushEvent(runId, "system", "covea", `COVEA start — ${coveFailures.length} CoVe + ${advDefects.length} adversarial target(s)${innovationCtx ? " · innovation context attached" : ""}${researchEv ? " · research evidence attached" : ""}`);
|
|
497
|
+
const result = await runCoveaRepair({
|
|
498
|
+
apiKey,
|
|
499
|
+
question,
|
|
500
|
+
draft,
|
|
501
|
+
coveFailures,
|
|
502
|
+
advDefects,
|
|
503
|
+
citationAudit: audit,
|
|
504
|
+
innovationContext: innovationCtx,
|
|
505
|
+
researchEvidence: researchEv,
|
|
506
|
+
onProgress: (m) => pushEvent(runId, "progress", "covea", m),
|
|
507
|
+
});
|
|
508
|
+
attachCovea(runId, draft, result);
|
|
509
|
+
pushEvent(
|
|
510
|
+
runId,
|
|
511
|
+
"system",
|
|
512
|
+
"covea",
|
|
513
|
+
`COVEA done — accepted=${result.acceptedCount} rejected=${result.rejectedCount} skipped=${result.skippedCount} · ${result.charsChanged}ch (${(result.charsChangedPct * 100).toFixed(1)}%)`
|
|
514
|
+
);
|
|
515
|
+
} catch (e) {
|
|
516
|
+
pushEvent(runId, "system", "error", `COVEA repair failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// ── Public API — same signatures, additive behaviour ───────────────────────
|
|
521
|
+
type V15Args = Parameters<typeof packageRunV15>;
|
|
522
|
+
type V15Result = Awaited<ReturnType<typeof packageRunV15>>;
|
|
523
|
+
|
|
524
|
+
export async function runV15OnQuestion(...args: V15Args): Promise<V15Result> {
|
|
525
|
+
installScraperBridge();
|
|
526
|
+
const opts = args[0] as Record<string, any> | undefined;
|
|
527
|
+
const originalQuestion = opts?.question ? String(opts.question) : "";
|
|
528
|
+
|
|
529
|
+
let runId: string | null = null;
|
|
530
|
+
let unifiedPlan: UnifiedInnovationPlan | null = null;
|
|
531
|
+
let researchPhase: ResearchPhaseResult | null = null;
|
|
532
|
+
try {
|
|
533
|
+
runId = startRun("v15", originalQuestion, opts);
|
|
534
|
+
} catch {
|
|
535
|
+
runId = null;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (runId && opts) {
|
|
539
|
+
opts.onProgress = teeProgress(runId, opts.onProgress);
|
|
540
|
+
try {
|
|
541
|
+
const profile = opts.profile ?? {};
|
|
542
|
+
pushEvent(
|
|
543
|
+
runId,
|
|
544
|
+
"system",
|
|
545
|
+
"init",
|
|
546
|
+
`profile: webSearch=${!!profile.webSearch} · template=${profile.templateId ?? "none"} · style=${profile.styleOverride ?? "none"} · williams=${profile.williamsPersona ?? "none"} · maxDepth=${opts.maxDepth ?? "default"} · advancedGates=${!!opts.advancedGates} · runJudge=${opts.runJudge !== false}`
|
|
547
|
+
);
|
|
548
|
+
} catch {
|
|
549
|
+
/* fail-open */
|
|
550
|
+
}
|
|
551
|
+
// G3 must run before prompt mutation.
|
|
552
|
+
mutateProfileForNumericQuestion(opts, runId);
|
|
553
|
+
unifiedPlan = buildUnifiedInnovationPlan(originalQuestion, {
|
|
554
|
+
personaSeed: Number(opts.personaSeed ?? opts.profile?.personaSeed ?? undefined) || undefined,
|
|
555
|
+
risk: opts.profile?.risk ?? "medium",
|
|
556
|
+
});
|
|
557
|
+
researchPhase = await preparePrewritingResearch(opts, runId, originalQuestion, unifiedPlan);
|
|
558
|
+
// G7: Intent Facet Lattice — decompose the (untruncated) prompt into
|
|
559
|
+
// per-section high-signal keyword queries so the package's relative-path
|
|
560
|
+
// grounding stops dispatching the raw prompt (the observed cause of
|
|
561
|
+
// off-topic "CHAGEE tea" / "Moldovan youth" results). Deterministic floor
|
|
562
|
+
// first; optional LLM enrichment adds facets but never removes the floor
|
|
563
|
+
// and fails safe on 429/503.
|
|
564
|
+
await injectIntentLattice(opts, runId, originalQuestion);
|
|
565
|
+
// G2 injects one base genome + v2 expansion + immutable research dossier.
|
|
566
|
+
injectGenomeAndResearch(opts, runId, originalQuestion, unifiedPlan, researchPhase);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
try {
|
|
570
|
+
const outcome = await packageRunV15(...args);
|
|
571
|
+
// Restore the caller-facing question — the shim already restores its own
|
|
572
|
+
// v10 injection; we restore ours here so downstream consumers see the
|
|
573
|
+
// original user text, not our prepended directives.
|
|
574
|
+
if (originalQuestion && outcome && typeof outcome === "object") {
|
|
575
|
+
(outcome as any).question = originalQuestion;
|
|
576
|
+
(outcome as any).unifiedInnovation = unifiedPlan;
|
|
577
|
+
(outcome as any).prewritingResearch = researchPhase;
|
|
578
|
+
}
|
|
579
|
+
// Finish the standard-pipeline capture BEFORE running COVEA, so the run
|
|
580
|
+
// record already has the pre-COVEA outcome for diffing.
|
|
581
|
+
if (runId) {
|
|
582
|
+
try {
|
|
583
|
+
finishRun(runId, outcome);
|
|
584
|
+
} catch {
|
|
585
|
+
/* fail-open */
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
// G5: missing-section stub insertion (deterministic, no model).
|
|
589
|
+
try {
|
|
590
|
+
applyMissingSectionStubs(outcome, runId);
|
|
591
|
+
} catch {
|
|
592
|
+
/* fail-open */
|
|
593
|
+
}
|
|
594
|
+
// G6: deterministic floor when judge is unavailable.
|
|
595
|
+
try {
|
|
596
|
+
applyDeterministicFloor(outcome, runId);
|
|
597
|
+
} catch {
|
|
598
|
+
/* fail-open */
|
|
599
|
+
}
|
|
600
|
+
// G4: post-completion targeted repair (runs last because it reads fixed text).
|
|
601
|
+
if (runId && opts) {
|
|
602
|
+
await maybeRunCoveaRepair(runId, String(opts.apiKey ?? ""), originalQuestion, outcome);
|
|
603
|
+
}
|
|
604
|
+
if (runId) clearRetrievalContext(runId);
|
|
605
|
+
return outcome;
|
|
606
|
+
} catch (err) {
|
|
607
|
+
if (runId) clearRetrievalContext(runId);
|
|
608
|
+
if (runId) {
|
|
609
|
+
try {
|
|
610
|
+
finishRun(runId, undefined, err);
|
|
611
|
+
} catch {
|
|
612
|
+
/* fail-open */
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
throw err;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
type BaseArgs = Parameters<typeof packageRunBaseline>;
|
|
620
|
+
type BaseResult = Awaited<ReturnType<typeof packageRunBaseline>>;
|
|
621
|
+
|
|
622
|
+
export async function runBaselineOnQuestion(...args: BaseArgs): Promise<BaseResult> {
|
|
623
|
+
installScraperBridge();
|
|
624
|
+
const opts = args[0] as Record<string, any> | undefined;
|
|
625
|
+
const question = opts?.question ? String(opts.question) : "";
|
|
626
|
+
|
|
627
|
+
let runId: string | null = null;
|
|
628
|
+
let unifiedPlan: UnifiedInnovationPlan | null = null;
|
|
629
|
+
let researchPhase: ResearchPhaseResult | null = null;
|
|
630
|
+
try {
|
|
631
|
+
runId = startRun("baseline", question, opts);
|
|
632
|
+
} catch {
|
|
633
|
+
runId = null;
|
|
634
|
+
}
|
|
635
|
+
if (runId && opts) {
|
|
636
|
+
opts.onProgress = teeProgress(runId, opts.onProgress);
|
|
637
|
+
unifiedPlan = buildUnifiedInnovationPlan(question, {
|
|
638
|
+
personaSeed: Number(opts.personaSeed ?? opts.profile?.personaSeed ?? undefined) || undefined,
|
|
639
|
+
risk: opts.profile?.risk ?? "medium",
|
|
640
|
+
});
|
|
641
|
+
researchPhase = await preparePrewritingResearch(opts, runId, question, unifiedPlan);
|
|
642
|
+
injectGenomeAndResearch(opts, runId, question, unifiedPlan, researchPhase);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
try {
|
|
646
|
+
const outcome = await packageRunBaseline(...args);
|
|
647
|
+
if (outcome && typeof outcome === "object") {
|
|
648
|
+
(outcome as any).question = question;
|
|
649
|
+
(outcome as any).unifiedInnovation = unifiedPlan;
|
|
650
|
+
(outcome as any).prewritingResearch = researchPhase;
|
|
651
|
+
}
|
|
652
|
+
if (runId) {
|
|
653
|
+
try {
|
|
654
|
+
finishRun(runId, outcome);
|
|
655
|
+
} catch {
|
|
656
|
+
/* fail-open */
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
return outcome;
|
|
660
|
+
} catch (err) {
|
|
661
|
+
if (runId) {
|
|
662
|
+
try {
|
|
663
|
+
finishRun(runId, undefined, err);
|
|
664
|
+
} catch {
|
|
665
|
+
/* fail-open */
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
throw err;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
// [unify.mjs] Explicit value re-exports for Rollup resolution
|
|
674
|
+
export { judgePanelEnhanced, runComparativeJudge } from "./v15-pipeline.orig";
|