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,1149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pipeline-diagnosis.ts — NET-NEW (Type C). See flatten-guide.md.
|
|
3
|
+
* ===========================================================================
|
|
4
|
+
* REFRAMED PROMPT-FORGE: from "improve the prompt" → "improve the PIPELINE".
|
|
5
|
+
*
|
|
6
|
+
* User's turn-3 clarification: "My original goal is to review any LOGIC
|
|
7
|
+
* PIPELINE ARCHITECTURAL CHANGES that are needed for a prompt output to
|
|
8
|
+
* improve, not to improve the prompt itself to make it better."
|
|
9
|
+
*
|
|
10
|
+
* This module maps observable defects in the final output to the SPECIFIC
|
|
11
|
+
* pipeline step that produced them, and for each step emits two independent
|
|
12
|
+
* repair routes:
|
|
13
|
+
*
|
|
14
|
+
* (A) DETERMINISTIC — a configuration flag, gate insertion, module toggle,
|
|
15
|
+
* or code path swap that requires NO prompt edit. Preferred when
|
|
16
|
+
* available because it is auditable, reversible, and non-flaky.
|
|
17
|
+
* (B) LLM — a prompt-level tweak scoped to a single pipeline step. Used
|
|
18
|
+
* only when (A) does not exist or is insufficient.
|
|
19
|
+
*
|
|
20
|
+
* Each route also has a BACKUP so at least one route is always executable
|
|
21
|
+
* even when the primary route's dependency (network, API key, template,
|
|
22
|
+
* model tier) is unavailable.
|
|
23
|
+
*
|
|
24
|
+
* Diagnoses are keyed by:
|
|
25
|
+
* · defect type (structural / factual / stylistic / evidential)
|
|
26
|
+
* · pipeline step (best-of-N / draft / HDIG / CoVe / adversarial / etc.)
|
|
27
|
+
* · template id (per-template override)
|
|
28
|
+
* · style override
|
|
29
|
+
* · section id (per-section override)
|
|
30
|
+
* ===========================================================================
|
|
31
|
+
*/
|
|
32
|
+
import { splitSentences } from "@/lib/debug/step-attribution";
|
|
33
|
+
import type { RunRecord } from "@/lib/debug/pipeline-trace-bus";
|
|
34
|
+
import { loadTemplateRubric, type TemplateRubric } from "@/lib/debug/template-rubric";
|
|
35
|
+
import { buildForensics, type ForensicsReport } from "@/lib/debug/scraper-forensics";
|
|
36
|
+
import { sitesFor, repairFileSummary, exportRepairOrder, type RepairSite } from "@/lib/debug/repair-sites";
|
|
37
|
+
|
|
38
|
+
// ── Defect taxonomy ────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
export type DefectKind =
|
|
41
|
+
| "truncation" // sentence ends mid-clause / connector word
|
|
42
|
+
| "unresolved-placeholder" // [DATA GAP], [ASSUMPTION], [TBD]
|
|
43
|
+
| "orphan-citation" // [S#] with no References section entry
|
|
44
|
+
| "untrusted-citation" // citation whose snippet has <20% overlap with claim
|
|
45
|
+
| "missing-references" // References section absent
|
|
46
|
+
| "cove-inconsistent" // CoVe verified as inconsistent → NOT REPAIRED
|
|
47
|
+
| "adversarial-blocking" // adversarial verdict revise, defects unfixed
|
|
48
|
+
| "missing-section" // template section absent from output
|
|
49
|
+
| "no-numerics" // section that should quantify has no numbers with units
|
|
50
|
+
| "no-actions" // recommendation section without verbs/owners/thresholds
|
|
51
|
+
| "style-violation" // persona-directive breach
|
|
52
|
+
| "compute-missing" // numeric question but no compute records
|
|
53
|
+
| "hedge-explosion" // >5 hedges per 100w
|
|
54
|
+
| "genome-ignored" // genome directive present but no discovery framing in output
|
|
55
|
+
// ── turn-5 additions: retrieval-plane + evaluation-plane detectors ──────
|
|
56
|
+
| "placeholder-citation-url" // ledger url is `source-N` / `*-attested`, cannot resolve
|
|
57
|
+
| "lane-zero-yield" // lane packed atoms but zero real documents (D14)
|
|
58
|
+
| "lane-quarantined" // lane delegated away with no acceptable result (D14B)
|
|
59
|
+
| "weak-content-gate" // source admitted on length alone, no relevance floor
|
|
60
|
+
| "depth-repair-abandoned" // N-Deep broke on first rejection, budget unspent
|
|
61
|
+
| "judge-unavailable" // all judges excluded → no independent signal
|
|
62
|
+
| "template-coverage-gap" // < 100% of template sections present
|
|
63
|
+
;
|
|
64
|
+
|
|
65
|
+
export type PipelineStep =
|
|
66
|
+
| "profile-selection"
|
|
67
|
+
| "genome-injection"
|
|
68
|
+
| "template-directive"
|
|
69
|
+
| "grounding" // template-directed + single-query
|
|
70
|
+
| "best-of-n-outlines"
|
|
71
|
+
| "best-of-n-expansion" // = draft
|
|
72
|
+
| "hdig" // hypothesis-driven iterative grounding
|
|
73
|
+
| "cove"
|
|
74
|
+
| "cove-repair" // the missing step this project adds
|
|
75
|
+
| "adversarial-preflight"
|
|
76
|
+
| "depth-repair" // N-Deep localised patch loop
|
|
77
|
+
| "adversarial-red-team"
|
|
78
|
+
| "adversarial-repair"
|
|
79
|
+
| "polish"
|
|
80
|
+
| "citation-audit"
|
|
81
|
+
| "citation-entailment"
|
|
82
|
+
| "judge-panel"
|
|
83
|
+
;
|
|
84
|
+
|
|
85
|
+
export interface Route {
|
|
86
|
+
kind: "deterministic" | "llm";
|
|
87
|
+
action: string;
|
|
88
|
+
/** How to apply, in concrete terms — one sentence. */
|
|
89
|
+
how: string;
|
|
90
|
+
/** What must exist for this route to work. */
|
|
91
|
+
requires: string[];
|
|
92
|
+
/** If requires is unmet, what to fall back to. */
|
|
93
|
+
backup: string;
|
|
94
|
+
/** Whether this can be applied without editing the package. */
|
|
95
|
+
applicableInSidecar: boolean;
|
|
96
|
+
/** Which config flag / code seam controls it. */
|
|
97
|
+
hook?: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface PerScopeAdvice {
|
|
101
|
+
scope: string; // "global" | template id | style code | section id
|
|
102
|
+
routes: Route[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface StepDiagnosis {
|
|
106
|
+
defect: DefectKind;
|
|
107
|
+
step: PipelineStep;
|
|
108
|
+
/** Why THIS step is responsible for this defect, tied to observed evidence. */
|
|
109
|
+
attribution: string;
|
|
110
|
+
/** Concrete evidence from the run (sentence excerpts, log lines, counts). */
|
|
111
|
+
evidence: string[];
|
|
112
|
+
/** Cross-scope routes: global, per-template, per-style, per-section. */
|
|
113
|
+
advice: PerScopeAdvice[];
|
|
114
|
+
/**
|
|
115
|
+
* turn-5: exact code coordinates (file, line, symbol, anchor, current code)
|
|
116
|
+
* for this defect. Empty when no verified coordinate exists — never guessed.
|
|
117
|
+
*/
|
|
118
|
+
repairSites: RepairSite[];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface DiagnosisReport {
|
|
122
|
+
runId: string;
|
|
123
|
+
finalScore: number | null;
|
|
124
|
+
targetScore: number;
|
|
125
|
+
templateId: string;
|
|
126
|
+
styleOverride: string | null;
|
|
127
|
+
williamsPersona: string | null;
|
|
128
|
+
totalDefects: number;
|
|
129
|
+
diagnoses: StepDiagnosis[];
|
|
130
|
+
/** Ordered playbook — apply top routes first, in this exact order. */
|
|
131
|
+
playbook: Array<{ rank: number; defect: DefectKind; step: PipelineStep; route: Route; scope: string; expectedLift: number }>;
|
|
132
|
+
/** What this run could still not diagnose — kept honest, never fabricated. */
|
|
133
|
+
unresolvedIssues: string[];
|
|
134
|
+
/** turn-5: every verified code coordinate implicated, deduped. */
|
|
135
|
+
allRepairSites: RepairSite[];
|
|
136
|
+
/** turn-5: distinct files to touch, with reachability + edit count. */
|
|
137
|
+
repairFiles: Array<{ file: string; reach: string; count: number }>;
|
|
138
|
+
/** turn-5: how many sites are fixable today in src/ vs need materialize.mjs. */
|
|
139
|
+
reachabilitySplit: { sidecarToday: number; postPass: number; needsMaterialize: number };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ── Deterministic defect detectors — pure text/state, no network ───────────
|
|
143
|
+
|
|
144
|
+
function detectDefects(run: RunRecord, rubric: TemplateRubric | null): Array<{ kind: DefectKind; evidence: string[] }> {
|
|
145
|
+
const out: Array<{ kind: DefectKind; evidence: string[] }> = [];
|
|
146
|
+
const finalText = run.finalText ?? "";
|
|
147
|
+
const output = (run.output ?? {}) as Record<string, any>;
|
|
148
|
+
|
|
149
|
+
// Truncation
|
|
150
|
+
const sents = splitSentences(finalText);
|
|
151
|
+
const truncEndings = sents.filter((s) => /[a-z]\s+(and|but|or|which|that|because|however|so|thereby|although|by)\s*[.!]?\s*$/i.test(s));
|
|
152
|
+
if (truncEndings.length > 0) {
|
|
153
|
+
out.push({ kind: "truncation", evidence: truncEndings.slice(0, 3).map((s) => `"${s.slice(-80)}"`) });
|
|
154
|
+
}
|
|
155
|
+
// Placeholders
|
|
156
|
+
const gaps = (finalText.match(/\[(DATA GAP|ASSUMPTION|TBD|PROPOSED)\]/gi) ?? []);
|
|
157
|
+
if (gaps.length > 0) {
|
|
158
|
+
out.push({ kind: "unresolved-placeholder", evidence: [`${gaps.length} placeholder(s): ${[...new Set(gaps)].join(", ")}`] });
|
|
159
|
+
}
|
|
160
|
+
// Orphan / untrusted citations from citationAudit
|
|
161
|
+
const audit = output.citationAudit;
|
|
162
|
+
if (audit) {
|
|
163
|
+
const untrusted = (audit.auditResults ?? []).filter((r: any) => r.trusted === false);
|
|
164
|
+
if (untrusted.length > 0) {
|
|
165
|
+
out.push({
|
|
166
|
+
kind: "untrusted-citation",
|
|
167
|
+
evidence: [`${untrusted.length}/${audit.totalCitations} untrusted (overlap<0.2): ${untrusted.slice(0, 3).map((r: any) => `${r.tag}=${(r.snippetOverlap * 100).toFixed(0)}%`).join(", ")}`],
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if ((audit.missingCount ?? 0) > 0) {
|
|
171
|
+
out.push({ kind: "orphan-citation", evidence: [`${audit.missingCount} tag(s) reference missing source ids`] });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (!/##\s*references|source list|bibliography/i.test(finalText)) {
|
|
175
|
+
out.push({ kind: "missing-references", evidence: ["no References/Source-list section in the final text"] });
|
|
176
|
+
}
|
|
177
|
+
// CoVe inconsistencies that were NOT repaired
|
|
178
|
+
const cove = output.coveReport;
|
|
179
|
+
if (cove && (cove.inconsistencies ?? 0) > 0) {
|
|
180
|
+
const failures = (cove.questions ?? []).filter((q: any) => !q.consistent);
|
|
181
|
+
out.push({
|
|
182
|
+
kind: "cove-inconsistent",
|
|
183
|
+
evidence: [
|
|
184
|
+
`${cove.inconsistencies}/${cove.questions?.length ?? "?"} CoVe claim(s) failed — with no follow-up repair pass in the standard pipeline`,
|
|
185
|
+
...failures.slice(0, 2).map((q: any) => `"${String(q.question).slice(0, 90)}" → verified: "${String(q.verifiedAnswer).slice(0, 60)}"`),
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// Adversarial blocking defects with rejected repair
|
|
190
|
+
const advPreview = output.adversarialPreview;
|
|
191
|
+
if (advPreview && (advPreview.defectCount ?? 0) > 0 && advPreview.verdict !== "pass") {
|
|
192
|
+
out.push({
|
|
193
|
+
kind: "adversarial-blocking",
|
|
194
|
+
evidence: [
|
|
195
|
+
`verdict=${advPreview.verdict} · ${advPreview.defectCount} defect(s) · categories: ${(advPreview.categories ?? []).join(", ")}`,
|
|
196
|
+
"adversarial monotonic repair rejected in the log (\"shrank too much\") — no targeted fallback in-package",
|
|
197
|
+
],
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
// Missing sections
|
|
201
|
+
if (rubric) {
|
|
202
|
+
for (const sec of rubric.sections) {
|
|
203
|
+
const heading = new RegExp(`##\\s*${sec.title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i");
|
|
204
|
+
if (!heading.test(finalText)) {
|
|
205
|
+
out.push({ kind: "missing-section", evidence: [`template ${rubric.templateId} requires section "${sec.title}"; not found in output`] });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Numerics/actionability check on relevant sections
|
|
210
|
+
const nums = (finalText.match(/\b\d[\d,.]*\s?(%|USD|\$|billion|million|bps|x|years?|months?|Q[1-4])\b/gi) ?? []).length;
|
|
211
|
+
if (nums < 5 && /market|financ|estimat|npv|irr|share/i.test(run.question || "")) {
|
|
212
|
+
out.push({ kind: "no-numerics", evidence: [`only ${nums} quantified figure(s) with units in a numeric-heavy question`] });
|
|
213
|
+
}
|
|
214
|
+
const actions = (finalText.match(/\b(recommend|proceed|approve|reject|hire|deploy|pause|escalate|deadline|owner:|by Q[1-4])\b/gi) ?? []).length;
|
|
215
|
+
if (actions < 2 && /(recommend|should|action|next step)/i.test(run.question || "")) {
|
|
216
|
+
out.push({ kind: "no-actions", evidence: [`only ${actions} action verb(s) in a recommendation-oriented question`] });
|
|
217
|
+
}
|
|
218
|
+
// Compute
|
|
219
|
+
const isNumeric = /\b(calculate|estimate|npv|irr|percent|ratio|market size)\b/i.test(run.question || "");
|
|
220
|
+
const computes = ((output.passHistory ?? [])[0]?.computeRecords ?? []).length ?? 0;
|
|
221
|
+
if (isNumeric && computes === 0 && (output.issues ?? []).some((i: any) => i?.code === "MISSING_COMPUTE_RECORDS")) {
|
|
222
|
+
out.push({ kind: "compute-missing", evidence: ["numeric prompt detected · no deterministic compute records"] });
|
|
223
|
+
}
|
|
224
|
+
// Hedge explosion
|
|
225
|
+
const hedges = (finalText.match(/\b(might|may|could|perhaps|possibly|generally|typically|often|arguably)\b/gi) ?? []).length;
|
|
226
|
+
const words = Math.max(1, finalText.split(/\s+/).length);
|
|
227
|
+
if ((hedges / words) * 100 > 2.5) {
|
|
228
|
+
out.push({ kind: "hedge-explosion", evidence: [`${hedges} hedge word(s) in ${words} words (${((hedges / words) * 100).toFixed(2)}/100w)`] });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ── turn-5: RETRIEVAL-PLANE detectors, driven by real lane forensics ─────
|
|
232
|
+
// These fire on parsed emitter output, never on inference. If the run
|
|
233
|
+
// produced no grounding telemetry the detectors stay silent rather than
|
|
234
|
+
// guessing that retrieval was fine.
|
|
235
|
+
let forensics: ForensicsReport | null = null;
|
|
236
|
+
try {
|
|
237
|
+
forensics = buildForensics(run);
|
|
238
|
+
} catch {
|
|
239
|
+
forensics = null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (forensics) {
|
|
243
|
+
// D-URL: ledger urls that can never resolve (root cause v15-grounding:113/:131)
|
|
244
|
+
if (forensics.allPlaceholderUrls.length > 0) {
|
|
245
|
+
out.push({
|
|
246
|
+
kind: "placeholder-citation-url",
|
|
247
|
+
evidence: [
|
|
248
|
+
`${forensics.allPlaceholderUrls.length} non-resolvable citation URL(s): ${forensics.allPlaceholderUrls.slice(0, 6).join(", ")}`,
|
|
249
|
+
`${forensics.totals.realUrlCount} of ${forensics.totals.ledgerEntries} ledger entries carry an absolute http(s) URL.`,
|
|
250
|
+
"Generated verbatim by `source-${sourceIndex+1}` at v15-grounding.orig.ts:113 (vanguard) and :131 (palisade).",
|
|
251
|
+
],
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// D14: atoms packed, zero real documents
|
|
255
|
+
if (forensics.zeroYieldLanes.length > 0) {
|
|
256
|
+
out.push({
|
|
257
|
+
kind: "lane-zero-yield",
|
|
258
|
+
evidence: forensics.zeroYieldLanes
|
|
259
|
+
.slice(0, 6)
|
|
260
|
+
.map((l) => `${l.lane}[${l.section ?? "-"}]: ${l.atomsPacked} atoms / ${l.sourcesPacked} sources / util=${l.utilizationPct ?? "?"}%`),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
// D14B: delegation chain exhausted
|
|
264
|
+
if (forensics.quarantinedLanes.length > 0) {
|
|
265
|
+
out.push({
|
|
266
|
+
kind: "lane-quarantined",
|
|
267
|
+
evidence: [
|
|
268
|
+
`${forensics.quarantinedLanes.length} lane(s) reported no acceptable result: ${[...new Set(forensics.quarantinedLanes.map((l) => l.lane))].join(", ")}`,
|
|
269
|
+
],
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
// Weak content gate: symptom is an admitted source with no lexical tie to the question.
|
|
273
|
+
const qTokens = new Set(
|
|
274
|
+
(run.question || "").toLowerCase().match(/[a-z]{4,}/g) ?? []
|
|
275
|
+
);
|
|
276
|
+
if (qTokens.size >= 3) {
|
|
277
|
+
const irrelevant = (forensics.lanes.flatMap((l) => l.citations) as Array<{ title?: string; snippet?: string; url?: string }>)
|
|
278
|
+
.filter((c) => {
|
|
279
|
+
const hay = `${c.title ?? ""} ${c.snippet ?? ""}`.toLowerCase();
|
|
280
|
+
if (hay.trim().length < 20) return false;
|
|
281
|
+
const hits = [...qTokens].filter((t) => hay.includes(t)).length;
|
|
282
|
+
return hits === 0;
|
|
283
|
+
});
|
|
284
|
+
if (irrelevant.length > 0) {
|
|
285
|
+
out.push({
|
|
286
|
+
kind: "weak-content-gate",
|
|
287
|
+
evidence: [
|
|
288
|
+
`${irrelevant.length} admitted source(s) share ZERO content words with the question.`,
|
|
289
|
+
...irrelevant.slice(0, 3).map((c) => `"${String(c.title ?? "(untitled)").slice(0, 80)}"`),
|
|
290
|
+
"Admission filter at v15-grounding.orig.ts:221 is `content.length>=80` with no relevance floor.",
|
|
291
|
+
],
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// ── turn-5: EXECUTION-PLANE detectors ────────────────────────────────────
|
|
298
|
+
const settings = ((run.output ?? {}) as any).runSettings ?? ((run.input ?? {}) as any) ?? {};
|
|
299
|
+
const requestedDepth = Number(settings.depth ?? settings.maxDepth ?? (run.input as any)?.maxDepth ?? 0);
|
|
300
|
+
const executedDepths = new Set(
|
|
301
|
+
run.events.filter((e) => e.phase === "repair").map((e) => /^depth (\d+)/.exec(e.message)?.[1]).filter(Boolean)
|
|
302
|
+
).size;
|
|
303
|
+
if (requestedDepth > 1 && executedDepths > 0 && executedDepths < requestedDepth) {
|
|
304
|
+
out.push({
|
|
305
|
+
kind: "depth-repair-abandoned",
|
|
306
|
+
evidence: [
|
|
307
|
+
`maxDepth=${requestedDepth} requested but only ${executedDepths} depth(s) executed.`,
|
|
308
|
+
...run.events.filter((e) => /rejected localized patches/.test(e.message)).slice(0, 1).map((e) => e.message),
|
|
309
|
+
],
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Judge availability
|
|
314
|
+
const excluded = (output.judgeExcluded ?? []) as Array<{ model?: string; reason?: string }>;
|
|
315
|
+
if (output.judgeScore == null && excluded.length > 0) {
|
|
316
|
+
out.push({
|
|
317
|
+
kind: "judge-unavailable",
|
|
318
|
+
evidence: [
|
|
319
|
+
`All ${excluded.length} judge(s) excluded — no independent signal for this run.`,
|
|
320
|
+
...excluded.slice(0, 3).map((e) => `${e.model}: ${String(e.reason ?? "").slice(0, 90)}`),
|
|
321
|
+
"Pipeline correctly refused to fabricate a fallback score; deterministic guard is the only remaining gate.",
|
|
322
|
+
],
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Template coverage as a measured percentage
|
|
327
|
+
if (rubric && rubric.sections.length > 0) {
|
|
328
|
+
const present = rubric.sections.filter((s) =>
|
|
329
|
+
new RegExp(`##\\s*(?:§\\d+\\s*)?${s.title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i").test(finalText)
|
|
330
|
+
).length;
|
|
331
|
+
const pct = (present / rubric.sections.length) * 100;
|
|
332
|
+
if (pct < 100) {
|
|
333
|
+
out.push({
|
|
334
|
+
kind: "template-coverage-gap",
|
|
335
|
+
evidence: [
|
|
336
|
+
`${present}/${rubric.sections.length} template sections present (${pct.toFixed(0)}% coverage).`,
|
|
337
|
+
`Missing: ${rubric.sections.filter((s) => !new RegExp(`##\\s*(?:§\\d+\\s*)?${s.title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i").test(finalText)).map((s) => s.title).join(", ")}`,
|
|
338
|
+
],
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return out;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// ── Map defect → responsible step ──────────────────────────────────────────
|
|
347
|
+
|
|
348
|
+
const STEP_FOR_DEFECT: Record<DefectKind, PipelineStep> = {
|
|
349
|
+
truncation: "best-of-n-expansion",
|
|
350
|
+
"unresolved-placeholder": "best-of-n-expansion",
|
|
351
|
+
"orphan-citation": "citation-audit",
|
|
352
|
+
"untrusted-citation": "citation-entailment",
|
|
353
|
+
"missing-references": "polish",
|
|
354
|
+
"cove-inconsistent": "cove-repair",
|
|
355
|
+
"adversarial-blocking": "adversarial-repair",
|
|
356
|
+
"missing-section": "template-directive",
|
|
357
|
+
"no-numerics": "grounding",
|
|
358
|
+
"no-actions": "template-directive",
|
|
359
|
+
"style-violation": "best-of-n-expansion",
|
|
360
|
+
"compute-missing": "best-of-n-expansion",
|
|
361
|
+
"hedge-explosion": "best-of-n-expansion",
|
|
362
|
+
"genome-ignored": "genome-injection",
|
|
363
|
+
// turn-5 additions
|
|
364
|
+
"placeholder-citation-url": "grounding",
|
|
365
|
+
"lane-zero-yield": "grounding",
|
|
366
|
+
"lane-quarantined": "grounding",
|
|
367
|
+
"weak-content-gate": "hdig",
|
|
368
|
+
"depth-repair-abandoned": "depth-repair",
|
|
369
|
+
"judge-unavailable": "judge-panel",
|
|
370
|
+
"template-coverage-gap": "template-directive",
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
// ── Route library. Every route has BOTH kinds and BOTH backups. ────────────
|
|
374
|
+
//
|
|
375
|
+
// Each entry gives (deterministic, llm) routes. `applicableInSidecar` marks
|
|
376
|
+
// routes that can be implemented via the workspace overlay WITHOUT editing
|
|
377
|
+
// the package. `hook` names the file/flag that implements the change.
|
|
378
|
+
|
|
379
|
+
const ROUTES: Record<DefectKind, { deterministic: Route; llm: Route }> = {
|
|
380
|
+
truncation: {
|
|
381
|
+
deterministic: {
|
|
382
|
+
kind: "deterministic",
|
|
383
|
+
action: "Raise draft/expansion token budget and disable *-lite model routing for expansion.",
|
|
384
|
+
how: "In `runV15OnQuestion` opts, set `draftMaxToks ≥ 6144` and route expansion through the non-lite pool via `models.ts` intelligenceOf. The 503 in the log came from `gemini-2.5-flash-lite` — a documented low-availability tier.",
|
|
385
|
+
requires: ["v15-pipeline seam", "models.ts intelligence tier"],
|
|
386
|
+
backup: "If the higher tier is 429-limited, insert an outline-then-stitch pass so no single expansion call exceeds ~4k tokens.",
|
|
387
|
+
applicableInSidecar: true,
|
|
388
|
+
hook: "src/lib/v15-pipeline.ts (Type-B wrapper) + profile.draftMaxToks",
|
|
389
|
+
},
|
|
390
|
+
llm: {
|
|
391
|
+
kind: "llm",
|
|
392
|
+
action: "Append an explicit stop-condition to the expansion prompt.",
|
|
393
|
+
how: "Prepend: `Do NOT end on a connector word (and/but/or/which/that/because). If the token budget is close, close every open sentence before stopping.`",
|
|
394
|
+
requires: ["template-directive seam"],
|
|
395
|
+
backup: "Fall back to the deterministic truncation-gate that already exists in the adversarial preflight — but wired to trigger the COVEA repair, not just log.",
|
|
396
|
+
applicableInSidecar: true,
|
|
397
|
+
hook: "src/lib/v15-pipeline.ts pre-call directive injection",
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
"unresolved-placeholder": {
|
|
401
|
+
deterministic: {
|
|
402
|
+
kind: "deterministic",
|
|
403
|
+
action: "Emit a placeholder-scan gate that runs COVEA on any surviving [DATA GAP] / [ASSUMPTION].",
|
|
404
|
+
how: "Post-completion: scan the fixed draft, extract sentences containing placeholder markers, feed to `covea-repair.ts` as a synthetic defect list.",
|
|
405
|
+
requires: ["covea-repair.ts (this project)"],
|
|
406
|
+
backup: "Deterministic annotation only — tag the surviving placeholders with a machine-readable `[COVEA:PLACEHOLDER_UNRESOLVED]` suffix for reviewer triage.",
|
|
407
|
+
applicableInSidecar: true,
|
|
408
|
+
hook: "src/lib/v15-pipeline.ts post-completion hook",
|
|
409
|
+
},
|
|
410
|
+
llm: {
|
|
411
|
+
kind: "llm",
|
|
412
|
+
action: "Fire a targeted grounding query for each placeholder subject.",
|
|
413
|
+
how: "For each sentence containing a placeholder, extract the noun phrase and re-run template-directed grounding with that as a section query.",
|
|
414
|
+
requires: ["web grounding enabled", "template-directive hook"],
|
|
415
|
+
backup: "If grounding returns 0 sources, downgrade the sentence to an explicit `[UNVERIFIED]` claim rather than fabricating a value.",
|
|
416
|
+
applicableInSidecar: true,
|
|
417
|
+
hook: "src/lib/v15-pipeline.ts + HDIG re-entry",
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
"orphan-citation": {
|
|
421
|
+
deterministic: {
|
|
422
|
+
kind: "deterministic",
|
|
423
|
+
action: "Add a References-section synthesiser gate.",
|
|
424
|
+
how: "In the polish pass, if `citationAudit.entries.length > 0` and no References section exists, append one built from the ledger — with real URLs only.",
|
|
425
|
+
requires: ["polish seam", "citationAudit"],
|
|
426
|
+
backup: "If the polish pass rejects the addition on score-drop, prepend the reference list before Recommendation instead of after — polish rejects size shrinkage, not size growth.",
|
|
427
|
+
applicableInSidecar: true,
|
|
428
|
+
hook: "src/lib/v15-pipeline.ts post-completion, before finishRun",
|
|
429
|
+
},
|
|
430
|
+
llm: {
|
|
431
|
+
kind: "llm",
|
|
432
|
+
action: "Add References to the template's required sections list.",
|
|
433
|
+
how: "In the workspace copy of the template directive, declare References as MANDATORY, not optional.",
|
|
434
|
+
requires: ["template rubric seam"],
|
|
435
|
+
backup: "If the template is inherited from the package, apply the mandatory-references override in `template-rubric.ts` as a workspace annotation.",
|
|
436
|
+
applicableInSidecar: true,
|
|
437
|
+
hook: "src/lib/debug/template-rubric.ts tenPointContract",
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
"untrusted-citation": {
|
|
441
|
+
deterministic: {
|
|
442
|
+
kind: "deterministic",
|
|
443
|
+
action: "Raise the entailment-overlap threshold before a citation is marked trusted; force re-grounding on any failure.",
|
|
444
|
+
how: "Lower `trustedThreshold` in `citationLedger.verifyEntailment`; on fail, add the claim to HDIG's re-grounding queue rather than only logging.",
|
|
445
|
+
requires: ["citation-ledger-store seam"],
|
|
446
|
+
backup: "If the entailment model is unavailable (429), fall back to lexical trigram-Jaccard against the snippet with a threshold of 0.35.",
|
|
447
|
+
applicableInSidecar: true,
|
|
448
|
+
hook: "src/lib/citation-ledger-store.ts (Type-A now → promote to Type-B when needed)",
|
|
449
|
+
},
|
|
450
|
+
llm: {
|
|
451
|
+
kind: "llm",
|
|
452
|
+
action: "Instruct the draft step to quote a ≤20-word span from the source when citing.",
|
|
453
|
+
how: "Add to the template directive: `Every [S#] must be immediately preceded by a ≤20-word verbatim quote from the source snippet, in quotation marks.`",
|
|
454
|
+
requires: ["template-directive seam"],
|
|
455
|
+
backup: "If the source snippet is empty (as seen for `source-1` in log entries 5/6/9), drop the tag entirely rather than fabricate a quote.",
|
|
456
|
+
applicableInSidecar: true,
|
|
457
|
+
hook: "src/lib/v15-pipeline.ts template-directive injection",
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
"missing-references": {
|
|
461
|
+
deterministic: {
|
|
462
|
+
kind: "deterministic",
|
|
463
|
+
action: "Same as orphan-citation deterministic route — synthesise from ledger.",
|
|
464
|
+
how: "Post-completion append if absent.",
|
|
465
|
+
requires: ["citationAudit non-empty"],
|
|
466
|
+
backup: "Prepend before Recommendation.",
|
|
467
|
+
applicableInSidecar: true,
|
|
468
|
+
hook: "src/lib/v15-pipeline.ts",
|
|
469
|
+
},
|
|
470
|
+
llm: {
|
|
471
|
+
kind: "llm",
|
|
472
|
+
action: "Add References to template as mandatory section.",
|
|
473
|
+
how: "Extend `TemplateRubric.sections` with References for every template.",
|
|
474
|
+
requires: ["template-rubric.ts"],
|
|
475
|
+
backup: "Reader adds their own — but flag on export.",
|
|
476
|
+
applicableInSidecar: true,
|
|
477
|
+
hook: "src/lib/debug/template-rubric.ts",
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
"cove-inconsistent": {
|
|
481
|
+
deterministic: {
|
|
482
|
+
kind: "deterministic",
|
|
483
|
+
action: "Route CoVe failures into COVEA repair pass (this project's new step).",
|
|
484
|
+
how: "After the standard pipeline returns, extract `coveReport.questions.filter(!consistent)` and pass to `runCoveaRepair` for TARGETED sentence-level repair (never full rewrite).",
|
|
485
|
+
requires: ["covea-repair.ts", "gemini API key"],
|
|
486
|
+
backup: "If the LLM route fails on all models, apply deterministic `[COVEA:UNVERIFIED]` annotation so the reviewer sees the failure — never silently retain the original claim as-is.",
|
|
487
|
+
applicableInSidecar: true,
|
|
488
|
+
hook: "src/lib/v15-pipeline.ts post-completion (turn-4 change)",
|
|
489
|
+
},
|
|
490
|
+
llm: {
|
|
491
|
+
kind: "llm",
|
|
492
|
+
action: "Increase CoVe question count and enable independent-model answering.",
|
|
493
|
+
how: "CoVe currently caps at 4 claims (`opts.draft.slice(0,6000)` truncation). In our COVEA reimplementation we pass the FULL draft and lift the claim cap.",
|
|
494
|
+
requires: ["gemini API + rate budget"],
|
|
495
|
+
backup: "Fall back to lexical entailment check on cached ledger sources.",
|
|
496
|
+
applicableInSidecar: true,
|
|
497
|
+
hook: "src/lib/debug/covea-repair.ts (no draft truncation)",
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
"adversarial-blocking": {
|
|
501
|
+
deterministic: {
|
|
502
|
+
kind: "deterministic",
|
|
503
|
+
action: "Same COVEA repair pass — convert adversarial defects to sentence-anchored targets.",
|
|
504
|
+
how: "Extract each blocking defect message, locate the offending sentence(s) via lexical overlap, apply targeted rewrite with a hard shrink-cap of 40% (which is precisely the failure mode the package's monotonic repair hits when it rejects on size drop).",
|
|
505
|
+
requires: ["covea-repair.ts"],
|
|
506
|
+
backup: "Deterministic annotation `[COVEA:ADV_DEFECT:<code>]` if the LLM route is unavailable.",
|
|
507
|
+
applicableInSidecar: true,
|
|
508
|
+
hook: "src/lib/v15-pipeline.ts post-completion",
|
|
509
|
+
},
|
|
510
|
+
llm: {
|
|
511
|
+
kind: "llm",
|
|
512
|
+
action: "Feed defect list into the adversarial-preflight prompt as MANDATORY not INFORMATIONAL.",
|
|
513
|
+
how: "Rewrite the injected N-Deep constraint block from `may consider` to `must resolve or the answer is invalid`.",
|
|
514
|
+
requires: ["adversarial-engine seam"],
|
|
515
|
+
backup: "Backstop with the COVEA pass either way.",
|
|
516
|
+
applicableInSidecar: true,
|
|
517
|
+
hook: "src/lib/adversarial-engine.ts wrapper (currently Type A — promote when this route is enabled)",
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
"missing-section": {
|
|
521
|
+
deterministic: {
|
|
522
|
+
kind: "deterministic",
|
|
523
|
+
action: "Section-presence gate; on absence, insert a template-derived stub with `[MISSING SECTION — please supply]`.",
|
|
524
|
+
how: "Post-completion, walk `rubric.sections`; for each absent title, insert a stub heading with the section's `hint` as body.",
|
|
525
|
+
requires: ["template-rubric.ts"],
|
|
526
|
+
backup: "Log-only if inserting would trigger a truncation gate.",
|
|
527
|
+
applicableInSidecar: true,
|
|
528
|
+
hook: "src/lib/v15-pipeline.ts post-completion",
|
|
529
|
+
},
|
|
530
|
+
llm: {
|
|
531
|
+
kind: "llm",
|
|
532
|
+
action: "Pass the template's full section list verbatim in the draft directive (fixes the log's `2 claims packed, 0 sources packed, utilization=3.3%`).",
|
|
533
|
+
how: "Reinject the template directive at the START of the expansion prompt, not just the outline.",
|
|
534
|
+
requires: ["template-directive seam"],
|
|
535
|
+
backup: "Deterministic post-completion insertion route.",
|
|
536
|
+
applicableInSidecar: true,
|
|
537
|
+
hook: "src/lib/v15-pipeline.ts pre-call directive",
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
"no-numerics": {
|
|
541
|
+
deterministic: {
|
|
542
|
+
kind: "deterministic",
|
|
543
|
+
action: "Route the query through the compute sandbox for any number the draft would otherwise placeholder.",
|
|
544
|
+
how: "Enable `computeSandbox` in profile; on absence in package, add a deterministic pre-draft numeric extraction that emits [S#] tags backed by ledger entries with numeric snippets.",
|
|
545
|
+
requires: ["compute-sandbox seam (Type A now)"],
|
|
546
|
+
backup: "Fall back to a deterministic `[NUMERIC:UNKNOWN]` tag — never fabricate a figure.",
|
|
547
|
+
applicableInSidecar: true,
|
|
548
|
+
hook: "src/lib/v15-pipeline.ts pre-call profile mutation",
|
|
549
|
+
},
|
|
550
|
+
llm: {
|
|
551
|
+
kind: "llm",
|
|
552
|
+
action: "Add to template: `Any numeric claim without a unit and a source is a defect.`",
|
|
553
|
+
how: "Template-level anchor.",
|
|
554
|
+
requires: ["template-rubric.ts"],
|
|
555
|
+
backup: "Deterministic tag route.",
|
|
556
|
+
applicableInSidecar: true,
|
|
557
|
+
hook: "src/lib/debug/template-rubric.ts",
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
"no-actions": {
|
|
561
|
+
deterministic: {
|
|
562
|
+
kind: "deterministic",
|
|
563
|
+
action: "Post-completion action-block synthesiser using template Recommendation section as scaffold.",
|
|
564
|
+
how: "If the section exists but has < 2 action verbs, append a `Priority Actions` table (Action | Owner | Threshold | Verification) built from ledger evidence.",
|
|
565
|
+
requires: ["template-rubric.ts"],
|
|
566
|
+
backup: "Deterministic bullet-list scaffold with `[OWNER: TBD]` — visible defect, not silent.",
|
|
567
|
+
applicableInSidecar: true,
|
|
568
|
+
hook: "src/lib/v15-pipeline.ts post-completion",
|
|
569
|
+
},
|
|
570
|
+
llm: {
|
|
571
|
+
kind: "llm",
|
|
572
|
+
action: "Template-directive addition: `End Recommendation with a Priority Actions table.`",
|
|
573
|
+
how: "Directive tweak.",
|
|
574
|
+
requires: ["template-directive seam"],
|
|
575
|
+
backup: "Deterministic scaffold.",
|
|
576
|
+
applicableInSidecar: true,
|
|
577
|
+
hook: "src/lib/debug/template-rubric.ts",
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
"style-violation": {
|
|
581
|
+
deterministic: {
|
|
582
|
+
kind: "deterministic",
|
|
583
|
+
action: "Persona-directive lint gate.",
|
|
584
|
+
how: "Post-completion, scan for anti-patterns from `getPersonaDirective(personaName).avoid`; if any triggered, target them via COVEA.",
|
|
585
|
+
requires: ["williams-style.ts avoid list"],
|
|
586
|
+
backup: "Log only.",
|
|
587
|
+
applicableInSidecar: true,
|
|
588
|
+
hook: "src/lib/v15-pipeline.ts post-completion",
|
|
589
|
+
},
|
|
590
|
+
llm: {
|
|
591
|
+
kind: "llm",
|
|
592
|
+
action: "Prepend persona directive VERBATIM to the expansion prompt (including cadence rule).",
|
|
593
|
+
how: "Currently the persona is passed as a name only; inject the full DO/AVOID/CADENCE block.",
|
|
594
|
+
requires: ["williams-style.ts"],
|
|
595
|
+
backup: "Log only.",
|
|
596
|
+
applicableInSidecar: true,
|
|
597
|
+
hook: "src/lib/v15-pipeline.ts template-directive injection",
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
"compute-missing": {
|
|
601
|
+
deterministic: {
|
|
602
|
+
kind: "deterministic",
|
|
603
|
+
action: "Enable compute-sandbox in profile automatically for numeric questions.",
|
|
604
|
+
how: "Detect via regex on the question; if matched, force `profile.computeSandbox = true`.",
|
|
605
|
+
requires: ["profile seam"],
|
|
606
|
+
backup: "Emit `[NUMERIC:UNKNOWN]` for any unsupported computation.",
|
|
607
|
+
applicableInSidecar: true,
|
|
608
|
+
hook: "src/lib/v15-pipeline.ts pre-call profile mutation",
|
|
609
|
+
},
|
|
610
|
+
llm: {
|
|
611
|
+
kind: "llm",
|
|
612
|
+
action: "Instruct the draft to defer numeric claims to the compute step.",
|
|
613
|
+
how: "Template directive addition.",
|
|
614
|
+
requires: ["template-directive seam"],
|
|
615
|
+
backup: "Deterministic route.",
|
|
616
|
+
applicableInSidecar: true,
|
|
617
|
+
hook: "src/lib/debug/template-rubric.ts",
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
"hedge-explosion": {
|
|
621
|
+
deterministic: {
|
|
622
|
+
kind: "deterministic",
|
|
623
|
+
action: "Persona swap: if draft exceeds hedge density threshold, apply `The Surgeon` post-completion via COVEA to targeted paragraphs.",
|
|
624
|
+
how: "Detect density; over threshold, invoke COVEA with defect `HEDGE_DENSITY_EXCEEDED` on the offending paragraphs.",
|
|
625
|
+
requires: ["covea-repair.ts"],
|
|
626
|
+
backup: "Deterministic annotation only.",
|
|
627
|
+
applicableInSidecar: true,
|
|
628
|
+
hook: "src/lib/v15-pipeline.ts post-completion",
|
|
629
|
+
},
|
|
630
|
+
llm: {
|
|
631
|
+
kind: "llm",
|
|
632
|
+
action: "Directive: ban {might, may, could, perhaps, generally, typically, often, arguably}.",
|
|
633
|
+
how: "Template directive addition.",
|
|
634
|
+
requires: ["template-directive seam"],
|
|
635
|
+
backup: "COVEA post-completion.",
|
|
636
|
+
applicableInSidecar: true,
|
|
637
|
+
hook: "src/lib/debug/template-rubric.ts",
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
"genome-ignored": {
|
|
641
|
+
deterministic: {
|
|
642
|
+
kind: "deterministic",
|
|
643
|
+
action: "Inject genome v1 + v2 directives (in addition to v10) into BOTH question and template directive.",
|
|
644
|
+
how: "The package currently injects only v10. This project's wrapper additionally injects v1 (`compileCompactDirective`) and v2 (`compileCompactDirectiveV2`), verbatim, no truncation.",
|
|
645
|
+
requires: ["innovation-genome-engine v1 + v2"],
|
|
646
|
+
backup: "If genome roll fails, use the v10 directive alone (existing behaviour).",
|
|
647
|
+
applicableInSidecar: true,
|
|
648
|
+
hook: "src/lib/v15-pipeline.ts (turn-4 change: dual-genome injection)",
|
|
649
|
+
},
|
|
650
|
+
llm: {
|
|
651
|
+
kind: "llm",
|
|
652
|
+
action: "Ask the model to explicitly cite which genome branches it drew on.",
|
|
653
|
+
how: "Template directive: `Under Discovery Framing, name the two branches from the v1/v2 directive you used.`",
|
|
654
|
+
requires: ["template-rubric.ts"],
|
|
655
|
+
backup: "Deterministic injection only.",
|
|
656
|
+
applicableInSidecar: true,
|
|
657
|
+
hook: "src/lib/debug/template-rubric.ts",
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
|
|
661
|
+
// ══ turn-5 additions — see repair-sites.ts for verified file:line coords ══
|
|
662
|
+
"placeholder-citation-url": {
|
|
663
|
+
deterministic: {
|
|
664
|
+
kind: "deterministic",
|
|
665
|
+
action: "Stop manufacturing URLs from array indices at v15-grounding.orig.ts:113 and :131.",
|
|
666
|
+
how: "Those two lines build `source-${sourceIndex+1}` as the url field. Resolve the real URL from the lane's source table; if it does not resolve to http(s), route the claim to a non-citable `derivedClaims[]` instead of the source list.",
|
|
667
|
+
requires: ["materialize.mjs (package file must become editable)"],
|
|
668
|
+
backup: "Post-pass containment is LIVE: COVEA strips [S#] whose ledger url fails the http test, and the Scrapers tab lists every placeholder URL per lane.",
|
|
669
|
+
applicableInSidecar: false,
|
|
670
|
+
hook: "node materialize.mjs lib/v15-grounding.orig.ts → then edit :113 and :131",
|
|
671
|
+
},
|
|
672
|
+
llm: {
|
|
673
|
+
kind: "llm",
|
|
674
|
+
action: "None applicable — asking a model to supply the missing URL IS citation fabrication.",
|
|
675
|
+
how: "Do not route this defect to a model under any circumstance.",
|
|
676
|
+
requires: [],
|
|
677
|
+
backup: "Deterministic route only.",
|
|
678
|
+
applicableInSidecar: false,
|
|
679
|
+
hook: "n/a",
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
"lane-zero-yield": {
|
|
683
|
+
deterministic: {
|
|
684
|
+
kind: "deterministic",
|
|
685
|
+
action: "Gate tier acceptance on real documents, not epistemic atoms (v15-grounding.orig.ts:116).",
|
|
686
|
+
how: "`if (vanguard.ok && vanguardSources.length >= 1)` counts CLAIMS. Change to require `vanguard.tokenBudget.sourcesPacked >= 1` AND at least one absolute-URL source, else fall through to palisade.",
|
|
687
|
+
requires: ["materialize.mjs"],
|
|
688
|
+
backup: "Alias-seam partial: src/lib/v15-grounding.ts can assert yield on the RETURN value for alias callers. The pipeline calls groundQuestion relatively, so this does NOT cover the main draft path — visibility only.",
|
|
689
|
+
applicableInSidecar: false,
|
|
690
|
+
hook: "node materialize.mjs lib/v15-grounding.orig.ts → edit predicate at :116 (and :134 for palisade)",
|
|
691
|
+
},
|
|
692
|
+
llm: {
|
|
693
|
+
kind: "llm",
|
|
694
|
+
action: "On zero yield, re-dispatch query-strategist once with a broadened query.",
|
|
695
|
+
how: "Insert a single capped retry between the failed predicate and the palisade fallthrough.",
|
|
696
|
+
requires: ["web grounding enabled", "rate budget"],
|
|
697
|
+
backup: "Deterministic predicate change above.",
|
|
698
|
+
applicableInSidecar: false,
|
|
699
|
+
hook: "materialized v15-grounding.orig.ts",
|
|
700
|
+
},
|
|
701
|
+
},
|
|
702
|
+
"lane-quarantined": {
|
|
703
|
+
deterministic: {
|
|
704
|
+
kind: "deterministic",
|
|
705
|
+
action: "Assert on the whole delegation CHAIN, not per-hop (v15-grounding.orig.ts:98).",
|
|
706
|
+
how: "At the end of groundQuestion, if the accumulated source list has zero absolute-URL entries, return `{ ok:false, error:'EVIDENCE_STARVED' }` so the section emits an explicit gap instead of confident unsourced prose.",
|
|
707
|
+
requires: ["materialize.mjs"],
|
|
708
|
+
backup: "Scrapers tab already surfaces every quarantined lane and its delegation target — diagnosis without cure.",
|
|
709
|
+
applicableInSidecar: false,
|
|
710
|
+
hook: "src/lib/debug/scraper-forensics.ts → quarantinedLanes (observability, LIVE)",
|
|
711
|
+
},
|
|
712
|
+
llm: {
|
|
713
|
+
kind: "llm",
|
|
714
|
+
action: "None — orchestration control flow.",
|
|
715
|
+
how: "n/a",
|
|
716
|
+
requires: [],
|
|
717
|
+
backup: "Deterministic only.",
|
|
718
|
+
applicableInSidecar: false,
|
|
719
|
+
hook: "n/a",
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
"weak-content-gate": {
|
|
723
|
+
deterministic: {
|
|
724
|
+
kind: "deterministic",
|
|
725
|
+
action: "Add a lexical-overlap floor to the 80-char admission filter (v15-grounding.orig.ts:221).",
|
|
726
|
+
how: "`content.length>=80` is the ONLY bar. Compute token-Jaccard between the dispatch query and the first 2000 chars; reject below ~0.04 and log the rejection score so the drop is auditable.",
|
|
727
|
+
requires: ["materialize.mjs"],
|
|
728
|
+
backup: "Smaller alternative: guard the HDIG dispatch instead — refuse to search when the extracted hypothesis is <12 chars or pure punctuation. That alone kills the '...' ellipsis query at source.",
|
|
729
|
+
applicableInSidecar: false,
|
|
730
|
+
hook: "node materialize.mjs lib/v15-grounding.orig.ts → edit filter at :221",
|
|
731
|
+
},
|
|
732
|
+
llm: {
|
|
733
|
+
kind: "llm",
|
|
734
|
+
action: "Batch-score candidate snippets for relevance before admission.",
|
|
735
|
+
how: "10 snippets per call, keep/drop verdict.",
|
|
736
|
+
requires: ["rate budget"],
|
|
737
|
+
backup: "Deterministic Jaccard floor needs no network — prefer it.",
|
|
738
|
+
applicableInSidecar: false,
|
|
739
|
+
hook: "materialized v15-grounding.orig.ts",
|
|
740
|
+
},
|
|
741
|
+
},
|
|
742
|
+
"depth-repair-abandoned": {
|
|
743
|
+
deterministic: {
|
|
744
|
+
kind: "deterministic",
|
|
745
|
+
action: "Score patches per-defect and continue the loop (v15-pipeline.orig.ts:988).",
|
|
746
|
+
how: "The loop `break`s on the first rejected pass, abandoning the remaining depth budget. Accept a patch when its TARGET gate clears even if the global score is flat; replace `break` with a no-progress counter that breaks only after 2 consecutive flat depths.",
|
|
747
|
+
requires: ["materialize.mjs"],
|
|
748
|
+
backup: "COVEA post-pass performs per-target anchored repair with exactly these acceptance semantics — LIVE today.",
|
|
749
|
+
applicableInSidecar: false,
|
|
750
|
+
hook: "src/lib/debug/covea-repair.ts (per-target accept/reject, LIVE)",
|
|
751
|
+
},
|
|
752
|
+
llm: {
|
|
753
|
+
kind: "llm",
|
|
754
|
+
action: "None — control-flow defect.",
|
|
755
|
+
how: "n/a",
|
|
756
|
+
requires: [],
|
|
757
|
+
backup: "Deterministic only.",
|
|
758
|
+
applicableInSidecar: false,
|
|
759
|
+
hook: "n/a",
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
"judge-unavailable": {
|
|
763
|
+
deterministic: {
|
|
764
|
+
kind: "deterministic",
|
|
765
|
+
action: "Emit a labelled deterministic rubric floor beside the judge score — never into it.",
|
|
766
|
+
how: "Compute from template coverage, citation trust ratio, placeholder density, truncation state. Report as `deterministicFloor`. `judgeScore` must stay null on exclusion.",
|
|
767
|
+
requires: ["template-rubric.ts", "citationAudit"],
|
|
768
|
+
backup: "Report 'no independent signal available' honestly and rely on deterministic gates.",
|
|
769
|
+
applicableInSidecar: true,
|
|
770
|
+
hook: "src/lib/v15-pipeline.ts post-completion (proposed)",
|
|
771
|
+
},
|
|
772
|
+
llm: {
|
|
773
|
+
kind: "llm",
|
|
774
|
+
action: "Retry the excluded judge on a supported model after backoff.",
|
|
775
|
+
how: "Rotate off the 429'd tier and re-submit the IDENTICAL final text hash — not a regenerated candidate.",
|
|
776
|
+
requires: ["alternate model tier"],
|
|
777
|
+
backup: "Deterministic floor above.",
|
|
778
|
+
applicableInSidecar: true,
|
|
779
|
+
hook: "src/lib/v15-pipeline.ts post-completion",
|
|
780
|
+
},
|
|
781
|
+
},
|
|
782
|
+
"template-coverage-gap": {
|
|
783
|
+
deterministic: {
|
|
784
|
+
kind: "deterministic",
|
|
785
|
+
action: "Insert a template-derived stub for every absent section.",
|
|
786
|
+
how: "Walk rubric.sections; for each missing title insert `## <title>` with the section's own hint as an explicit open item. Coverage becomes measurable instead of silently partial.",
|
|
787
|
+
requires: ["template-rubric.ts"],
|
|
788
|
+
backup: "Log-only if insertion would trip the truncation gate.",
|
|
789
|
+
applicableInSidecar: true,
|
|
790
|
+
hook: "src/lib/v15-pipeline.ts post-completion",
|
|
791
|
+
},
|
|
792
|
+
llm: {
|
|
793
|
+
kind: "llm",
|
|
794
|
+
action: "Re-inject the full template section list at the START of the expansion prompt.",
|
|
795
|
+
how: "Currently the contract is strongest at outline time and weakest at expansion time, which is when sections actually get dropped.",
|
|
796
|
+
requires: ["template-directive seam"],
|
|
797
|
+
backup: "Deterministic stub insertion above.",
|
|
798
|
+
applicableInSidecar: true,
|
|
799
|
+
hook: "src/lib/v15-pipeline.ts pre-call directive",
|
|
800
|
+
},
|
|
801
|
+
},
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
// ── Cross-scope amplifiers ─────────────────────────────────────────────────
|
|
805
|
+
|
|
806
|
+
/** Section- and template-specific overrides layered on top of the base route. */
|
|
807
|
+
function scopedRoutes(defect: DefectKind, rubric: TemplateRubric | null): PerScopeAdvice[] {
|
|
808
|
+
const base = ROUTES[defect];
|
|
809
|
+
const scopes: PerScopeAdvice[] = [{ scope: "global", routes: [base.deterministic, base.llm] }];
|
|
810
|
+
|
|
811
|
+
if (rubric) {
|
|
812
|
+
// Per-template overrides
|
|
813
|
+
const perTpl: Route[] = [];
|
|
814
|
+
if (defect === "no-numerics" && rubric.templateId === "OMEGA-STRATEGY") {
|
|
815
|
+
perTpl.push({
|
|
816
|
+
kind: "deterministic",
|
|
817
|
+
action: `Template ${rubric.templateId}: force TAM/SAM/SOM triple + 5-year ramp table.`,
|
|
818
|
+
how: "Detect the market-entry template; if TAM/SAM/SOM triple is absent, insert scaffold from `--market-entry` style-hooks.",
|
|
819
|
+
requires: ["template-rubric.ts", "style overrides registry"],
|
|
820
|
+
backup: "Deterministic annotation.",
|
|
821
|
+
applicableInSidecar: true,
|
|
822
|
+
hook: "src/lib/debug/template-rubric.ts SECTION_HINTS.Diagnostic",
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
if (defect === "adversarial-blocking" && rubric.templateId === "NIH-GRANT-SRF") {
|
|
826
|
+
perTpl.push({
|
|
827
|
+
kind: "deterministic",
|
|
828
|
+
action: "Template NIH-GRANT-SRF: Schedule-I compliance pre-check gate.",
|
|
829
|
+
how: "Detect Schedule-I substances in the question; if present, insert a compliance framing constraint BEFORE draft, not just at adversarial time — matches critic_3's finding in the user's log.",
|
|
830
|
+
requires: ["profile seam"],
|
|
831
|
+
backup: "Log-only warning.",
|
|
832
|
+
applicableInSidecar: true,
|
|
833
|
+
hook: "src/lib/v15-pipeline.ts pre-call",
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
if (perTpl.length) scopes.push({ scope: `template:${rubric.templateId}`, routes: perTpl });
|
|
837
|
+
|
|
838
|
+
// Per-style overrides
|
|
839
|
+
if (rubric.styleOverrideCode) {
|
|
840
|
+
const perStyle: Route[] = [];
|
|
841
|
+
if (defect === "hedge-explosion" && rubric.styleOverrideCode === "--bain-pe") {
|
|
842
|
+
perStyle.push({
|
|
843
|
+
kind: "deterministic",
|
|
844
|
+
action: `Style ${rubric.styleOverrideCode}: enforce Bain PE red-flag list — hedges banned in Findings only.`,
|
|
845
|
+
how: "Restrict hedge-scan to the Findings section rather than global.",
|
|
846
|
+
requires: ["template-rubric.ts"],
|
|
847
|
+
backup: "Global hedge scan.",
|
|
848
|
+
applicableInSidecar: true,
|
|
849
|
+
hook: "src/lib/debug/template-rubric.ts",
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
if (perStyle.length) scopes.push({ scope: `style:${rubric.styleOverrideCode}`, routes: perStyle });
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// Per-section overrides
|
|
856
|
+
const secOverrides: Route[] = [];
|
|
857
|
+
for (const sec of rubric.sections) {
|
|
858
|
+
if (defect === "unresolved-placeholder" && /BLUF|Recommendation/i.test(sec.title)) {
|
|
859
|
+
secOverrides.push({
|
|
860
|
+
kind: "deterministic",
|
|
861
|
+
action: `Section ${sec.title}: zero-placeholder policy.`,
|
|
862
|
+
how: `Any placeholder in "${sec.title}" is a hard-fail; block emission until resolved or explicitly demoted.`,
|
|
863
|
+
requires: ["template-rubric.ts detectors"],
|
|
864
|
+
backup: "Emit with visible annotation.",
|
|
865
|
+
applicableInSidecar: true,
|
|
866
|
+
hook: "src/lib/debug/template-rubric.ts SECTION_HINTS",
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
if (secOverrides.length) scopes.push({ scope: `section:*`, routes: secOverrides });
|
|
871
|
+
}
|
|
872
|
+
return scopes;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// ── Public API ─────────────────────────────────────────────────────────────
|
|
876
|
+
|
|
877
|
+
const EXPECTED_LIFT: Record<DefectKind, number> = {
|
|
878
|
+
truncation: 1.5,
|
|
879
|
+
"unresolved-placeholder": 1.0,
|
|
880
|
+
"orphan-citation": 0.5,
|
|
881
|
+
"untrusted-citation": 0.8,
|
|
882
|
+
"missing-references": 0.4,
|
|
883
|
+
"cove-inconsistent": 1.4,
|
|
884
|
+
"adversarial-blocking": 1.6,
|
|
885
|
+
"missing-section": 0.6,
|
|
886
|
+
"no-numerics": 1.0,
|
|
887
|
+
"no-actions": 0.6,
|
|
888
|
+
"style-violation": 0.4,
|
|
889
|
+
"compute-missing": 0.8,
|
|
890
|
+
"hedge-explosion": 0.4,
|
|
891
|
+
"genome-ignored": 0.6,
|
|
892
|
+
// turn-5 additions — retrieval-plane defects dominate because an ungrounded
|
|
893
|
+
// draft cannot be repaired into a 10 by any downstream pass.
|
|
894
|
+
"placeholder-citation-url": 1.8,
|
|
895
|
+
"lane-zero-yield": 2.2,
|
|
896
|
+
"lane-quarantined": 0.8,
|
|
897
|
+
"weak-content-gate": 0.9,
|
|
898
|
+
"depth-repair-abandoned": 1.2,
|
|
899
|
+
"judge-unavailable": 0.7,
|
|
900
|
+
"template-coverage-gap": 0.6,
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
export function diagnoseRun(run: RunRecord, targetScore = 9.0): DiagnosisReport {
|
|
904
|
+
const settings = ((run.output ?? {}) as any).runSettings ?? ((run.input ?? {}) as any).profile ?? {};
|
|
905
|
+
const templateId = settings.templateId ?? "OMEGA-STRATEGY";
|
|
906
|
+
const styleOverride = settings.styleOverride ?? null;
|
|
907
|
+
const williamsPersona = settings.williamsPersona ?? null;
|
|
908
|
+
const rubric = loadTemplateRubric(templateId, styleOverride, williamsPersona);
|
|
909
|
+
|
|
910
|
+
const defects = detectDefects(run, rubric);
|
|
911
|
+
const diagnoses: StepDiagnosis[] = defects.map(({ kind, evidence }) => {
|
|
912
|
+
const step = STEP_FOR_DEFECT[kind];
|
|
913
|
+
const repairSites = sitesFor(kind);
|
|
914
|
+
return {
|
|
915
|
+
defect: kind,
|
|
916
|
+
step,
|
|
917
|
+
attribution: repairSites.length
|
|
918
|
+
? `Attributed to \`${step}\`. ${repairSites.length} verified code coordinate(s): ${repairSites.map((s) => `${s.file.split("/").pop()}:${s.line}`).join(", ")}.`
|
|
919
|
+
: `Observed in the final output; attributed to \`${step}\` — see routes. No verified code coordinate registered for this defect yet.`,
|
|
920
|
+
evidence,
|
|
921
|
+
advice: scopedRoutes(kind, rubric),
|
|
922
|
+
repairSites,
|
|
923
|
+
};
|
|
924
|
+
});
|
|
925
|
+
|
|
926
|
+
const playbook: DiagnosisReport["playbook"] = [];
|
|
927
|
+
diagnoses
|
|
928
|
+
.slice()
|
|
929
|
+
.sort((a, b) => (EXPECTED_LIFT[b.defect] ?? 0) - (EXPECTED_LIFT[a.defect] ?? 0))
|
|
930
|
+
.forEach((d, i) => {
|
|
931
|
+
// Prefer deterministic-global first.
|
|
932
|
+
const globalScope = d.advice.find((s) => s.scope === "global");
|
|
933
|
+
const det = globalScope?.routes.find((r) => r.kind === "deterministic");
|
|
934
|
+
if (det) {
|
|
935
|
+
playbook.push({
|
|
936
|
+
rank: i * 2 + 1,
|
|
937
|
+
defect: d.defect,
|
|
938
|
+
step: d.step,
|
|
939
|
+
route: det,
|
|
940
|
+
scope: "global",
|
|
941
|
+
expectedLift: EXPECTED_LIFT[d.defect] ?? 0,
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
const llm = globalScope?.routes.find((r) => r.kind === "llm");
|
|
945
|
+
if (llm) {
|
|
946
|
+
playbook.push({
|
|
947
|
+
rank: i * 2 + 2,
|
|
948
|
+
defect: d.defect,
|
|
949
|
+
step: d.step,
|
|
950
|
+
route: llm,
|
|
951
|
+
scope: "global",
|
|
952
|
+
expectedLift: (EXPECTED_LIFT[d.defect] ?? 0) * 0.6,
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
const unresolvedIssues: string[] = [];
|
|
958
|
+
if (defects.length === 0 && (run.guardScore ?? 0) < targetScore) {
|
|
959
|
+
unresolvedIssues.push(
|
|
960
|
+
"No defect pattern matched but the score is below target — this indicates a class of defect we don't yet detect. Consider adding a detector for the failing dimension."
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
if (!run.output?.citationAudit) {
|
|
964
|
+
unresolvedIssues.push("No citationAudit in outcome — citation-derived diagnoses are unavailable for this run.");
|
|
965
|
+
}
|
|
966
|
+
if (!run.output?.coveReport) {
|
|
967
|
+
unresolvedIssues.push("No coveReport in outcome — CoVe-derived diagnoses are unavailable.");
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// turn-5: dedupe repair sites across defects (one coordinate can serve several).
|
|
971
|
+
const seen = new Set<string>();
|
|
972
|
+
const allRepairSites: RepairSite[] = [];
|
|
973
|
+
for (const d of diagnoses) {
|
|
974
|
+
for (const s of d.repairSites) {
|
|
975
|
+
const k = `${s.file}:${s.line}:${s.anchor}`;
|
|
976
|
+
if (seen.has(k)) continue;
|
|
977
|
+
seen.add(k);
|
|
978
|
+
allRepairSites.push(s);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
allRepairSites.sort((a, b) => b.expectedLift - a.expectedLift);
|
|
982
|
+
const containedDetectors = new Set(
|
|
983
|
+
allRepairSites
|
|
984
|
+
.filter((s) => s.reachability !== "materialize")
|
|
985
|
+
.map((s) => s.detector)
|
|
986
|
+
);
|
|
987
|
+
const materializeStillRequired = allRepairSites.filter(
|
|
988
|
+
(s) => s.reachability === "materialize" && !containedDetectors.has(s.detector)
|
|
989
|
+
);
|
|
990
|
+
|
|
991
|
+
return {
|
|
992
|
+
runId: run.id,
|
|
993
|
+
finalScore: run.guardScore ?? null,
|
|
994
|
+
targetScore,
|
|
995
|
+
templateId,
|
|
996
|
+
styleOverride,
|
|
997
|
+
williamsPersona,
|
|
998
|
+
totalDefects: defects.length,
|
|
999
|
+
diagnoses,
|
|
1000
|
+
playbook,
|
|
1001
|
+
unresolvedIssues,
|
|
1002
|
+
allRepairSites,
|
|
1003
|
+
repairFiles: repairFileSummary(allRepairSites),
|
|
1004
|
+
reachabilitySplit: {
|
|
1005
|
+
sidecarToday: allRepairSites.filter((s) => s.reachability === "workspace-seam" || s.reachability === "alias-seam").length,
|
|
1006
|
+
postPass: allRepairSites.filter((s) => s.reachability === "post-pass").length,
|
|
1007
|
+
// materialize is counted only when there is no no-materialize containment
|
|
1008
|
+
// site for that same detector. Root-cause package coordinates remain
|
|
1009
|
+
// visible in repair cards, but no longer imply the current repo is
|
|
1010
|
+
// blocked on materialization.
|
|
1011
|
+
needsMaterialize: materializeStillRequired.length,
|
|
1012
|
+
},
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1017
|
+
// turn-5: STANDALONE DIAGNOSIS FROM (prompt, settings, output)
|
|
1018
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1019
|
+
// User's stated architecture goal: "you enter prompt, settings (which are
|
|
1020
|
+
// carried over from the v15 overlay anyway) for the run, and output. Then the
|
|
1021
|
+
// system gives you diagnosis and repair direction based on all the information
|
|
1022
|
+
// provided. The idea is to use the prompt output as a guide to fix the system."
|
|
1023
|
+
//
|
|
1024
|
+
// This synthesises a minimal RunRecord so EVERY detector above runs unchanged.
|
|
1025
|
+
// Detectors that require live telemetry (lane forensics, depth execution,
|
|
1026
|
+
// judge exclusion) will find nothing and stay silent — their absence is
|
|
1027
|
+
// reported in `unresolvedIssues` rather than silently passing.
|
|
1028
|
+
|
|
1029
|
+
export interface DiagnoseInputs {
|
|
1030
|
+
prompt: string;
|
|
1031
|
+
output: string;
|
|
1032
|
+
settings?: {
|
|
1033
|
+
templateId?: string;
|
|
1034
|
+
styleOverride?: string | null;
|
|
1035
|
+
williamsPersona?: string | null;
|
|
1036
|
+
maxDepth?: number;
|
|
1037
|
+
webSearch?: boolean;
|
|
1038
|
+
advancedGates?: boolean;
|
|
1039
|
+
[k: string]: unknown;
|
|
1040
|
+
};
|
|
1041
|
+
/** Optional: paste an exported run JSON to unlock telemetry-dependent detectors. */
|
|
1042
|
+
pastedRunJson?: string;
|
|
1043
|
+
targetScore?: number;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
export function diagnoseFromInputs(inp: DiagnoseInputs): DiagnosisReport {
|
|
1047
|
+
const target = inp.targetScore ?? 9.0;
|
|
1048
|
+
|
|
1049
|
+
// If the user pasted a full exported run, prefer it — every detector fires.
|
|
1050
|
+
if (inp.pastedRunJson && inp.pastedRunJson.trim()) {
|
|
1051
|
+
try {
|
|
1052
|
+
const parsed = JSON.parse(inp.pastedRunJson);
|
|
1053
|
+
const r = (parsed?.run ?? parsed) as Partial<RunRecord>;
|
|
1054
|
+
if (r && typeof r === "object" && (r.events || r.output)) {
|
|
1055
|
+
const synth: RunRecord = {
|
|
1056
|
+
id: String(r.id ?? "pasted"),
|
|
1057
|
+
mode: "external",
|
|
1058
|
+
question: String(r.question ?? inp.prompt),
|
|
1059
|
+
startedAt: Number(r.startedAt ?? 0),
|
|
1060
|
+
endedAt: Number(r.endedAt ?? 0),
|
|
1061
|
+
status: "complete",
|
|
1062
|
+
events: (r.events as RunRecord["events"]) ?? [],
|
|
1063
|
+
phaseStats: (r.phaseStats as RunRecord["phaseStats"]) ?? {},
|
|
1064
|
+
passes: (r.passes as RunRecord["passes"]) ?? [],
|
|
1065
|
+
sources: (r.sources as RunRecord["sources"]) ?? [],
|
|
1066
|
+
input: (r.input as RunRecord["input"]) ?? { profile: inp.settings },
|
|
1067
|
+
output: (r.output as RunRecord["output"]) ?? {},
|
|
1068
|
+
finalText: String(r.finalText ?? inp.output),
|
|
1069
|
+
guardScore: (r as any).guardScore,
|
|
1070
|
+
judgeScore: (r as any).judgeScore ?? null,
|
|
1071
|
+
};
|
|
1072
|
+
const rep = diagnoseRun(synth, target);
|
|
1073
|
+
rep.unresolvedIssues.unshift("Diagnosis derived from a PASTED run export — telemetry-dependent detectors used the pasted events.");
|
|
1074
|
+
return rep;
|
|
1075
|
+
}
|
|
1076
|
+
} catch {
|
|
1077
|
+
/* fall through to the minimal synthetic path */
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// Minimal synthetic run: text-plane detectors only.
|
|
1082
|
+
const s = inp.settings ?? {};
|
|
1083
|
+
const synth: RunRecord = {
|
|
1084
|
+
id: `inputs_${Date.now().toString(36)}`,
|
|
1085
|
+
mode: "external",
|
|
1086
|
+
question: inp.prompt,
|
|
1087
|
+
startedAt: Date.now(),
|
|
1088
|
+
endedAt: Date.now(),
|
|
1089
|
+
status: "complete",
|
|
1090
|
+
events: [],
|
|
1091
|
+
phaseStats: {},
|
|
1092
|
+
passes: [],
|
|
1093
|
+
sources: [],
|
|
1094
|
+
input: { profile: s },
|
|
1095
|
+
output: {
|
|
1096
|
+
runSettings: {
|
|
1097
|
+
templateId: s.templateId ?? "OMEGA-STRATEGY",
|
|
1098
|
+
styleOverride: s.styleOverride ?? null,
|
|
1099
|
+
williamsPersona: s.williamsPersona ?? null,
|
|
1100
|
+
depth: s.maxDepth,
|
|
1101
|
+
},
|
|
1102
|
+
},
|
|
1103
|
+
finalText: inp.output,
|
|
1104
|
+
guardScore: undefined,
|
|
1105
|
+
judgeScore: null,
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
const rep = diagnoseRun(synth, target);
|
|
1109
|
+
rep.unresolvedIssues.unshift(
|
|
1110
|
+
"Diagnosis ran in TEXT-ONLY mode: no run telemetry supplied. Retrieval-plane detectors (lane zero-yield, quarantined lanes, placeholder URLs, weak content gate), depth-execution and judge-availability detectors could NOT run and are neither passing nor failing — they are unmeasured. Paste an exported run JSON to unlock them."
|
|
1111
|
+
);
|
|
1112
|
+
return rep;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
/** Machine-readable repair order for the current diagnosis. */
|
|
1116
|
+
export function exportRepairOrderFor(report: DiagnosisReport, prompt: string): string {
|
|
1117
|
+
return exportRepairOrder(report.allRepairSites, {
|
|
1118
|
+
runId: report.runId,
|
|
1119
|
+
prompt,
|
|
1120
|
+
template: report.templateId,
|
|
1121
|
+
style: report.styleOverride ?? undefined,
|
|
1122
|
+
persona: report.williamsPersona ?? undefined,
|
|
1123
|
+
guard: report.finalScore,
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
/** Build a text bundle to hand to a third-party LLM instance for independent review. */
|
|
1128
|
+
export function bundleForExternalReview(report: DiagnosisReport, run: RunRecord, rubric: TemplateRubric | null): string {
|
|
1129
|
+
return `# PIPELINE DIAGNOSIS BUNDLE — veritas.pipeline-diagnosis/1
|
|
1130
|
+
Run: ${run.id}
|
|
1131
|
+
Generated: ${new Date().toISOString()}
|
|
1132
|
+
Final guard score: ${report.finalScore ?? "n/a"} · target: ${report.targetScore}
|
|
1133
|
+
Template: ${report.templateId} · Style: ${report.styleOverride ?? "none"} · Williams: ${report.williamsPersona ?? "none"}
|
|
1134
|
+
|
|
1135
|
+
## Ten-point contract for this template
|
|
1136
|
+
${rubric ? rubric.tenPointContract.map((c, i) => `${i + 1}. ${c}`).join("\n") : "(no rubric loaded)"}
|
|
1137
|
+
|
|
1138
|
+
## Detected defects (${report.totalDefects})
|
|
1139
|
+
${report.diagnoses.map((d) => `- ${d.defect} → step \`${d.step}\`\n ${d.evidence.map((e) => `· ${e}`).join("\n ")}`).join("\n")}
|
|
1140
|
+
|
|
1141
|
+
## Prioritised playbook
|
|
1142
|
+
${report.playbook.map((p) => `${p.rank}. [${p.route.kind}] ${p.defect} · step=${p.step} · scope=${p.scope} · expectedLift=+${p.expectedLift.toFixed(2)}\n action: ${p.route.action}\n how: ${p.route.how}\n requires: ${p.route.requires.join(", ")}\n backup: ${p.route.backup}\n hook: ${p.route.hook ?? "n/a"}`).join("\n\n")}
|
|
1143
|
+
|
|
1144
|
+
## Unresolved
|
|
1145
|
+
${report.unresolvedIssues.map((u) => `- ${u}`).join("\n") || "(none)"}
|
|
1146
|
+
|
|
1147
|
+
## Your task (third-party reviewer)
|
|
1148
|
+
Independently name the SINGLE change to the pipeline (not to the prompt) that would move this run's guard score from ${report.finalScore ?? "?"} to ${report.targetScore}. Reference a specific pipeline step by name. If the change is a prompt tweak, say so explicitly and justify why no configuration-level change would suffice.`;
|
|
1149
|
+
}
|