nodedex 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/claude-code-watcher.mjs +336 -0
- package/adapters/hermes-statedb-watcher.mjs +234 -0
- package/adapters/nodedex-capture-core.mjs +129 -0
- package/adapters/nodedex-capture.mjs +169 -0
- package/dist/agent-protocol.d.ts +7 -0
- package/dist/agent-protocol.d.ts.map +1 -0
- package/dist/agent-protocol.js +38 -0
- package/dist/agent-protocol.js.map +1 -0
- package/dist/api-server.d.ts +5 -0
- package/dist/api-server.d.ts.map +1 -0
- package/dist/api-server.js +351 -0
- package/dist/api-server.js.map +1 -0
- package/dist/boot-env.d.ts +2 -0
- package/dist/boot-env.d.ts.map +1 -0
- package/dist/boot-env.js +12 -0
- package/dist/boot-env.js.map +1 -0
- package/dist/engine/__tests__/search-core.test.d.ts +2 -0
- package/dist/engine/__tests__/search-core.test.d.ts.map +1 -0
- package/dist/engine/__tests__/search-core.test.js +139 -0
- package/dist/engine/__tests__/search-core.test.js.map +1 -0
- package/dist/engine/ai-provider.d.ts +45 -0
- package/dist/engine/ai-provider.d.ts.map +1 -0
- package/dist/engine/ai-provider.js +5 -0
- package/dist/engine/ai-provider.js.map +1 -0
- package/dist/engine/embeddings.d.ts +51 -0
- package/dist/engine/embeddings.d.ts.map +1 -0
- package/dist/engine/embeddings.js +89 -0
- package/dist/engine/embeddings.js.map +1 -0
- package/dist/engine/providers/__tests__/failure-policy.test.d.ts +2 -0
- package/dist/engine/providers/__tests__/failure-policy.test.d.ts.map +1 -0
- package/dist/engine/providers/__tests__/failure-policy.test.js +134 -0
- package/dist/engine/providers/__tests__/failure-policy.test.js.map +1 -0
- package/dist/engine/providers/__tests__/model-caps.test.d.ts +2 -0
- package/dist/engine/providers/__tests__/model-caps.test.d.ts.map +1 -0
- package/dist/engine/providers/__tests__/model-caps.test.js +38 -0
- package/dist/engine/providers/__tests__/model-caps.test.js.map +1 -0
- package/dist/engine/providers/__tests__/openai-structured.test.d.ts +2 -0
- package/dist/engine/providers/__tests__/openai-structured.test.d.ts.map +1 -0
- package/dist/engine/providers/__tests__/openai-structured.test.js +73 -0
- package/dist/engine/providers/__tests__/openai-structured.test.js.map +1 -0
- package/dist/engine/providers/__tests__/usage-ledger.test.d.ts +2 -0
- package/dist/engine/providers/__tests__/usage-ledger.test.d.ts.map +1 -0
- package/dist/engine/providers/__tests__/usage-ledger.test.js +108 -0
- package/dist/engine/providers/__tests__/usage-ledger.test.js.map +1 -0
- package/dist/engine/providers/anthropic.d.ts +17 -0
- package/dist/engine/providers/anthropic.d.ts.map +1 -0
- package/dist/engine/providers/anthropic.js +125 -0
- package/dist/engine/providers/anthropic.js.map +1 -0
- package/dist/engine/providers/failure-policy.d.ts +56 -0
- package/dist/engine/providers/failure-policy.d.ts.map +1 -0
- package/dist/engine/providers/failure-policy.js +120 -0
- package/dist/engine/providers/failure-policy.js.map +1 -0
- package/dist/engine/providers/gemini.d.ts +22 -0
- package/dist/engine/providers/gemini.d.ts.map +1 -0
- package/dist/engine/providers/gemini.js +180 -0
- package/dist/engine/providers/gemini.js.map +1 -0
- package/dist/engine/providers/index.d.ts +8 -0
- package/dist/engine/providers/index.d.ts.map +1 -0
- package/dist/engine/providers/index.js +67 -0
- package/dist/engine/providers/index.js.map +1 -0
- package/dist/engine/providers/local.d.ts +12 -0
- package/dist/engine/providers/local.d.ts.map +1 -0
- package/dist/engine/providers/local.js +46 -0
- package/dist/engine/providers/local.js.map +1 -0
- package/dist/engine/providers/model-caps.d.ts +6 -0
- package/dist/engine/providers/model-caps.d.ts.map +1 -0
- package/dist/engine/providers/model-caps.js +49 -0
- package/dist/engine/providers/model-caps.js.map +1 -0
- package/dist/engine/providers/openai.d.ts +30 -0
- package/dist/engine/providers/openai.d.ts.map +1 -0
- package/dist/engine/providers/openai.js +309 -0
- package/dist/engine/providers/openai.js.map +1 -0
- package/dist/engine/providers/usage-ledger.d.ts +69 -0
- package/dist/engine/providers/usage-ledger.d.ts.map +1 -0
- package/dist/engine/providers/usage-ledger.js +209 -0
- package/dist/engine/providers/usage-ledger.js.map +1 -0
- package/dist/engine/search-core.d.ts +40 -0
- package/dist/engine/search-core.d.ts.map +1 -0
- package/dist/engine/search-core.js +109 -0
- package/dist/engine/search-core.js.map +1 -0
- package/dist/engine/vector-math.d.ts +5 -0
- package/dist/engine/vector-math.d.ts.map +1 -0
- package/dist/engine/vector-math.js +25 -0
- package/dist/engine/vector-math.js.map +1 -0
- package/dist/home-env.d.ts +26 -0
- package/dist/home-env.d.ts.map +1 -0
- package/dist/home-env.js +87 -0
- package/dist/home-env.js.map +1 -0
- package/dist/mcp-server.d.ts +13 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +79 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/middleware/auth.d.ts +23 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +104 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/auto-recall.d.ts +7 -0
- package/dist/middleware/auto-recall.d.ts.map +1 -0
- package/dist/middleware/auto-recall.js +257 -0
- package/dist/middleware/auto-recall.js.map +1 -0
- package/dist/middleware/auto-reflect.d.ts +4 -0
- package/dist/middleware/auto-reflect.d.ts.map +1 -0
- package/dist/middleware/auto-reflect.js +5 -0
- package/dist/middleware/auto-reflect.js.map +1 -0
- package/dist/middleware/reflect/apply-flag-verdict.d.ts +27 -0
- package/dist/middleware/reflect/apply-flag-verdict.d.ts.map +1 -0
- package/dist/middleware/reflect/apply-flag-verdict.js +57 -0
- package/dist/middleware/reflect/apply-flag-verdict.js.map +1 -0
- package/dist/middleware/reflect/arc-entity-resolve.d.ts +29 -0
- package/dist/middleware/reflect/arc-entity-resolve.d.ts.map +1 -0
- package/dist/middleware/reflect/arc-entity-resolve.js +356 -0
- package/dist/middleware/reflect/arc-entity-resolve.js.map +1 -0
- package/dist/middleware/reflect/arc-inactivity-timer.d.ts +47 -0
- package/dist/middleware/reflect/arc-inactivity-timer.d.ts.map +1 -0
- package/dist/middleware/reflect/arc-inactivity-timer.js +175 -0
- package/dist/middleware/reflect/arc-inactivity-timer.js.map +1 -0
- package/dist/middleware/reflect/arc-pipeline.d.ts +33 -0
- package/dist/middleware/reflect/arc-pipeline.d.ts.map +1 -0
- package/dist/middleware/reflect/arc-pipeline.js +498 -0
- package/dist/middleware/reflect/arc-pipeline.js.map +1 -0
- package/dist/middleware/reflect/comprehend-pergroup.d.ts +100 -0
- package/dist/middleware/reflect/comprehend-pergroup.d.ts.map +1 -0
- package/dist/middleware/reflect/comprehend-pergroup.js +610 -0
- package/dist/middleware/reflect/comprehend-pergroup.js.map +1 -0
- package/dist/middleware/reflect/comprehend.d.ts +237 -0
- package/dist/middleware/reflect/comprehend.d.ts.map +1 -0
- package/dist/middleware/reflect/comprehend.js +706 -0
- package/dist/middleware/reflect/comprehend.js.map +1 -0
- package/dist/middleware/reflect/config.d.ts +34 -0
- package/dist/middleware/reflect/config.d.ts.map +1 -0
- package/dist/middleware/reflect/config.js +131 -0
- package/dist/middleware/reflect/config.js.map +1 -0
- package/dist/middleware/reflect/context.d.ts +138 -0
- package/dist/middleware/reflect/context.d.ts.map +1 -0
- package/dist/middleware/reflect/context.js +619 -0
- package/dist/middleware/reflect/context.js.map +1 -0
- package/dist/middleware/reflect/cost-breakdown.d.ts +69 -0
- package/dist/middleware/reflect/cost-breakdown.d.ts.map +1 -0
- package/dist/middleware/reflect/cost-breakdown.js +63 -0
- package/dist/middleware/reflect/cost-breakdown.js.map +1 -0
- package/dist/middleware/reflect/cost-guard.d.ts +102 -0
- package/dist/middleware/reflect/cost-guard.d.ts.map +1 -0
- package/dist/middleware/reflect/cost-guard.js +243 -0
- package/dist/middleware/reflect/cost-guard.js.map +1 -0
- package/dist/middleware/reflect/cost-pricing.d.ts +54 -0
- package/dist/middleware/reflect/cost-pricing.d.ts.map +1 -0
- package/dist/middleware/reflect/cost-pricing.js +148 -0
- package/dist/middleware/reflect/cost-pricing.js.map +1 -0
- package/dist/middleware/reflect/cross-group-link.d.ts +61 -0
- package/dist/middleware/reflect/cross-group-link.d.ts.map +1 -0
- package/dist/middleware/reflect/cross-group-link.js +212 -0
- package/dist/middleware/reflect/cross-group-link.js.map +1 -0
- package/dist/middleware/reflect/dedup-by-source-and-value.d.ts +70 -0
- package/dist/middleware/reflect/dedup-by-source-and-value.d.ts.map +1 -0
- package/dist/middleware/reflect/dedup-by-source-and-value.js +0 -0
- package/dist/middleware/reflect/dedup-by-source-and-value.js.map +1 -0
- package/dist/middleware/reflect/describe-roots.d.ts +58 -0
- package/dist/middleware/reflect/describe-roots.d.ts.map +1 -0
- package/dist/middleware/reflect/describe-roots.js +266 -0
- package/dist/middleware/reflect/describe-roots.js.map +1 -0
- package/dist/middleware/reflect/flag-reviewer-startup.d.ts +16 -0
- package/dist/middleware/reflect/flag-reviewer-startup.d.ts.map +1 -0
- package/dist/middleware/reflect/flag-reviewer-startup.js +107 -0
- package/dist/middleware/reflect/flag-reviewer-startup.js.map +1 -0
- package/dist/middleware/reflect/flag-reviewer.d.ts +69 -0
- package/dist/middleware/reflect/flag-reviewer.d.ts.map +1 -0
- package/dist/middleware/reflect/flag-reviewer.js +520 -0
- package/dist/middleware/reflect/flag-reviewer.js.map +1 -0
- package/dist/middleware/reflect/inline-dedup.d.ts +26 -0
- package/dist/middleware/reflect/inline-dedup.d.ts.map +1 -0
- package/dist/middleware/reflect/inline-dedup.js +131 -0
- package/dist/middleware/reflect/inline-dedup.js.map +1 -0
- package/dist/middleware/reflect/justify-decisions.d.ts +37 -0
- package/dist/middleware/reflect/justify-decisions.d.ts.map +1 -0
- package/dist/middleware/reflect/justify-decisions.js +159 -0
- package/dist/middleware/reflect/justify-decisions.js.map +1 -0
- package/dist/middleware/reflect/nl-accept.d.ts +35 -0
- package/dist/middleware/reflect/nl-accept.d.ts.map +1 -0
- package/dist/middleware/reflect/nl-accept.js +167 -0
- package/dist/middleware/reflect/nl-accept.js.map +1 -0
- package/dist/middleware/reflect/pass0.d.ts +20 -0
- package/dist/middleware/reflect/pass0.d.ts.map +1 -0
- package/dist/middleware/reflect/pass0.js +423 -0
- package/dist/middleware/reflect/pass0.js.map +1 -0
- package/dist/middleware/reflect/pass1.d.ts +17 -0
- package/dist/middleware/reflect/pass1.d.ts.map +1 -0
- package/dist/middleware/reflect/pass1.js +241 -0
- package/dist/middleware/reflect/pass1.js.map +1 -0
- package/dist/middleware/reflect/pass2-quarantine.d.ts +129 -0
- package/dist/middleware/reflect/pass2-quarantine.d.ts.map +1 -0
- package/dist/middleware/reflect/pass2-quarantine.js +272 -0
- package/dist/middleware/reflect/pass2-quarantine.js.map +1 -0
- package/dist/middleware/reflect/pass2-seams.d.ts +205 -0
- package/dist/middleware/reflect/pass2-seams.d.ts.map +1 -0
- package/dist/middleware/reflect/pass2-seams.js +279 -0
- package/dist/middleware/reflect/pass2-seams.js.map +1 -0
- package/dist/middleware/reflect/pass2-split-orchestrator.d.ts +37 -0
- package/dist/middleware/reflect/pass2-split-orchestrator.d.ts.map +1 -0
- package/dist/middleware/reflect/pass2-split-orchestrator.js +531 -0
- package/dist/middleware/reflect/pass2-split-orchestrator.js.map +1 -0
- package/dist/middleware/reflect/pass2.d.ts +17 -0
- package/dist/middleware/reflect/pass2.d.ts.map +1 -0
- package/dist/middleware/reflect/pass2.js +324 -0
- package/dist/middleware/reflect/pass2.js.map +1 -0
- package/dist/middleware/reflect/pass2a.d.ts +141 -0
- package/dist/middleware/reflect/pass2a.d.ts.map +1 -0
- package/dist/middleware/reflect/pass2a.js +404 -0
- package/dist/middleware/reflect/pass2a.js.map +1 -0
- package/dist/middleware/reflect/pass2b.d.ts +108 -0
- package/dist/middleware/reflect/pass2b.d.ts.map +1 -0
- package/dist/middleware/reflect/pass2b.js +480 -0
- package/dist/middleware/reflect/pass2b.js.map +1 -0
- package/dist/middleware/reflect/pass2c.d.ts +113 -0
- package/dist/middleware/reflect/pass2c.d.ts.map +1 -0
- package/dist/middleware/reflect/pass2c.js +360 -0
- package/dist/middleware/reflect/pass2c.js.map +1 -0
- package/dist/middleware/reflect/pass3-batch.d.ts +62 -0
- package/dist/middleware/reflect/pass3-batch.d.ts.map +1 -0
- package/dist/middleware/reflect/pass3-batch.js +139 -0
- package/dist/middleware/reflect/pass3-batch.js.map +1 -0
- package/dist/middleware/reflect/pass3.d.ts +23 -0
- package/dist/middleware/reflect/pass3.d.ts.map +1 -0
- package/dist/middleware/reflect/pass3.js +371 -0
- package/dist/middleware/reflect/pass3.js.map +1 -0
- package/dist/middleware/reflect/pass4-slice.d.ts +25 -0
- package/dist/middleware/reflect/pass4-slice.d.ts.map +1 -0
- package/dist/middleware/reflect/pass4-slice.js +315 -0
- package/dist/middleware/reflect/pass4-slice.js.map +1 -0
- package/dist/middleware/reflect/pass4.d.ts +30 -0
- package/dist/middleware/reflect/pass4.d.ts.map +1 -0
- package/dist/middleware/reflect/pass4.js +193 -0
- package/dist/middleware/reflect/pass4.js.map +1 -0
- package/dist/middleware/reflect/pass5.d.ts +22 -0
- package/dist/middleware/reflect/pass5.d.ts.map +1 -0
- package/dist/middleware/reflect/pass5.js +178 -0
- package/dist/middleware/reflect/pass5.js.map +1 -0
- package/dist/middleware/reflect/pass_judge.d.ts +44 -0
- package/dist/middleware/reflect/pass_judge.d.ts.map +1 -0
- package/dist/middleware/reflect/pass_judge.js +263 -0
- package/dist/middleware/reflect/pass_judge.js.map +1 -0
- package/dist/middleware/reflect/pipeline-flags.d.ts +140 -0
- package/dist/middleware/reflect/pipeline-flags.d.ts.map +1 -0
- package/dist/middleware/reflect/pipeline-flags.js +314 -0
- package/dist/middleware/reflect/pipeline-flags.js.map +1 -0
- package/dist/middleware/reflect/pipeline.d.ts +237 -0
- package/dist/middleware/reflect/pipeline.d.ts.map +1 -0
- package/dist/middleware/reflect/pipeline.js +3114 -0
- package/dist/middleware/reflect/pipeline.js.map +1 -0
- package/dist/middleware/reflect/promptOverride.d.ts +14 -0
- package/dist/middleware/reflect/promptOverride.d.ts.map +1 -0
- package/dist/middleware/reflect/promptOverride.js +28 -0
- package/dist/middleware/reflect/promptOverride.js.map +1 -0
- package/dist/middleware/reflect/provenance-check.d.ts +48 -0
- package/dist/middleware/reflect/provenance-check.d.ts.map +1 -0
- package/dist/middleware/reflect/provenance-check.js +180 -0
- package/dist/middleware/reflect/provenance-check.js.map +1 -0
- package/dist/middleware/reflect/provenance-reviewer.d.ts +52 -0
- package/dist/middleware/reflect/provenance-reviewer.d.ts.map +1 -0
- package/dist/middleware/reflect/provenance-reviewer.js +253 -0
- package/dist/middleware/reflect/provenance-reviewer.js.map +1 -0
- package/dist/middleware/reflect/prune-collapsed-types.d.ts +11 -0
- package/dist/middleware/reflect/prune-collapsed-types.d.ts.map +1 -0
- package/dist/middleware/reflect/prune-collapsed-types.js +32 -0
- package/dist/middleware/reflect/prune-collapsed-types.js.map +1 -0
- package/dist/middleware/reflect/recognize-root.d.ts +75 -0
- package/dist/middleware/reflect/recognize-root.d.ts.map +1 -0
- package/dist/middleware/reflect/recognize-root.js +204 -0
- package/dist/middleware/reflect/recognize-root.js.map +1 -0
- package/dist/middleware/reflect/render-agent-flag.d.ts +25 -0
- package/dist/middleware/reflect/render-agent-flag.d.ts.map +1 -0
- package/dist/middleware/reflect/render-agent-flag.js +39 -0
- package/dist/middleware/reflect/render-agent-flag.js.map +1 -0
- package/dist/middleware/reflect/retrieve-graph-slice.d.ts +54 -0
- package/dist/middleware/reflect/retrieve-graph-slice.d.ts.map +1 -0
- package/dist/middleware/reflect/retrieve-graph-slice.js +173 -0
- package/dist/middleware/reflect/retrieve-graph-slice.js.map +1 -0
- package/dist/middleware/reflect/root-relatedness.d.ts +31 -0
- package/dist/middleware/reflect/root-relatedness.d.ts.map +1 -0
- package/dist/middleware/reflect/root-relatedness.js +92 -0
- package/dist/middleware/reflect/root-relatedness.js.map +1 -0
- package/dist/middleware/reflect/schema-heal.d.ts +22 -0
- package/dist/middleware/reflect/schema-heal.d.ts.map +1 -0
- package/dist/middleware/reflect/schema-heal.js +119 -0
- package/dist/middleware/reflect/schema-heal.js.map +1 -0
- package/dist/middleware/reflect/schema-validator.d.ts +85 -0
- package/dist/middleware/reflect/schema-validator.d.ts.map +1 -0
- package/dist/middleware/reflect/schema-validator.js +196 -0
- package/dist/middleware/reflect/schema-validator.js.map +1 -0
- package/dist/middleware/reflect/stage-audit-graph.d.ts +115 -0
- package/dist/middleware/reflect/stage-audit-graph.d.ts.map +1 -0
- package/dist/middleware/reflect/stage-audit-graph.js +563 -0
- package/dist/middleware/reflect/stage-audit-graph.js.map +1 -0
- package/dist/middleware/reflect/stage-d-resolve-graph.d.ts +87 -0
- package/dist/middleware/reflect/stage-d-resolve-graph.d.ts.map +1 -0
- package/dist/middleware/reflect/stage-d-resolve-graph.js +256 -0
- package/dist/middleware/reflect/stage-d-resolve-graph.js.map +1 -0
- package/dist/middleware/reflect/synthesizeFromSceneCard.d.ts +15 -0
- package/dist/middleware/reflect/synthesizeFromSceneCard.d.ts.map +1 -0
- package/dist/middleware/reflect/synthesizeFromSceneCard.js +91 -0
- package/dist/middleware/reflect/synthesizeFromSceneCard.js.map +1 -0
- package/dist/middleware/reflect/types.d.ts +261 -0
- package/dist/middleware/reflect/types.d.ts.map +1 -0
- package/dist/middleware/reflect/types.js +3 -0
- package/dist/middleware/reflect/types.js.map +1 -0
- package/dist/middleware/reflect/v2-integrate.d.ts +120 -0
- package/dist/middleware/reflect/v2-integrate.d.ts.map +1 -0
- package/dist/middleware/reflect/v2-integrate.js +388 -0
- package/dist/middleware/reflect/v2-integrate.js.map +1 -0
- package/dist/middleware/reflect/v2-judge.d.ts +44 -0
- package/dist/middleware/reflect/v2-judge.d.ts.map +1 -0
- package/dist/middleware/reflect/v2-judge.js +191 -0
- package/dist/middleware/reflect/v2-judge.js.map +1 -0
- package/dist/relation-sets.d.ts +2 -0
- package/dist/relation-sets.d.ts.map +1 -0
- package/dist/relation-sets.js +35 -0
- package/dist/relation-sets.js.map +1 -0
- package/dist/routes/__tests__/flags.test.d.ts +2 -0
- package/dist/routes/__tests__/flags.test.d.ts.map +1 -0
- package/dist/routes/__tests__/flags.test.js +257 -0
- package/dist/routes/__tests__/flags.test.js.map +1 -0
- package/dist/routes/__tests__/models-catalog.test.d.ts +2 -0
- package/dist/routes/__tests__/models-catalog.test.d.ts.map +1 -0
- package/dist/routes/__tests__/models-catalog.test.js +130 -0
- package/dist/routes/__tests__/models-catalog.test.js.map +1 -0
- package/dist/routes/__tests__/reflect-pause-drain.test.d.ts +2 -0
- package/dist/routes/__tests__/reflect-pause-drain.test.d.ts.map +1 -0
- package/dist/routes/__tests__/reflect-pause-drain.test.js +38 -0
- package/dist/routes/__tests__/reflect-pause-drain.test.js.map +1 -0
- package/dist/routes/__tests__/spend-pause-drain.test.d.ts +2 -0
- package/dist/routes/__tests__/spend-pause-drain.test.d.ts.map +1 -0
- package/dist/routes/__tests__/spend-pause-drain.test.js +38 -0
- package/dist/routes/__tests__/spend-pause-drain.test.js.map +1 -0
- package/dist/routes/admin.d.ts +49 -0
- package/dist/routes/admin.d.ts.map +1 -0
- package/dist/routes/admin.js +471 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/blocks.d.ts +4 -0
- package/dist/routes/blocks.d.ts.map +1 -0
- package/dist/routes/blocks.js +893 -0
- package/dist/routes/blocks.js.map +1 -0
- package/dist/routes/chat-proxy.d.ts +5 -0
- package/dist/routes/chat-proxy.d.ts.map +1 -0
- package/dist/routes/chat-proxy.js +225 -0
- package/dist/routes/chat-proxy.js.map +1 -0
- package/dist/routes/conversations.d.ts +4 -0
- package/dist/routes/conversations.d.ts.map +1 -0
- package/dist/routes/conversations.js +139 -0
- package/dist/routes/conversations.js.map +1 -0
- package/dist/routes/flags.d.ts +4 -0
- package/dist/routes/flags.d.ts.map +1 -0
- package/dist/routes/flags.js +151 -0
- package/dist/routes/flags.js.map +1 -0
- package/dist/routes/inject.d.ts +4 -0
- package/dist/routes/inject.d.ts.map +1 -0
- package/dist/routes/inject.js +183 -0
- package/dist/routes/inject.js.map +1 -0
- package/dist/routes/mcp-http.d.ts +5 -0
- package/dist/routes/mcp-http.d.ts.map +1 -0
- package/dist/routes/mcp-http.js +94 -0
- package/dist/routes/mcp-http.js.map +1 -0
- package/dist/routes/quarantine.d.ts +4 -0
- package/dist/routes/quarantine.d.ts.map +1 -0
- package/dist/routes/quarantine.js +66 -0
- package/dist/routes/quarantine.js.map +1 -0
- package/dist/routes/recall.d.ts +5 -0
- package/dist/routes/recall.d.ts.map +1 -0
- package/dist/routes/recall.js +573 -0
- package/dist/routes/recall.js.map +1 -0
- package/dist/routes/reflect.d.ts +5 -0
- package/dist/routes/reflect.d.ts.map +1 -0
- package/dist/routes/reflect.js +231 -0
- package/dist/routes/reflect.js.map +1 -0
- package/dist/routes/session.d.ts +4 -0
- package/dist/routes/session.d.ts.map +1 -0
- package/dist/routes/session.js +418 -0
- package/dist/routes/session.js.map +1 -0
- package/dist/routes/state.d.ts +116 -0
- package/dist/routes/state.d.ts.map +1 -0
- package/dist/routes/state.js +621 -0
- package/dist/routes/state.js.map +1 -0
- package/dist/routes/usage.d.ts +3 -0
- package/dist/routes/usage.d.ts.map +1 -0
- package/dist/routes/usage.js +141 -0
- package/dist/routes/usage.js.map +1 -0
- package/dist/routes/workspace.d.ts +5 -0
- package/dist/routes/workspace.d.ts.map +1 -0
- package/dist/routes/workspace.js +435 -0
- package/dist/routes/workspace.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +298 -0
- package/dist/server.js.map +1 -0
- package/dist/store/__tests__/backup.test.d.ts +2 -0
- package/dist/store/__tests__/backup.test.d.ts.map +1 -0
- package/dist/store/__tests__/backup.test.js +53 -0
- package/dist/store/__tests__/backup.test.js.map +1 -0
- package/dist/store/__tests__/quality.test.d.ts +2 -0
- package/dist/store/__tests__/quality.test.d.ts.map +1 -0
- package/dist/store/__tests__/quality.test.js +75 -0
- package/dist/store/__tests__/quality.test.js.map +1 -0
- package/dist/store/backup.d.ts +14 -0
- package/dist/store/backup.d.ts.map +1 -0
- package/dist/store/backup.js +95 -0
- package/dist/store/backup.js.map +1 -0
- package/dist/store/database.d.ts +407 -0
- package/dist/store/database.d.ts.map +1 -0
- package/dist/store/database.js +2004 -0
- package/dist/store/database.js.map +1 -0
- package/dist/store/quality.d.ts +25 -0
- package/dist/store/quality.d.ts.map +1 -0
- package/dist/store/quality.js +48 -0
- package/dist/store/quality.js.map +1 -0
- package/dist/tools/__tests__/assemble-block-chains.test.d.ts +2 -0
- package/dist/tools/__tests__/assemble-block-chains.test.d.ts.map +1 -0
- package/dist/tools/__tests__/assemble-block-chains.test.js +118 -0
- package/dist/tools/__tests__/assemble-block-chains.test.js.map +1 -0
- package/dist/tools/__tests__/filter-roots-by-concepts.test.d.ts +2 -0
- package/dist/tools/__tests__/filter-roots-by-concepts.test.d.ts.map +1 -0
- package/dist/tools/__tests__/filter-roots-by-concepts.test.js +68 -0
- package/dist/tools/__tests__/filter-roots-by-concepts.test.js.map +1 -0
- package/dist/tools/__tests__/flag-surface.test.d.ts +2 -0
- package/dist/tools/__tests__/flag-surface.test.d.ts.map +1 -0
- package/dist/tools/__tests__/flag-surface.test.js +130 -0
- package/dist/tools/__tests__/flag-surface.test.js.map +1 -0
- package/dist/tools/core.d.ts +5 -0
- package/dist/tools/core.d.ts.map +1 -0
- package/dist/tools/core.js +962 -0
- package/dist/tools/core.js.map +1 -0
- package/dist/tools/derive.d.ts +5 -0
- package/dist/tools/derive.d.ts.map +1 -0
- package/dist/tools/derive.js +182 -0
- package/dist/tools/derive.js.map +1 -0
- package/dist/tools/flag-surface.d.ts +26 -0
- package/dist/tools/flag-surface.d.ts.map +1 -0
- package/dist/tools/flag-surface.js +59 -0
- package/dist/tools/flag-surface.js.map +1 -0
- package/dist/tools/helpers.d.ts +99 -0
- package/dist/tools/helpers.d.ts.map +1 -0
- package/dist/tools/helpers.js +243 -0
- package/dist/tools/helpers.js.map +1 -0
- package/dist/tools/projects.d.ts +5 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +175 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/system.d.ts +5 -0
- package/dist/tools/system.d.ts.map +1 -0
- package/dist/tools/system.js +1361 -0
- package/dist/tools/system.js.map +1 -0
- package/dist/tools/tasks.d.ts +5 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +289 -0
- package/dist/tools/tasks.js.map +1 -0
- package/package.json +69 -0
- package/scripts/nodedex-entry.mjs +396 -0
- package/tui-dist/App.js +185 -0
- package/tui-dist/api.js +197 -0
- package/tui-dist/cli.js +53 -0
- package/tui-dist/components.js +63 -0
- package/tui-dist/config.js +242 -0
- package/tui-dist/connect-snippets.js +98 -0
- package/tui-dist/feed.js +51 -0
- package/tui-dist/health.js +465 -0
- package/tui-dist/hooks.js +23 -0
- package/tui-dist/memory.js +220 -0
- package/tui-dist/onboarding.js +498 -0
- package/tui-dist/review.js +193 -0
- package/tui-dist/servers.js +556 -0
- package/tui-dist/smoke.js +15 -0
- package/tui-dist/theme.js +106 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { reflectTokenStats } from "./context.js";
|
|
2
|
+
import { getThinkingBudget, modelForPass } from "./config.js";
|
|
3
|
+
import { withOverride } from "./promptOverride.js";
|
|
4
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
// PASS 1 — EXTRACT
|
|
6
|
+
// Job: find every discrete piece of information in the agent's output.
|
|
7
|
+
// Assigns provisional types using scene card APPROACHES context as primary signal.
|
|
8
|
+
// Runs BACKWARD TRACE and CONTRAST CHECK after every decision extraction.
|
|
9
|
+
// Tuned for recall — a missed item is gone forever; a wrong type is fixable in Pass 2.
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
11
|
+
export const PASS1_PROMPT = withOverride("NODEDEX_TEST_PROMPT_PASS1", `You receive raw agent output — thinking and final response from an AI assistant.
|
|
12
|
+
For each passage, read it in two steps, then decide whether to keep it.
|
|
13
|
+
|
|
14
|
+
── STATE CONVENTION ─────────────────────────────────────────────────────────
|
|
15
|
+
"State" in this prompt = text in marked regions below (SCENE CARD, RECENTLY SAVED,
|
|
16
|
+
OPEN BLUEPRINTS, AGENT THINKING, AGENT OUTPUT). Your training knowledge and
|
|
17
|
+
"what's commonly known" are NOT state. When you skip an item as redundant with
|
|
18
|
+
RECENTLY SAVED, you must be able to quote the matching entry. Familiarity ≠ recorded.
|
|
19
|
+
|
|
20
|
+
── THINKING vs OUTPUT ──────────────────────────────────────────────────────
|
|
21
|
+
Same session, two angles. If the same event appears in both → extract ONCE from OUTPUT.
|
|
22
|
+
Only extract from thinking when it contains information NOT present in output.
|
|
23
|
+
Ask: "Does the output already capture this event, even in different words?"
|
|
24
|
+
YES → skip. NO → extract from thinking.
|
|
25
|
+
|
|
26
|
+
── SCENE CARD CONTEXT (if provided) ────────────────────────────────────────
|
|
27
|
+
The scene card describes what was observed — it does not assign types.
|
|
28
|
+
The scene card is NOT a substitute for extraction. Every discrete claim in the
|
|
29
|
+
transcript must still be extracted as its own item — the scene card provides context
|
|
30
|
+
for classification (engagement level, source tagging), not content to be saved.
|
|
31
|
+
Use it as INPUT CONTEXT when answering the classification tree below:
|
|
32
|
+
APPROACHES descriptions → consult at Q3b for engagement level.
|
|
33
|
+
REPLACEMENTS → predecessors have confirmed engagement (Q3b = YES).
|
|
34
|
+
UNCHANGED entries / resolved APPROACHES → source = "recap".
|
|
35
|
+
TASKS entries → extract as task. CAUSAL LINKS → consult at backward trace.
|
|
36
|
+
OPEN BLUEPRINTS → if passage shows one completing → extract as decision.
|
|
37
|
+
When scene card conflicts with transcript text → trust the transcript.
|
|
38
|
+
|
|
39
|
+
── GATE ────────────────────────────────────────────────────────────────────
|
|
40
|
+
"Would a future agent reading only this block learn something that changes
|
|
41
|
+
what they should do or avoid?"
|
|
42
|
+
YES → enter the classification tree.
|
|
43
|
+
NO → skip this passage entirely.
|
|
44
|
+
Core types (decision, dead_end, constraint, blueprint, preference) always pass.
|
|
45
|
+
Tasks pass IF: "Would a future agent's approach change knowing this exists?"
|
|
46
|
+
|
|
47
|
+
── CLASSIFICATION TREE — Q1 through Q7 ────────────────────────────────────
|
|
48
|
+
Answer YES or NO from passage text alone. Stop at the first YES.
|
|
49
|
+
Write the full Q1…Qn trace in extraction_reasoning before provisional_type.
|
|
50
|
+
|
|
51
|
+
Q1: Are two values of the same measured quantity named — a starting state and a
|
|
52
|
+
later state — where the CHANGE between them is what is being reported?
|
|
53
|
+
YES → metric (always its own item, even co-located with a decision).
|
|
54
|
+
NO → Q2.
|
|
55
|
+
|
|
56
|
+
Q2: Is something stated as an expected answer or proposed mechanism that had
|
|
57
|
+
not yet been confirmed or denied when put forward?
|
|
58
|
+
YES → hypothesis (extract even if same passage reports the outcome).
|
|
59
|
+
NO → Q3.
|
|
60
|
+
|
|
61
|
+
Q3: Is something recorded as closed off, committed to, or imposed from outside?
|
|
62
|
+
YES → Q3a–Q3d in order, stop at first YES:
|
|
63
|
+
|
|
64
|
+
Q3a: Closure set by something outside those involved (rule, law, policy)?
|
|
65
|
+
YES → constraint.
|
|
66
|
+
|
|
67
|
+
Q3b: Were resources committed INSIDE this approach before it was closed?
|
|
68
|
+
Test: "If I removed the closing event, would there be active work to stop?"
|
|
69
|
+
The scene card's APPROACHES section states each approach's engagement
|
|
70
|
+
level. Actual use, a trial, or a structured evaluation count as
|
|
71
|
+
committed resources. A suggestion raised and dropped without any trial
|
|
72
|
+
does not. Judge from the engagement the APPROACHES entry describes.
|
|
73
|
+
YES → dead_end. NO → Q3c.
|
|
74
|
+
|
|
75
|
+
Q3c: Was a specific outcome selected, AND IS THIS ITEM the selected outcome
|
|
76
|
+
(not a competing alternative that was considered and rejected)?
|
|
77
|
+
YES → decision. (Pending implementation ≠ unmade choice.)
|
|
78
|
+
NO → Q3d. An item naming a rejected/considered alternative is NOT a
|
|
79
|
+
decision even if a decision was made elsewhere this session.
|
|
80
|
+
If engagement existed for this alternative, Q3b above would have
|
|
81
|
+
caught it as dead_end. If no engagement, it falls through to Q7
|
|
82
|
+
(fact). REDUNDANCY check at KEEP OR SKIP applies after the tree.
|
|
83
|
+
|
|
84
|
+
Q3d: Was a specific path committed to, but destination still unknown?
|
|
85
|
+
YES → blueprint. (Brainstorming/non-binding → Q4.)
|
|
86
|
+
|
|
87
|
+
Q3a–Q3d all NO → Q4.
|
|
88
|
+
NO → Q4.
|
|
89
|
+
|
|
90
|
+
Q4: Something left open and unresolved, no path committed to resolving it?
|
|
91
|
+
YES → question. (Pure affirmation with no subject → skip.)
|
|
92
|
+
NO → Q5.
|
|
93
|
+
|
|
94
|
+
Q5: Specific work actively assigned or already underway right now?
|
|
95
|
+
YES → task. NO → Q6.
|
|
96
|
+
|
|
97
|
+
Q6: A standing direction that shapes repeated situations, not a one-time choice?
|
|
98
|
+
YES → preference. NO → Q7.
|
|
99
|
+
|
|
100
|
+
Q7: Q7a: Discrete occurrence at a specific point in time? YES → event.
|
|
101
|
+
Q7b: Conclusion combining 2+ things not directly connected before? YES → insight.
|
|
102
|
+
Otherwise → fact.
|
|
103
|
+
|
|
104
|
+
── POST-TYPE RULES — implied additional roles ──────────────────────────────
|
|
105
|
+
|
|
106
|
+
A single passage can carry multiple distinct claims that play different roles
|
|
107
|
+
in agent reasoning. After assigning the primary type, check whether the passage
|
|
108
|
+
also carries a second role; if so, extract a second item for that role and link
|
|
109
|
+
it with based_on. Different roles → different blocks, related by causality.
|
|
110
|
+
|
|
111
|
+
type = decision:
|
|
112
|
+
BACKWARD TRACE (mandatory): "What was in active use before this?"
|
|
113
|
+
Check scene card CAUSAL LINKS. Produce one of:
|
|
114
|
+
Predecessor + engagement confirmed → extract dead_end
|
|
115
|
+
Predecessor + engagement unclear → extract dead_end (uncertain = true)
|
|
116
|
+
Greenfield (no replacement language) → nothing
|
|
117
|
+
CONTRAST CHECK: "Competing path genuinely weighed but not chosen?"
|
|
118
|
+
YES + engagement → dead_end. YES + speculative → fact. YES + unclear → dead_end (uncertain).
|
|
119
|
+
TWO-LEVEL: "Also describes HOW?" YES → extract detail item (extends_id = this item).
|
|
120
|
+
|
|
121
|
+
type = dead_end:
|
|
122
|
+
ENGAGEMENT: "Work done INSIDE this path?" No → reclassify as fact. From REPLACEMENTS → skip check.
|
|
123
|
+
"Also ruled out by external rule?" YES → also extract constraint.
|
|
124
|
+
|
|
125
|
+
type = blueprint: "Also announces a committed outcome?" YES → also extract decision.
|
|
126
|
+
type = hypothesis: "Same passage reports the finding?" YES → also extract fact.
|
|
127
|
+
type = constraint: "Excluded option also previously tried?" YES → also extract dead_end.
|
|
128
|
+
|
|
129
|
+
type = fact OR insight:
|
|
130
|
+
IMPLIED-CONSTRAINT CHECK (mandatory):
|
|
131
|
+
"If the project accepted this item as true, does it make any choice the
|
|
132
|
+
project could otherwise have made unavailable — or force a specific choice
|
|
133
|
+
that would otherwise have been open?"
|
|
134
|
+
|
|
135
|
+
YES → also extract constraint, linked to this item via based_on.
|
|
136
|
+
Fill unique{} per the constraint schema, drawing the limit, reason,
|
|
137
|
+
and source from the item's content as stated.
|
|
138
|
+
NO → no additional item.
|
|
139
|
+
|
|
140
|
+
── KEEP OR SKIP ────────────────────────────────────────────────────────────
|
|
141
|
+
REDUNDANCY: "Can this content be recovered from another item?" YES → skip.
|
|
142
|
+
Always keep: core types (decision, dead_end, constraint, blueprint, preference).
|
|
143
|
+
Always keep: state snapshots with concrete measured values.
|
|
144
|
+
fact → keep if specific value/finding. Skip if vague. question → keep if unresolved.
|
|
145
|
+
Skip: agent narration, pure logistics, exact re-statements of RECENTLY SAVED
|
|
146
|
+
(same claim AND same values). If a value has CHANGED → extract as new item.
|
|
147
|
+
|
|
148
|
+
SKIP EVIDENCE: A skip claim that cites RECENTLY SAVED must reference the
|
|
149
|
+
matching label/value visible in that section. If RECENTLY SAVED is empty or
|
|
150
|
+
the claim cannot be quoted from it, you may NOT skip on that grounds.
|
|
151
|
+
|
|
152
|
+
── EXTRACTION RULES ────────────────────────────────────────────────────────
|
|
153
|
+
1. One outcome = one item. "X failed, adopted Y" → TWO items.
|
|
154
|
+
2. Two-level: commitment + detail → two items. extends_id test:
|
|
155
|
+
"If I deleted Item A, would Item B make sense standalone?" NO → extends_id.
|
|
156
|
+
3. Preserve exact quotes, names, numbers verbatim.
|
|
157
|
+
4. source: "output" | "thinking" (from thinking only) | "recap" (UNCHANGED/resolved).
|
|
158
|
+
5. Item IDs: item_1, item_2, … Never block-label format.
|
|
159
|
+
6. uncertain = true for core types with incomplete context. Never on fact/question/task.
|
|
160
|
+
7. extraction_reasoning — REQUIRED. Format:
|
|
161
|
+
"<Q-tree trace> → <Q-tree type>. [post-type rules]: <fired rule(s) + verdict, or 'none'>. [final]: <type>."
|
|
162
|
+
Example: "Q1=NO. Q2=NO. Q3=YES. Q3b=YES → dead_end. [post-type rules]: ENGAGEMENT=no → revise to fact. [final]: fact."
|
|
163
|
+
8. provisional_type = the [final] type from the trace — NOT the Q-tree's intermediate output.
|
|
164
|
+
Post-type rules can REVISE this item's type (e.g. dead_end ENGAGEMENT check → fact).
|
|
165
|
+
Post-type rules that ADD SEPARATE items (BACKWARD TRACE → separate predecessor dead_end,
|
|
166
|
+
IMPLIED-CONSTRAINT → separate companion constraint, CONTRAST → separate dead_end, etc.)
|
|
167
|
+
produce ADDITIONAL items with their own provisional_type; they do NOT alter THIS item's
|
|
168
|
+
provisional_type. Read each post-type rule carefully: "extract X" with a SEPARATE subject
|
|
169
|
+
means add an item; "revise to X" or "reclassify as X" means change this item's type.
|
|
170
|
+
`);
|
|
171
|
+
const PASS1_SCHEMA = {
|
|
172
|
+
type: "object",
|
|
173
|
+
properties: {
|
|
174
|
+
items: {
|
|
175
|
+
type: "array",
|
|
176
|
+
items: {
|
|
177
|
+
type: "object",
|
|
178
|
+
properties: {
|
|
179
|
+
id: { type: "string" },
|
|
180
|
+
text: { type: "string" },
|
|
181
|
+
source: { type: "string" },
|
|
182
|
+
excerpt: { type: "string" },
|
|
183
|
+
extraction_reasoning: { type: "string" },
|
|
184
|
+
provisional_type: { type: "string" },
|
|
185
|
+
extends_id: { type: "string" },
|
|
186
|
+
uncertain: { type: "boolean" },
|
|
187
|
+
},
|
|
188
|
+
required: ["id", "text", "source", "excerpt", "extraction_reasoning", "provisional_type"],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
required: ["items"],
|
|
193
|
+
};
|
|
194
|
+
// Appended ONLY when a USER turn is present (NODEDEX_EXTRACT_ALL_SOURCES on). Frames
|
|
195
|
+
// the user's turn for PASS 1's job — RECALL is source-agnostic; the user is a source
|
|
196
|
+
// of claims (decisions/constraints/preferences/lived attempts), equal to the agent.
|
|
197
|
+
const PASS1_TWO_PARTY_SUFFIX = `
|
|
198
|
+
|
|
199
|
+
── TWO-PARTY INPUT (a USER turn is present) ────────────────────────────────
|
|
200
|
+
Extract claims from BOTH the USER turn and the AGENT turn — recall is source-agnostic.
|
|
201
|
+
The USER turn is frequently where a decision, constraint, preference, or lived attempt
|
|
202
|
+
ORIGINATES ("use X not Y", "must be Z", "I tried W and it failed"); the agent's reply
|
|
203
|
+
often only elaborates or confirms it. Do not privilege the agent's wording. Attribute
|
|
204
|
+
each item to what was actually said, and put the verbatim source span in the excerpt
|
|
205
|
+
field regardless of which party said it.`;
|
|
206
|
+
export async function callPass1LLM(provider, agentThinking, agentOutput, recentSaves, sceneCard, openBlueprints = [], userMessage = "") {
|
|
207
|
+
const sceneCardSection = sceneCard
|
|
208
|
+
? `SCENE CARD (use to guide extraction):\n${sceneCard}\n\n---\n\n`
|
|
209
|
+
: "";
|
|
210
|
+
const recentSection = recentSaves
|
|
211
|
+
? `RECENTLY SAVED THIS SESSION (do not re-extract these):\n${recentSaves}\n\n---\n\n`
|
|
212
|
+
: "";
|
|
213
|
+
const blueprintSection = openBlueprints.length > 0
|
|
214
|
+
? `OPEN BLUEPRINTS (from graph — if any appear as completed or deployed in this session, extract as decision and include the blueprint label in item text for Pass 2 to set supersedes_ref):\n${openBlueprints.map(b => `- ${b.label}: "${b.essence}"`).join("\n")}\n\n---\n\n`
|
|
215
|
+
: "";
|
|
216
|
+
const thinkingSection = agentThinking
|
|
217
|
+
? `AGENT THINKING:\n${agentThinking}\n\n---\n\n`
|
|
218
|
+
: "";
|
|
219
|
+
const userSection = userMessage && userMessage.trim()
|
|
220
|
+
? `USER:\n${userMessage}\n\n---\n\n`
|
|
221
|
+
: "";
|
|
222
|
+
const userInput = `${sceneCardSection}${recentSection}${blueprintSection}${userSection}${thinkingSection}AGENT OUTPUT:\n${agentOutput}`;
|
|
223
|
+
const p1Prompt = userSection ? PASS1_PROMPT + PASS1_TWO_PARTY_SUFFIX : PASS1_PROMPT;
|
|
224
|
+
const r = await provider.generateStructured(p1Prompt, userInput, PASS1_SCHEMA, { thinkingBudget: getThinkingBudget(1024), maxOutputTokens: 16384, modelOverride: modelForPass("pass1") });
|
|
225
|
+
if (r.result) {
|
|
226
|
+
reflectTokenStats.pass1.input += r.usage?.input ?? 0;
|
|
227
|
+
reflectTokenStats.pass1.thinking += r.usage?.thinking ?? 0;
|
|
228
|
+
reflectTokenStats.pass1.output += r.usage?.output ?? 0;
|
|
229
|
+
reflectTokenStats.pass1.calls += 1;
|
|
230
|
+
const tag = provider.getName() !== "gemini" ? ` [${provider.getName()}]` : "";
|
|
231
|
+
console.log(`Auto-Reflect Pass 1: ${r.result.items.length} item(s) extracted | tokens: ${r.usage?.input ?? "?"}→${r.usage?.output ?? "?"}${tag}`);
|
|
232
|
+
for (const item of r.result.items) {
|
|
233
|
+
console.log(` [Pass 1 item] ${item.id} provisional_type=${item.provisional_type} text="${item.text.slice(0, 80)}"`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
console.error(`Auto-Reflect Pass 1: ${r.rateLimited ? "rate limited" : "failed"} [${provider.getName()}]`);
|
|
238
|
+
}
|
|
239
|
+
return { result: r.result, thinking: r.thinking ?? "", rateLimited: r.rateLimited, model: r.model, attempts: r.attempts };
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=pass1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pass1.js","sourceRoot":"","sources":["../../../src/middleware/reflect/pass1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAInD,kFAAkF;AAClF,mBAAmB;AACnB,uEAAuE;AACvE,mFAAmF;AACnF,0EAA0E;AAC1E,uFAAuF;AACvF,kFAAkF;AAElF,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC,2BAA2B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+JrE,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG;IACnB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,EAAE,EAAgB,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,IAAI,EAAc,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,MAAM,EAAY,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,OAAO,EAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACxC,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,UAAU,EAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,SAAS,EAAS,EAAE,IAAI,EAAE,SAAS,EAAE;iBACtC;gBACD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,sBAAsB,EAAE,kBAAkB,CAAC;aAC1F;SACF;KACF;IACD,QAAQ,EAAE,CAAC,OAAO,CAAC;CACpB,CAAC;AAEF,qFAAqF;AACrF,qFAAqF;AACrF,oFAAoF;AACpF,MAAM,sBAAsB,GAAG;;;;;;;;yCAQU,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAqB,EACrB,aAAqB,EACrB,WAAmB,EACnB,WAAmB,EACnB,SAAkB,EAClB,iBAA4D,EAAE,EAC9D,cAAsB,EAAE;IAExB,MAAM,gBAAgB,GAAG,SAAS;QAChC,CAAC,CAAC,0CAA0C,SAAS,aAAa;QAClE,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,aAAa,GAAG,WAAW;QAC/B,CAAC,CAAC,2DAA2D,WAAW,aAAa;QACrF,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC;QAChD,CAAC,CAAC,8LAA8L,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa;QAC/Q,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,eAAe,GAAG,aAAa;QACnC,CAAC,CAAC,oBAAoB,aAAa,aAAa;QAChD,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,WAAW,GAAG,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE;QACnD,CAAC,CAAC,UAAU,WAAW,aAAa;QACpC,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,SAAS,GAAG,GAAG,gBAAgB,GAAG,aAAa,GAAG,gBAAgB,GAAG,WAAW,GAAG,eAAe,kBAAkB,WAAW,EAAE,CAAC;IACxI,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,YAAY,GAAG,sBAAsB,CAAC,CAAC,CAAC,YAAY,CAAC;IAEpF,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAc,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,iBAAiB,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEvM,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACb,iBAAiB,CAAC,KAAK,CAAC,KAAK,IAAO,CAAC,CAAC,KAAK,EAAE,KAAK,IAAO,CAAC,CAAC;QAC3D,iBAAiB,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,IAAI,CAAC,CAAC;QAC3D,iBAAiB,CAAC,KAAK,CAAC,MAAM,IAAM,CAAC,CAAC,KAAK,EAAE,MAAM,IAAM,CAAC,CAAC;QAC3D,iBAAiB,CAAC,KAAK,CAAC,KAAK,IAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,gCAAgC,CAAC,CAAC,KAAK,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;QAClJ,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,EAAE,qBAAqB,IAAI,CAAC,gBAAgB,UAAU,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QACvH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7G,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC5H,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
/**
|
|
3
|
+
* Full quarantine entry shape per PASS2-SPLIT-DESIGN.md §3.
|
|
4
|
+
*
|
|
5
|
+
* Origin fields (from Pass 1): immutable after first write.
|
|
6
|
+
* 2a fields: populated by Pass 2a's classify attempt.
|
|
7
|
+
* 2b fields: populated by Pass 2b's fill attempt.
|
|
8
|
+
* Retry fields: filled if the seam tried route-back to 2a.
|
|
9
|
+
* Enrichment fields: managed by future debt 2 work.
|
|
10
|
+
* agent_clarification: reserved for debt 2b (agent-in-the-loop).
|
|
11
|
+
*/
|
|
12
|
+
export interface QuarantineEntry {
|
|
13
|
+
id: string;
|
|
14
|
+
pass1_text: string;
|
|
15
|
+
pass1_provisional_type: string;
|
|
16
|
+
pass1_reasoning: string | null;
|
|
17
|
+
pass1_excerpt: string | null;
|
|
18
|
+
pass2a_classified: string;
|
|
19
|
+
pass2a_reasoning: string;
|
|
20
|
+
pass2a_alternatives: string[];
|
|
21
|
+
pass2b_attempted: Record<string, unknown>;
|
|
22
|
+
pass2b_failure_reason: string;
|
|
23
|
+
retry_attempted: boolean;
|
|
24
|
+
retry_2a_classified: string | null;
|
|
25
|
+
retry_outcome: "success" | "different_type_quarantined" | "same_type_quarantined" | null;
|
|
26
|
+
batch_id: string;
|
|
27
|
+
source_session_id: string;
|
|
28
|
+
quarantined_at: string;
|
|
29
|
+
siblings_promoted: string[];
|
|
30
|
+
queued_for_enrichment: boolean;
|
|
31
|
+
enrichment_attempts: Array<{
|
|
32
|
+
when: string;
|
|
33
|
+
pass_used: string;
|
|
34
|
+
outcome: string;
|
|
35
|
+
}>;
|
|
36
|
+
promotion_blocked_until: string | null;
|
|
37
|
+
agent_clarification: {
|
|
38
|
+
resolved_at: string;
|
|
39
|
+
agent_verdict: string;
|
|
40
|
+
agent_notes: string;
|
|
41
|
+
} | null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Filter parameters for `getQuarantineEntries`. All optional; AND-combined.
|
|
45
|
+
*/
|
|
46
|
+
export interface QuarantineFilters {
|
|
47
|
+
project?: string;
|
|
48
|
+
failure_reason?: string;
|
|
49
|
+
batch_id?: string;
|
|
50
|
+
source_session_id?: string;
|
|
51
|
+
queued_for_enrichment?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create the quarantine table if it doesn't exist. Safe to call repeatedly
|
|
55
|
+
* (CREATE IF NOT EXISTS + indexes are idempotent).
|
|
56
|
+
*
|
|
57
|
+
* Caller responsibility: invoke once at server boot or test setup. Writers do
|
|
58
|
+
* NOT auto-create the table — they assume it exists. This keeps the call graph
|
|
59
|
+
* predictable (no silent side effects in hot paths).
|
|
60
|
+
*
|
|
61
|
+
* The audit-trail fields are stored as TEXT (JSON-serialized) so the shape can
|
|
62
|
+
* evolve without per-field column adds. SQLite JSON1 functions can query into
|
|
63
|
+
* them if we ever need composition analysis (debt-3 work).
|
|
64
|
+
*/
|
|
65
|
+
export declare function ensureQuarantineTable(db: Database.Database): void;
|
|
66
|
+
/**
|
|
67
|
+
* Insert a new quarantine entry. Throws if `id` already exists (writes are
|
|
68
|
+
* additive — re-quarantining the same id is a logic error in the caller, not
|
|
69
|
+
* something this module silently handles).
|
|
70
|
+
*
|
|
71
|
+
* The caller (typically `pass2-seams.ts`) is responsible for assembling the
|
|
72
|
+
* full audit trail before calling this — see `QuarantineEntry` shape.
|
|
73
|
+
*/
|
|
74
|
+
export declare function writeQuarantineEntry(db: Database.Database, entry: QuarantineEntry): void;
|
|
75
|
+
/**
|
|
76
|
+
* Record an enrichment attempt — appends to enrichment_attempts[] without
|
|
77
|
+
* touching other fields. Used by future debt 2a (pipeline self-enrichment).
|
|
78
|
+
*/
|
|
79
|
+
export declare function recordEnrichmentAttempt(db: Database.Database, id: string, attempt: {
|
|
80
|
+
when: string;
|
|
81
|
+
pass_used: string;
|
|
82
|
+
outcome: string;
|
|
83
|
+
}, options?: {
|
|
84
|
+
newQueuedFlag?: boolean;
|
|
85
|
+
newBlockedUntil?: string | null;
|
|
86
|
+
}): void;
|
|
87
|
+
/**
|
|
88
|
+
* Mark a quarantine entry as PROMOTED — caller has already created a live
|
|
89
|
+
* block from this candidate. Future enrichment will not pick it up again.
|
|
90
|
+
*
|
|
91
|
+
* Does NOT delete the row — the audit trail stays for inspection.
|
|
92
|
+
* Records the promotion as the final enrichment_attempts entry with
|
|
93
|
+
* `outcome: "promoted_to:<block_id>"`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function markQuarantinePromoted(db: Database.Database, id: string, promotedBlockId: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* Fetch a single quarantine entry by its Pass 1 item id. Returns `null` if
|
|
98
|
+
* not found.
|
|
99
|
+
*/
|
|
100
|
+
export declare function getQuarantineEntry(db: Database.Database, id: string): QuarantineEntry | null;
|
|
101
|
+
/**
|
|
102
|
+
* List quarantine entries matching the given filters. All filters are optional
|
|
103
|
+
* and AND-combined. Sorted by `quarantined_at` DESC (most recent first).
|
|
104
|
+
*
|
|
105
|
+
* `failure_reason` is a SUBSTRING match (LIKE %term%) — useful for finding all
|
|
106
|
+
* entries with a specific failure pattern (e.g. "missing=[implication]") which
|
|
107
|
+
* is the debt-3 composition-shift signal from §3.
|
|
108
|
+
*/
|
|
109
|
+
export declare function getQuarantineEntries(db: Database.Database, filters?: QuarantineFilters): QuarantineEntry[];
|
|
110
|
+
/**
|
|
111
|
+
* Count quarantine entries — cheap aggregate for the tier-based signal monitor
|
|
112
|
+
* referenced in §3. Returns total + grouped-by-failure_reason for composition
|
|
113
|
+
* analysis.
|
|
114
|
+
*
|
|
115
|
+
* NOTE: this is the lowest-level primitive. Tier interpretation (Watch / Notice
|
|
116
|
+
* / Investigate / Rollback per §3) lives in the telemetry layer, not here.
|
|
117
|
+
*/
|
|
118
|
+
export declare function summarizeQuarantine(db: Database.Database): {
|
|
119
|
+
total: number;
|
|
120
|
+
by_failure_reason: Array<{
|
|
121
|
+
reason: string;
|
|
122
|
+
count: number;
|
|
123
|
+
}>;
|
|
124
|
+
by_session: Array<{
|
|
125
|
+
session_id: string;
|
|
126
|
+
count: number;
|
|
127
|
+
}>;
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=pass2-quarantine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pass2-quarantine.d.ts","sourceRoot":"","sources":["../../../src/middleware/reflect/pass2-quarantine.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAE9B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAG7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAG9B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,qBAAqB,EAAE,MAAM,CAAC;IAG9B,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,SAAS,GAAG,4BAA4B,GAAG,uBAAuB,GAAG,IAAI,CAAC;IAGzF,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAG5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,mBAAmB,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjF,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGvC,mBAAmB,EAAE;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI,CAAC;CACV;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAoCjE;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,eAAe,GACrB,IAAI,CAoDN;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC7D,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACrE,IAAI,CAiBN;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,GACtB,IAAI,CAON;AAsDD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,EAAE,EAAE,MAAM,GACT,eAAe,GAAG,IAAI,CAIxB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,GAAE,iBAAsB,GAC9B,eAAe,EAAE,CA+BnB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,UAAU,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D,CAsBA"}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// PASS 2 AUDIT QUARANTINE — Week 1, debt #1 (2026-05-25)
|
|
3
|
+
//
|
|
4
|
+
// Role: When Pass 2's split-mode seam validation (§3 of PASS2-SPLIT-DESIGN.md)
|
|
5
|
+
// cannot resolve a candidate into a valid block — after one retry — the
|
|
6
|
+
// candidate is preserved here with its full audit trail. NEVER lost,
|
|
7
|
+
// NEVER ships to the live graph as a flagged-block.
|
|
8
|
+
//
|
|
9
|
+
// Design choices (locked 2026-05-25):
|
|
10
|
+
// - SEPARATE TABLE `pass2_audit_quarantine`, not `blocks.status='quarantined'`.
|
|
11
|
+
// Reason: prevents silent leakage into existing `getAllBlocks()` and other
|
|
12
|
+
// unfiltered queries. Default agent navigation can ONLY reach quarantine via
|
|
13
|
+
// explicit `/api/quarantine` endpoints — the visibility contract from §3 is
|
|
14
|
+
// enforced structurally, not by remembering to add WHERE-clauses.
|
|
15
|
+
// - NO absolute size limit. Tier-based signal monitoring only (§3).
|
|
16
|
+
// - `agent_clarification` field is a RESERVED slot for debt 2b (future); writers
|
|
17
|
+
// leave it null. Future enrichment passes will populate it.
|
|
18
|
+
//
|
|
19
|
+
// What this module does NOT do:
|
|
20
|
+
// - It does NOT decide what to quarantine — that's `pass2-seams.ts`.
|
|
21
|
+
// - It does NOT call any LLM.
|
|
22
|
+
// - It does NOT mutate live blocks (`blocks` table).
|
|
23
|
+
// - It does NOT do composition analysis or tier-signal alerts — those live in
|
|
24
|
+
// a future telemetry layer; this module just stores and retrieves.
|
|
25
|
+
//
|
|
26
|
+
// Charter alignment:
|
|
27
|
+
// - Rule 2 (never delete vetted blocks): quarantine entries aren't blocks; they
|
|
28
|
+
// are candidates that failed the gate. The seam decides whether a candidate
|
|
29
|
+
// becomes a block. Quarantine preserves the rest.
|
|
30
|
+
// - Rule 6 (guards catch failure, never override success): writes are additive;
|
|
31
|
+
// existing blocks are never touched by quarantine code paths.
|
|
32
|
+
// - Rule 14 (store the path): the full audit trail (Pass 1 text, Pass 2a
|
|
33
|
+
// classification reasoning, Pass 2b attempt, failure reason, retry status)
|
|
34
|
+
// is preserved so a future session can reason about what happened.
|
|
35
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
36
|
+
// ─── Schema migration ──────────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Create the quarantine table if it doesn't exist. Safe to call repeatedly
|
|
39
|
+
* (CREATE IF NOT EXISTS + indexes are idempotent).
|
|
40
|
+
*
|
|
41
|
+
* Caller responsibility: invoke once at server boot or test setup. Writers do
|
|
42
|
+
* NOT auto-create the table — they assume it exists. This keeps the call graph
|
|
43
|
+
* predictable (no silent side effects in hot paths).
|
|
44
|
+
*
|
|
45
|
+
* The audit-trail fields are stored as TEXT (JSON-serialized) so the shape can
|
|
46
|
+
* evolve without per-field column adds. SQLite JSON1 functions can query into
|
|
47
|
+
* them if we ever need composition analysis (debt-3 work).
|
|
48
|
+
*/
|
|
49
|
+
export function ensureQuarantineTable(db) {
|
|
50
|
+
db.exec(`
|
|
51
|
+
CREATE TABLE IF NOT EXISTS pass2_audit_quarantine (
|
|
52
|
+
id TEXT PRIMARY KEY,
|
|
53
|
+
pass1_text TEXT NOT NULL,
|
|
54
|
+
pass1_provisional_type TEXT NOT NULL,
|
|
55
|
+
pass1_reasoning TEXT,
|
|
56
|
+
pass1_excerpt TEXT,
|
|
57
|
+
|
|
58
|
+
pass2a_classified TEXT NOT NULL,
|
|
59
|
+
pass2a_reasoning TEXT NOT NULL,
|
|
60
|
+
pass2a_alternatives TEXT NOT NULL DEFAULT '[]', -- JSON array
|
|
61
|
+
|
|
62
|
+
pass2b_attempted TEXT NOT NULL DEFAULT '{}', -- JSON object
|
|
63
|
+
pass2b_failure_reason TEXT NOT NULL,
|
|
64
|
+
|
|
65
|
+
retry_attempted INTEGER NOT NULL DEFAULT 0, -- boolean
|
|
66
|
+
retry_2a_classified TEXT,
|
|
67
|
+
retry_outcome TEXT, -- nullable enum
|
|
68
|
+
|
|
69
|
+
batch_id TEXT NOT NULL,
|
|
70
|
+
source_session_id TEXT NOT NULL,
|
|
71
|
+
quarantined_at TEXT NOT NULL,
|
|
72
|
+
siblings_promoted TEXT NOT NULL DEFAULT '[]', -- JSON array of block ids
|
|
73
|
+
|
|
74
|
+
queued_for_enrichment INTEGER NOT NULL DEFAULT 1, -- boolean
|
|
75
|
+
enrichment_attempts TEXT NOT NULL DEFAULT '[]', -- JSON array
|
|
76
|
+
promotion_blocked_until TEXT, -- nullable ISO ts
|
|
77
|
+
|
|
78
|
+
agent_clarification TEXT -- nullable JSON object
|
|
79
|
+
)
|
|
80
|
+
`);
|
|
81
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_quarantine_batch ON pass2_audit_quarantine(batch_id)`);
|
|
82
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_quarantine_session ON pass2_audit_quarantine(source_session_id)`);
|
|
83
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_quarantine_queued ON pass2_audit_quarantine(queued_for_enrichment)`);
|
|
84
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_quarantine_quarantined ON pass2_audit_quarantine(quarantined_at)`);
|
|
85
|
+
}
|
|
86
|
+
// ─── Writers ───────────────────────────────────────────────────────────────────
|
|
87
|
+
/**
|
|
88
|
+
* Insert a new quarantine entry. Throws if `id` already exists (writes are
|
|
89
|
+
* additive — re-quarantining the same id is a logic error in the caller, not
|
|
90
|
+
* something this module silently handles).
|
|
91
|
+
*
|
|
92
|
+
* The caller (typically `pass2-seams.ts`) is responsible for assembling the
|
|
93
|
+
* full audit trail before calling this — see `QuarantineEntry` shape.
|
|
94
|
+
*/
|
|
95
|
+
export function writeQuarantineEntry(db, entry) {
|
|
96
|
+
const stmt = db.prepare(`
|
|
97
|
+
INSERT INTO pass2_audit_quarantine (
|
|
98
|
+
id, pass1_text, pass1_provisional_type, pass1_reasoning, pass1_excerpt,
|
|
99
|
+
pass2a_classified, pass2a_reasoning, pass2a_alternatives,
|
|
100
|
+
pass2b_attempted, pass2b_failure_reason,
|
|
101
|
+
retry_attempted, retry_2a_classified, retry_outcome,
|
|
102
|
+
batch_id, source_session_id, quarantined_at, siblings_promoted,
|
|
103
|
+
queued_for_enrichment, enrichment_attempts, promotion_blocked_until,
|
|
104
|
+
agent_clarification
|
|
105
|
+
) VALUES (
|
|
106
|
+
@id, @pass1_text, @pass1_provisional_type, @pass1_reasoning, @pass1_excerpt,
|
|
107
|
+
@pass2a_classified, @pass2a_reasoning, @pass2a_alternatives,
|
|
108
|
+
@pass2b_attempted, @pass2b_failure_reason,
|
|
109
|
+
@retry_attempted, @retry_2a_classified, @retry_outcome,
|
|
110
|
+
@batch_id, @source_session_id, @quarantined_at, @siblings_promoted,
|
|
111
|
+
@queued_for_enrichment, @enrichment_attempts, @promotion_blocked_until,
|
|
112
|
+
@agent_clarification
|
|
113
|
+
)
|
|
114
|
+
`);
|
|
115
|
+
stmt.run({
|
|
116
|
+
id: entry.id,
|
|
117
|
+
pass1_text: entry.pass1_text,
|
|
118
|
+
pass1_provisional_type: entry.pass1_provisional_type,
|
|
119
|
+
pass1_reasoning: entry.pass1_reasoning,
|
|
120
|
+
pass1_excerpt: entry.pass1_excerpt,
|
|
121
|
+
pass2a_classified: entry.pass2a_classified,
|
|
122
|
+
pass2a_reasoning: entry.pass2a_reasoning,
|
|
123
|
+
pass2a_alternatives: JSON.stringify(entry.pass2a_alternatives ?? []),
|
|
124
|
+
pass2b_attempted: JSON.stringify(entry.pass2b_attempted ?? {}),
|
|
125
|
+
pass2b_failure_reason: entry.pass2b_failure_reason,
|
|
126
|
+
retry_attempted: entry.retry_attempted ? 1 : 0,
|
|
127
|
+
retry_2a_classified: entry.retry_2a_classified,
|
|
128
|
+
retry_outcome: entry.retry_outcome,
|
|
129
|
+
batch_id: entry.batch_id,
|
|
130
|
+
source_session_id: entry.source_session_id,
|
|
131
|
+
quarantined_at: entry.quarantined_at,
|
|
132
|
+
siblings_promoted: JSON.stringify(entry.siblings_promoted ?? []),
|
|
133
|
+
queued_for_enrichment: entry.queued_for_enrichment ? 1 : 0,
|
|
134
|
+
enrichment_attempts: JSON.stringify(entry.enrichment_attempts ?? []),
|
|
135
|
+
promotion_blocked_until: entry.promotion_blocked_until,
|
|
136
|
+
agent_clarification: entry.agent_clarification
|
|
137
|
+
? JSON.stringify(entry.agent_clarification)
|
|
138
|
+
: null,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Record an enrichment attempt — appends to enrichment_attempts[] without
|
|
143
|
+
* touching other fields. Used by future debt 2a (pipeline self-enrichment).
|
|
144
|
+
*/
|
|
145
|
+
export function recordEnrichmentAttempt(db, id, attempt, options) {
|
|
146
|
+
const row = getQuarantineEntry(db, id);
|
|
147
|
+
if (!row)
|
|
148
|
+
throw new Error(`recordEnrichmentAttempt: no quarantine entry ${id}`);
|
|
149
|
+
const updated = [...row.enrichment_attempts, attempt];
|
|
150
|
+
db.prepare(`
|
|
151
|
+
UPDATE pass2_audit_quarantine
|
|
152
|
+
SET enrichment_attempts = @attempts,
|
|
153
|
+
queued_for_enrichment = @queued,
|
|
154
|
+
promotion_blocked_until = @blocked
|
|
155
|
+
WHERE id = @id
|
|
156
|
+
`).run({
|
|
157
|
+
id,
|
|
158
|
+
attempts: JSON.stringify(updated),
|
|
159
|
+
queued: (options?.newQueuedFlag ?? row.queued_for_enrichment) ? 1 : 0,
|
|
160
|
+
blocked: options?.newBlockedUntil ?? row.promotion_blocked_until,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Mark a quarantine entry as PROMOTED — caller has already created a live
|
|
165
|
+
* block from this candidate. Future enrichment will not pick it up again.
|
|
166
|
+
*
|
|
167
|
+
* Does NOT delete the row — the audit trail stays for inspection.
|
|
168
|
+
* Records the promotion as the final enrichment_attempts entry with
|
|
169
|
+
* `outcome: "promoted_to:<block_id>"`.
|
|
170
|
+
*/
|
|
171
|
+
export function markQuarantinePromoted(db, id, promotedBlockId) {
|
|
172
|
+
recordEnrichmentAttempt(db, id, { when: new Date().toISOString(), pass_used: "manual_or_enrichment", outcome: `promoted_to:${promotedBlockId}` }, { newQueuedFlag: false, newBlockedUntil: null });
|
|
173
|
+
}
|
|
174
|
+
function rowToEntry(row) {
|
|
175
|
+
return {
|
|
176
|
+
id: row.id,
|
|
177
|
+
pass1_text: row.pass1_text,
|
|
178
|
+
pass1_provisional_type: row.pass1_provisional_type,
|
|
179
|
+
pass1_reasoning: row.pass1_reasoning,
|
|
180
|
+
pass1_excerpt: row.pass1_excerpt,
|
|
181
|
+
pass2a_classified: row.pass2a_classified,
|
|
182
|
+
pass2a_reasoning: row.pass2a_reasoning,
|
|
183
|
+
pass2a_alternatives: JSON.parse(row.pass2a_alternatives || "[]"),
|
|
184
|
+
pass2b_attempted: JSON.parse(row.pass2b_attempted || "{}"),
|
|
185
|
+
pass2b_failure_reason: row.pass2b_failure_reason,
|
|
186
|
+
retry_attempted: row.retry_attempted === 1,
|
|
187
|
+
retry_2a_classified: row.retry_2a_classified,
|
|
188
|
+
retry_outcome: row.retry_outcome,
|
|
189
|
+
batch_id: row.batch_id,
|
|
190
|
+
source_session_id: row.source_session_id,
|
|
191
|
+
quarantined_at: row.quarantined_at,
|
|
192
|
+
siblings_promoted: JSON.parse(row.siblings_promoted || "[]"),
|
|
193
|
+
queued_for_enrichment: row.queued_for_enrichment === 1,
|
|
194
|
+
enrichment_attempts: JSON.parse(row.enrichment_attempts || "[]"),
|
|
195
|
+
promotion_blocked_until: row.promotion_blocked_until,
|
|
196
|
+
agent_clarification: row.agent_clarification ? JSON.parse(row.agent_clarification) : null,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Fetch a single quarantine entry by its Pass 1 item id. Returns `null` if
|
|
201
|
+
* not found.
|
|
202
|
+
*/
|
|
203
|
+
export function getQuarantineEntry(db, id) {
|
|
204
|
+
const row = db.prepare(`SELECT * FROM pass2_audit_quarantine WHERE id = ?`).get(id);
|
|
205
|
+
if (!row)
|
|
206
|
+
return null;
|
|
207
|
+
return rowToEntry(row);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* List quarantine entries matching the given filters. All filters are optional
|
|
211
|
+
* and AND-combined. Sorted by `quarantined_at` DESC (most recent first).
|
|
212
|
+
*
|
|
213
|
+
* `failure_reason` is a SUBSTRING match (LIKE %term%) — useful for finding all
|
|
214
|
+
* entries with a specific failure pattern (e.g. "missing=[implication]") which
|
|
215
|
+
* is the debt-3 composition-shift signal from §3.
|
|
216
|
+
*/
|
|
217
|
+
export function getQuarantineEntries(db, filters = {}) {
|
|
218
|
+
const where = [];
|
|
219
|
+
const params = {};
|
|
220
|
+
if (filters.batch_id !== undefined) {
|
|
221
|
+
where.push("batch_id = @batch_id");
|
|
222
|
+
params.batch_id = filters.batch_id;
|
|
223
|
+
}
|
|
224
|
+
if (filters.source_session_id !== undefined) {
|
|
225
|
+
where.push("source_session_id = @session");
|
|
226
|
+
params.session = filters.source_session_id;
|
|
227
|
+
}
|
|
228
|
+
if (filters.queued_for_enrichment !== undefined) {
|
|
229
|
+
where.push("queued_for_enrichment = @queued");
|
|
230
|
+
params.queued = filters.queued_for_enrichment ? 1 : 0;
|
|
231
|
+
}
|
|
232
|
+
if (filters.failure_reason !== undefined) {
|
|
233
|
+
where.push("pass2b_failure_reason LIKE @reason");
|
|
234
|
+
params.reason = `%${filters.failure_reason}%`;
|
|
235
|
+
}
|
|
236
|
+
// `project` filter is intentionally NOT implemented yet — quarantine entries
|
|
237
|
+
// don't carry a project column. If we need this, add a project column to the
|
|
238
|
+
// entry shape (Pass 2a does emit a project — pipe it through). Defer until
|
|
239
|
+
// there's a real use case.
|
|
240
|
+
const whereSql = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
|
|
241
|
+
const rows = db.prepare(`SELECT * FROM pass2_audit_quarantine ${whereSql} ORDER BY quarantined_at DESC`).all(params);
|
|
242
|
+
return rows.map(rowToEntry);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Count quarantine entries — cheap aggregate for the tier-based signal monitor
|
|
246
|
+
* referenced in §3. Returns total + grouped-by-failure_reason for composition
|
|
247
|
+
* analysis.
|
|
248
|
+
*
|
|
249
|
+
* NOTE: this is the lowest-level primitive. Tier interpretation (Watch / Notice
|
|
250
|
+
* / Investigate / Rollback per §3) lives in the telemetry layer, not here.
|
|
251
|
+
*/
|
|
252
|
+
export function summarizeQuarantine(db) {
|
|
253
|
+
const total = db.prepare(`SELECT COUNT(*) AS n FROM pass2_audit_quarantine`).get().n;
|
|
254
|
+
const byReason = db.prepare(`
|
|
255
|
+
SELECT pass2b_failure_reason AS reason, COUNT(*) AS n
|
|
256
|
+
FROM pass2_audit_quarantine
|
|
257
|
+
GROUP BY pass2b_failure_reason
|
|
258
|
+
ORDER BY n DESC
|
|
259
|
+
`).all();
|
|
260
|
+
const bySession = db.prepare(`
|
|
261
|
+
SELECT source_session_id AS session_id, COUNT(*) AS n
|
|
262
|
+
FROM pass2_audit_quarantine
|
|
263
|
+
GROUP BY source_session_id
|
|
264
|
+
ORDER BY n DESC
|
|
265
|
+
`).all();
|
|
266
|
+
return {
|
|
267
|
+
total,
|
|
268
|
+
by_failure_reason: byReason.map((r) => ({ reason: r.reason, count: r.n })),
|
|
269
|
+
by_session: bySession.map((r) => ({ session_id: r.session_id, count: r.n })),
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=pass2-quarantine.js.map
|