@tyroneross/build-loop 0.30.3
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/.agents/plugins/marketplace.json +10 -0
- package/.claude-plugin/marketplace.json +38 -0
- package/.claude-plugin/plugin.json +30 -0
- package/.codex-plugin/plugin.json +41 -0
- package/.cursor/rules/build-loop-surface.mdc +22 -0
- package/AGENTS.md +498 -0
- package/LICENSE +202 -0
- package/README.md +403 -0
- package/agents/alignment-checker.md +124 -0
- package/agents/api-assessor.md +136 -0
- package/agents/architecture-scout.md +185 -0
- package/agents/assessment-orchestrator.md +163 -0
- package/agents/build-orchestrator.md +198 -0
- package/agents/database-assessor.md +133 -0
- package/agents/design-contract-specialist.md +239 -0
- package/agents/fact-checker.md +69 -0
- package/agents/fix-critique.md +161 -0
- package/agents/frontend-assessor.md +136 -0
- package/agents/implementer.md +185 -0
- package/agents/independent-auditor.md +143 -0
- package/agents/mock-scanner.md +78 -0
- package/agents/optimize-runner.md +112 -0
- package/agents/overfitting-reviewer.md +96 -0
- package/agents/performance-assessor.md +159 -0
- package/agents/plan-critic.md +85 -0
- package/agents/promotion-reviewer.md +121 -0
- package/agents/recurring-pattern-detector.md +248 -0
- package/agents/retrospective-synthesizer.md +109 -0
- package/agents/root-cause-investigator.md +285 -0
- package/agents/scope-auditor.md +121 -0
- package/agents/security-reviewer.md +151 -0
- package/agents/self-improvement-architect.md +125 -0
- package/agents/synthesis-critic.md +99 -0
- package/agents/transcript-pattern-miner.md +165 -0
- package/agents/ui-validator.md +193 -0
- package/codex-skills/build-loop/SKILL.md +20 -0
- package/codex-skills/debug-loop/SKILL.md +18 -0
- package/codex-skills/handoff/SKILL.md +22 -0
- package/codex-skills/knowledge/SKILL.md +21 -0
- package/codex-skills/optimize/SKILL.md +18 -0
- package/codex-skills/research/SKILL.md +18 -0
- package/commands/agent-rally-point.md +301 -0
- package/commands/assess.md +41 -0
- package/commands/debug.md +20 -0
- package/commands/debugger-detail.md +34 -0
- package/commands/debugger-scan.md +15 -0
- package/commands/debugger-status.md +20 -0
- package/commands/debugger.md +32 -0
- package/commands/handoff.md +113 -0
- package/commands/knowledge-review.md +16 -0
- package/commands/optimize.md +31 -0
- package/commands/plan-verify.md +39 -0
- package/commands/promote-experiment.md +129 -0
- package/commands/research.md +22 -0
- package/commands/run.md +12 -0
- package/commands/self-review.md +51 -0
- package/commands/start-prd.md +57 -0
- package/commands/test.md +34 -0
- package/dist/src/assessment-orchestrator.d.ts +78 -0
- package/dist/src/assessment-orchestrator.d.ts.map +1 -0
- package/dist/src/assessment-orchestrator.js +304 -0
- package/dist/src/assessment-orchestrator.js.map +1 -0
- package/dist/src/audit-miner.d.ts +21 -0
- package/dist/src/audit-miner.d.ts.map +1 -0
- package/dist/src/audit-miner.js +421 -0
- package/dist/src/audit-miner.js.map +1 -0
- package/dist/src/batch-operations.d.ts +30 -0
- package/dist/src/batch-operations.d.ts.map +1 -0
- package/dist/src/batch-operations.js +339 -0
- package/dist/src/batch-operations.js.map +1 -0
- package/dist/src/config.d.ts +83 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +176 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/context-engine.d.ts +45 -0
- package/dist/src/context-engine.d.ts.map +1 -0
- package/dist/src/context-engine.js +135 -0
- package/dist/src/context-engine.js.map +1 -0
- package/dist/src/debug-wrapper.d.ts +58 -0
- package/dist/src/debug-wrapper.d.ts.map +1 -0
- package/dist/src/debug-wrapper.js +285 -0
- package/dist/src/debug-wrapper.js.map +1 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +149 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interactive-verifier.d.ts +26 -0
- package/dist/src/interactive-verifier.d.ts.map +1 -0
- package/dist/src/interactive-verifier.js +435 -0
- package/dist/src/interactive-verifier.js.map +1 -0
- package/dist/src/lessons.d.ts +59 -0
- package/dist/src/lessons.d.ts.map +1 -0
- package/dist/src/lessons.js +172 -0
- package/dist/src/lessons.js.map +1 -0
- package/dist/src/log-reader.d.ts +39 -0
- package/dist/src/log-reader.d.ts.map +1 -0
- package/dist/src/log-reader.js +291 -0
- package/dist/src/log-reader.js.map +1 -0
- package/dist/src/logger.d.ts +59 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +328 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/parallel-retrieval.d.ts +52 -0
- package/dist/src/parallel-retrieval.d.ts.map +1 -0
- package/dist/src/parallel-retrieval.js +309 -0
- package/dist/src/parallel-retrieval.js.map +1 -0
- package/dist/src/pattern-extractor.d.ts +30 -0
- package/dist/src/pattern-extractor.d.ts.map +1 -0
- package/dist/src/pattern-extractor.js +386 -0
- package/dist/src/pattern-extractor.js.map +1 -0
- package/dist/src/result-aggregator.d.ts +44 -0
- package/dist/src/result-aggregator.d.ts.map +1 -0
- package/dist/src/result-aggregator.js +315 -0
- package/dist/src/result-aggregator.js.map +1 -0
- package/dist/src/retrieval.d.ts +139 -0
- package/dist/src/retrieval.d.ts.map +1 -0
- package/dist/src/retrieval.js +724 -0
- package/dist/src/retrieval.js.map +1 -0
- package/dist/src/setup/auto-setup.d.ts +15 -0
- package/dist/src/setup/auto-setup.d.ts.map +1 -0
- package/dist/src/setup/auto-setup.js +157 -0
- package/dist/src/setup/auto-setup.js.map +1 -0
- package/dist/src/setup/configure-hooks.d.ts +8 -0
- package/dist/src/setup/configure-hooks.d.ts.map +1 -0
- package/dist/src/setup/configure-hooks.js +16 -0
- package/dist/src/setup/configure-hooks.js.map +1 -0
- package/dist/src/setup/create-slash-commands.d.ts +8 -0
- package/dist/src/setup/create-slash-commands.d.ts.map +1 -0
- package/dist/src/setup/create-slash-commands.js +101 -0
- package/dist/src/setup/create-slash-commands.js.map +1 -0
- package/dist/src/setup/index.d.ts +8 -0
- package/dist/src/setup/index.d.ts.map +1 -0
- package/dist/src/setup/index.js +17 -0
- package/dist/src/setup/index.js.map +1 -0
- package/dist/src/setup/inject-claude-md.d.ts +10 -0
- package/dist/src/setup/inject-claude-md.d.ts.map +1 -0
- package/dist/src/setup/inject-claude-md.js +150 -0
- package/dist/src/setup/inject-claude-md.js.map +1 -0
- package/dist/src/setup/uninstall.d.ts +22 -0
- package/dist/src/setup/uninstall.d.ts.map +1 -0
- package/dist/src/setup/uninstall.js +235 -0
- package/dist/src/setup/uninstall.js.map +1 -0
- package/dist/src/storage.d.ts +192 -0
- package/dist/src/storage.d.ts.map +1 -0
- package/dist/src/storage.js +1037 -0
- package/dist/src/storage.js.map +1 -0
- package/dist/src/string-similarity.d.ts +8 -0
- package/dist/src/string-similarity.d.ts.map +1 -0
- package/dist/src/string-similarity.js +57 -0
- package/dist/src/string-similarity.js.map +1 -0
- package/dist/src/traces/adapters/browser.d.ts +69 -0
- package/dist/src/traces/adapters/browser.d.ts.map +1 -0
- package/dist/src/traces/adapters/browser.js +280 -0
- package/dist/src/traces/adapters/browser.js.map +1 -0
- package/dist/src/traces/adapters/index.d.ts +23 -0
- package/dist/src/traces/adapters/index.d.ts.map +1 -0
- package/dist/src/traces/adapters/index.js +67 -0
- package/dist/src/traces/adapters/index.js.map +1 -0
- package/dist/src/traces/adapters/langchain.d.ts +42 -0
- package/dist/src/traces/adapters/langchain.d.ts.map +1 -0
- package/dist/src/traces/adapters/langchain.js +151 -0
- package/dist/src/traces/adapters/langchain.js.map +1 -0
- package/dist/src/traces/adapters/opentelemetry.d.ts +46 -0
- package/dist/src/traces/adapters/opentelemetry.d.ts.map +1 -0
- package/dist/src/traces/adapters/opentelemetry.js +164 -0
- package/dist/src/traces/adapters/opentelemetry.js.map +1 -0
- package/dist/src/traces/adapters/sentry.d.ts +58 -0
- package/dist/src/traces/adapters/sentry.d.ts.map +1 -0
- package/dist/src/traces/adapters/sentry.js +212 -0
- package/dist/src/traces/adapters/sentry.js.map +1 -0
- package/dist/src/traces/index.d.ts +10 -0
- package/dist/src/traces/index.d.ts.map +1 -0
- package/dist/src/traces/index.js +45 -0
- package/dist/src/traces/index.js.map +1 -0
- package/dist/src/traces/storage.d.ts +78 -0
- package/dist/src/traces/storage.d.ts.map +1 -0
- package/dist/src/traces/storage.js +399 -0
- package/dist/src/traces/storage.js.map +1 -0
- package/dist/src/traces/summarizer.d.ts +83 -0
- package/dist/src/traces/summarizer.d.ts.map +1 -0
- package/dist/src/traces/summarizer.js +247 -0
- package/dist/src/traces/summarizer.js.map +1 -0
- package/dist/src/traces/types.d.ts +365 -0
- package/dist/src/traces/types.d.ts.map +1 -0
- package/dist/src/traces/types.js +14 -0
- package/dist/src/traces/types.js.map +1 -0
- package/dist/src/types.d.ts +495 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +27 -0
- package/dist/src/types.js.map +1 -0
- package/docs/agent-surface-policy.md +45 -0
- package/docs/memory-setup.md +226 -0
- package/hooks/_arch_scan_bg.py +88 -0
- package/hooks/_plugin_drift_check_bg.py +85 -0
- package/hooks/_session_start_lib.sh +42 -0
- package/hooks/git/pre-push +141 -0
- package/hooks/hooks.json +126 -0
- package/hooks/post-commit +30 -0
- package/hooks/pre-commit +29 -0
- package/hooks/pre-edit-apppulse.sh +6 -0
- package/hooks/pre-edit-architecture.sh +106 -0
- package/hooks/pre-edit-rally-point.sh +92 -0
- package/hooks/session-start-apppulse.sh +6 -0
- package/hooks/session-start-architecture.sh +10 -0
- package/hooks/session-start-git-hooks.sh +12 -0
- package/hooks/session-start-plugin-drift.sh +27 -0
- package/hooks/session-start-rally-point.sh +44 -0
- package/hooks/session-start-retrieval.sh +24 -0
- package/hooks/session-start-worktree-gc.sh +105 -0
- package/hooks/test_apppulse_hooks.sh +6 -0
- package/hooks/test_rally_point_hooks.sh +388 -0
- package/hooks/test_sec008_hooks.sh +66 -0
- package/package.json +111 -0
- package/scripts/README.md +301 -0
- package/scripts/_db_url.py +61 -0
- package/scripts/_paths.py +445 -0
- package/scripts/blm.py +162 -0
- package/scripts/blm_api.py +263 -0
- package/scripts/check_cache_sync.py +490 -0
- package/scripts/embed_backend.py +475 -0
- package/scripts/install_memory.py +556 -0
- package/scripts/lessons_index/__init__.py +77 -0
- package/scripts/lessons_index/__main__.py +135 -0
- package/scripts/lessons_index/ingest.py +288 -0
- package/scripts/lessons_index/query.py +285 -0
- package/scripts/lessons_index/schema.py +114 -0
- package/scripts/memory_context/__init__.py +610 -0
- package/scripts/memory_graph/__init__.py +393 -0
- package/scripts/project_resolver.py +172 -0
- package/scripts/prune_codex_plugin_cache.py +23 -0
- package/scripts/prune_plugin_cache.py +359 -0
- package/scripts/semantic_index/__init__.py +482 -0
- package/scripts/semantic_index/_bench_hybrid.py +175 -0
- package/scripts/semantic_index/backfill.py +263 -0
- package/scripts/semantic_index/hybrid.py +174 -0
- package/scripts/semantic_index/test_backfill.py +292 -0
- package/scripts/semantic_index/test_hybrid.py +541 -0
- package/scripts/sync_navgator_lessons.py +666 -0
- package/scripts/sync_plugin_cache.py +388 -0
- package/skills/agent-rally-point/SKILL.md +165 -0
- package/skills/agent-rally-watcher/SKILL.md +83 -0
- package/skills/api-registry-bridge/SKILL.md +59 -0
- package/skills/architecture/dead/SKILL.md +56 -0
- package/skills/architecture/impact/SKILL.md +88 -0
- package/skills/architecture/review/SKILL.md +227 -0
- package/skills/architecture/rules/SKILL.md +72 -0
- package/skills/architecture/scan/SKILL.md +79 -0
- package/skills/architecture/trace/SKILL.md +65 -0
- package/skills/attribution-standard/SKILL.md +122 -0
- package/skills/authentication/SKILL.md +81 -0
- package/skills/authentication/references/better-auth-magic-link.md +135 -0
- package/skills/authentication/references/better-auth-setup.md +224 -0
- package/skills/authentication/references/google-calendar-sync.md +278 -0
- package/skills/authentication/references/google-cloud-console.md +159 -0
- package/skills/authentication/references/google-geocoding-directions.md +126 -0
- package/skills/authentication/references/google-lessons-example-web-app.md +177 -0
- package/skills/authentication/references/google-maps.md +162 -0
- package/skills/authentication/references/google-oauth-setup.md +343 -0
- package/skills/authentication/references/google-places.md +173 -0
- package/skills/authentication/references/lessons-example-web-app-better-auth.md +126 -0
- package/skills/authentication/references/resend-email.md +227 -0
- package/skills/authentication/references/resend-otp-magic-link.md +153 -0
- package/skills/authentication/references/supabase-auth.md +172 -0
- package/skills/auto-decision-capture/SKILL.md +419 -0
- package/skills/build-loop/SKILL.md +516 -0
- package/skills/build-loop/detect-plugins.mjs +82 -0
- package/skills/build-loop/eval-guide.md +65 -0
- package/skills/build-loop/fallbacks.md +549 -0
- package/skills/build-loop/phases/fact-check.md +42 -0
- package/skills/build-loop/phases/ui-validation.md +267 -0
- package/skills/build-loop/references/apple-native-planning.md +439 -0
- package/skills/build-loop/references/capability-routing.md +181 -0
- package/skills/build-loop/references/codex-subagents.md +98 -0
- package/skills/build-loop/references/coordination.md +161 -0
- package/skills/build-loop/references/correction-aware-capture.md +177 -0
- package/skills/build-loop/references/independent-auditor.md +72 -0
- package/skills/build-loop/references/intent-capability-pack.md +170 -0
- package/skills/build-loop/references/intent-exploration-prompts.md +96 -0
- package/skills/build-loop/references/leadership.md +72 -0
- package/skills/build-loop/references/memory.md +284 -0
- package/skills/build-loop/references/modular-systems-pack.md +96 -0
- package/skills/build-loop/references/output-style.md +129 -0
- package/skills/build-loop/references/pay-it-forward-arch.md +98 -0
- package/skills/build-loop/references/phase-1-assess.md +218 -0
- package/skills/build-loop/references/phase-2-plan.md +77 -0
- package/skills/build-loop/references/phase-3-execute.md +47 -0
- package/skills/build-loop/references/phase-4-review.md +310 -0
- package/skills/build-loop/references/phase-5-iterate.md +71 -0
- package/skills/build-loop/references/phase-6-learn.md +56 -0
- package/skills/build-loop/references/recent-design-structures.md +274 -0
- package/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
- package/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
- package/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
- package/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
- package/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
- package/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
- package/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
- package/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
- package/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
- package/skills/build-loop/references/self-recursive-dev.md +77 -0
- package/skills/build-loop/references/self-review.md +232 -0
- package/skills/build-loop/references/ui-io-contract.md +116 -0
- package/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
- package/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
- package/skills/build-loop/templates/backlog-item.md +35 -0
- package/skills/build-loop/templates/codex-worker-prompt.md +89 -0
- package/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
- package/skills/build-loop/templates/ux-fix-plan.md +40 -0
- package/skills/building-with-deepagents/SKILL.md +195 -0
- package/skills/building-with-deepagents/references/anti-patterns.md +141 -0
- package/skills/building-with-deepagents/references/api-quick-reference.md +184 -0
- package/skills/capabilities/SKILL.md +91 -0
- package/skills/debug-loop/SKILL.md +278 -0
- package/skills/debug-loop/references/convergence-rules.md +145 -0
- package/skills/debug-loop/references/swiftui-macos-clunky-ui-debugger.html +823 -0
- package/skills/debugging/assess/SKILL.md +111 -0
- package/skills/debugging/debug-loop/SKILL.md +231 -0
- package/skills/debugging/memory/SKILL.md +147 -0
- package/skills/debugging/store/SKILL.md +153 -0
- package/skills/debugging-memory/SKILL.md +440 -0
- package/skills/debugging-memory/examples/incident-example.json +67 -0
- package/skills/debugging-memory/references/incident-documentation.md +280 -0
- package/skills/debugging-memory/references/ios-notification-alarm-playbook.md +300 -0
- package/skills/debugging-memory/references/pattern-extraction.md +163 -0
- package/skills/debugging-memory/references/subagent-integration.md +312 -0
- package/skills/defenseclaw-bridge/SKILL.md +156 -0
- package/skills/defenseclaw-bridge/references/dc-config-mapping.md +162 -0
- package/skills/defenseclaw-bridge/references/output-format.md +108 -0
- package/skills/handoff/SKILL.md +94 -0
- package/skills/ibr-bridge/SKILL.md +68 -0
- package/skills/knowledge/SKILL.md +127 -0
- package/skills/knowledge/references/recall-integration.md +83 -0
- package/skills/knowledge/templates/madr-minimal.md +56 -0
- package/skills/knowledge-review/SKILL.md +112 -0
- package/skills/logging-tracer/SKILL.md +202 -0
- package/skills/logging-tracer/references/log-analysis.md +128 -0
- package/skills/logging-tracer/references/stack-templates.md +274 -0
- package/skills/logging-tracer-bridge/SKILL.md +70 -0
- package/skills/mcp-builder/SKILL.md +278 -0
- package/skills/mcp-builder/references/mcp-security.md +106 -0
- package/skills/model-tiering/SKILL.md +216 -0
- package/skills/native-ax-driver/SKILL.md +220 -0
- package/skills/native-ax-driver/scripts/layout_fill.py +222 -0
- package/skills/native-ax-driver/scripts/native_driver.py +495 -0
- package/skills/native-ax-driver/swift/bl-ax-driver/Package.swift +20 -0
- package/skills/native-ax-driver/swift/bl-ax-driver/Sources/main.swift +542 -0
- package/skills/optimize/SKILL.md +202 -0
- package/skills/optimize/profiles.md +61 -0
- package/skills/plan-verify/SKILL.md +115 -0
- package/skills/plan-verify/test-fixtures/example-app-v20-findings.json +27 -0
- package/skills/plan-verify/test-fixtures/example-app-v20.md +42 -0
- package/skills/plan-verify/test-fixtures/example-app-v22-findings.json +15 -0
- package/skills/plan-verify/test-fixtures/example-app-v22.md +1608 -0
- package/skills/plan-verify/test-fixtures/unrelated-good-plan-findings.json +15 -0
- package/skills/plan-verify/test-fixtures/unrelated-good-plan.md +55 -0
- package/skills/plugin-builder/SKILL.md +329 -0
- package/skills/plugin-builder/references/authoritative-sources.md +104 -0
- package/skills/plugin-builder/references/build-loop-phase-guidance.md +94 -0
- package/skills/plugin-builder/references/components-guide.md +221 -0
- package/skills/plugin-builder/references/distribution.md +317 -0
- package/skills/plugin-builder/references/dual-host-claude-codex.md +220 -0
- package/skills/plugin-builder/references/hooks-reference.md +210 -0
- package/skills/plugin-builder/references/manifest-schema.md +111 -0
- package/skills/plugin-builder/references/plugin-hygiene-lessons.md +307 -0
- package/skills/plugin-tests/SKILL.md +94 -0
- package/skills/prd-bridge/SKILL.md +135 -0
- package/skills/research/SKILL.md +80 -0
- package/skills/security-methodology/SKILL.md +105 -0
- package/skills/security-methodology/references/cross-source-matrix.md +77 -0
- package/skills/security-methodology/references/mitre-atlas-starter.md +83 -0
- package/skills/security-methodology/references/nist-600-1-mapping.md +119 -0
- package/skills/security-methodology/references/owasp-agentic-top-10.md +157 -0
- package/skills/security-methodology/references/owasp-llm-top-10.md +144 -0
- package/skills/security-methodology/references/owasp-web-top-10.md +65 -0
- package/skills/self-improve/SKILL.md +298 -0
- package/skills/spec-writing/SKILL.md +548 -0
- package/skills/spec-writing/scripts/check_checklist.py +478 -0
- package/skills/sync-skills/SKILL.md +132 -0
- package/skills/telemetry/SKILL.md +66 -0
- package/skills/ui-design/SKILL.md +75 -0
- package/skills/ui-design/references/design-patterns-multi.md +165 -0
- package/skills/ui-design/references/design-preferences-from-owned-apps.md +150 -0
- package/skills/ui-design/references/evidence-capture-policy.md +55 -0
- package/skills/ui-design/references/ui-guidance-sources.md +330 -0
- package/skills/ui-design/references/universal-design-principles.alt.md +182 -0
- package/skills/ui-design/references/universal-design-principles.md +419 -0
- package/templates/memory/MEMORY.md.template +55 -0
- package/templates/memory/constitution.md.template +64 -0
- package/templates/memory/manifest.json +47 -0
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
/**
|
|
5
|
+
* Debugging Memory System - Retrieval Layer
|
|
6
|
+
*
|
|
7
|
+
* Finds similar incidents and patterns based on symptom description.
|
|
8
|
+
* Uses multi-strategy search: exact → tag → fuzzy → semantic (optional).
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.checkMemory = checkMemory;
|
|
45
|
+
exports.getFullIncident = getFullIncident;
|
|
46
|
+
exports.searchByTags = searchByTags;
|
|
47
|
+
exports.getRecentIncidents = getRecentIncidents;
|
|
48
|
+
exports.enhancedSearch = enhancedSearch;
|
|
49
|
+
exports.checkMemoryTiered = checkMemoryTiered;
|
|
50
|
+
exports.quickMemoryCheck = quickMemoryCheck;
|
|
51
|
+
exports.getIncidentDetails = getIncidentDetails;
|
|
52
|
+
exports.getPatternDetails = getPatternDetails;
|
|
53
|
+
exports.estimateTokensForTier = estimateTokensForTier;
|
|
54
|
+
exports.classifyVerdict = classifyVerdict;
|
|
55
|
+
exports.checkMemoryWithVerdict = checkMemoryWithVerdict;
|
|
56
|
+
exports.checkMemoryProgressive = checkMemoryProgressive;
|
|
57
|
+
exports.checkMemoryScaled = checkMemoryScaled;
|
|
58
|
+
const storage_1 = require("./storage");
|
|
59
|
+
const string_similarity_1 = require("./string-similarity");
|
|
60
|
+
const logger_1 = require("./logger");
|
|
61
|
+
/**
|
|
62
|
+
* Default retrieval configuration
|
|
63
|
+
*/
|
|
64
|
+
const DEFAULT_CONFIG = {
|
|
65
|
+
similarity_threshold: 0.5, // 50% similarity minimum (keyword-based matching)
|
|
66
|
+
max_results: 5, // Top 5 results
|
|
67
|
+
temporal_preference: 90, // Prefer last 90 days
|
|
68
|
+
include_unvalidated: true // Include unvalidated (guardian rarely runs in this project)
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Check memory for similar incidents
|
|
72
|
+
*
|
|
73
|
+
* This is the main entry point for memory retrieval.
|
|
74
|
+
*/
|
|
75
|
+
async function checkMemory(symptom, config = {}) {
|
|
76
|
+
return (0, logger_1.traced)('retrieval:checkMemory', { symptom: symptom.slice(0, 100) }, async () => {
|
|
77
|
+
const { memoryConfig, ...retrievalConfig } = config;
|
|
78
|
+
const fullConfig = { ...DEFAULT_CONFIG, ...retrievalConfig };
|
|
79
|
+
console.log(`🧠 Checking memory for: "${symptom.substring(0, 50)}..."`);
|
|
80
|
+
// Step 1: Try to match patterns first (most efficient)
|
|
81
|
+
const patterns = await matchPatterns(symptom, fullConfig, memoryConfig);
|
|
82
|
+
if (patterns.length > 0) {
|
|
83
|
+
console.log(`✅ Found ${patterns.length} matching patterns`);
|
|
84
|
+
return {
|
|
85
|
+
incidents: [],
|
|
86
|
+
patterns,
|
|
87
|
+
confidence: 0.9, // High confidence if pattern matches
|
|
88
|
+
retrieval_method: 'pattern',
|
|
89
|
+
tokens_used: estimateTokens(patterns)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Step 2: No patterns, search incidents
|
|
93
|
+
const incidents = await searchIncidents(symptom, fullConfig, memoryConfig);
|
|
94
|
+
console.log(`✅ Found ${incidents.length} similar incidents`);
|
|
95
|
+
return {
|
|
96
|
+
incidents,
|
|
97
|
+
patterns: [],
|
|
98
|
+
confidence: incidents.length > 0 ? 0.7 : 0.0,
|
|
99
|
+
retrieval_method: 'incident',
|
|
100
|
+
tokens_used: estimateTokens(incidents)
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Match patterns based on symptom
|
|
106
|
+
*/
|
|
107
|
+
async function matchPatterns(symptom, config, memoryConfig) {
|
|
108
|
+
const allPatterns = await (0, storage_1.loadAllPatterns)(memoryConfig);
|
|
109
|
+
const symptomLower = symptom.toLowerCase();
|
|
110
|
+
const symptomWords = extractKeywords(symptomLower);
|
|
111
|
+
const scored = allPatterns.map(pattern => {
|
|
112
|
+
// Check detection signatures
|
|
113
|
+
const signatureMatches = pattern.detection_signature.filter(sig => symptomWords.some(word => sig.toLowerCase().includes(word))).length;
|
|
114
|
+
// Check tags
|
|
115
|
+
const patternTags = pattern.tags ?? [];
|
|
116
|
+
const tagMatches = patternTags.filter(tag => symptomWords.includes(tag.toLowerCase())).length;
|
|
117
|
+
// Calculate score
|
|
118
|
+
const score = (signatureMatches / Math.max(pattern.detection_signature.length, 1)) * 0.7 +
|
|
119
|
+
(tagMatches / Math.max(patternTags.length, 1)) * 0.3;
|
|
120
|
+
return { pattern, score };
|
|
121
|
+
});
|
|
122
|
+
// Filter and sort
|
|
123
|
+
return scored
|
|
124
|
+
.filter(item => item.score >= config.similarity_threshold)
|
|
125
|
+
.sort((a, b) => b.score - a.score)
|
|
126
|
+
.slice(0, config.max_results)
|
|
127
|
+
.map(item => item.pattern);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Search for similar incidents
|
|
131
|
+
*/
|
|
132
|
+
async function searchIncidents(symptom, config, memoryConfig) {
|
|
133
|
+
const allIncidents = await (0, storage_1.loadAllIncidents)(memoryConfig);
|
|
134
|
+
const symptomLower = symptom.toLowerCase();
|
|
135
|
+
const symptomWords = extractKeywords(symptomLower);
|
|
136
|
+
const now = Date.now();
|
|
137
|
+
const temporalCutoff = now - (config.temporal_preference || 90) * 24 * 60 * 60 * 1000;
|
|
138
|
+
const scored = allIncidents.map(incident => {
|
|
139
|
+
// Skip unvalidated if configured
|
|
140
|
+
if (!config.include_unvalidated &&
|
|
141
|
+
incident.quality_gates &&
|
|
142
|
+
!incident.quality_gates.guardian_validated) {
|
|
143
|
+
return { incident, score: 0 };
|
|
144
|
+
}
|
|
145
|
+
// Skip incidents without valid symptom
|
|
146
|
+
if (!incident.symptom || typeof incident.symptom !== 'string') {
|
|
147
|
+
return { incident, score: 0 };
|
|
148
|
+
}
|
|
149
|
+
// Calculate similarity
|
|
150
|
+
const symptomSimilarity = calculateKeywordSimilarity(symptomWords, extractKeywords(incident.symptom.toLowerCase()));
|
|
151
|
+
// Tag similarity with bidirectional matching
|
|
152
|
+
const incidentTagWords = (incident.tags ?? []).flatMap(tag => tag.toLowerCase().split(/\s+/));
|
|
153
|
+
const tagMatches = symptomWords.filter(word => incidentTagWords.some(tagWord => tagWord.includes(word) || word.includes(tagWord))).length;
|
|
154
|
+
const tagSimilarity = tagMatches / Math.max(symptomWords.length, 1);
|
|
155
|
+
// Temporal boost (prefer recent)
|
|
156
|
+
const age = now - incident.timestamp;
|
|
157
|
+
const temporalBoost = age < temporalCutoff ? 1.2 : 1.0;
|
|
158
|
+
// Weight: 60% symptom keywords, 40% tags (tags are more semantic)
|
|
159
|
+
const score = (symptomSimilarity * 0.6 + tagSimilarity * 0.4) * temporalBoost;
|
|
160
|
+
return { incident, score };
|
|
161
|
+
});
|
|
162
|
+
// Filter and sort
|
|
163
|
+
const results = scored
|
|
164
|
+
.filter(item => item.score >= config.similarity_threshold)
|
|
165
|
+
.sort((a, b) => b.score - a.score)
|
|
166
|
+
.slice(0, config.max_results)
|
|
167
|
+
.map(item => ({ ...item.incident, similarity_score: item.score }));
|
|
168
|
+
return results;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Calculate keyword-based similarity
|
|
172
|
+
*/
|
|
173
|
+
function calculateKeywordSimilarity(words1, words2) {
|
|
174
|
+
if (words1.length === 0 || words2.length === 0)
|
|
175
|
+
return 0;
|
|
176
|
+
const set1 = new Set(words1);
|
|
177
|
+
const set2 = new Set(words2);
|
|
178
|
+
const intersection = new Set([...set1].filter(x => set2.has(x)));
|
|
179
|
+
const union = new Set([...set1, ...set2]);
|
|
180
|
+
return intersection.size / union.size; // Jaccard similarity
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Extract keywords from text
|
|
184
|
+
*/
|
|
185
|
+
function extractKeywords(text) {
|
|
186
|
+
// Remove common words (simple stop words)
|
|
187
|
+
const stopWords = new Set([
|
|
188
|
+
'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
|
|
189
|
+
'of', 'with', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
190
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'should',
|
|
191
|
+
'can', 'could', 'may', 'might', 'must', 'this', 'that', 'these', 'those'
|
|
192
|
+
]);
|
|
193
|
+
return text
|
|
194
|
+
.toLowerCase()
|
|
195
|
+
.replace(/[^\w\s]/g, ' ') // Remove punctuation
|
|
196
|
+
.split(/\s+/)
|
|
197
|
+
.filter(word => word.length > 2 && !stopWords.has(word));
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Estimate token usage for context injection
|
|
201
|
+
*/
|
|
202
|
+
function estimateTokens(items) {
|
|
203
|
+
// Rough estimate: 4 chars ≈ 1 token
|
|
204
|
+
const totalChars = items.reduce((sum, item) => {
|
|
205
|
+
return sum + JSON.stringify(item).length;
|
|
206
|
+
}, 0);
|
|
207
|
+
return Math.ceil(totalChars / 4);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get full incident details (for lazy loading)
|
|
211
|
+
*/
|
|
212
|
+
async function getFullIncident(incident_id) {
|
|
213
|
+
const { loadIncident } = await Promise.resolve().then(() => __importStar(require('./storage')));
|
|
214
|
+
return loadIncident(incident_id);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Simple search by tags
|
|
218
|
+
*/
|
|
219
|
+
async function searchByTags(tags, config) {
|
|
220
|
+
const allIncidents = await (0, storage_1.loadAllIncidents)(config);
|
|
221
|
+
return allIncidents.filter(incident => tags.some(tag => (incident.tags ?? []).includes(tag)));
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get recent incidents
|
|
225
|
+
*/
|
|
226
|
+
async function getRecentIncidents(days = 7, config) {
|
|
227
|
+
const allIncidents = await (0, storage_1.loadAllIncidents)(config);
|
|
228
|
+
const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;
|
|
229
|
+
return allIncidents
|
|
230
|
+
.filter(incident => incident.timestamp >= cutoff)
|
|
231
|
+
.sort((a, b) => b.timestamp - a.timestamp);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Enhanced multi-strategy search
|
|
235
|
+
*
|
|
236
|
+
* Strategy order: exact → tag → fuzzy → category
|
|
237
|
+
* Each strategy adds results with appropriate confidence scores
|
|
238
|
+
*/
|
|
239
|
+
async function enhancedSearch(query, options) {
|
|
240
|
+
const threshold = options?.threshold ?? 0.5;
|
|
241
|
+
const maxResults = options?.maxResults ?? 10;
|
|
242
|
+
const allIncidents = await (0, storage_1.loadAllIncidents)(options?.memoryConfig);
|
|
243
|
+
if (allIncidents.length === 0) {
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
const queryLower = query.toLowerCase();
|
|
247
|
+
const queryWords = extractKeywords(queryLower);
|
|
248
|
+
const results = [];
|
|
249
|
+
const seenIds = new Set();
|
|
250
|
+
// STRATEGY 1: EXACT MATCH (score: 1.0)
|
|
251
|
+
// Check if symptom description contains query (case-insensitive)
|
|
252
|
+
for (const incident of allIncidents) {
|
|
253
|
+
if (seenIds.has(incident.incident_id))
|
|
254
|
+
continue;
|
|
255
|
+
if (!incident.symptom || typeof incident.symptom !== 'string')
|
|
256
|
+
continue;
|
|
257
|
+
const symptomLower = incident.symptom.toLowerCase();
|
|
258
|
+
if (symptomLower.includes(queryLower)) {
|
|
259
|
+
results.push({
|
|
260
|
+
incident,
|
|
261
|
+
score: 1.0,
|
|
262
|
+
matchType: 'exact',
|
|
263
|
+
highlights: [incident.symptom]
|
|
264
|
+
});
|
|
265
|
+
seenIds.add(incident.incident_id);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// STRATEGY 2: TAG MATCH (score: 0.9)
|
|
269
|
+
// Check if any tags match normalized query
|
|
270
|
+
for (const incident of allIncidents) {
|
|
271
|
+
if (seenIds.has(incident.incident_id))
|
|
272
|
+
continue;
|
|
273
|
+
const incidentTags = incident.tags ?? [];
|
|
274
|
+
const normalizedTags = incidentTags.map(tag => tag.toLowerCase());
|
|
275
|
+
const matchedTags = normalizedTags.filter(tag => queryWords.some(word => tag.includes(word) || word.includes(tag)));
|
|
276
|
+
if (matchedTags.length > 0) {
|
|
277
|
+
results.push({
|
|
278
|
+
incident,
|
|
279
|
+
score: 0.9,
|
|
280
|
+
matchType: 'tag',
|
|
281
|
+
highlights: incidentTags.filter(tag => matchedTags.includes(tag.toLowerCase()))
|
|
282
|
+
});
|
|
283
|
+
seenIds.add(incident.incident_id);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// STRATEGY 3: FUZZY MATCH (score: 0.7-0.85)
|
|
287
|
+
// Use Jaro-Winkler distance for similar strings
|
|
288
|
+
const fuzzyThreshold = 0.7;
|
|
289
|
+
for (const incident of allIncidents) {
|
|
290
|
+
if (seenIds.has(incident.incident_id))
|
|
291
|
+
continue;
|
|
292
|
+
if (!incident.symptom || typeof incident.symptom !== 'string')
|
|
293
|
+
continue;
|
|
294
|
+
const symptomScore = fuzzyMatch(queryLower, incident.symptom.toLowerCase(), fuzzyThreshold);
|
|
295
|
+
const rootCauseDesc = incident.root_cause?.description ?? '';
|
|
296
|
+
const rootCauseScore = rootCauseDesc
|
|
297
|
+
? fuzzyMatch(queryLower, rootCauseDesc.toLowerCase(), fuzzyThreshold)
|
|
298
|
+
: 0;
|
|
299
|
+
const maxScore = Math.max(symptomScore, rootCauseScore);
|
|
300
|
+
if (maxScore >= fuzzyThreshold) {
|
|
301
|
+
const highlight = symptomScore >= rootCauseScore
|
|
302
|
+
? incident.symptom
|
|
303
|
+
: (rootCauseDesc || incident.symptom);
|
|
304
|
+
results.push({
|
|
305
|
+
incident,
|
|
306
|
+
score: maxScore,
|
|
307
|
+
matchType: 'fuzzy',
|
|
308
|
+
highlights: [highlight]
|
|
309
|
+
});
|
|
310
|
+
seenIds.add(incident.incident_id);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// STRATEGY 4: CATEGORY MATCH (score: 0.6)
|
|
314
|
+
// If we have top matches, find similar categories
|
|
315
|
+
if (results.length > 0) {
|
|
316
|
+
const topCategories = new Set(results.slice(0, 3)
|
|
317
|
+
.map(r => r.incident.root_cause?.category)
|
|
318
|
+
.filter(Boolean));
|
|
319
|
+
for (const incident of allIncidents) {
|
|
320
|
+
if (seenIds.has(incident.incident_id))
|
|
321
|
+
continue;
|
|
322
|
+
const category = incident.root_cause?.category;
|
|
323
|
+
if (!category)
|
|
324
|
+
continue;
|
|
325
|
+
if (topCategories.has(category)) {
|
|
326
|
+
results.push({
|
|
327
|
+
incident,
|
|
328
|
+
score: 0.6,
|
|
329
|
+
matchType: 'category',
|
|
330
|
+
highlights: [category]
|
|
331
|
+
});
|
|
332
|
+
seenIds.add(incident.incident_id);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Sort by score descending and return top results
|
|
337
|
+
return results
|
|
338
|
+
.filter(r => r.score >= threshold)
|
|
339
|
+
.sort((a, b) => b.score - a.score)
|
|
340
|
+
.slice(0, maxResults);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Fuzzy string matching using Jaro-Winkler distance
|
|
344
|
+
* Returns score between 0 and 1 if above threshold, 0 otherwise
|
|
345
|
+
*/
|
|
346
|
+
function fuzzyMatch(query, text, threshold) {
|
|
347
|
+
const distance = (0, string_similarity_1.jaroWinklerDistance)(query.toLowerCase(), text.toLowerCase());
|
|
348
|
+
return distance >= threshold ? distance : 0;
|
|
349
|
+
}
|
|
350
|
+
const storage_2 = require("./storage");
|
|
351
|
+
/**
|
|
352
|
+
* Token-optimized memory check with tiered retrieval
|
|
353
|
+
*
|
|
354
|
+
* Tiers:
|
|
355
|
+
* - 'summary': Minimal representation (~100 tokens/incident) for quick scans
|
|
356
|
+
* - 'compact': Short keys, truncated fields (~200 tokens/incident) - DEFAULT
|
|
357
|
+
* - 'full': Complete incident data (~550 tokens/incident) for detailed analysis
|
|
358
|
+
*
|
|
359
|
+
* Token budget enforcement ensures context doesn't exceed limits.
|
|
360
|
+
*/
|
|
361
|
+
async function checkMemoryTiered(symptom, config = {}) {
|
|
362
|
+
const { memoryConfig, tier = 'compact', token_budget = 2500, ...retrievalConfig } = config;
|
|
363
|
+
const fullConfig = { ...DEFAULT_CONFIG, ...retrievalConfig };
|
|
364
|
+
// Get raw results using existing search
|
|
365
|
+
const rawResult = await checkMemory(symptom, { memoryConfig, ...fullConfig });
|
|
366
|
+
// Transform based on tier
|
|
367
|
+
if (tier === 'summary') {
|
|
368
|
+
return transformToSummaryTier(rawResult, token_budget);
|
|
369
|
+
}
|
|
370
|
+
if (tier === 'compact') {
|
|
371
|
+
return transformToCompactTier(rawResult, token_budget);
|
|
372
|
+
}
|
|
373
|
+
// 'full' tier - return as-is with full data
|
|
374
|
+
return {
|
|
375
|
+
confidence: rawResult.confidence,
|
|
376
|
+
tokens_used: rawResult.tokens_used,
|
|
377
|
+
has_more_details: false,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Transform results to summary tier (~100 tokens per incident)
|
|
382
|
+
*/
|
|
383
|
+
function transformToSummaryTier(result, budget) {
|
|
384
|
+
const summaries = result.incidents.map(storage_2.generateIncidentSummary);
|
|
385
|
+
const patternSummaries = result.patterns.map(p => ({
|
|
386
|
+
id: p.pattern_id,
|
|
387
|
+
name: p.name,
|
|
388
|
+
success_rate: p.success_rate,
|
|
389
|
+
}));
|
|
390
|
+
// Estimate tokens (100 per summary, 50 per pattern summary)
|
|
391
|
+
const tokensPerSummary = 100;
|
|
392
|
+
const tokensPerPatternSummary = 50;
|
|
393
|
+
const maxSummaries = Math.floor((budget * 0.6) / tokensPerSummary);
|
|
394
|
+
const maxPatternSummaries = Math.floor((budget * 0.3) / tokensPerPatternSummary);
|
|
395
|
+
const limitedSummaries = summaries.slice(0, maxSummaries);
|
|
396
|
+
const limitedPatternSummaries = patternSummaries.slice(0, maxPatternSummaries);
|
|
397
|
+
const tokensUsed = limitedSummaries.length * tokensPerSummary +
|
|
398
|
+
limitedPatternSummaries.length * tokensPerPatternSummary +
|
|
399
|
+
Math.floor(budget * 0.1);
|
|
400
|
+
return {
|
|
401
|
+
summaries: limitedSummaries,
|
|
402
|
+
pattern_summaries: limitedPatternSummaries,
|
|
403
|
+
confidence: result.confidence,
|
|
404
|
+
tokens_used: tokensUsed,
|
|
405
|
+
has_more_details: true,
|
|
406
|
+
truncated: {
|
|
407
|
+
incidents: summaries.length - limitedSummaries.length,
|
|
408
|
+
patterns: patternSummaries.length - limitedPatternSummaries.length,
|
|
409
|
+
},
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Transform results to compact tier (~200 tokens per incident)
|
|
414
|
+
*/
|
|
415
|
+
function transformToCompactTier(result, budget) {
|
|
416
|
+
// Convert to compact format
|
|
417
|
+
const compactIncidents = result.incidents.map(storage_2.toCompactIncident);
|
|
418
|
+
const compactPatterns = result.patterns.map(storage_2.toCompactPattern);
|
|
419
|
+
// Apply token budget
|
|
420
|
+
const { limitedIncidents, limitedPatterns, tokensUsed, truncated } = (0, storage_2.enforceTokenBudget)(compactIncidents, compactPatterns, budget);
|
|
421
|
+
return {
|
|
422
|
+
incidents: limitedIncidents,
|
|
423
|
+
patterns: limitedPatterns,
|
|
424
|
+
confidence: result.confidence,
|
|
425
|
+
tokens_used: tokensUsed,
|
|
426
|
+
has_more_details: truncated.incidents > 0 || truncated.patterns > 0,
|
|
427
|
+
truncated,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Quick memory check with minimal output
|
|
432
|
+
*
|
|
433
|
+
* Returns only essential fields for rapid assessment.
|
|
434
|
+
* Useful when token budget is very tight.
|
|
435
|
+
*/
|
|
436
|
+
async function quickMemoryCheck(symptom, config) {
|
|
437
|
+
const result = await checkMemoryTiered(symptom, {
|
|
438
|
+
memoryConfig: config?.memoryConfig,
|
|
439
|
+
tier: 'summary',
|
|
440
|
+
token_budget: 500, // Minimal budget
|
|
441
|
+
max_results: config?.maxResults || 3,
|
|
442
|
+
});
|
|
443
|
+
const summaries = result.summaries || [];
|
|
444
|
+
return {
|
|
445
|
+
hasMatches: summaries.length > 0,
|
|
446
|
+
matchCount: summaries.length,
|
|
447
|
+
topMatch: summaries[0]
|
|
448
|
+
? {
|
|
449
|
+
id: summaries[0].incident_id,
|
|
450
|
+
symptom: summaries[0].symptom_preview,
|
|
451
|
+
category: summaries[0].category,
|
|
452
|
+
confidence: summaries[0].confidence,
|
|
453
|
+
}
|
|
454
|
+
: undefined,
|
|
455
|
+
tokensUsed: result.tokens_used,
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Get incident details on demand (lazy loading)
|
|
460
|
+
*
|
|
461
|
+
* Use this when compact/summary tier found a match and full details are needed.
|
|
462
|
+
*/
|
|
463
|
+
async function getIncidentDetails(incident_id, config) {
|
|
464
|
+
const { loadIncident } = await Promise.resolve().then(() => __importStar(require('./storage')));
|
|
465
|
+
return loadIncident(incident_id, config);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Get pattern details on demand (lazy loading)
|
|
469
|
+
*/
|
|
470
|
+
async function getPatternDetails(pattern_id, config) {
|
|
471
|
+
const { loadPattern } = await Promise.resolve().then(() => __importStar(require('./storage')));
|
|
472
|
+
return loadPattern(pattern_id, config);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Estimate token usage for different retrieval tiers
|
|
476
|
+
*/
|
|
477
|
+
function estimateTokensForTier(incidentCount, patternCount, tier) {
|
|
478
|
+
const multipliers = {
|
|
479
|
+
summary: { incident: 100, pattern: 50 },
|
|
480
|
+
compact: { incident: 200, pattern: 120 },
|
|
481
|
+
full: { incident: 550, pattern: 250 },
|
|
482
|
+
};
|
|
483
|
+
const m = multipliers[tier];
|
|
484
|
+
return incidentCount * m.incident + patternCount * m.pattern + 50; // +50 for overhead
|
|
485
|
+
}
|
|
486
|
+
// ============================================================================
|
|
487
|
+
// VERDICT-FIRST RESPONSES - Actionable classification of search results
|
|
488
|
+
// ============================================================================
|
|
489
|
+
/**
|
|
490
|
+
* Classify search results into an actionable verdict
|
|
491
|
+
*
|
|
492
|
+
* Verdicts:
|
|
493
|
+
* - KNOWN_FIX: High-confidence match with verified pattern (>0.8, verified)
|
|
494
|
+
* - LIKELY_MATCH: Good match with relevant incidents (0.5-0.8)
|
|
495
|
+
* - WEAK_SIGNAL: Possible relation, worth reviewing (0.3-0.5)
|
|
496
|
+
* - NO_MATCH: Nothing found, debug fresh
|
|
497
|
+
*/
|
|
498
|
+
function classifyVerdict(result) {
|
|
499
|
+
// Pattern match with high confidence
|
|
500
|
+
if (result.patterns.length > 0 && result.confidence >= 0.8) {
|
|
501
|
+
const hasVerified = result.patterns.some(p => p.success_rate >= 0.7);
|
|
502
|
+
if (hasVerified)
|
|
503
|
+
return 'KNOWN_FIX';
|
|
504
|
+
}
|
|
505
|
+
// Strong incident match
|
|
506
|
+
if (result.confidence >= 0.5) {
|
|
507
|
+
if (result.incidents.length > 0 || result.patterns.length > 0) {
|
|
508
|
+
return 'LIKELY_MATCH';
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
// Weak signal
|
|
512
|
+
if (result.confidence >= 0.3 && (result.incidents.length > 0 || result.patterns.length > 0)) {
|
|
513
|
+
return 'WEAK_SIGNAL';
|
|
514
|
+
}
|
|
515
|
+
return 'NO_MATCH';
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Generate verdict action text
|
|
519
|
+
*/
|
|
520
|
+
function verdictAction(verdict) {
|
|
521
|
+
switch (verdict) {
|
|
522
|
+
case 'KNOWN_FIX': return 'Apply the known fix pattern below';
|
|
523
|
+
case 'LIKELY_MATCH': return 'Review these similar incidents for guidance';
|
|
524
|
+
case 'WEAK_SIGNAL': return 'Consider these loosely related incidents';
|
|
525
|
+
case 'NO_MATCH': return 'No prior knowledge found — debug fresh';
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Generate verdict summary text
|
|
530
|
+
*/
|
|
531
|
+
function verdictSummary(verdict, result) {
|
|
532
|
+
switch (verdict) {
|
|
533
|
+
case 'KNOWN_FIX':
|
|
534
|
+
return `Known fix available (${result.patterns.length} pattern${result.patterns.length > 1 ? 's' : ''}, ${(result.confidence * 100).toFixed(0)}% confidence)`;
|
|
535
|
+
case 'LIKELY_MATCH':
|
|
536
|
+
return `${result.incidents.length} similar incident${result.incidents.length > 1 ? 's' : ''} found (${(result.confidence * 100).toFixed(0)}% confidence)`;
|
|
537
|
+
case 'WEAK_SIGNAL':
|
|
538
|
+
return `${result.incidents.length + result.patterns.length} loosely related result${result.incidents.length + result.patterns.length > 1 ? 's' : ''}`;
|
|
539
|
+
case 'NO_MATCH':
|
|
540
|
+
return 'This appears to be a new type of issue';
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Check memory and return verdict-wrapped results
|
|
545
|
+
*
|
|
546
|
+
* This is the recommended entry point for memory-first debugging.
|
|
547
|
+
* Returns an actionable verdict instead of raw scores.
|
|
548
|
+
*/
|
|
549
|
+
async function checkMemoryWithVerdict(symptom, config = {}) {
|
|
550
|
+
return (0, logger_1.traced)('retrieval:checkMemoryWithVerdict', { symptom: symptom.slice(0, 100) }, async () => {
|
|
551
|
+
const { memoryConfig, ...retrievalConfig } = config;
|
|
552
|
+
const fullConfig = { ...DEFAULT_CONFIG, ...retrievalConfig };
|
|
553
|
+
const result = await checkMemory(symptom, { memoryConfig, ...fullConfig });
|
|
554
|
+
const verdict = classifyVerdict(result);
|
|
555
|
+
const compactIncidents = result.incidents.map(storage_2.toCompactIncident);
|
|
556
|
+
const compactPatterns = result.patterns.map(storage_2.toCompactPattern);
|
|
557
|
+
return {
|
|
558
|
+
verdict,
|
|
559
|
+
summary: verdictSummary(verdict, result),
|
|
560
|
+
confidence: result.confidence,
|
|
561
|
+
incidents: compactIncidents,
|
|
562
|
+
patterns: compactPatterns,
|
|
563
|
+
tokens_used: result.tokens_used,
|
|
564
|
+
action: verdictAction(verdict),
|
|
565
|
+
};
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
// ============================================================================
|
|
569
|
+
// PROGRESSIVE DEPTH - One-liner matches with drill-down
|
|
570
|
+
// ============================================================================
|
|
571
|
+
/**
|
|
572
|
+
* Build a one-liner summary for an incident
|
|
573
|
+
*/
|
|
574
|
+
function buildOneLiner(incident) {
|
|
575
|
+
const cat = incident.root_cause?.category || 'unknown';
|
|
576
|
+
const conf = incident.root_cause?.confidence || 0;
|
|
577
|
+
const sym = (incident.symptom || '').substring(0, 50);
|
|
578
|
+
return `${sym} → ${cat} (${(conf * 100).toFixed(0)}% conf)`;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Build a one-liner summary for a pattern
|
|
582
|
+
*/
|
|
583
|
+
function buildPatternOneLiner(pattern) {
|
|
584
|
+
const sr = (pattern.success_rate * 100).toFixed(0);
|
|
585
|
+
const desc = pattern.description.substring(0, 50);
|
|
586
|
+
return `${desc} (${sr}% success, ${pattern.usage_history?.total_uses || 0} uses)`;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Check memory with progressive depth — returns one-liner matches with drill-down commands
|
|
590
|
+
*
|
|
591
|
+
* Total output stays under 500 tokens even with 10 matches.
|
|
592
|
+
* Use /debugger-detail <ID> to get full incident data on demand.
|
|
593
|
+
*/
|
|
594
|
+
async function checkMemoryProgressive(symptom, config = {}) {
|
|
595
|
+
const { memoryConfig, ...retrievalConfig } = config;
|
|
596
|
+
const fullConfig = { ...DEFAULT_CONFIG, ...retrievalConfig };
|
|
597
|
+
const result = await checkMemory(symptom, { memoryConfig, ...fullConfig });
|
|
598
|
+
const verdict = classifyVerdict(result);
|
|
599
|
+
const matches = [];
|
|
600
|
+
// Patterns first (highest value)
|
|
601
|
+
for (const pattern of result.patterns) {
|
|
602
|
+
matches.push({
|
|
603
|
+
id: pattern.pattern_id,
|
|
604
|
+
type: 'pattern',
|
|
605
|
+
one_liner: buildPatternOneLiner(pattern),
|
|
606
|
+
verdict,
|
|
607
|
+
confidence: pattern.success_rate,
|
|
608
|
+
detail_command: `/debugger-detail ${pattern.pattern_id}`,
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
// Then incidents
|
|
612
|
+
for (const incident of result.incidents) {
|
|
613
|
+
matches.push({
|
|
614
|
+
id: incident.incident_id,
|
|
615
|
+
type: 'incident',
|
|
616
|
+
one_liner: buildOneLiner(incident),
|
|
617
|
+
verdict,
|
|
618
|
+
confidence: incident.similarity_score || incident.root_cause?.confidence || 0,
|
|
619
|
+
detail_command: `/debugger-detail ${incident.incident_id}`,
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
// Estimate tokens (~40 tokens per one-liner match)
|
|
623
|
+
const tokensUsed = matches.length * 40 + 60; // 60 for header/summary
|
|
624
|
+
return {
|
|
625
|
+
verdict,
|
|
626
|
+
summary: verdictSummary(verdict, result),
|
|
627
|
+
matches,
|
|
628
|
+
total_matches: matches.length,
|
|
629
|
+
tokens_used: tokensUsed,
|
|
630
|
+
action: verdictAction(verdict),
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
// ============================================================================
|
|
634
|
+
// SCALED RETRIEVAL - Keyword index for O(log n) instead of O(n) search
|
|
635
|
+
// ============================================================================
|
|
636
|
+
/**
|
|
637
|
+
* Check memory using keyword index for scalable retrieval
|
|
638
|
+
*
|
|
639
|
+
* Instead of loading ALL incidents (O(n) file reads), this:
|
|
640
|
+
* 1. Extracts query keywords
|
|
641
|
+
* 2. Loads keyword index (1 file read)
|
|
642
|
+
* 3. Finds candidate IDs via set intersection
|
|
643
|
+
* 4. Loads only top candidates (max 20 file reads)
|
|
644
|
+
* 5. Scores and ranks
|
|
645
|
+
*
|
|
646
|
+
* Falls back to checkMemory() if keyword index doesn't exist.
|
|
647
|
+
*/
|
|
648
|
+
async function checkMemoryScaled(symptom, config = {}) {
|
|
649
|
+
const { memoryConfig, ...retrievalConfig } = config;
|
|
650
|
+
const fullConfig = { ...DEFAULT_CONFIG, ...retrievalConfig };
|
|
651
|
+
// Load keyword index
|
|
652
|
+
const kwIndex = await (0, storage_2.loadKeywordIndex)(memoryConfig);
|
|
653
|
+
if (!kwIndex || kwIndex.total_incidents < 10) {
|
|
654
|
+
// Too few incidents to benefit from index — use standard path
|
|
655
|
+
return checkMemory(symptom, { memoryConfig, ...fullConfig });
|
|
656
|
+
}
|
|
657
|
+
const queryWords = extractKeywords(symptom.toLowerCase());
|
|
658
|
+
if (queryWords.length === 0) {
|
|
659
|
+
return { incidents: [], patterns: [], confidence: 0, retrieval_method: 'incident', tokens_used: 0 };
|
|
660
|
+
}
|
|
661
|
+
// Find candidates via keyword index (O(1) per keyword)
|
|
662
|
+
const candidateIds = (0, storage_2.findCandidatesByKeyword)(queryWords, kwIndex, 20);
|
|
663
|
+
if (candidateIds.length === 0) {
|
|
664
|
+
// No keyword matches — check patterns via standard path
|
|
665
|
+
const patterns = await matchPatterns(symptom, fullConfig, memoryConfig);
|
|
666
|
+
if (patterns.length > 0) {
|
|
667
|
+
return {
|
|
668
|
+
incidents: [],
|
|
669
|
+
patterns,
|
|
670
|
+
confidence: 0.9,
|
|
671
|
+
retrieval_method: 'pattern',
|
|
672
|
+
tokens_used: estimateTokens(patterns),
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
return { incidents: [], patterns: [], confidence: 0, retrieval_method: 'incident', tokens_used: 0 };
|
|
676
|
+
}
|
|
677
|
+
// Load only candidate incidents (max 20 file reads instead of all)
|
|
678
|
+
const candidateIncidents = [];
|
|
679
|
+
for (const id of candidateIds) {
|
|
680
|
+
const inc = await (0, storage_2.loadIncident)(id, memoryConfig);
|
|
681
|
+
if (inc)
|
|
682
|
+
candidateIncidents.push(inc);
|
|
683
|
+
}
|
|
684
|
+
// Score candidates
|
|
685
|
+
const now = Date.now();
|
|
686
|
+
const temporalCutoff = now - (fullConfig.temporal_preference || 90) * 24 * 60 * 60 * 1000;
|
|
687
|
+
const scored = candidateIncidents.map(incident => {
|
|
688
|
+
if (!incident.symptom || typeof incident.symptom !== 'string') {
|
|
689
|
+
return { incident, score: 0 };
|
|
690
|
+
}
|
|
691
|
+
const symptomSimilarity = calculateKeywordSimilarity(queryWords, extractKeywords(incident.symptom.toLowerCase()));
|
|
692
|
+
const incidentTagWords = (incident.tags ?? []).flatMap(tag => tag.toLowerCase().split(/\s+/));
|
|
693
|
+
const tagMatches = queryWords.filter(word => incidentTagWords.some(tagWord => tagWord.includes(word) || word.includes(tagWord))).length;
|
|
694
|
+
const tagSimilarity = tagMatches / Math.max(queryWords.length, 1);
|
|
695
|
+
const age = now - incident.timestamp;
|
|
696
|
+
const temporalBoost = age < temporalCutoff ? 1.2 : 1.0;
|
|
697
|
+
const score = (symptomSimilarity * 0.6 + tagSimilarity * 0.4) * temporalBoost;
|
|
698
|
+
return { incident, score };
|
|
699
|
+
});
|
|
700
|
+
const incidents = scored
|
|
701
|
+
.filter(item => item.score >= fullConfig.similarity_threshold)
|
|
702
|
+
.sort((a, b) => b.score - a.score)
|
|
703
|
+
.slice(0, fullConfig.max_results)
|
|
704
|
+
.map(item => ({ ...item.incident, similarity_score: item.score }));
|
|
705
|
+
// Also check patterns
|
|
706
|
+
const patterns = await matchPatterns(symptom, fullConfig, memoryConfig);
|
|
707
|
+
if (patterns.length > 0 && incidents.length === 0) {
|
|
708
|
+
return {
|
|
709
|
+
incidents: [],
|
|
710
|
+
patterns,
|
|
711
|
+
confidence: 0.9,
|
|
712
|
+
retrieval_method: 'pattern',
|
|
713
|
+
tokens_used: estimateTokens(patterns),
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
return {
|
|
717
|
+
incidents,
|
|
718
|
+
patterns,
|
|
719
|
+
confidence: incidents.length > 0 ? 0.7 : 0.0,
|
|
720
|
+
retrieval_method: incidents.length > 0 && patterns.length > 0 ? 'hybrid' : 'incident',
|
|
721
|
+
tokens_used: estimateTokens([...incidents, ...patterns]),
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
//# sourceMappingURL=retrieval.js.map
|