@soleri/core 9.0.3 → 9.2.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/dist/brain/intelligence.d.ts +27 -0
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +160 -14
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/learning-radar.d.ts +4 -0
- package/dist/brain/learning-radar.d.ts.map +1 -1
- package/dist/brain/learning-radar.js +20 -1
- package/dist/brain/learning-radar.js.map +1 -1
- package/dist/brain/strength-scorer.d.ts +31 -0
- package/dist/brain/strength-scorer.d.ts.map +1 -0
- package/dist/brain/strength-scorer.js +264 -0
- package/dist/brain/strength-scorer.js.map +1 -0
- package/dist/chat/agent-loop.d.ts.map +1 -1
- package/dist/chat/agent-loop.js +2 -0
- package/dist/chat/agent-loop.js.map +1 -1
- package/dist/chat/notifications.d.ts.map +1 -1
- package/dist/chat/notifications.js +2 -0
- package/dist/chat/notifications.js.map +1 -1
- package/dist/claudemd/compose.js +1 -1
- package/dist/claudemd/compose.js.map +1 -1
- package/dist/control/intent-router.d.ts.map +1 -1
- package/dist/control/intent-router.js +12 -4
- package/dist/control/intent-router.js.map +1 -1
- package/dist/curator/contradiction-detector.d.ts +27 -0
- package/dist/curator/contradiction-detector.d.ts.map +1 -0
- package/dist/curator/contradiction-detector.js +62 -0
- package/dist/curator/contradiction-detector.js.map +1 -0
- package/dist/curator/curator.d.ts +3 -4
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +90 -525
- package/dist/curator/curator.js.map +1 -1
- package/dist/curator/duplicate-detector.d.ts +14 -0
- package/dist/curator/duplicate-detector.d.ts.map +1 -0
- package/dist/curator/duplicate-detector.js +77 -0
- package/dist/curator/duplicate-detector.js.map +1 -0
- package/dist/curator/health-audit.d.ts +15 -0
- package/dist/curator/health-audit.d.ts.map +1 -0
- package/dist/curator/health-audit.js +97 -0
- package/dist/curator/health-audit.js.map +1 -0
- package/dist/curator/metadata-enricher.d.ts +17 -0
- package/dist/curator/metadata-enricher.d.ts.map +1 -0
- package/dist/curator/metadata-enricher.js +60 -0
- package/dist/curator/metadata-enricher.js.map +1 -0
- package/dist/curator/schema.d.ts +7 -0
- package/dist/curator/schema.d.ts.map +1 -0
- package/dist/curator/schema.js +62 -0
- package/dist/curator/schema.js.map +1 -0
- package/dist/curator/tag-manager.d.ts +36 -0
- package/dist/curator/tag-manager.d.ts.map +1 -0
- package/dist/curator/tag-manager.js +78 -0
- package/dist/curator/tag-manager.js.map +1 -0
- package/dist/engine/bin/soleri-engine.js +55 -3
- package/dist/engine/bin/soleri-engine.js.map +1 -1
- package/dist/engine/core-ops.d.ts.map +1 -1
- package/dist/engine/core-ops.js +33 -10
- package/dist/engine/core-ops.js.map +1 -1
- package/dist/engine/module-manifest.d.ts.map +1 -1
- package/dist/engine/module-manifest.js +22 -2
- package/dist/engine/module-manifest.js.map +1 -1
- package/dist/engine/register-engine.d.ts.map +1 -1
- package/dist/engine/register-engine.js +26 -2
- package/dist/engine/register-engine.js.map +1 -1
- package/dist/errors/retry.d.ts.map +1 -1
- package/dist/errors/retry.js +2 -0
- package/dist/errors/retry.js.map +1 -1
- package/dist/facades/types.d.ts +1 -1
- package/dist/flows/chain-types.d.ts +18 -18
- package/dist/flows/gate-evaluator.d.ts.map +1 -1
- package/dist/flows/gate-evaluator.js +22 -0
- package/dist/flows/gate-evaluator.js.map +1 -1
- package/dist/flows/types.d.ts +157 -28
- package/dist/flows/types.d.ts.map +1 -1
- package/dist/flows/types.js +4 -0
- package/dist/flows/types.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/intake/intake-pipeline.d.ts.map +1 -1
- package/dist/intake/intake-pipeline.js +1 -0
- package/dist/intake/intake-pipeline.js.map +1 -1
- package/dist/intake/text-ingester.d.ts.map +1 -1
- package/dist/intake/text-ingester.js +2 -0
- package/dist/intake/text-ingester.js.map +1 -1
- package/dist/llm/key-pool.d.ts +1 -1
- package/dist/llm/key-pool.d.ts.map +1 -1
- package/dist/llm/key-pool.js +3 -4
- package/dist/llm/key-pool.js.map +1 -1
- package/dist/llm/utils.d.ts.map +1 -1
- package/dist/llm/utils.js +2 -0
- package/dist/llm/utils.js.map +1 -1
- package/dist/migrations/migration-runner.test-helpers.d.ts +13 -0
- package/dist/migrations/migration-runner.test-helpers.d.ts.map +1 -0
- package/dist/migrations/migration-runner.test-helpers.js +47 -0
- package/dist/migrations/migration-runner.test-helpers.js.map +1 -0
- package/dist/operator/operator-profile.d.ts +44 -0
- package/dist/operator/operator-profile.d.ts.map +1 -0
- package/dist/operator/operator-profile.js +377 -0
- package/dist/operator/operator-profile.js.map +1 -0
- package/dist/operator/operator-signals.d.ts +45 -0
- package/dist/operator/operator-signals.d.ts.map +1 -0
- package/dist/operator/operator-signals.js +228 -0
- package/dist/operator/operator-signals.js.map +1 -0
- package/dist/operator/operator-types.d.ts +360 -0
- package/dist/operator/operator-types.d.ts.map +1 -0
- package/dist/operator/operator-types.js +24 -0
- package/dist/operator/operator-types.js.map +1 -0
- package/dist/packs/types.d.ts +27 -27
- package/dist/paths.d.ts +40 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +98 -0
- package/dist/paths.js.map +1 -0
- package/dist/persistence/index.d.ts +1 -1
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +1 -1
- package/dist/persistence/index.js.map +1 -1
- package/dist/persistence/sqlite-provider.d.ts +2 -0
- package/dist/persistence/sqlite-provider.d.ts.map +1 -1
- package/dist/persistence/sqlite-provider.js +8 -5
- package/dist/persistence/sqlite-provider.js.map +1 -1
- package/dist/planning/evidence-collector.d.ts +13 -1
- package/dist/planning/evidence-collector.d.ts.map +1 -1
- package/dist/planning/evidence-collector.js +33 -0
- package/dist/planning/evidence-collector.js.map +1 -1
- package/dist/planning/gap-analysis.d.ts +5 -4
- package/dist/planning/gap-analysis.d.ts.map +1 -1
- package/dist/planning/gap-analysis.js +7 -341
- package/dist/planning/gap-analysis.js.map +1 -1
- package/dist/planning/gap-passes.d.ts +19 -0
- package/dist/planning/gap-passes.d.ts.map +1 -0
- package/dist/planning/gap-passes.js +157 -0
- package/dist/planning/gap-passes.js.map +1 -0
- package/dist/planning/gap-patterns.d.ts +29 -0
- package/dist/planning/gap-patterns.d.ts.map +1 -0
- package/dist/planning/gap-patterns.js +129 -0
- package/dist/planning/gap-patterns.js.map +1 -0
- package/dist/planning/gap-types.d.ts +1 -1
- package/dist/planning/gap-types.d.ts.map +1 -1
- package/dist/planning/gap-types.js +1 -0
- package/dist/planning/gap-types.js.map +1 -1
- package/dist/planning/github-projection.d.ts +122 -0
- package/dist/planning/github-projection.d.ts.map +1 -0
- package/dist/planning/github-projection.js +294 -0
- package/dist/planning/github-projection.js.map +1 -0
- package/dist/planning/impact-analyzer.d.ts +26 -0
- package/dist/planning/impact-analyzer.d.ts.map +1 -0
- package/dist/planning/impact-analyzer.js +199 -0
- package/dist/planning/impact-analyzer.js.map +1 -0
- package/dist/planning/plan-lifecycle.d.ts +136 -0
- package/dist/planning/plan-lifecycle.d.ts.map +1 -0
- package/dist/planning/plan-lifecycle.js +296 -0
- package/dist/planning/plan-lifecycle.js.map +1 -0
- package/dist/planning/planner-types.d.ts +202 -0
- package/dist/planning/planner-types.d.ts.map +1 -0
- package/dist/planning/planner-types.js +6 -0
- package/dist/planning/planner-types.js.map +1 -0
- package/dist/planning/planner.d.ts +31 -383
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +154 -878
- package/dist/planning/planner.js.map +1 -1
- package/dist/planning/rationalization-detector.d.ts +32 -0
- package/dist/planning/rationalization-detector.d.ts.map +1 -0
- package/dist/planning/rationalization-detector.js +89 -0
- package/dist/planning/rationalization-detector.js.map +1 -0
- package/dist/planning/reconciliation-engine.d.ts +47 -0
- package/dist/planning/reconciliation-engine.d.ts.map +1 -0
- package/dist/planning/reconciliation-engine.js +128 -0
- package/dist/planning/reconciliation-engine.js.map +1 -0
- package/dist/planning/task-verifier.d.ts +85 -0
- package/dist/planning/task-verifier.d.ts.map +1 -0
- package/dist/planning/task-verifier.js +227 -0
- package/dist/planning/task-verifier.js.map +1 -0
- package/dist/plugins/types.d.ts +4 -4
- package/dist/runtime/admin-ops.d.ts +2 -2
- package/dist/runtime/admin-ops.d.ts.map +1 -1
- package/dist/runtime/admin-ops.js +44 -17
- package/dist/runtime/admin-ops.js.map +1 -1
- package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
- package/dist/runtime/admin-setup-ops.js +21 -46
- package/dist/runtime/admin-setup-ops.js.map +1 -1
- package/dist/runtime/archive-ops.d.ts +10 -0
- package/dist/runtime/archive-ops.d.ts.map +1 -0
- package/dist/runtime/archive-ops.js +310 -0
- package/dist/runtime/archive-ops.js.map +1 -0
- package/dist/runtime/capture-ops.d.ts.map +1 -1
- package/dist/runtime/capture-ops.js +42 -7
- package/dist/runtime/capture-ops.js.map +1 -1
- package/dist/runtime/claude-md-helpers.js +1 -1
- package/dist/runtime/claude-md-helpers.js.map +1 -1
- package/dist/runtime/context-health.d.ts +31 -0
- package/dist/runtime/context-health.d.ts.map +1 -0
- package/dist/runtime/context-health.js +57 -0
- package/dist/runtime/context-health.js.map +1 -0
- package/dist/runtime/facades/archive-facade.d.ts +10 -0
- package/dist/runtime/facades/archive-facade.d.ts.map +1 -0
- package/dist/runtime/facades/archive-facade.js +11 -0
- package/dist/runtime/facades/archive-facade.js.map +1 -0
- package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
- package/dist/runtime/facades/brain-facade.js +2 -0
- package/dist/runtime/facades/brain-facade.js.map +1 -1
- package/dist/runtime/facades/chat-facade.d.ts +7 -0
- package/dist/runtime/facades/chat-facade.d.ts.map +1 -1
- package/dist/runtime/facades/chat-facade.js +15 -800
- package/dist/runtime/facades/chat-facade.js.map +1 -1
- package/dist/runtime/facades/chat-service-ops.d.ts +9 -0
- package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -0
- package/dist/runtime/facades/chat-service-ops.js +330 -0
- package/dist/runtime/facades/chat-service-ops.js.map +1 -0
- package/dist/runtime/facades/chat-session-ops.d.ts +8 -0
- package/dist/runtime/facades/chat-session-ops.d.ts.map +1 -0
- package/dist/runtime/facades/chat-session-ops.js +136 -0
- package/dist/runtime/facades/chat-session-ops.js.map +1 -0
- package/dist/runtime/facades/chat-state.d.ts +31 -0
- package/dist/runtime/facades/chat-state.d.ts.map +1 -0
- package/dist/runtime/facades/chat-state.js +32 -0
- package/dist/runtime/facades/chat-state.js.map +1 -0
- package/dist/runtime/facades/chat-transport-ops.d.ts +9 -0
- package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -0
- package/dist/runtime/facades/chat-transport-ops.js +337 -0
- package/dist/runtime/facades/chat-transport-ops.js.map +1 -0
- package/dist/runtime/facades/control-facade.d.ts.map +1 -1
- package/dist/runtime/facades/control-facade.js +4 -1
- package/dist/runtime/facades/control-facade.js.map +1 -1
- package/dist/runtime/facades/index.d.ts.map +1 -1
- package/dist/runtime/facades/index.js +6 -0
- package/dist/runtime/facades/index.js.map +1 -1
- package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
- package/dist/runtime/facades/memory-facade.js +75 -6
- package/dist/runtime/facades/memory-facade.js.map +1 -1
- package/dist/runtime/facades/operator-facade.d.ts +8 -0
- package/dist/runtime/facades/operator-facade.d.ts.map +1 -0
- package/dist/runtime/facades/operator-facade.js +220 -0
- package/dist/runtime/facades/operator-facade.js.map +1 -0
- package/dist/runtime/facades/orchestrate-facade.js +3 -3
- package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
- package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
- package/dist/runtime/facades/plan-facade.js +39 -6
- package/dist/runtime/facades/plan-facade.js.map +1 -1
- package/dist/runtime/facades/review-facade.d.ts +7 -0
- package/dist/runtime/facades/review-facade.d.ts.map +1 -0
- package/dist/runtime/facades/review-facade.js +8 -0
- package/dist/runtime/facades/review-facade.js.map +1 -0
- package/dist/runtime/facades/sync-facade.d.ts +7 -0
- package/dist/runtime/facades/sync-facade.d.ts.map +1 -0
- package/dist/runtime/facades/sync-facade.js +8 -0
- package/dist/runtime/facades/sync-facade.js.map +1 -0
- package/dist/runtime/facades/vault-facade.d.ts +4 -1
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
- package/dist/runtime/facades/vault-facade.js +13 -66
- package/dist/runtime/facades/vault-facade.js.map +1 -1
- package/dist/runtime/github-integration.d.ts +49 -0
- package/dist/runtime/github-integration.d.ts.map +1 -0
- package/dist/runtime/github-integration.js +113 -0
- package/dist/runtime/github-integration.js.map +1 -0
- package/dist/runtime/grading-ops.js +1 -1
- package/dist/runtime/grading-ops.js.map +1 -1
- package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
- package/dist/runtime/memory-extra-ops.js +6 -2
- package/dist/runtime/memory-extra-ops.js.map +1 -1
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
- package/dist/runtime/orchestrate-ops.js +367 -40
- package/dist/runtime/orchestrate-ops.js.map +1 -1
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
- package/dist/runtime/planning-extra-ops.js +69 -4
- package/dist/runtime/planning-extra-ops.js.map +1 -1
- package/dist/runtime/review-ops.d.ts +10 -0
- package/dist/runtime/review-ops.d.ts.map +1 -0
- package/dist/runtime/review-ops.js +97 -0
- package/dist/runtime/review-ops.js.map +1 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +27 -12
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/session-briefing.d.ts +3 -0
- package/dist/runtime/session-briefing.d.ts.map +1 -1
- package/dist/runtime/session-briefing.js +68 -1
- package/dist/runtime/session-briefing.js.map +1 -1
- package/dist/runtime/sync-ops.d.ts +12 -0
- package/dist/runtime/sync-ops.d.ts.map +1 -0
- package/dist/runtime/sync-ops.js +288 -0
- package/dist/runtime/sync-ops.js.map +1 -0
- package/dist/runtime/types.d.ts +10 -4
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.d.ts +5 -4
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.js +5 -300
- package/dist/runtime/vault-extra-ops.js.map +1 -1
- package/dist/runtime/vault-sharing-ops.d.ts +4 -4
- package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
- package/dist/runtime/vault-sharing-ops.js +5 -300
- package/dist/runtime/vault-sharing-ops.js.map +1 -1
- package/dist/skills/sync-skills.d.ts +27 -0
- package/dist/skills/sync-skills.d.ts.map +1 -0
- package/dist/skills/sync-skills.js +81 -0
- package/dist/skills/sync-skills.js.map +1 -0
- package/dist/update-check.d.ts +14 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +96 -0
- package/dist/update-check.js.map +1 -0
- package/dist/vault/linking.d.ts +10 -12
- package/dist/vault/linking.d.ts.map +1 -1
- package/dist/vault/linking.js +104 -161
- package/dist/vault/linking.js.map +1 -1
- package/dist/vault/vault-entries.d.ts +69 -0
- package/dist/vault/vault-entries.d.ts.map +1 -0
- package/dist/vault/vault-entries.js +257 -0
- package/dist/vault/vault-entries.js.map +1 -0
- package/dist/vault/vault-interfaces.d.ts +153 -0
- package/dist/vault/vault-interfaces.d.ts.map +1 -0
- package/dist/vault/vault-interfaces.js +2 -0
- package/dist/vault/vault-interfaces.js.map +1 -0
- package/dist/vault/vault-maintenance.d.ts +40 -0
- package/dist/vault/vault-maintenance.d.ts.map +1 -0
- package/dist/vault/vault-maintenance.js +142 -0
- package/dist/vault/vault-maintenance.js.map +1 -0
- package/dist/vault/vault-markdown-sync.d.ts +22 -0
- package/dist/vault/vault-markdown-sync.d.ts.map +1 -0
- package/dist/vault/vault-markdown-sync.js +143 -0
- package/dist/vault/vault-markdown-sync.js.map +1 -0
- package/dist/vault/vault-memories.d.ts +61 -0
- package/dist/vault/vault-memories.d.ts.map +1 -0
- package/dist/vault/vault-memories.js +240 -0
- package/dist/vault/vault-memories.js.map +1 -0
- package/dist/vault/vault-schema.d.ts +9 -0
- package/dist/vault/vault-schema.d.ts.map +1 -0
- package/dist/vault/vault-schema.js +179 -0
- package/dist/vault/vault-schema.js.map +1 -0
- package/dist/vault/vault.d.ts +29 -81
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +78 -931
- package/dist/vault/vault.js.map +1 -1
- package/package.json +1 -1
- package/src/agency/agency-manager.test.ts +600 -0
- package/src/agency/default-rules.test.ts +228 -0
- package/src/{__tests__ → brain}/brain-intelligence.test.ts +37 -14
- package/src/{__tests__ → brain}/brain.test.ts +1 -1
- package/src/brain/intelligence.ts +196 -15
- package/src/brain/learning-radar.ts +22 -1
- package/src/{__tests__ → brain}/second-brain-features.test.ts +4 -4
- package/src/{__tests__ → brain}/session-lifecycle.test.ts +2 -2
- package/src/brain/strength-scorer.ts +404 -0
- package/src/capabilities/chain-mapping.test.ts +66 -0
- package/src/capabilities/registry.test.ts +369 -0
- package/src/chat/agent-loop.test.ts +394 -0
- package/src/chat/agent-loop.ts +2 -0
- package/src/{__tests__ → chat}/chat-differentiators.test.ts +3 -3
- package/src/{__tests__ → chat}/chat-enhanced.test.ts +4 -4
- package/src/{__tests__ → chat}/chat-transport.test.ts +6 -6
- package/src/chat/mcp-bridge.test.ts +173 -0
- package/src/chat/notifications.ts +2 -0
- package/src/chat/output-compressor.test.ts +164 -0
- package/src/claudemd/compose.test.ts +178 -0
- package/src/claudemd/compose.ts +1 -1
- package/src/claudemd/inject.test.ts +211 -0
- package/src/context/context-engine.test.ts +461 -0
- package/src/control/identity-manager.test.ts +305 -0
- package/src/control/intent-router.test.ts +360 -0
- package/src/control/intent-router.ts +13 -4
- package/src/curator/classifier.test.ts +104 -0
- package/src/curator/contradiction-detector.test.ts +180 -0
- package/src/curator/contradiction-detector.ts +87 -0
- package/src/{__tests__ → curator}/curator-pipeline-e2e.test.ts +10 -10
- package/src/{__tests__ → curator}/curator.test.ts +77 -1
- package/src/curator/curator.ts +115 -777
- package/src/curator/duplicate-detector.test.ts +183 -0
- package/src/curator/duplicate-detector.ts +103 -0
- package/src/curator/health-audit.ts +126 -0
- package/src/curator/metadata-enricher.ts +84 -0
- package/src/curator/quality-gate.test.ts +135 -0
- package/src/curator/schema.ts +65 -0
- package/src/curator/tag-manager.test.ts +165 -0
- package/src/curator/tag-manager.ts +109 -0
- package/src/domain-packs/inject-rules.test.ts +117 -0
- package/src/domain-packs/knowledge-installer.test.ts +171 -0
- package/src/domain-packs/loader.test.ts +86 -0
- package/src/domain-packs/pack-runtime.test.ts +140 -0
- package/src/domain-packs/skills-installer.test.ts +135 -0
- package/src/domain-packs/token-resolver.test.ts +150 -0
- package/src/domain-packs/types.test.ts +130 -0
- package/src/enforcement/adapters/claude-code.test.ts +216 -0
- package/src/enforcement/registry.test.ts +264 -0
- package/src/engine/bin/soleri-engine.ts +59 -3
- package/src/engine/core-ops.test.ts +254 -0
- package/src/engine/core-ops.ts +35 -10
- package/src/engine/module-manifest.test.ts +124 -0
- package/src/engine/module-manifest.ts +22 -2
- package/src/engine/register-engine.test.ts +230 -0
- package/src/engine/register-engine.ts +26 -2
- package/src/errors/classify.test.ts +199 -0
- package/src/errors/retry.test.ts +156 -0
- package/src/errors/retry.ts +2 -0
- package/src/errors/types.test.ts +108 -0
- package/src/events/event-bus.test.ts +149 -0
- package/src/extensions/middleware.test.ts +234 -0
- package/src/facades/facade-factory.test.ts +424 -0
- package/src/flows/chain-runner.test.ts +273 -0
- package/src/flows/context-router.test.ts +52 -0
- package/src/flows/dispatch-registry.test.ts +128 -0
- package/src/flows/epilogue.test.ts +107 -0
- package/src/flows/executor.test.ts +263 -0
- package/src/flows/gate-evaluator.test.ts +194 -0
- package/src/flows/gate-evaluator.ts +25 -0
- package/src/flows/types.ts +4 -0
- package/src/governance/governance.test.ts +726 -0
- package/src/health/health-registry.test.ts +186 -0
- package/src/health/vault-integrity.test.ts +110 -0
- package/src/index.ts +92 -0
- package/src/intake/content-classifier.test.ts +209 -0
- package/src/intake/dedup-gate.test.ts +131 -0
- package/src/intake/intake-pipeline.test.ts +506 -0
- package/src/intake/intake-pipeline.ts +1 -0
- package/src/intake/text-ingester.test.ts +194 -0
- package/src/intake/text-ingester.ts +2 -0
- package/src/llm/key-pool.test.ts +236 -0
- package/src/llm/key-pool.ts +3 -4
- package/src/llm/llm-client.test.ts +345 -0
- package/src/llm/oauth-discovery.test.ts +180 -0
- package/src/llm/utils.test.ts +327 -0
- package/src/llm/utils.ts +2 -0
- package/src/{__tests__ → logging}/logger.test.ts +41 -62
- package/src/loop/loop-manager.test.ts +519 -0
- package/src/migrations/migration-runner.edge-cases.test.ts +319 -0
- package/src/migrations/migration-runner.test-helpers.ts +64 -0
- package/src/migrations/migration-runner.test.ts +385 -0
- package/src/operator/auto-signal-pipeline.test.ts +207 -0
- package/src/operator/operator-profile-extended.test.ts +320 -0
- package/src/operator/operator-profile.test.ts +314 -0
- package/src/operator/operator-profile.ts +469 -0
- package/src/operator/operator-signals-extended.test.ts +245 -0
- package/src/operator/operator-signals.test.ts +281 -0
- package/src/operator/operator-signals.ts +261 -0
- package/src/operator/operator-types.ts +444 -0
- package/src/operator/prompts/hook-precompact-operator-dispatch.md +94 -0
- package/src/operator/prompts/subagent-soft-signal-extractor.md +125 -0
- package/src/operator/prompts/subagent-synthesis-cognition.md +181 -0
- package/src/operator/prompts/subagent-synthesis-communication.md +140 -0
- package/src/operator/prompts/subagent-synthesis-technical.md +160 -0
- package/src/operator/prompts/subagent-synthesis-trust.md +143 -0
- package/src/{__tests__ → packs}/pack-lockfile.test.ts +3 -3
- package/src/{__tests__ → packs}/pack-system.test.ts +2 -2
- package/src/paths.ts +115 -0
- package/src/persistence/index.ts +1 -1
- package/src/persistence/sqlite-provider.test.ts +540 -0
- package/src/persistence/sqlite-provider.ts +8 -5
- package/src/persona/defaults.test.ts +59 -0
- package/src/persona/loader.test.ts +67 -0
- package/src/persona/prompt-generator.test.ts +127 -0
- package/src/planning/evidence-collector.test.ts +406 -0
- package/src/planning/evidence-collector.ts +50 -0
- package/src/planning/gap-analysis-alternatives.test.ts +169 -0
- package/src/planning/gap-analysis.ts +21 -636
- package/src/planning/gap-passes.test.ts +372 -0
- package/src/planning/gap-passes.ts +298 -0
- package/src/planning/gap-patterns.test.ts +320 -0
- package/src/planning/gap-patterns.ts +234 -0
- package/src/planning/gap-types.ts +4 -1
- package/src/planning/github-projection.test.ts +177 -0
- package/src/planning/github-projection.ts +425 -0
- package/src/planning/impact-analyzer.test.ts +180 -0
- package/src/planning/impact-analyzer.ts +264 -0
- package/src/planning/plan-lifecycle.test.ts +312 -0
- package/src/planning/plan-lifecycle.ts +346 -0
- package/src/planning/planner-types.ts +215 -0
- package/src/{__tests__ → planning}/planner.test.ts +169 -15
- package/src/planning/planner.ts +197 -1228
- package/src/planning/rationalization-detector.test.ts +171 -0
- package/src/planning/rationalization-detector.ts +138 -0
- package/src/planning/reconciliation-engine.test.ts +141 -0
- package/src/planning/reconciliation-engine.ts +162 -0
- package/src/planning/task-verifier.test.ts +235 -0
- package/src/planning/task-verifier.ts +303 -0
- package/src/planning/verification-protocol.test.ts +201 -0
- package/src/playbooks/generic/generic-playbooks.test.ts +438 -0
- package/src/playbooks/index.test.ts +77 -0
- package/src/playbooks/playbook-executor.test.ts +255 -0
- package/src/playbooks/playbook-registry.test.ts +232 -0
- package/src/playbooks/playbook-seeder.test.ts +153 -0
- package/src/plugins/plugin-loader.test.ts +212 -0
- package/src/plugins/plugin-registry.test.ts +272 -0
- package/src/project/project-registry.test.ts +428 -0
- package/src/prompts/parser.test.ts +100 -0
- package/src/prompts/template-manager.test.ts +109 -0
- package/src/{__tests__ → queue}/async-infrastructure.test.ts +3 -3
- package/src/queue/job-queue.test.ts +331 -0
- package/src/queue/pipeline-runner.test.ts +209 -0
- package/src/runtime/admin-extra-ops.test.ts +527 -0
- package/src/runtime/admin-ops.test.ts +257 -0
- package/src/runtime/admin-ops.ts +45 -17
- package/src/runtime/admin-setup-ops.test.ts +328 -0
- package/src/runtime/admin-setup-ops.ts +20 -43
- package/src/runtime/archive-ops.test.ts +269 -0
- package/src/runtime/archive-ops.ts +347 -0
- package/src/runtime/capture-ops.test.ts +433 -0
- package/src/runtime/capture-ops.ts +50 -8
- package/src/runtime/chain-ops.test.ts +149 -0
- package/src/runtime/claude-md-helpers.test.ts +191 -0
- package/src/runtime/claude-md-helpers.ts +1 -1
- package/src/runtime/context-health.test.ts +78 -0
- package/src/runtime/context-health.ts +85 -0
- package/src/runtime/curator-extra-ops.test.ts +202 -0
- package/src/runtime/deprecation.test.ts +98 -0
- package/src/runtime/domain-ops.test.ts +268 -0
- package/src/runtime/facades/admin-facade.test.ts +333 -0
- package/src/runtime/facades/agency-facade.test.ts +278 -0
- package/src/runtime/facades/archive-facade.test.ts +294 -0
- package/src/runtime/facades/archive-facade.ts +14 -0
- package/src/runtime/facades/brain-facade.test.ts +714 -0
- package/src/runtime/facades/brain-facade.ts +2 -0
- package/src/runtime/facades/chat-facade.test.ts +166 -0
- package/src/runtime/facades/chat-facade.ts +15 -906
- package/src/runtime/facades/chat-service-ops.test.ts +276 -0
- package/src/runtime/facades/chat-service-ops.ts +374 -0
- package/src/runtime/facades/chat-session-ops.test.ts +197 -0
- package/src/runtime/facades/chat-session-ops.ts +146 -0
- package/src/runtime/facades/chat-state.ts +60 -0
- package/src/runtime/facades/chat-transport-ops.test.ts +269 -0
- package/src/runtime/facades/chat-transport-ops.ts +380 -0
- package/src/runtime/facades/context-facade.test.ts +108 -0
- package/src/runtime/facades/control-facade.test.ts +436 -0
- package/src/runtime/facades/control-facade.ts +6 -1
- package/src/runtime/facades/curator-facade.test.ts +303 -0
- package/src/runtime/facades/index.ts +6 -0
- package/src/runtime/facades/loop-facade.test.ts +245 -0
- package/src/runtime/facades/memory-facade.test.ts +269 -0
- package/src/runtime/facades/memory-facade.ts +78 -6
- package/src/runtime/facades/operator-facade.test.ts +208 -0
- package/src/runtime/facades/operator-facade.ts +236 -0
- package/src/runtime/facades/orchestrate-facade.test.ts +185 -0
- package/src/runtime/facades/orchestrate-facade.ts +3 -3
- package/src/runtime/facades/plan-facade.test.ts +266 -0
- package/src/runtime/facades/plan-facade.ts +42 -6
- package/src/runtime/facades/review-facade.test.ts +82 -0
- package/src/runtime/facades/review-facade.ts +11 -0
- package/src/runtime/facades/sync-facade.test.ts +113 -0
- package/src/runtime/facades/sync-facade.ts +11 -0
- package/src/runtime/facades/vault-facade.test.ts +631 -0
- package/src/runtime/facades/vault-facade.ts +15 -70
- package/src/runtime/feature-flags.test.ts +140 -0
- package/src/runtime/github-integration.test.ts +89 -0
- package/src/runtime/github-integration.ts +159 -0
- package/src/runtime/grading-ops.test.ts +141 -0
- package/src/runtime/grading-ops.ts +1 -1
- package/src/runtime/intake-ops.test.ts +208 -0
- package/src/runtime/loop-ops.test.ts +238 -0
- package/src/runtime/memory-cross-project-ops.test.ts +177 -0
- package/src/runtime/memory-extra-ops.test.ts +453 -0
- package/src/runtime/memory-extra-ops.ts +6 -2
- package/src/runtime/orchestrate-ops.test.ts +302 -0
- package/src/runtime/orchestrate-ops.ts +435 -46
- package/src/runtime/pack-ops.test.ts +158 -0
- package/src/runtime/planning-extra-ops.test.ts +583 -0
- package/src/runtime/planning-extra-ops.ts +72 -4
- package/src/{__tests__ → runtime}/playbook-ops-execution.test.ts +3 -3
- package/src/runtime/playbook-ops.test.ts +262 -0
- package/src/runtime/plugin-ops.test.ts +201 -0
- package/src/runtime/project-ops.test.ts +235 -0
- package/src/runtime/review-ops.test.ts +142 -0
- package/src/runtime/review-ops.ts +99 -0
- package/src/runtime/runtime.test.ts +363 -0
- package/src/runtime/runtime.ts +39 -12
- package/src/runtime/session-briefing.test.ts +302 -0
- package/src/runtime/session-briefing.ts +80 -1
- package/src/runtime/sync-ops.test.ts +221 -0
- package/src/runtime/sync-ops.ts +325 -0
- package/src/runtime/telemetry-ops.test.ts +132 -0
- package/src/runtime/types.ts +10 -4
- package/src/runtime/vault-extra-ops.test.ts +246 -0
- package/src/runtime/vault-extra-ops.ts +5 -332
- package/src/runtime/vault-linking-ops.test.ts +237 -0
- package/src/runtime/vault-sharing-ops.test.ts +130 -0
- package/src/runtime/vault-sharing-ops.ts +5 -329
- package/src/skills/sync-skills.ts +108 -0
- package/src/streams/normalize.test.ts +95 -0
- package/src/streams/replayable-stream.test.ts +166 -0
- package/src/telemetry/telemetry.test.ts +143 -0
- package/src/transport/http-server.test.ts +394 -0
- package/src/transport/lsp-server.test.ts +458 -0
- package/src/transport/rate-limiter.test.ts +126 -0
- package/src/transport/session-manager.test.ts +133 -0
- package/src/transport/token-auth.test.ts +136 -0
- package/src/transport/ws-server.test.ts +294 -0
- package/src/update-check.ts +111 -0
- package/src/vault/__tests__/vault-characterization.test.ts +168 -0
- package/src/vault/content-hash.test.ts +78 -0
- package/src/vault/git-vault-sync.test.ts +234 -0
- package/src/vault/knowledge-review.test.ts +269 -0
- package/src/vault/linking.test.ts +358 -0
- package/src/vault/linking.ts +149 -183
- package/src/vault/obsidian-sync.test.ts +342 -0
- package/src/vault/playbook.test.ts +152 -0
- package/src/vault/scope-detector.test.ts +187 -0
- package/src/vault/vault-branching.test.ts +250 -0
- package/src/{__tests__ → vault}/vault-connect.test.ts +1 -1
- package/src/vault/vault-entries.ts +282 -0
- package/src/vault/vault-interfaces.ts +56 -0
- package/src/vault/vault-maintenance.ts +205 -0
- package/src/vault/vault-manager.test.ts +206 -0
- package/src/vault/vault-markdown-sync.test.ts +203 -0
- package/src/vault/vault-markdown-sync.ts +160 -0
- package/src/vault/vault-memories.ts +339 -0
- package/src/{__tests__ → vault}/vault-scaling.test.ts +1 -1
- package/src/vault/vault-schema.ts +181 -0
- package/src/{__tests__ → vault}/vault-sharing.test.ts +4 -4
- package/src/{__tests__ → vault}/vault.test.ts +2 -2
- package/src/vault/vault.ts +89 -1171
- package/dist/cognee/client.d.ts +0 -43
- package/dist/cognee/client.d.ts.map +0 -1
- package/dist/cognee/client.js +0 -375
- package/dist/cognee/client.js.map +0 -1
- package/dist/cognee/sync-manager.d.ts +0 -153
- package/dist/cognee/sync-manager.d.ts.map +0 -1
- package/dist/cognee/sync-manager.js +0 -390
- package/dist/cognee/sync-manager.js.map +0 -1
- package/dist/cognee/types.d.ts +0 -62
- package/dist/cognee/types.d.ts.map +0 -1
- package/dist/cognee/types.js +0 -3
- package/dist/cognee/types.js.map +0 -1
- package/dist/governance/index.d.ts +0 -3
- package/dist/governance/index.d.ts.map +0 -1
- package/dist/governance/index.js +0 -2
- package/dist/governance/index.js.map +0 -1
- package/dist/health/doctor-checks.d.ts +0 -15
- package/dist/health/doctor-checks.d.ts.map +0 -1
- package/dist/health/doctor-checks.js +0 -98
- package/dist/health/doctor-checks.js.map +0 -1
- package/dist/persistence/postgres-provider.d.ts +0 -81
- package/dist/persistence/postgres-provider.d.ts.map +0 -1
- package/dist/persistence/postgres-provider.js +0 -256
- package/dist/persistence/postgres-provider.js.map +0 -1
- package/dist/runtime/cognee-sync-ops.d.ts +0 -12
- package/dist/runtime/cognee-sync-ops.d.ts.map +0 -1
- package/dist/runtime/cognee-sync-ops.js +0 -93
- package/dist/runtime/cognee-sync-ops.js.map +0 -1
- package/dist/runtime/core-ops.d.ts +0 -23
- package/dist/runtime/core-ops.d.ts.map +0 -1
- package/dist/runtime/core-ops.js +0 -1296
- package/dist/runtime/core-ops.js.map +0 -1
- package/dist/runtime/facades/cognee-facade.d.ts +0 -8
- package/dist/runtime/facades/cognee-facade.d.ts.map +0 -1
- package/dist/runtime/facades/cognee-facade.js +0 -156
- package/dist/runtime/facades/cognee-facade.js.map +0 -1
- package/src/__tests__/admin-extra-ops.test.ts +0 -484
- package/src/__tests__/admin-ops.test.ts +0 -268
- package/src/__tests__/admin-setup-ops.test.ts +0 -355
- package/src/__tests__/agency-manager.test.ts +0 -374
- package/src/__tests__/agent-loop.test.ts +0 -256
- package/src/__tests__/capture-ops.test.ts +0 -784
- package/src/__tests__/claudemd.test.ts +0 -282
- package/src/__tests__/content-hash.test.ts +0 -60
- package/src/__tests__/context-engine.test.ts +0 -251
- package/src/__tests__/core-ops.test.ts +0 -550
- package/src/__tests__/curator-extra-ops.test.ts +0 -383
- package/src/__tests__/deprecation.test.ts +0 -78
- package/src/__tests__/domain-ops.test.ts +0 -226
- package/src/__tests__/domain-packs.test.ts +0 -421
- package/src/__tests__/enforcement.test.ts +0 -153
- package/src/__tests__/errors.test.ts +0 -388
- package/src/__tests__/extensions.test.ts +0 -233
- package/src/__tests__/facade-factory.test.ts +0 -271
- package/src/__tests__/feature-flags.test.ts +0 -137
- package/src/__tests__/flows.test.ts +0 -604
- package/src/__tests__/git-vault-sync.test.ts +0 -230
- package/src/__tests__/governance.test.ts +0 -522
- package/src/__tests__/grading-ops.test.ts +0 -361
- package/src/__tests__/health-registry.test.ts +0 -173
- package/src/__tests__/identity-manager.test.ts +0 -243
- package/src/__tests__/intake-pipeline.test.ts +0 -162
- package/src/__tests__/intent-router.test.ts +0 -222
- package/src/__tests__/knowledge-review.test.ts +0 -104
- package/src/__tests__/llm-client.test.ts +0 -69
- package/src/__tests__/llm.test.ts +0 -556
- package/src/__tests__/loader.test.ts +0 -176
- package/src/__tests__/loop-ops.test.ts +0 -469
- package/src/__tests__/lsp-transport.test.ts +0 -442
- package/src/__tests__/memory-cross-project-ops.test.ts +0 -248
- package/src/__tests__/memory-extra-ops.test.ts +0 -352
- package/src/__tests__/migration-runner.test.ts +0 -170
- package/src/__tests__/module-manifest-drift.test.ts +0 -59
- package/src/__tests__/normalize.test.ts +0 -85
- package/src/__tests__/obsidian-sync.test.ts +0 -354
- package/src/__tests__/orchestrate-ops.test.ts +0 -289
- package/src/__tests__/pack-ops.test.ts +0 -146
- package/src/__tests__/persistence.test.ts +0 -291
- package/src/__tests__/planning-extra-ops.test.ts +0 -706
- package/src/__tests__/playbook-executor.test.ts +0 -249
- package/src/__tests__/playbook-registry.test.ts +0 -326
- package/src/__tests__/playbook-seeder.test.ts +0 -163
- package/src/__tests__/playbook.test.ts +0 -389
- package/src/__tests__/plugin-ops.test.ts +0 -411
- package/src/__tests__/plugin-system.test.ts +0 -509
- package/src/__tests__/project-ops.test.ts +0 -381
- package/src/__tests__/replayable-stream.test.ts +0 -177
- package/src/__tests__/runtime.test.ts +0 -95
- package/src/__tests__/scope-detector.test.ts +0 -121
- package/src/__tests__/template-manager.test.ts +0 -222
- package/src/__tests__/token-resolver.test.ts +0 -79
- package/src/__tests__/transport.test.ts +0 -758
- package/src/__tests__/vault-branching.test.ts +0 -274
- package/src/__tests__/vault-extra-ops.test.ts +0 -482
- package/src/__tests__/vault-integrity.test.ts +0 -71
- package/src/__tests__/vault-manager.test.ts +0 -238
- package/src/__tests__/ws-transport.test.ts +0 -479
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for gap-patterns.ts — helpers, constants, and passes 1-4.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect } from 'vitest';
|
|
6
|
+
import type { Plan } from './planner.js';
|
|
7
|
+
import {
|
|
8
|
+
gap,
|
|
9
|
+
taskText,
|
|
10
|
+
decisionText,
|
|
11
|
+
decisionsText,
|
|
12
|
+
containsAny,
|
|
13
|
+
analyzeStructure,
|
|
14
|
+
analyzeCompleteness,
|
|
15
|
+
analyzeFeasibility,
|
|
16
|
+
analyzeRisk,
|
|
17
|
+
METRIC_PATTERNS,
|
|
18
|
+
EXCLUSION_KEYWORDS,
|
|
19
|
+
OVERLY_BROAD_PATTERNS,
|
|
20
|
+
DEPENDENCY_KEYWORDS,
|
|
21
|
+
BREAKING_CHANGE_KEYWORDS,
|
|
22
|
+
MITIGATION_KEYWORDS,
|
|
23
|
+
VERIFICATION_KEYWORDS,
|
|
24
|
+
} from './gap-patterns.js';
|
|
25
|
+
|
|
26
|
+
function makePlan(overrides: Partial<Plan> = {}): Plan {
|
|
27
|
+
return {
|
|
28
|
+
id: 'plan-test',
|
|
29
|
+
objective: 'Implement user authentication with JWT tokens and session management',
|
|
30
|
+
scope: 'Auth module, middleware, and user service. Does not include OAuth providers.',
|
|
31
|
+
status: 'draft',
|
|
32
|
+
decisions: [
|
|
33
|
+
{ decision: 'Use JWT for stateless auth', rationale: 'Because it scales horizontally without shared session store' },
|
|
34
|
+
],
|
|
35
|
+
tasks: [
|
|
36
|
+
{ id: 'task-1', title: 'Add JWT signing', description: 'Implement JWT sign/verify using built-in crypto module', status: 'pending', updatedAt: Date.now() },
|
|
37
|
+
{ id: 'task-2', title: 'Add auth middleware', description: 'Create Express middleware that validates JWT from Authorization header', status: 'pending', updatedAt: Date.now() },
|
|
38
|
+
{ id: 'task-3', title: 'Add login endpoint', description: 'POST /auth/login returns JWT after verifying credentials', status: 'pending', updatedAt: Date.now() },
|
|
39
|
+
{ id: 'task-4', title: 'Add test coverage', description: 'Test JWT signing, middleware rejection, and login flow end-to-end', status: 'pending', updatedAt: Date.now() },
|
|
40
|
+
],
|
|
41
|
+
checks: [],
|
|
42
|
+
createdAt: Date.now(),
|
|
43
|
+
updatedAt: Date.now(),
|
|
44
|
+
...overrides,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe('Helper functions', () => {
|
|
49
|
+
describe('gap()', () => {
|
|
50
|
+
it('creates a PlanGap with auto-generated id', () => {
|
|
51
|
+
const result = gap('critical', 'structure', 'desc', 'rec');
|
|
52
|
+
expect(result.id).toMatch(/^gap_/);
|
|
53
|
+
expect(result.severity).toBe('critical');
|
|
54
|
+
expect(result.category).toBe('structure');
|
|
55
|
+
expect(result.description).toBe('desc');
|
|
56
|
+
expect(result.recommendation).toBe('rec');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('includes location when provided', () => {
|
|
60
|
+
const result = gap('minor', 'clarity', 'd', 'r', 'objective');
|
|
61
|
+
expect(result.location).toBe('objective');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('excludes location when undefined', () => {
|
|
65
|
+
const result = gap('minor', 'clarity', 'd', 'r');
|
|
66
|
+
expect(result).not.toHaveProperty('location');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('includes _trigger when provided', () => {
|
|
70
|
+
const result = gap('minor', 'clarity', 'd', 'r', undefined, 'test_trigger');
|
|
71
|
+
expect(result._trigger).toBe('test_trigger');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('excludes _trigger when undefined', () => {
|
|
75
|
+
const result = gap('minor', 'clarity', 'd', 'r');
|
|
76
|
+
expect(result).not.toHaveProperty('_trigger');
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('taskText()', () => {
|
|
81
|
+
it('combines task titles and descriptions', () => {
|
|
82
|
+
const plan = makePlan();
|
|
83
|
+
const text = taskText(plan);
|
|
84
|
+
expect(text).toContain('Add JWT signing');
|
|
85
|
+
expect(text).toContain('Implement JWT sign/verify');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('returns empty string for plan with no tasks', () => {
|
|
89
|
+
const plan = makePlan({ tasks: [] });
|
|
90
|
+
expect(taskText(plan)).toBe('');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('decisionText()', () => {
|
|
95
|
+
it('extracts text from string decision', () => {
|
|
96
|
+
expect(decisionText('Use JWT')).toBe('Use JWT');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('extracts text from structured decision', () => {
|
|
100
|
+
const result = decisionText({ decision: 'Use JWT', rationale: 'scales well' });
|
|
101
|
+
expect(result).toBe('Use JWT scales well');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('decisionsText()', () => {
|
|
106
|
+
it('combines all decisions', () => {
|
|
107
|
+
const plan = makePlan();
|
|
108
|
+
const text = decisionsText(plan);
|
|
109
|
+
expect(text).toContain('Use JWT for stateless auth');
|
|
110
|
+
expect(text).toContain('scales horizontally');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('containsAny()', () => {
|
|
115
|
+
it('returns true when text contains a pattern', () => {
|
|
116
|
+
expect(containsAny('rewrite everything from scratch', ['from scratch'])).toBe(true);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('is case-insensitive', () => {
|
|
120
|
+
expect(containsAny('FROM SCRATCH', ['from scratch'])).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('returns false when no patterns match', () => {
|
|
124
|
+
expect(containsAny('simple change', ['everything', 'rewrite'])).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('returns false for empty text', () => {
|
|
128
|
+
expect(containsAny('', ['test'])).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('returns false for empty patterns', () => {
|
|
132
|
+
expect(containsAny('hello world', [])).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('Pattern constants', () => {
|
|
138
|
+
it('METRIC_PATTERNS matches numbers', () => {
|
|
139
|
+
expect(METRIC_PATTERNS.some((p) => p.test('reduce latency by 50%'))).toBe(true);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('EXCLUSION_KEYWORDS includes common exclusion words', () => {
|
|
143
|
+
expect(EXCLUSION_KEYWORDS).toContain('exclude');
|
|
144
|
+
expect(EXCLUSION_KEYWORDS).toContain('not');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('OVERLY_BROAD_PATTERNS includes dangerous scope terms', () => {
|
|
148
|
+
expect(OVERLY_BROAD_PATTERNS).toContain('complete rewrite');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('DEPENDENCY_KEYWORDS includes ordering terms', () => {
|
|
152
|
+
expect(DEPENDENCY_KEYWORDS).toContain('depends');
|
|
153
|
+
expect(DEPENDENCY_KEYWORDS).toContain('prerequisite');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('BREAKING_CHANGE_KEYWORDS includes migration terms', () => {
|
|
157
|
+
expect(BREAKING_CHANGE_KEYWORDS).toContain('breaking change');
|
|
158
|
+
expect(BREAKING_CHANGE_KEYWORDS).toContain('database migration');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('MITIGATION_KEYWORDS includes safety terms', () => {
|
|
162
|
+
expect(MITIGATION_KEYWORDS).toContain('rollback');
|
|
163
|
+
expect(MITIGATION_KEYWORDS).toContain('feature flag');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('VERIFICATION_KEYWORDS includes testing terms', () => {
|
|
167
|
+
expect(VERIFICATION_KEYWORDS).toContain('test');
|
|
168
|
+
expect(VERIFICATION_KEYWORDS).toContain('coverage');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe('Pass 1: Structure', () => {
|
|
173
|
+
it('returns no gaps for a well-structured plan', () => {
|
|
174
|
+
const gaps = analyzeStructure(makePlan());
|
|
175
|
+
expect(gaps).toHaveLength(0);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('returns critical gap for missing objective', () => {
|
|
179
|
+
const gaps = analyzeStructure(makePlan({ objective: '' }));
|
|
180
|
+
expect(gaps.some((g) => g._trigger === 'missing_or_short_objective')).toBe(true);
|
|
181
|
+
expect(gaps.find((g) => g._trigger === 'missing_or_short_objective')?.severity).toBe('critical');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('returns critical gap for short objective', () => {
|
|
185
|
+
const gaps = analyzeStructure(makePlan({ objective: 'Fix' }));
|
|
186
|
+
expect(gaps.some((g) => g._trigger === 'missing_or_short_objective')).toBe(true);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('returns critical gap for missing scope', () => {
|
|
190
|
+
const gaps = analyzeStructure(makePlan({ scope: '' }));
|
|
191
|
+
expect(gaps.some((g) => g._trigger === 'missing_or_short_scope')).toBe(true);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('returns critical gap for no tasks', () => {
|
|
195
|
+
const gaps = analyzeStructure(makePlan({ tasks: [] }));
|
|
196
|
+
expect(gaps.some((g) => g._trigger === 'no_tasks')).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('returns multiple gaps for completely empty plan', () => {
|
|
200
|
+
const gaps = analyzeStructure(makePlan({ objective: '', scope: '', tasks: [] }));
|
|
201
|
+
expect(gaps.length).toBe(3);
|
|
202
|
+
expect(gaps.every((g) => g.severity === 'critical')).toBe(true);
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe('Pass 2: Completeness', () => {
|
|
207
|
+
it('flags objective without measurable metrics', () => {
|
|
208
|
+
const plan = makePlan({ objective: 'Improve the login experience for all users globally' });
|
|
209
|
+
const gaps = analyzeCompleteness(plan);
|
|
210
|
+
expect(gaps.some((g) => g._trigger === 'no_metrics_in_objective')).toBe(true);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('does not flag objective with numbers', () => {
|
|
214
|
+
const plan = makePlan({ objective: 'Reduce login latency to under 200ms for 95% of users' });
|
|
215
|
+
const gaps = analyzeCompleteness(plan);
|
|
216
|
+
expect(gaps.some((g) => g._trigger === 'no_metrics_in_objective')).toBe(false);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('flags short decisions', () => {
|
|
220
|
+
const plan = makePlan({ decisions: [{ decision: 'JWT', rationale: '' }] });
|
|
221
|
+
const gaps = analyzeCompleteness(plan);
|
|
222
|
+
expect(gaps.some((g) => g._trigger === 'short_decision')).toBe(true);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('flags scope without exclusions', () => {
|
|
226
|
+
const plan = makePlan({ scope: 'Auth module and middleware for the API layer' });
|
|
227
|
+
const gaps = analyzeCompleteness(plan);
|
|
228
|
+
expect(gaps.some((g) => g._trigger === 'no_exclusions_in_scope')).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('does not flag scope with exclusion keywords', () => {
|
|
232
|
+
const plan = makePlan({ scope: 'Auth module. Does not include OAuth providers.' });
|
|
233
|
+
const gaps = analyzeCompleteness(plan);
|
|
234
|
+
expect(gaps.some((g) => g._trigger === 'no_exclusions_in_scope')).toBe(false);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe('Pass 3: Feasibility', () => {
|
|
239
|
+
it('flags overly broad scope', () => {
|
|
240
|
+
const plan = makePlan({ scope: 'Complete rewrite of the entire codebase' });
|
|
241
|
+
const gaps = analyzeFeasibility(plan);
|
|
242
|
+
expect(gaps.some((g) => g._trigger === 'overly_broad_scope')).toBe(true);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('does not flag reasonable scope', () => {
|
|
246
|
+
const plan = makePlan();
|
|
247
|
+
const gaps = analyzeFeasibility(plan);
|
|
248
|
+
expect(gaps.some((g) => g._trigger === 'overly_broad_scope')).toBe(false);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('flags missing dependencies for 4+ tasks', () => {
|
|
252
|
+
const plan = makePlan();
|
|
253
|
+
// Default plan has 4 tasks, no dependency keywords
|
|
254
|
+
const gaps = analyzeFeasibility(plan);
|
|
255
|
+
expect(gaps.some((g) => g._trigger === 'no_dependency_awareness')).toBe(true);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('does not flag when tasks have dependsOn', () => {
|
|
259
|
+
const plan = makePlan({
|
|
260
|
+
tasks: [
|
|
261
|
+
{ id: 't1', title: 'Setup', description: 'Setup project', status: 'pending', updatedAt: Date.now() },
|
|
262
|
+
{ id: 't2', title: 'Build', description: 'Build feature', status: 'pending', dependsOn: ['t1'], updatedAt: Date.now() },
|
|
263
|
+
{ id: 't3', title: 'Test', description: 'Test feature', status: 'pending', dependsOn: ['t2'], updatedAt: Date.now() },
|
|
264
|
+
{ id: 't4', title: 'Deploy', description: 'Deploy to prod', status: 'pending', dependsOn: ['t3'], updatedAt: Date.now() },
|
|
265
|
+
],
|
|
266
|
+
});
|
|
267
|
+
const gaps = analyzeFeasibility(plan);
|
|
268
|
+
expect(gaps.some((g) => g._trigger === 'no_dependency_awareness')).toBe(false);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('does not flag when 3 or fewer tasks', () => {
|
|
272
|
+
const plan = makePlan({
|
|
273
|
+
tasks: [
|
|
274
|
+
{ id: 't1', title: 'Task 1', description: 'Do something', status: 'pending', updatedAt: Date.now() },
|
|
275
|
+
{ id: 't2', title: 'Task 2', description: 'Do another thing', status: 'pending', updatedAt: Date.now() },
|
|
276
|
+
],
|
|
277
|
+
});
|
|
278
|
+
const gaps = analyzeFeasibility(plan);
|
|
279
|
+
expect(gaps.some((g) => g._trigger === 'no_dependency_awareness')).toBe(false);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe('Pass 4: Risk', () => {
|
|
284
|
+
it('flags breaking changes without mitigation', () => {
|
|
285
|
+
const plan = makePlan({
|
|
286
|
+
objective: 'Database migration to new schema with breaking changes',
|
|
287
|
+
scope: 'All tables and models. Does not include frontend.',
|
|
288
|
+
});
|
|
289
|
+
const gaps = analyzeRisk(plan);
|
|
290
|
+
expect(gaps.some((g) => g._trigger === 'breaking_without_mitigation')).toBe(true);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('does not flag when mitigation is mentioned', () => {
|
|
294
|
+
const plan = makePlan({
|
|
295
|
+
objective: 'Database migration with breaking changes and rollback plan',
|
|
296
|
+
scope: 'All tables. Not including frontend.',
|
|
297
|
+
});
|
|
298
|
+
const gaps = analyzeRisk(plan);
|
|
299
|
+
expect(gaps.some((g) => g._trigger === 'breaking_without_mitigation')).toBe(false);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('flags missing verification', () => {
|
|
303
|
+
const plan = makePlan({
|
|
304
|
+
objective: 'Refactor the authentication module for better performance',
|
|
305
|
+
scope: 'Auth module only. Not including user service.',
|
|
306
|
+
decisions: [{ decision: 'Use new pattern', rationale: 'Because it is cleaner code' }],
|
|
307
|
+
tasks: [
|
|
308
|
+
{ id: 't1', title: 'Refactor auth', description: 'Change the auth flow implementation', status: 'pending', updatedAt: Date.now() },
|
|
309
|
+
],
|
|
310
|
+
});
|
|
311
|
+
const gaps = analyzeRisk(plan);
|
|
312
|
+
expect(gaps.some((g) => g._trigger === 'no_verification_mentioned')).toBe(true);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it('does not flag when testing is mentioned', () => {
|
|
316
|
+
const plan = makePlan(); // default plan has "test" in task descriptions
|
|
317
|
+
const gaps = analyzeRisk(plan);
|
|
318
|
+
expect(gaps.some((g) => g._trigger === 'no_verification_mentioned')).toBe(false);
|
|
319
|
+
});
|
|
320
|
+
});
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gap analysis helpers, pattern constants, and structural passes (1-4).
|
|
3
|
+
* Contains shared utilities and the first four analysis passes that check
|
|
4
|
+
* structure, completeness, feasibility, and risk.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Plan, PlanDecision } from './planner.js';
|
|
8
|
+
import type { PlanGap, GapSeverity, GapCategory } from './gap-types.js';
|
|
9
|
+
import {
|
|
10
|
+
generateGapId,
|
|
11
|
+
MIN_OBJECTIVE_LENGTH,
|
|
12
|
+
MIN_SCOPE_LENGTH,
|
|
13
|
+
MIN_DECISION_LENGTH,
|
|
14
|
+
} from './gap-types.js';
|
|
15
|
+
|
|
16
|
+
// ─── Helper Functions ────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
/** Create a PlanGap with auto-generated ID. */
|
|
19
|
+
export function gap(
|
|
20
|
+
severity: GapSeverity,
|
|
21
|
+
category: GapCategory,
|
|
22
|
+
description: string,
|
|
23
|
+
recommendation: string,
|
|
24
|
+
location?: string,
|
|
25
|
+
trigger?: string,
|
|
26
|
+
): PlanGap {
|
|
27
|
+
return {
|
|
28
|
+
id: generateGapId(),
|
|
29
|
+
severity,
|
|
30
|
+
category,
|
|
31
|
+
description,
|
|
32
|
+
recommendation,
|
|
33
|
+
...(location ? { location } : {}),
|
|
34
|
+
...(trigger ? { _trigger: trigger } : {}),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Combine all task descriptions + titles into a single text blob for analysis. */
|
|
39
|
+
export function taskText(plan: Plan): string {
|
|
40
|
+
return plan.tasks.map((t) => `${t.title} ${t.description}`).join(' ');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Extract text from a decision (supports both string and structured format). */
|
|
44
|
+
export function decisionText(d: string | PlanDecision): string {
|
|
45
|
+
return typeof d === 'string' ? d : `${d.decision} ${d.rationale}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Combine all decisions into a single text blob. */
|
|
49
|
+
export function decisionsText(plan: Plan): string {
|
|
50
|
+
return plan.decisions.map(decisionText).join(' ');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Check if text contains any of the given patterns (case-insensitive). */
|
|
54
|
+
export function containsAny(text: string, patterns: string[]): boolean {
|
|
55
|
+
const lower = text.toLowerCase();
|
|
56
|
+
return patterns.some((p) => lower.includes(p.toLowerCase()));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ─── Pattern Constants (Passes 1-4) ─────────────────────────────
|
|
60
|
+
|
|
61
|
+
export const METRIC_PATTERNS = [
|
|
62
|
+
/\d+/, /percent/i, /reduce/i, /increase/i, /measure/i,
|
|
63
|
+
/target/i, /goal/i, /kpi/i, /metric/i, /benchmark/i,
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
export const EXCLUSION_KEYWORDS = [
|
|
67
|
+
'not', 'exclude', 'outside', 'beyond', 'limit', 'except', "won't", 'will not',
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
export const OVERLY_BROAD_PATTERNS = [
|
|
71
|
+
'everything', 'all systems', 'entire codebase', 'complete rewrite',
|
|
72
|
+
'from scratch', 'total overhaul', 'rewrite everything',
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
export const DEPENDENCY_KEYWORDS = [
|
|
76
|
+
'depends', 'dependency', 'prerequisite', 'requires', 'blocked', 'before',
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
export const BREAKING_CHANGE_KEYWORDS = [
|
|
80
|
+
'breaking change', 'breaking', 'migration', 'deprecate',
|
|
81
|
+
'remove api', 'remove endpoint', 'schema change', 'database migration',
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
export const MITIGATION_KEYWORDS = [
|
|
85
|
+
'rollback', 'backward compatible', 'backwards compatible', 'feature flag',
|
|
86
|
+
'gradual', 'phased', 'fallback', 'backup', 'canary', 'blue-green',
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
export const VERIFICATION_KEYWORDS = [
|
|
90
|
+
'test', 'verify', 'validate', 'check', 'assert', 'confirm', 'spec', 'coverage',
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
// ─── Pass 1: Structure ───────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
export function analyzeStructure(plan: Plan): PlanGap[] {
|
|
96
|
+
const gaps: PlanGap[] = [];
|
|
97
|
+
|
|
98
|
+
if (!plan.objective || plan.objective.trim().length < MIN_OBJECTIVE_LENGTH) {
|
|
99
|
+
gaps.push(
|
|
100
|
+
gap(
|
|
101
|
+
'critical', 'structure',
|
|
102
|
+
plan.objective
|
|
103
|
+
? `Objective too short (${plan.objective.trim().length} chars, need ${MIN_OBJECTIVE_LENGTH}+).`
|
|
104
|
+
: 'Plan has no objective.',
|
|
105
|
+
'Add a clear objective describing what this plan achieves.',
|
|
106
|
+
'objective', 'missing_or_short_objective',
|
|
107
|
+
),
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!plan.scope || plan.scope.trim().length < MIN_SCOPE_LENGTH) {
|
|
112
|
+
gaps.push(
|
|
113
|
+
gap(
|
|
114
|
+
'critical', 'structure',
|
|
115
|
+
plan.scope
|
|
116
|
+
? `Scope too short (${plan.scope.trim().length} chars, need ${MIN_SCOPE_LENGTH}+).`
|
|
117
|
+
: 'Plan has no scope defined.',
|
|
118
|
+
'Define the scope — what is included and excluded.',
|
|
119
|
+
'scope', 'missing_or_short_scope',
|
|
120
|
+
),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (plan.tasks.length === 0) {
|
|
125
|
+
gaps.push(
|
|
126
|
+
gap('critical', 'structure', 'Plan has no tasks.',
|
|
127
|
+
'Add at least one task to make the plan actionable.',
|
|
128
|
+
'tasks', 'no_tasks'),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return gaps;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ─── Pass 2: Completeness ────────────────────────────────────────
|
|
136
|
+
|
|
137
|
+
export function analyzeCompleteness(plan: Plan): PlanGap[] {
|
|
138
|
+
const gaps: PlanGap[] = [];
|
|
139
|
+
|
|
140
|
+
if (plan.objective && !METRIC_PATTERNS.some((p) => p.test(plan.objective))) {
|
|
141
|
+
gaps.push(
|
|
142
|
+
gap('minor', 'completeness',
|
|
143
|
+
'Objective has no measurable targets or metrics.',
|
|
144
|
+
'Include quantifiable success criteria (numbers, percentages, concrete outcomes).',
|
|
145
|
+
'objective', 'no_metrics_in_objective'),
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (plan.decisions.length > 0) {
|
|
150
|
+
for (let i = 0; i < plan.decisions.length; i++) {
|
|
151
|
+
const d = plan.decisions[i];
|
|
152
|
+
const text = decisionText(d);
|
|
153
|
+
if (text.trim().length < MIN_DECISION_LENGTH) {
|
|
154
|
+
gaps.push(
|
|
155
|
+
gap('major', 'completeness',
|
|
156
|
+
`Decision ${i + 1} is too short (${text.trim().length} chars) — lacks rationale.`,
|
|
157
|
+
'Expand each decision to include the reasoning (why this choice over alternatives).',
|
|
158
|
+
`decisions[${i}]`, 'short_decision'),
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (plan.scope && !containsAny(plan.scope, EXCLUSION_KEYWORDS)) {
|
|
165
|
+
gaps.push(
|
|
166
|
+
gap('minor', 'completeness',
|
|
167
|
+
'Scope does not mention what is excluded.',
|
|
168
|
+
'Add explicit exclusions to prevent scope creep (e.g., "does NOT include…").',
|
|
169
|
+
'scope', 'no_exclusions_in_scope'),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return gaps;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ─── Pass 3: Feasibility ─────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
export function analyzeFeasibility(plan: Plan): PlanGap[] {
|
|
179
|
+
const gaps: PlanGap[] = [];
|
|
180
|
+
const scopeAndTasks = `${plan.scope} ${taskText(plan)}`;
|
|
181
|
+
|
|
182
|
+
if (containsAny(scopeAndTasks, OVERLY_BROAD_PATTERNS)) {
|
|
183
|
+
gaps.push(
|
|
184
|
+
gap('major', 'feasibility',
|
|
185
|
+
'Scope contains overly broad indicators — risk of unrealistic delivery.',
|
|
186
|
+
'Narrow the scope to a well-defined subset. Prefer incremental delivery over big-bang rewrites.',
|
|
187
|
+
'scope', 'overly_broad_scope'),
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (plan.tasks.length > 3 && !containsAny(scopeAndTasks, DEPENDENCY_KEYWORDS)) {
|
|
192
|
+
const hasDeps = plan.tasks.some((t) => t.dependsOn && t.dependsOn.length > 0);
|
|
193
|
+
if (!hasDeps) {
|
|
194
|
+
gaps.push(
|
|
195
|
+
gap('minor', 'feasibility',
|
|
196
|
+
`${plan.tasks.length} tasks with no dependency mentions — execution order unclear.`,
|
|
197
|
+
'Identify dependencies between tasks or add explicit ordering notes.',
|
|
198
|
+
'tasks', 'no_dependency_awareness'),
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return gaps;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ─── Pass 4: Risk ────────────────────────────────────────────────
|
|
207
|
+
|
|
208
|
+
export function analyzeRisk(plan: Plan): PlanGap[] {
|
|
209
|
+
const gaps: PlanGap[] = [];
|
|
210
|
+
const allText = `${plan.objective} ${plan.scope} ${taskText(plan)} ${decisionsText(plan)}`;
|
|
211
|
+
|
|
212
|
+
if (
|
|
213
|
+
containsAny(allText, BREAKING_CHANGE_KEYWORDS) &&
|
|
214
|
+
!containsAny(allText, MITIGATION_KEYWORDS)
|
|
215
|
+
) {
|
|
216
|
+
gaps.push(
|
|
217
|
+
gap('major', 'risk',
|
|
218
|
+
'Plan involves breaking changes but mentions no mitigation strategy.',
|
|
219
|
+
'Add a rollback plan, feature flags, or phased migration approach.',
|
|
220
|
+
undefined, 'breaking_without_mitigation'),
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (plan.tasks.length > 0 && !containsAny(allText, VERIFICATION_KEYWORDS)) {
|
|
225
|
+
gaps.push(
|
|
226
|
+
gap('minor', 'risk',
|
|
227
|
+
'No verification or testing mentioned in the plan.',
|
|
228
|
+
'Add at least one task or note about testing/validation.',
|
|
229
|
+
'tasks', 'no_verification_mentioned'),
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return gaps;
|
|
234
|
+
}
|
|
@@ -15,9 +15,11 @@ export type GapCategory =
|
|
|
15
15
|
| 'clarity'
|
|
16
16
|
| 'semantic-quality'
|
|
17
17
|
| 'knowledge-depth'
|
|
18
|
+
| 'alternative-analysis'
|
|
18
19
|
| 'tool-feasibility'
|
|
19
20
|
| 'flow-alignment'
|
|
20
|
-
| 'anti-pattern'
|
|
21
|
+
| 'anti-pattern'
|
|
22
|
+
| 'rationalization';
|
|
21
23
|
|
|
22
24
|
export interface PlanGap {
|
|
23
25
|
id: string;
|
|
@@ -48,6 +50,7 @@ export const SEVERITY_WEIGHTS: Record<GapSeverity, number> = {
|
|
|
48
50
|
*/
|
|
49
51
|
export const CATEGORY_PENALTY_CAPS: Record<string, number> = {
|
|
50
52
|
clarity: 10,
|
|
53
|
+
'alternative-analysis': 15,
|
|
51
54
|
};
|
|
52
55
|
|
|
53
56
|
/**
|