@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
|
@@ -268,17 +268,26 @@ export class IntentRouter {
|
|
|
268
268
|
// ─── Mode Management ───────────────────────────────────────────────
|
|
269
269
|
|
|
270
270
|
morph(mode: OperationalMode): MorphResult {
|
|
271
|
-
|
|
271
|
+
// Handle "reset" as a built-in alias for GENERAL-MODE
|
|
272
|
+
const resolvedMode: OperationalMode = (mode as string) === 'reset' ? 'GENERAL-MODE' : mode;
|
|
273
|
+
|
|
274
|
+
const row = this.provider.get<ModeRow>('SELECT * FROM agent_modes WHERE mode = ?', [
|
|
275
|
+
resolvedMode,
|
|
276
|
+
]);
|
|
272
277
|
|
|
273
278
|
if (!row) {
|
|
274
|
-
|
|
279
|
+
const available = this.provider
|
|
280
|
+
.all<{ mode: string }>('SELECT mode FROM agent_modes ORDER BY mode')
|
|
281
|
+
.map((r) => r.mode)
|
|
282
|
+
.join(', ');
|
|
283
|
+
throw new Error(`Unknown mode: ${mode}. Available: ${available}`);
|
|
275
284
|
}
|
|
276
285
|
|
|
277
286
|
const previousMode = this.currentMode;
|
|
278
|
-
this.currentMode =
|
|
287
|
+
this.currentMode = resolvedMode;
|
|
279
288
|
const behaviorRules = JSON.parse(row.behavior_rules) as string[];
|
|
280
289
|
|
|
281
|
-
return { previousMode, currentMode:
|
|
290
|
+
return { previousMode, currentMode: resolvedMode, behaviorRules };
|
|
282
291
|
}
|
|
283
292
|
|
|
284
293
|
getCurrentMode(): OperationalMode {
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { classifyEntry } from './classifier.js';
|
|
3
|
+
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
4
|
+
import type { LLMClient } from '../llm/llm-client.js';
|
|
5
|
+
|
|
6
|
+
function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
|
|
7
|
+
return {
|
|
8
|
+
id: overrides.id ?? 'test-1',
|
|
9
|
+
type: overrides.type ?? 'pattern',
|
|
10
|
+
domain: overrides.domain ?? 'testing',
|
|
11
|
+
title: overrides.title ?? 'Test Pattern',
|
|
12
|
+
severity: overrides.severity ?? 'warning',
|
|
13
|
+
description: overrides.description ?? 'A test pattern.',
|
|
14
|
+
tags: overrides.tags ?? ['testing'],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function mockLLM(response: string): LLMClient {
|
|
19
|
+
return {
|
|
20
|
+
complete: vi.fn().mockResolvedValue({ text: response }),
|
|
21
|
+
} as unknown as LLMClient;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('classifyEntry', () => {
|
|
25
|
+
it('returns fallback when llm is null', async () => {
|
|
26
|
+
const result = await classifyEntry(makeEntry(), null);
|
|
27
|
+
expect(result.classified).toBe(false);
|
|
28
|
+
expect(result.suggestedDomain).toBeNull();
|
|
29
|
+
expect(result.suggestedSeverity).toBeNull();
|
|
30
|
+
expect(result.suggestedTags).toEqual([]);
|
|
31
|
+
expect(result.confidence).toBe(0);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('classifies entry with valid LLM response', async () => {
|
|
35
|
+
const llm = mockLLM(JSON.stringify({
|
|
36
|
+
domain: 'security',
|
|
37
|
+
severity: 'critical',
|
|
38
|
+
tags: ['auth', 'jwt', 'security'],
|
|
39
|
+
confidence: 0.9,
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
const result = await classifyEntry(makeEntry({ title: 'Use JWT securely' }), llm);
|
|
43
|
+
expect(result.classified).toBe(true);
|
|
44
|
+
expect(result.suggestedDomain).toBe('security');
|
|
45
|
+
expect(result.suggestedSeverity).toBe('critical');
|
|
46
|
+
expect(result.suggestedTags).toEqual(['auth', 'jwt', 'security']);
|
|
47
|
+
expect(result.confidence).toBe(0.9);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('returns fallback with error on LLM failure', async () => {
|
|
51
|
+
const llm = {
|
|
52
|
+
complete: vi.fn().mockRejectedValue(new Error('LLM unavailable')),
|
|
53
|
+
} as unknown as LLMClient;
|
|
54
|
+
|
|
55
|
+
const result = await classifyEntry(makeEntry(), llm);
|
|
56
|
+
expect(result.classified).toBe(false);
|
|
57
|
+
expect(result.error).toBe('LLM unavailable');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('returns fallback with error on invalid JSON response', async () => {
|
|
61
|
+
const llm = mockLLM('not valid json');
|
|
62
|
+
const result = await classifyEntry(makeEntry(), llm);
|
|
63
|
+
expect(result.classified).toBe(false);
|
|
64
|
+
expect(result.error).toBeDefined();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('handles missing fields in LLM response gracefully', async () => {
|
|
68
|
+
const llm = mockLLM(JSON.stringify({}));
|
|
69
|
+
const result = await classifyEntry(makeEntry(), llm);
|
|
70
|
+
expect(result.classified).toBe(true);
|
|
71
|
+
expect(result.suggestedDomain).toBeNull();
|
|
72
|
+
expect(result.suggestedSeverity).toBeNull();
|
|
73
|
+
expect(result.suggestedTags).toEqual([]);
|
|
74
|
+
expect(result.confidence).toBe(0.5);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('passes entry fields to LLM prompt', async () => {
|
|
78
|
+
const llm = mockLLM(JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }));
|
|
79
|
+
const entry = makeEntry({
|
|
80
|
+
title: 'Specific Title',
|
|
81
|
+
type: 'anti-pattern',
|
|
82
|
+
tags: ['tag-a', 'tag-b'],
|
|
83
|
+
description: 'Specific description.',
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await classifyEntry(entry, llm);
|
|
87
|
+
|
|
88
|
+
const call = (llm.complete as ReturnType<typeof vi.fn>).mock.calls[0][0];
|
|
89
|
+
expect(call.userPrompt).toContain('Specific Title');
|
|
90
|
+
expect(call.userPrompt).toContain('anti-pattern');
|
|
91
|
+
expect(call.userPrompt).toContain('tag-a, tag-b');
|
|
92
|
+
expect(call.userPrompt).toContain('Specific description.');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('uses empty tags placeholder when entry has no tags', async () => {
|
|
96
|
+
const llm = mockLLM(JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }));
|
|
97
|
+
const entry = makeEntry({ tags: [] });
|
|
98
|
+
|
|
99
|
+
await classifyEntry(entry, llm);
|
|
100
|
+
|
|
101
|
+
const call = (llm.complete as ReturnType<typeof vi.fn>).mock.calls[0][0];
|
|
102
|
+
expect(call.userPrompt).toContain('none');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
3
|
+
import { findContradictions, DEFAULT_CONTRADICTION_THRESHOLD } from './contradiction-detector.js';
|
|
4
|
+
|
|
5
|
+
function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
|
|
6
|
+
return {
|
|
7
|
+
id: overrides.id ?? 'test-1',
|
|
8
|
+
type: overrides.type ?? 'pattern',
|
|
9
|
+
domain: overrides.domain ?? 'testing',
|
|
10
|
+
title: overrides.title ?? 'Test Pattern',
|
|
11
|
+
severity: overrides.severity ?? 'warning',
|
|
12
|
+
description: overrides.description ?? 'A test pattern for testing.',
|
|
13
|
+
tags: overrides.tags ?? ['testing'],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('contradiction-detector', () => {
|
|
18
|
+
describe('constants', () => {
|
|
19
|
+
it('exports DEFAULT_CONTRADICTION_THRESHOLD', () => {
|
|
20
|
+
expect(DEFAULT_CONTRADICTION_THRESHOLD).toBe(0.4);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('findContradictions', () => {
|
|
25
|
+
it('returns empty array when no entries', () => {
|
|
26
|
+
expect(findContradictions([])).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('returns empty array when no anti-patterns', () => {
|
|
30
|
+
const entries = [
|
|
31
|
+
makeEntry({ id: 'p1', type: 'pattern' }),
|
|
32
|
+
makeEntry({ id: 'p2', type: 'pattern' }),
|
|
33
|
+
];
|
|
34
|
+
expect(findContradictions(entries)).toEqual([]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('returns empty array when no patterns', () => {
|
|
38
|
+
const entries = [
|
|
39
|
+
makeEntry({ id: 'ap1', type: 'anti-pattern' }),
|
|
40
|
+
makeEntry({ id: 'ap2', type: 'anti-pattern' }),
|
|
41
|
+
];
|
|
42
|
+
expect(findContradictions(entries)).toEqual([]);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('detects contradictions between similar pattern and anti-pattern', () => {
|
|
46
|
+
const entries = [
|
|
47
|
+
makeEntry({
|
|
48
|
+
id: 'p-inline',
|
|
49
|
+
type: 'pattern',
|
|
50
|
+
title: 'Use inline styles for dynamic values',
|
|
51
|
+
description: 'Apply inline styles when values are computed at runtime.',
|
|
52
|
+
tags: ['styling'],
|
|
53
|
+
}),
|
|
54
|
+
makeEntry({
|
|
55
|
+
id: 'ap-inline',
|
|
56
|
+
type: 'anti-pattern',
|
|
57
|
+
title: 'Avoid inline styles for styling',
|
|
58
|
+
description: 'Never use inline styles — prefer CSS classes.',
|
|
59
|
+
tags: ['styling'],
|
|
60
|
+
}),
|
|
61
|
+
];
|
|
62
|
+
const results = findContradictions(entries, 0.2);
|
|
63
|
+
expect(results.length).toBeGreaterThan(0);
|
|
64
|
+
expect(results[0].patternId).toBe('p-inline');
|
|
65
|
+
expect(results[0].antipatternId).toBe('ap-inline');
|
|
66
|
+
expect(results[0].similarity).toBeGreaterThanOrEqual(0.2);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('skips unrelated pattern/anti-pattern pairs', () => {
|
|
70
|
+
const entries = [
|
|
71
|
+
makeEntry({
|
|
72
|
+
id: 'p-auth',
|
|
73
|
+
type: 'pattern',
|
|
74
|
+
title: 'Use JWT for authentication',
|
|
75
|
+
description: 'JSON Web Tokens for stateless auth.',
|
|
76
|
+
tags: ['auth'],
|
|
77
|
+
}),
|
|
78
|
+
makeEntry({
|
|
79
|
+
id: 'ap-css',
|
|
80
|
+
type: 'anti-pattern',
|
|
81
|
+
title: 'Avoid CSS important',
|
|
82
|
+
description: 'Never use important in CSS declarations.',
|
|
83
|
+
tags: ['styling'],
|
|
84
|
+
}),
|
|
85
|
+
];
|
|
86
|
+
const results = findContradictions(entries, 0.8);
|
|
87
|
+
expect(results.length).toBe(0);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('uses searchFn when provided', () => {
|
|
91
|
+
const pattern = makeEntry({
|
|
92
|
+
id: 'p1',
|
|
93
|
+
type: 'pattern',
|
|
94
|
+
title: 'Use inline styles',
|
|
95
|
+
description: 'Apply inline styles.',
|
|
96
|
+
});
|
|
97
|
+
const antipattern = makeEntry({
|
|
98
|
+
id: 'ap1',
|
|
99
|
+
type: 'anti-pattern',
|
|
100
|
+
title: 'Avoid inline styles',
|
|
101
|
+
description: 'Do not use inline styles.',
|
|
102
|
+
});
|
|
103
|
+
const entries = [pattern, antipattern];
|
|
104
|
+
|
|
105
|
+
const searchFn = vi.fn().mockReturnValue([pattern]);
|
|
106
|
+
const results = findContradictions(entries, 0.2, searchFn);
|
|
107
|
+
|
|
108
|
+
expect(searchFn).toHaveBeenCalledWith('Avoid inline styles');
|
|
109
|
+
expect(results.length).toBeGreaterThan(0);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('falls back to all patterns when searchFn returns empty', () => {
|
|
113
|
+
const entries = [
|
|
114
|
+
makeEntry({ id: 'p1', type: 'pattern', title: 'Use inline styles', description: 'Inline.' }),
|
|
115
|
+
makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'Avoid inline styles', description: 'No inline.' }),
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
const searchFn = vi.fn().mockReturnValue([]);
|
|
119
|
+
const results = findContradictions(entries, 0.2, searchFn);
|
|
120
|
+
|
|
121
|
+
expect(searchFn).toHaveBeenCalled();
|
|
122
|
+
// Should still detect — falls back to full scan
|
|
123
|
+
expect(results.length).toBeGreaterThan(0);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('falls back to all patterns when searchFn throws', () => {
|
|
127
|
+
const entries = [
|
|
128
|
+
makeEntry({ id: 'p1', type: 'pattern', title: 'Use inline styles', description: 'Inline.' }),
|
|
129
|
+
makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'Avoid inline styles', description: 'No inline.' }),
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
const searchFn = vi.fn().mockImplementation(() => {
|
|
133
|
+
throw new Error('FTS5 unavailable');
|
|
134
|
+
});
|
|
135
|
+
const results = findContradictions(entries, 0.2, searchFn);
|
|
136
|
+
|
|
137
|
+
expect(results.length).toBeGreaterThan(0);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('respects threshold — high threshold reduces detections', () => {
|
|
141
|
+
const entries = [
|
|
142
|
+
makeEntry({
|
|
143
|
+
id: 'p1',
|
|
144
|
+
type: 'pattern',
|
|
145
|
+
title: 'Prefer inline styles for dynamic',
|
|
146
|
+
description: 'Use inline for dynamic values.',
|
|
147
|
+
}),
|
|
148
|
+
makeEntry({
|
|
149
|
+
id: 'ap1',
|
|
150
|
+
type: 'anti-pattern',
|
|
151
|
+
title: 'Avoid inline styles completely',
|
|
152
|
+
description: 'Never use inline styles at all.',
|
|
153
|
+
}),
|
|
154
|
+
];
|
|
155
|
+
const lowThreshold = findContradictions(entries, 0.1);
|
|
156
|
+
const highThreshold = findContradictions(entries, 0.99);
|
|
157
|
+
expect(highThreshold.length).toBeLessThanOrEqual(lowThreshold.length);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('uses default threshold when none provided', () => {
|
|
161
|
+
const entries = [
|
|
162
|
+
makeEntry({ id: 'p1', type: 'pattern', title: 'A', description: 'B' }),
|
|
163
|
+
makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'C', description: 'D' }),
|
|
164
|
+
];
|
|
165
|
+
// Should not throw
|
|
166
|
+
const results = findContradictions(entries);
|
|
167
|
+
expect(Array.isArray(results)).toBe(true);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('ignores entries that are neither pattern nor anti-pattern', () => {
|
|
171
|
+
const entries = [
|
|
172
|
+
makeEntry({ id: 'r1', type: 'rule', title: 'Use inline styles', description: 'Inline.' }),
|
|
173
|
+
makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'Avoid inline styles', description: 'No inline.' }),
|
|
174
|
+
];
|
|
175
|
+
// Rules should not be compared against anti-patterns
|
|
176
|
+
const results = findContradictions(entries, 0.1);
|
|
177
|
+
expect(results.length).toBe(0);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contradiction Detector — pure-logic module for finding contradictions
|
|
3
|
+
* between pattern and anti-pattern vault entries.
|
|
4
|
+
*
|
|
5
|
+
* Uses TF-IDF cosine similarity with optional FTS5 pre-filtering.
|
|
6
|
+
* Database persistence of detected contradictions is handled by the caller (Curator facade).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
10
|
+
import { tokenize, calculateTfIdf, cosineSimilarity } from '../text/similarity.js';
|
|
11
|
+
import { buildVocabulary, entryToText } from './duplicate-detector.js';
|
|
12
|
+
|
|
13
|
+
// ─── Constants ──────────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_CONTRADICTION_THRESHOLD = 0.4;
|
|
16
|
+
|
|
17
|
+
// ─── Types ──────────────────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
export interface ContradictionCandidate {
|
|
20
|
+
patternId: string;
|
|
21
|
+
antipatternId: string;
|
|
22
|
+
similarity: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface SearchFn {
|
|
26
|
+
(title: string): IntelligenceEntry[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ─── Detect Contradictions ──────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Find pattern/anti-pattern pairs with high textual similarity.
|
|
33
|
+
*
|
|
34
|
+
* @param entries - All vault entries
|
|
35
|
+
* @param threshold - Minimum cosine similarity to flag as contradiction
|
|
36
|
+
* @param searchFn - Optional FTS5-backed candidate retrieval (falls back to all patterns)
|
|
37
|
+
* @returns Array of contradiction candidates (not yet persisted)
|
|
38
|
+
*/
|
|
39
|
+
export function findContradictions(
|
|
40
|
+
entries: IntelligenceEntry[],
|
|
41
|
+
threshold?: number,
|
|
42
|
+
searchFn?: SearchFn,
|
|
43
|
+
): ContradictionCandidate[] {
|
|
44
|
+
const effectiveThreshold = threshold ?? DEFAULT_CONTRADICTION_THRESHOLD;
|
|
45
|
+
const antipatterns = entries.filter((e) => e.type === 'anti-pattern');
|
|
46
|
+
const patterns = entries.filter((e) => e.type === 'pattern');
|
|
47
|
+
|
|
48
|
+
if (antipatterns.length === 0 || patterns.length === 0) return [];
|
|
49
|
+
|
|
50
|
+
const vocabulary = buildVocabulary(entries);
|
|
51
|
+
const detected: ContradictionCandidate[] = [];
|
|
52
|
+
|
|
53
|
+
for (const ap of antipatterns) {
|
|
54
|
+
// Stage 1: FTS5 candidate retrieval (fall back to all patterns if FTS returns empty)
|
|
55
|
+
let candidates: IntelligenceEntry[];
|
|
56
|
+
if (searchFn) {
|
|
57
|
+
try {
|
|
58
|
+
const searchResults = searchFn(ap.title);
|
|
59
|
+
candidates = searchResults.length > 0 ? searchResults : patterns;
|
|
60
|
+
} catch {
|
|
61
|
+
candidates = patterns;
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
candidates = patterns;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Stage 2: TF-IDF cosine similarity
|
|
68
|
+
const apText = entryToText(ap);
|
|
69
|
+
const apVec = calculateTfIdf(tokenize(apText), vocabulary);
|
|
70
|
+
|
|
71
|
+
for (const pattern of candidates) {
|
|
72
|
+
const pText = entryToText(pattern);
|
|
73
|
+
const pVec = calculateTfIdf(tokenize(pText), vocabulary);
|
|
74
|
+
const similarity = cosineSimilarity(apVec, pVec);
|
|
75
|
+
|
|
76
|
+
if (similarity >= effectiveThreshold) {
|
|
77
|
+
detected.push({
|
|
78
|
+
patternId: pattern.id,
|
|
79
|
+
antipatternId: ap.id,
|
|
80
|
+
similarity,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return detected;
|
|
87
|
+
}
|
|
@@ -8,19 +8,19 @@
|
|
|
8
8
|
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
9
9
|
import { Vault } from '../vault/vault.js';
|
|
10
10
|
import { Brain } from '../brain/brain.js';
|
|
11
|
-
import { Curator } from '
|
|
11
|
+
import { Curator } from './curator.js';
|
|
12
12
|
import { JobQueue } from '../queue/job-queue.js';
|
|
13
13
|
import { PipelineRunner } from '../queue/pipeline-runner.js';
|
|
14
14
|
import { TypedEventBus } from '../events/event-bus.js';
|
|
15
15
|
import { LinkManager } from '../vault/linking.js';
|
|
16
|
-
import { evaluateQuality } from '
|
|
17
|
-
import { classifyEntry } from '
|
|
16
|
+
import { evaluateQuality } from './quality-gate.js';
|
|
17
|
+
import { classifyEntry } from './classifier.js';
|
|
18
18
|
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
19
19
|
|
|
20
20
|
// ─── Shared Setup ────────────────────────────────────────────────────
|
|
21
21
|
|
|
22
22
|
let vault: Vault;
|
|
23
|
-
let
|
|
23
|
+
let _brain: Brain;
|
|
24
24
|
let curator: Curator;
|
|
25
25
|
let queue: JobQueue;
|
|
26
26
|
let runner: PipelineRunner;
|
|
@@ -60,7 +60,7 @@ const SEED: IntelligenceEntry[] = [
|
|
|
60
60
|
beforeAll(() => {
|
|
61
61
|
vault = new Vault(':memory:');
|
|
62
62
|
vault.seed(SEED);
|
|
63
|
-
|
|
63
|
+
_brain = new Brain(vault);
|
|
64
64
|
curator = new Curator(vault);
|
|
65
65
|
queue = new JobQueue(vault.getProvider());
|
|
66
66
|
linkManager = new LinkManager(vault.getProvider());
|
|
@@ -153,7 +153,7 @@ describe('Job Queue — curator pipeline', () => {
|
|
|
153
153
|
|
|
154
154
|
const step1 = queue.enqueue('tag-normalize', { entryId, pipelineId });
|
|
155
155
|
const step2 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step1] });
|
|
156
|
-
|
|
156
|
+
queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step2] });
|
|
157
157
|
|
|
158
158
|
const jobs = queue.getByPipeline(pipelineId);
|
|
159
159
|
expect(jobs.length).toBe(3);
|
|
@@ -400,13 +400,13 @@ describe('Full Salvador DAG — 7-step curator pipeline', () => {
|
|
|
400
400
|
const step2 = queue.enqueue('enrich-frontmatter', { entryId, pipelineId, dependsOn: [step1] });
|
|
401
401
|
const step3 = queue.enqueue('tag-normalize', { entryId, pipelineId, dependsOn: [step2] });
|
|
402
402
|
const step4 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step3] });
|
|
403
|
-
const
|
|
403
|
+
const step5Id = queue.enqueue('detect-contradiction', {
|
|
404
404
|
entryId,
|
|
405
405
|
pipelineId,
|
|
406
406
|
dependsOn: [step4],
|
|
407
407
|
});
|
|
408
|
-
const
|
|
409
|
-
|
|
408
|
+
const step6Id = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step5Id] });
|
|
409
|
+
queue.enqueue('verify-searchable', { entryId, pipelineId, dependsOn: [step6Id] });
|
|
410
410
|
|
|
411
411
|
// Drain the DAG
|
|
412
412
|
for (let i = 0; i < 15; i++) {
|
|
@@ -492,7 +492,7 @@ describe('Full pipeline E2E — capture to completion', () => {
|
|
|
492
492
|
const step2 = queue.enqueue('tag-normalize', { entryId, pipelineId, dependsOn: [step1] });
|
|
493
493
|
const step3 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step2] });
|
|
494
494
|
const step4 = queue.enqueue('classify', { entryId, pipelineId, dependsOn: [step3] });
|
|
495
|
-
|
|
495
|
+
queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step4] });
|
|
496
496
|
|
|
497
497
|
// Process all steps — run enough batches to drain DAG
|
|
498
498
|
// (earlier tests may have left pending jobs, so process generously)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import { Vault } from '../vault/vault.js';
|
|
3
|
-
import { Curator } from '
|
|
3
|
+
import { Curator } from './curator.js';
|
|
4
4
|
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
5
5
|
|
|
6
6
|
function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
|
|
@@ -203,6 +203,82 @@ describe('Curator', () => {
|
|
|
203
203
|
const results = curator.detectDuplicates();
|
|
204
204
|
expect(results).toEqual([]);
|
|
205
205
|
});
|
|
206
|
+
|
|
207
|
+
it('should NOT flag cross-domain entries as duplicates', () => {
|
|
208
|
+
vault.seed([
|
|
209
|
+
makeEntry({
|
|
210
|
+
id: 'cross-1',
|
|
211
|
+
domain: 'design',
|
|
212
|
+
title: 'Use semantic tokens for colors',
|
|
213
|
+
description: 'Always use semantic tokens instead of raw hex values for color styling.',
|
|
214
|
+
tags: ['tokens', 'colors'],
|
|
215
|
+
}),
|
|
216
|
+
makeEntry({
|
|
217
|
+
id: 'cross-2',
|
|
218
|
+
domain: 'architecture',
|
|
219
|
+
title: 'Use semantic tokens for colors',
|
|
220
|
+
description: 'Always use semantic tokens instead of raw hex values for color styling.',
|
|
221
|
+
tags: ['tokens', 'colors'],
|
|
222
|
+
}),
|
|
223
|
+
]);
|
|
224
|
+
const results = curator.detectDuplicates(undefined, 0.3);
|
|
225
|
+
expect(results.length).toBe(0);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should still flag same-domain entries as duplicates', () => {
|
|
229
|
+
vault.seed([
|
|
230
|
+
makeEntry({
|
|
231
|
+
id: 'same-1',
|
|
232
|
+
domain: 'design',
|
|
233
|
+
title: 'Use semantic tokens for colors',
|
|
234
|
+
description: 'Always use semantic tokens instead of raw hex values for color styling.',
|
|
235
|
+
tags: ['tokens', 'colors'],
|
|
236
|
+
}),
|
|
237
|
+
makeEntry({
|
|
238
|
+
id: 'same-2',
|
|
239
|
+
domain: 'design',
|
|
240
|
+
title: 'Use semantic tokens for color values',
|
|
241
|
+
description: 'Prefer semantic color tokens over raw hex or rgb values in styling.',
|
|
242
|
+
tags: ['tokens', 'colors'],
|
|
243
|
+
}),
|
|
244
|
+
]);
|
|
245
|
+
const results = curator.detectDuplicates(undefined, 0.3);
|
|
246
|
+
expect(results.length).toBeGreaterThan(0);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should improve health audit score for cross-domain vaults', () => {
|
|
250
|
+
// Seed entries across different domains with similar vocabulary
|
|
251
|
+
vault.seed([
|
|
252
|
+
makeEntry({
|
|
253
|
+
id: 'ha-1',
|
|
254
|
+
domain: 'design',
|
|
255
|
+
type: 'pattern',
|
|
256
|
+
title: 'Use semantic tokens for colors',
|
|
257
|
+
description: 'Always use semantic tokens instead of raw hex values.',
|
|
258
|
+
tags: ['tokens', 'colors'],
|
|
259
|
+
}),
|
|
260
|
+
makeEntry({
|
|
261
|
+
id: 'ha-2',
|
|
262
|
+
domain: 'architecture',
|
|
263
|
+
type: 'anti-pattern',
|
|
264
|
+
title: 'Use semantic tokens for API responses',
|
|
265
|
+
description: 'Always use semantic tokens instead of raw values in API.',
|
|
266
|
+
tags: ['tokens', 'api'],
|
|
267
|
+
}),
|
|
268
|
+
makeEntry({
|
|
269
|
+
id: 'ha-3',
|
|
270
|
+
domain: 'testing',
|
|
271
|
+
type: 'rule',
|
|
272
|
+
title: 'Use semantic assertions',
|
|
273
|
+
description: 'Always use semantic assertions for test clarity.',
|
|
274
|
+
tags: ['tokens', 'testing'],
|
|
275
|
+
}),
|
|
276
|
+
]);
|
|
277
|
+
curator.groomAll();
|
|
278
|
+
const result = curator.healthAudit();
|
|
279
|
+
// Cross-domain entries should not be penalized as duplicates
|
|
280
|
+
expect(result.score).toBeGreaterThanOrEqual(90);
|
|
281
|
+
});
|
|
206
282
|
});
|
|
207
283
|
|
|
208
284
|
// ─── Contradictions ───────────────────────────────────────────
|