cognitive-core 0.1.2 → 0.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/CLAUDE.md +233 -0
- package/README.md +370 -54
- package/dist/atlas.d.ts +10 -10
- package/dist/atlas.d.ts.map +1 -1
- package/dist/atlas.js +79 -48
- package/dist/atlas.js.map +1 -1
- package/dist/bin/cli-utils.d.ts +37 -0
- package/dist/bin/cli-utils.d.ts.map +1 -0
- package/dist/bin/cli-utils.js +176 -0
- package/dist/bin/cli-utils.js.map +1 -0
- package/dist/bin/cognitive-core.d.ts +2 -12
- package/dist/bin/cognitive-core.d.ts.map +1 -1
- package/dist/bin/cognitive-core.js +76 -351
- package/dist/bin/cognitive-core.js.map +1 -1
- package/dist/bin/commands/kb.d.ts +6 -0
- package/dist/bin/commands/kb.d.ts.map +1 -0
- package/dist/bin/commands/kb.js +240 -0
- package/dist/bin/commands/kb.js.map +1 -0
- package/dist/bin/commands/learn.d.ts +6 -0
- package/dist/bin/commands/learn.d.ts.map +1 -0
- package/dist/bin/commands/learn.js +91 -0
- package/dist/bin/commands/learn.js.map +1 -0
- package/dist/bin/commands/legacy.d.ts +12 -0
- package/dist/bin/commands/legacy.d.ts.map +1 -0
- package/dist/bin/commands/legacy.js +142 -0
- package/dist/bin/commands/legacy.js.map +1 -0
- package/dist/bin/commands/run.d.ts +3 -0
- package/dist/bin/commands/run.d.ts.map +1 -0
- package/dist/bin/commands/run.js +99 -0
- package/dist/bin/commands/run.js.map +1 -0
- package/dist/bin/commands/sessions.d.ts +9 -0
- package/dist/bin/commands/sessions.d.ts.map +1 -0
- package/dist/bin/commands/sessions.js +183 -0
- package/dist/bin/commands/sessions.js.map +1 -0
- package/dist/bin/commands/skills.d.ts +6 -0
- package/dist/bin/commands/skills.d.ts.map +1 -0
- package/dist/bin/commands/skills.js +135 -0
- package/dist/bin/commands/skills.js.map +1 -0
- package/dist/embeddings/index.d.ts +1 -0
- package/dist/embeddings/index.d.ts.map +1 -1
- package/dist/embeddings/index.js +2 -0
- package/dist/embeddings/index.js.map +1 -1
- package/dist/embeddings/inverted-index.d.ts +47 -0
- package/dist/embeddings/inverted-index.d.ts.map +1 -0
- package/dist/embeddings/inverted-index.js +122 -0
- package/dist/embeddings/inverted-index.js.map +1 -0
- package/dist/embeddings/manager.d.ts +3 -1
- package/dist/embeddings/manager.d.ts.map +1 -1
- package/dist/embeddings/manager.js +12 -7
- package/dist/embeddings/manager.js.map +1 -1
- package/dist/embeddings/vector-store.d.ts +7 -3
- package/dist/embeddings/vector-store.d.ts.map +1 -1
- package/dist/embeddings/vector-store.js +22 -6
- package/dist/embeddings/vector-store.js.map +1 -1
- package/dist/factory.d.ts +11 -12
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +20 -7
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/learning/analyzer.d.ts.map +1 -1
- package/dist/learning/analyzer.js +17 -35
- package/dist/learning/analyzer.js.map +1 -1
- package/dist/learning/energy-evaluator.d.ts +128 -0
- package/dist/learning/energy-evaluator.d.ts.map +1 -0
- package/dist/learning/energy-evaluator.js +175 -0
- package/dist/learning/energy-evaluator.js.map +1 -0
- package/dist/learning/healing-orchestrator.d.ts +182 -0
- package/dist/learning/healing-orchestrator.d.ts.map +1 -0
- package/dist/learning/healing-orchestrator.js +250 -0
- package/dist/learning/healing-orchestrator.js.map +1 -0
- package/dist/learning/index.d.ts +7 -2
- package/dist/learning/index.d.ts.map +1 -1
- package/dist/learning/index.js +13 -2
- package/dist/learning/index.js.map +1 -1
- package/dist/learning/instant-loop.d.ts +87 -0
- package/dist/learning/instant-loop.d.ts.map +1 -0
- package/dist/learning/instant-loop.js +264 -0
- package/dist/learning/instant-loop.js.map +1 -0
- package/dist/learning/loop-coordinator.d.ts +61 -0
- package/dist/learning/loop-coordinator.d.ts.map +1 -0
- package/dist/learning/loop-coordinator.js +96 -0
- package/dist/learning/loop-coordinator.js.map +1 -0
- package/dist/learning/maintenance-scheduler.d.ts +141 -0
- package/dist/learning/maintenance-scheduler.d.ts.map +1 -0
- package/dist/learning/maintenance-scheduler.js +186 -0
- package/dist/learning/maintenance-scheduler.js.map +1 -0
- package/dist/learning/meta-learner.d.ts.map +1 -1
- package/dist/learning/meta-learner.js +4 -21
- package/dist/learning/meta-learner.js.map +1 -1
- package/dist/learning/pipeline.d.ts +31 -4
- package/dist/learning/pipeline.d.ts.map +1 -1
- package/dist/learning/pipeline.js +64 -12
- package/dist/learning/pipeline.js.map +1 -1
- package/dist/learning/reflexion-generator.d.ts +64 -0
- package/dist/learning/reflexion-generator.d.ts.map +1 -0
- package/dist/learning/reflexion-generator.js +194 -0
- package/dist/learning/reflexion-generator.js.map +1 -0
- package/dist/learning/trajectory-sources/entire.d.ts +8 -5
- package/dist/learning/trajectory-sources/entire.d.ts.map +1 -1
- package/dist/learning/trajectory-sources/entire.js +13 -6
- package/dist/learning/trajectory-sources/entire.js.map +1 -1
- package/dist/learning/trajectory-sources/index.d.ts +1 -1
- package/dist/learning/trajectory-sources/index.d.ts.map +1 -1
- package/dist/learning/trajectory-sources/index.js +1 -1
- package/dist/learning/trajectory-sources/index.js.map +1 -1
- package/dist/learning/trajectory-sources/pipeline.d.ts +4 -4
- package/dist/learning/trajectory-sources/pipeline.d.ts.map +1 -1
- package/dist/learning/trajectory-sources/pipeline.js +2 -2
- package/dist/learning/trajectory-sources/pipeline.js.map +1 -1
- package/dist/learning/unified-pipeline.d.ts +281 -0
- package/dist/learning/unified-pipeline.d.ts.map +1 -0
- package/dist/learning/unified-pipeline.js +637 -0
- package/dist/learning/unified-pipeline.js.map +1 -0
- package/dist/memory/candidate-retrieval.d.ts +43 -0
- package/dist/memory/candidate-retrieval.d.ts.map +1 -0
- package/dist/memory/candidate-retrieval.js +41 -0
- package/dist/memory/candidate-retrieval.js.map +1 -0
- package/dist/memory/causal-store.d.ts +97 -0
- package/dist/memory/causal-store.d.ts.map +1 -0
- package/dist/memory/causal-store.js +209 -0
- package/dist/memory/causal-store.js.map +1 -0
- package/dist/memory/coherence.d.ts +71 -0
- package/dist/memory/coherence.d.ts.map +1 -0
- package/dist/memory/coherence.js +176 -0
- package/dist/memory/coherence.js.map +1 -0
- package/dist/memory/experience.d.ts +39 -6
- package/dist/memory/experience.d.ts.map +1 -1
- package/dist/memory/experience.js +193 -49
- package/dist/memory/experience.js.map +1 -1
- package/dist/memory/index.d.ts +7 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +12 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/knowledge-bank.d.ts +14 -0
- package/dist/memory/knowledge-bank.d.ts.map +1 -1
- package/dist/memory/knowledge-bank.js +45 -0
- package/dist/memory/knowledge-bank.js.map +1 -1
- package/dist/memory/meta.d.ts +7 -8
- package/dist/memory/meta.d.ts.map +1 -1
- package/dist/memory/meta.js +73 -79
- package/dist/memory/meta.js.map +1 -1
- package/dist/memory/playbook.d.ts +26 -9
- package/dist/memory/playbook.d.ts.map +1 -1
- package/dist/memory/playbook.js +198 -74
- package/dist/memory/playbook.js.map +1 -1
- package/dist/memory/reasoning-bank.d.ts +130 -0
- package/dist/memory/reasoning-bank.d.ts.map +1 -0
- package/dist/memory/reasoning-bank.js +342 -0
- package/dist/memory/reasoning-bank.js.map +1 -0
- package/dist/memory/reflexion.d.ts +59 -0
- package/dist/memory/reflexion.d.ts.map +1 -0
- package/dist/memory/reflexion.js +96 -0
- package/dist/memory/reflexion.js.map +1 -0
- package/dist/memory/system.d.ts +7 -2
- package/dist/memory/system.d.ts.map +1 -1
- package/dist/memory/system.js +19 -7
- package/dist/memory/system.js.map +1 -1
- package/dist/memory/temporal-compressor.d.ts +126 -0
- package/dist/memory/temporal-compressor.d.ts.map +1 -0
- package/dist/memory/temporal-compressor.js +335 -0
- package/dist/memory/temporal-compressor.js.map +1 -0
- package/dist/persistence/index.d.ts +11 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +11 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/migrator.d.ts +40 -0
- package/dist/persistence/migrator.d.ts.map +1 -0
- package/dist/persistence/migrator.js +238 -0
- package/dist/persistence/migrator.js.map +1 -0
- package/dist/persistence/serializers.d.ts +45 -0
- package/dist/persistence/serializers.d.ts.map +1 -0
- package/dist/persistence/serializers.js +80 -0
- package/dist/persistence/serializers.js.map +1 -0
- package/dist/persistence/sqlite-persistence.d.ts +228 -0
- package/dist/persistence/sqlite-persistence.d.ts.map +1 -0
- package/dist/persistence/sqlite-persistence.js +588 -0
- package/dist/persistence/sqlite-persistence.js.map +1 -0
- package/dist/runtime/flows/learning.d.ts +10 -12
- package/dist/runtime/flows/learning.d.ts.map +1 -1
- package/dist/runtime/flows/learning.js +10 -23
- package/dist/runtime/flows/learning.js.map +1 -1
- package/dist/search/index.d.ts +1 -0
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +2 -0
- package/dist/search/index.js.map +1 -1
- package/dist/search/moe-gate.d.ts +124 -0
- package/dist/search/moe-gate.d.ts.map +1 -0
- package/dist/search/moe-gate.js +234 -0
- package/dist/search/moe-gate.js.map +1 -0
- package/dist/search/router.d.ts +32 -2
- package/dist/search/router.d.ts.map +1 -1
- package/dist/search/router.js +87 -4
- package/dist/search/router.js.map +1 -1
- package/dist/session-bank/git-reader.d.ts +9 -4
- package/dist/session-bank/git-reader.d.ts.map +1 -1
- package/dist/session-bank/git-reader.js +22 -15
- package/dist/session-bank/git-reader.js.map +1 -1
- package/dist/session-bank/index.d.ts +2 -2
- package/dist/session-bank/index.d.ts.map +1 -1
- package/dist/session-bank/index.js +2 -2
- package/dist/session-bank/index.js.map +1 -1
- package/dist/session-bank/parser.d.ts +16 -5
- package/dist/session-bank/parser.d.ts.map +1 -1
- package/dist/session-bank/parser.js +187 -80
- package/dist/session-bank/parser.js.map +1 -1
- package/dist/session-bank/session-bank.d.ts +5 -0
- package/dist/session-bank/session-bank.d.ts.map +1 -1
- package/dist/session-bank/session-bank.js +30 -9
- package/dist/session-bank/session-bank.js.map +1 -1
- package/dist/session-bank/types.d.ts +4 -1
- package/dist/session-bank/types.d.ts.map +1 -1
- package/dist/session-bank/types.js +3 -3
- package/dist/session-bank/types.js.map +1 -1
- package/dist/surfacing/skill-publisher.d.ts.map +1 -1
- package/dist/surfacing/skill-publisher.js +15 -43
- package/dist/surfacing/skill-publisher.js.map +1 -1
- package/dist/surfacing/sqlite-storage-adapter.d.ts.map +1 -1
- package/dist/surfacing/sqlite-storage-adapter.js +13 -21
- package/dist/surfacing/sqlite-storage-adapter.js.map +1 -1
- package/dist/types/config.d.ts +100 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +27 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/memory.d.ts +52 -0
- package/dist/types/memory.d.ts.map +1 -1
- package/dist/types/memory.js +13 -0
- package/dist/types/memory.js.map +1 -1
- package/dist/types/playbook.d.ts +4 -0
- package/dist/types/playbook.d.ts.map +1 -1
- package/dist/types/playbook.js.map +1 -1
- package/dist/utils/error-classifier.d.ts +30 -0
- package/dist/utils/error-classifier.d.ts.map +1 -0
- package/dist/utils/error-classifier.js +85 -0
- package/dist/utils/error-classifier.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/partitioned-store.d.ts +93 -0
- package/dist/utils/partitioned-store.d.ts.map +1 -0
- package/dist/utils/partitioned-store.js +251 -0
- package/dist/utils/partitioned-store.js.map +1 -0
- package/dist/utils/trajectory-helpers.d.ts +39 -0
- package/dist/utils/trajectory-helpers.d.ts.map +1 -0
- package/dist/utils/trajectory-helpers.js +57 -0
- package/dist/utils/trajectory-helpers.js.map +1 -0
- package/dist/workspace/runner.d.ts +3 -4
- package/dist/workspace/runner.d.ts.map +1 -1
- package/dist/workspace/runner.js.map +1 -1
- package/dist/workspace/types.d.ts +9 -2
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/types.js.map +1 -1
- package/package.json +6 -4
- package/references/sessionlog/.husky/pre-commit +1 -0
- package/references/sessionlog/.lintstagedrc.json +4 -0
- package/references/sessionlog/.prettierignore +4 -0
- package/references/sessionlog/.prettierrc.json +11 -0
- package/references/sessionlog/LICENSE +21 -0
- package/references/sessionlog/README.md +453 -0
- package/references/sessionlog/eslint.config.js +58 -0
- package/references/sessionlog/package-lock.json +3672 -0
- package/references/sessionlog/package.json +65 -0
- package/references/sessionlog/src/__tests__/agent-hooks.test.ts +570 -0
- package/references/sessionlog/src/__tests__/agent-registry.test.ts +127 -0
- package/references/sessionlog/src/__tests__/claude-code-hooks.test.ts +225 -0
- package/references/sessionlog/src/__tests__/claude-generator.test.ts +46 -0
- package/references/sessionlog/src/__tests__/commit-msg.test.ts +86 -0
- package/references/sessionlog/src/__tests__/cursor-agent.test.ts +224 -0
- package/references/sessionlog/src/__tests__/e2e-live.test.ts +890 -0
- package/references/sessionlog/src/__tests__/event-log.test.ts +183 -0
- package/references/sessionlog/src/__tests__/flush-sentinel.test.ts +105 -0
- package/references/sessionlog/src/__tests__/gemini-agent.test.ts +375 -0
- package/references/sessionlog/src/__tests__/git-hooks.test.ts +78 -0
- package/references/sessionlog/src/__tests__/hook-managers.test.ts +121 -0
- package/references/sessionlog/src/__tests__/lifecycle-tasks.test.ts +759 -0
- package/references/sessionlog/src/__tests__/opencode-agent.test.ts +338 -0
- package/references/sessionlog/src/__tests__/redaction.test.ts +136 -0
- package/references/sessionlog/src/__tests__/session-repo.test.ts +353 -0
- package/references/sessionlog/src/__tests__/session-store.test.ts +166 -0
- package/references/sessionlog/src/__tests__/setup-ccweb.test.ts +466 -0
- package/references/sessionlog/src/__tests__/skill-live.test.ts +461 -0
- package/references/sessionlog/src/__tests__/summarize.test.ts +348 -0
- package/references/sessionlog/src/__tests__/task-plan-e2e.test.ts +610 -0
- package/references/sessionlog/src/__tests__/task-plan-live.test.ts +632 -0
- package/references/sessionlog/src/__tests__/transcript-timestamp.test.ts +121 -0
- package/references/sessionlog/src/__tests__/types.test.ts +166 -0
- package/references/sessionlog/src/__tests__/utils.test.ts +333 -0
- package/references/sessionlog/src/__tests__/validation.test.ts +103 -0
- package/references/sessionlog/src/__tests__/worktree.test.ts +57 -0
- package/references/sessionlog/src/agent/agents/claude-code.ts +1089 -0
- package/references/sessionlog/src/agent/agents/cursor.ts +361 -0
- package/references/sessionlog/src/agent/agents/gemini-cli.ts +632 -0
- package/references/sessionlog/src/agent/agents/opencode.ts +540 -0
- package/references/sessionlog/src/agent/registry.ts +143 -0
- package/references/sessionlog/src/agent/session-types.ts +113 -0
- package/references/sessionlog/src/agent/types.ts +220 -0
- package/references/sessionlog/src/cli.ts +597 -0
- package/references/sessionlog/src/commands/clean.ts +133 -0
- package/references/sessionlog/src/commands/disable.ts +84 -0
- package/references/sessionlog/src/commands/doctor.ts +145 -0
- package/references/sessionlog/src/commands/enable.ts +202 -0
- package/references/sessionlog/src/commands/explain.ts +261 -0
- package/references/sessionlog/src/commands/reset.ts +105 -0
- package/references/sessionlog/src/commands/resume.ts +180 -0
- package/references/sessionlog/src/commands/rewind.ts +195 -0
- package/references/sessionlog/src/commands/setup-ccweb.ts +275 -0
- package/references/sessionlog/src/commands/status.ts +172 -0
- package/references/sessionlog/src/config.ts +165 -0
- package/references/sessionlog/src/events/event-log.ts +126 -0
- package/references/sessionlog/src/git-operations.ts +558 -0
- package/references/sessionlog/src/hooks/git-hooks.ts +165 -0
- package/references/sessionlog/src/hooks/lifecycle.ts +391 -0
- package/references/sessionlog/src/index.ts +650 -0
- package/references/sessionlog/src/security/redaction.ts +283 -0
- package/references/sessionlog/src/session/state-machine.ts +452 -0
- package/references/sessionlog/src/store/checkpoint-store.ts +509 -0
- package/references/sessionlog/src/store/native-store.ts +173 -0
- package/references/sessionlog/src/store/provider-types.ts +99 -0
- package/references/sessionlog/src/store/session-store.ts +266 -0
- package/references/sessionlog/src/strategy/attribution.ts +296 -0
- package/references/sessionlog/src/strategy/common.ts +207 -0
- package/references/sessionlog/src/strategy/content-overlap.ts +228 -0
- package/references/sessionlog/src/strategy/manual-commit.ts +988 -0
- package/references/sessionlog/src/strategy/types.ts +279 -0
- package/references/sessionlog/src/summarize/claude-generator.ts +115 -0
- package/references/sessionlog/src/summarize/summarize.ts +432 -0
- package/references/sessionlog/src/types.ts +508 -0
- package/references/sessionlog/src/utils/chunk-files.ts +49 -0
- package/references/sessionlog/src/utils/commit-message.ts +65 -0
- package/references/sessionlog/src/utils/detect-agent.ts +36 -0
- package/references/sessionlog/src/utils/hook-managers.ts +125 -0
- package/references/sessionlog/src/utils/ide-tags.ts +32 -0
- package/references/sessionlog/src/utils/paths.ts +79 -0
- package/references/sessionlog/src/utils/preview-rewind.ts +80 -0
- package/references/sessionlog/src/utils/rewind-conflict.ts +121 -0
- package/references/sessionlog/src/utils/shadow-branch.ts +109 -0
- package/references/sessionlog/src/utils/string-utils.ts +46 -0
- package/references/sessionlog/src/utils/todo-extract.ts +188 -0
- package/references/sessionlog/src/utils/trailers.ts +187 -0
- package/references/sessionlog/src/utils/transcript-parse.ts +177 -0
- package/references/sessionlog/src/utils/transcript-timestamp.ts +59 -0
- package/references/sessionlog/src/utils/tree-ops.ts +219 -0
- package/references/sessionlog/src/utils/tty.ts +72 -0
- package/references/sessionlog/src/utils/validation.ts +65 -0
- package/references/sessionlog/src/utils/worktree.ts +58 -0
- package/references/sessionlog/src/wire-types.ts +59 -0
- package/references/sessionlog/templates/setup-env.sh +153 -0
- package/references/sessionlog/tsconfig.json +18 -0
- package/references/sessionlog/vitest.config.ts +12 -0
- package/references/skill-tree/.sudocode/issues.jsonl +8 -0
- package/references/skill-tree/.sudocode/specs.jsonl +2 -0
- package/references/skill-tree/CLAUDE.md +56 -80
- package/references/skill-tree/README.md +188 -140
- package/references/skill-tree/examples/basic-usage.ts +95 -121
- package/references/skill-tree/package-lock.json +369 -26
- package/references/skill-tree/package.json +1 -1
- package/src/atlas.ts +97 -67
- package/src/bin/cli-utils.ts +220 -0
- package/src/bin/cognitive-core.ts +84 -392
- package/src/bin/commands/kb.ts +266 -0
- package/src/bin/commands/learn.ts +100 -0
- package/src/bin/commands/legacy.ts +182 -0
- package/src/bin/commands/run.ts +113 -0
- package/src/bin/commands/sessions.ts +221 -0
- package/src/bin/commands/skills.ts +146 -0
- package/src/embeddings/index.ts +3 -0
- package/src/embeddings/inverted-index.ts +134 -0
- package/src/embeddings/manager.ts +13 -8
- package/src/embeddings/vector-store.ts +21 -9
- package/src/factory.ts +33 -16
- package/src/index.ts +109 -9
- package/src/learning/analyzer.ts +21 -37
- package/src/learning/energy-evaluator.ts +282 -0
- package/src/learning/healing-orchestrator.ts +383 -0
- package/src/learning/index.ts +65 -9
- package/src/learning/instant-loop.ts +357 -0
- package/src/learning/maintenance-scheduler.ts +271 -0
- package/src/learning/meta-learner.ts +5 -23
- package/src/learning/reflexion-generator.ts +273 -0
- package/src/learning/trajectory-sources/entire.ts +24 -13
- package/src/learning/trajectory-sources/index.ts +2 -2
- package/src/learning/trajectory-sources/pipeline.ts +5 -5
- package/src/learning/unified-pipeline.ts +921 -0
- package/src/memory/candidate-retrieval.ts +71 -0
- package/src/memory/causal-store.ts +273 -0
- package/src/memory/coherence.ts +252 -0
- package/src/memory/experience.ts +217 -50
- package/src/memory/index.ts +43 -0
- package/src/memory/knowledge-bank.ts +57 -0
- package/src/memory/meta.ts +78 -96
- package/src/memory/playbook.ts +239 -75
- package/src/memory/reasoning-bank.ts +458 -0
- package/src/memory/reflexion.ts +122 -0
- package/src/memory/system.ts +21 -5
- package/src/memory/temporal-compressor.ts +409 -0
- package/src/persistence/index.ts +37 -0
- package/src/persistence/migrator.ts +298 -0
- package/src/persistence/serializers.ts +79 -0
- package/src/persistence/sqlite-persistence.ts +925 -0
- package/src/runtime/flows/learning.ts +25 -42
- package/src/search/index.ts +10 -0
- package/src/search/moe-gate.ts +304 -0
- package/src/search/router.ts +111 -4
- package/src/session-bank/git-reader.ts +29 -19
- package/src/session-bank/index.ts +4 -2
- package/src/session-bank/parser.ts +280 -98
- package/src/session-bank/session-bank.ts +33 -12
- package/src/session-bank/types.ts +8 -5
- package/src/surfacing/skill-publisher.ts +17 -49
- package/src/surfacing/sqlite-storage-adapter.ts +16 -32
- package/src/types/config.ts +30 -0
- package/src/types/index.ts +3 -0
- package/src/types/memory.ts +30 -0
- package/src/types/playbook.ts +4 -0
- package/src/utils/error-classifier.ts +113 -0
- package/src/utils/index.ts +18 -0
- package/src/utils/partitioned-store.ts +299 -0
- package/src/utils/trajectory-helpers.ts +79 -0
- package/src/workspace/runner.ts +3 -3
- package/src/workspace/types.ts +10 -2
- package/tests/embeddings/inverted-index.test.ts +138 -0
- package/tests/feature-toggles.test.ts +275 -0
- package/tests/gap-fixes.test.ts +17 -4
- package/tests/integration/cli-e2e.test.ts +621 -0
- package/tests/integration/e2e.test.ts +6 -5
- package/tests/integration/entire-e2e.test.ts +314 -125
- package/tests/integration/persistence-e2e.test.ts +741 -0
- package/tests/integration/phase-e2e.test.ts +1143 -0
- package/tests/integration/session-bank.test.ts +20 -14
- package/tests/integration/sessionlog-e2e.test.ts +329 -0
- package/tests/integration/unified-pipeline-e2e.test.ts +634 -0
- package/tests/learning/analyzer.test.ts +1 -1
- package/tests/learning/energy-evaluator.test.ts +180 -0
- package/tests/learning/entire-trajectory-source.test.ts +25 -25
- package/tests/learning/healing-orchestrator.test.ts +269 -0
- package/tests/learning/instant-loop.test.ts +243 -0
- package/tests/learning/maintenance-scheduler.test.ts +191 -0
- package/tests/learning/reflexion-generator.test.ts +411 -0
- package/tests/learning/trajectory-sources.test.ts +12 -4
- package/tests/learning/unified-pipeline.test.ts +322 -0
- package/tests/mcp/playbook-server.test.ts +6 -1
- package/tests/memory/causal-store.test.ts +276 -0
- package/tests/memory/coherence.test.ts +232 -0
- package/tests/memory/experience.test.ts +8 -3
- package/tests/memory/playbook.test.ts +307 -1
- package/tests/memory/provenance.test.ts +11 -2
- package/tests/memory/reasoning-bank.test.ts +239 -0
- package/tests/memory/reflexion.test.ts +166 -0
- package/tests/memory/skill-exporter.test.ts +6 -1
- package/tests/memory/system.test.ts +6 -1
- package/tests/memory/temporal-compressor.test.ts +318 -0
- package/tests/persistence/migrator.test.ts +1009 -0
- package/tests/persistence/sqlite-persistence.test.ts +635 -0
- package/tests/runtime/agent-manager.test.ts +6 -1
- package/tests/runtime/delegate.test.ts +6 -1
- package/tests/search/moe-gate.test.ts +250 -0
- package/tests/search/refinement-loop.test.ts +11 -2
- package/tests/search/router.test.ts +81 -2
- package/tests/session-bank/fixtures/sessionlog-root-metadata.json +16 -0
- package/tests/session-bank/fixtures/sessionlog-session/full.jsonl +6 -0
- package/tests/session-bank/fixtures/sessionlog-session/metadata.json +55 -0
- package/tests/session-bank/git-reader.test.ts +13 -13
- package/tests/session-bank/parser.test.ts +135 -3
- package/tests/session-bank/session-bank.test.ts +1 -1
- package/tests/surfacing/skill-library.test.ts +6 -1
- package/tests/surfacing/skill-publisher.test.ts +24 -58
- package/tests/surfacing/sqlite-storage-adapter.test.ts +11 -23
- package/tests/utils/partitioned-store.test.ts +230 -0
- package/tests/workspace/full-flow.test.ts +10 -4
- package/tests/workspace/runner.test.ts +10 -4
- package/docs/DESIGN-workspace-migration.md +0 -1079
- package/docs/PLAN-agentic-workspace-implementation.md +0 -717
- package/docs/PLAN-graph-migration.md +0 -299
- package/docs/PLAN-session-bank-implementation.md +0 -474
- package/src/learning/pipeline.ts +0 -323
- package/tests/learning/pipeline.test.ts +0 -176
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { CoherenceChecker } from '../../src/memory/coherence.js';
|
|
3
|
+
import { createObservation } from '../../src/types/knowledge.js';
|
|
4
|
+
import type { KnowledgeNote } from '../../src/types/knowledge.js';
|
|
5
|
+
|
|
6
|
+
function makeNote(opts: {
|
|
7
|
+
id?: string;
|
|
8
|
+
body: string;
|
|
9
|
+
domain?: string[];
|
|
10
|
+
entities?: string[];
|
|
11
|
+
}): KnowledgeNote {
|
|
12
|
+
return createObservation({
|
|
13
|
+
id: opts.id ?? `k-${crypto.randomUUID().slice(0, 8)}`,
|
|
14
|
+
title: 'Test note',
|
|
15
|
+
body: opts.body,
|
|
16
|
+
domain: opts.domain ?? ['testing'],
|
|
17
|
+
entities: opts.entities ?? ['vitest'],
|
|
18
|
+
confidence: 0.7,
|
|
19
|
+
source: { origin: 'extracted' },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('CoherenceChecker', () => {
|
|
24
|
+
const checker = new CoherenceChecker();
|
|
25
|
+
|
|
26
|
+
describe('coherent notes', () => {
|
|
27
|
+
it('should pass check for non-contradictory notes', async () => {
|
|
28
|
+
const newNote = makeNote({
|
|
29
|
+
body: 'Always use TypeScript for type safety in production code',
|
|
30
|
+
entities: ['typescript'],
|
|
31
|
+
domain: ['typescript'],
|
|
32
|
+
});
|
|
33
|
+
const existingNotes = [
|
|
34
|
+
makeNote({
|
|
35
|
+
body: 'TypeScript provides excellent type checking capabilities',
|
|
36
|
+
entities: ['typescript'],
|
|
37
|
+
domain: ['typescript'],
|
|
38
|
+
}),
|
|
39
|
+
makeNote({
|
|
40
|
+
body: 'Enable strict mode in tsconfig for better type safety',
|
|
41
|
+
entities: ['typescript'],
|
|
42
|
+
domain: ['typescript'],
|
|
43
|
+
}),
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const result = await checker.check(newNote, existingNotes);
|
|
47
|
+
|
|
48
|
+
expect(result.isCoherent).toBe(true);
|
|
49
|
+
expect(result.contradictions).toHaveLength(0);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should skip notes in different domains', async () => {
|
|
53
|
+
const newNote = makeNote({
|
|
54
|
+
body: 'Always use strict mode in Python for better error handling',
|
|
55
|
+
entities: ['python'],
|
|
56
|
+
domain: ['python'],
|
|
57
|
+
});
|
|
58
|
+
const existingNotes = [
|
|
59
|
+
makeNote({
|
|
60
|
+
body: 'Never use strict mode — it slows down development',
|
|
61
|
+
entities: ['javascript'],
|
|
62
|
+
domain: ['javascript'],
|
|
63
|
+
}),
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const result = await checker.check(newNote, existingNotes);
|
|
67
|
+
|
|
68
|
+
expect(result.isCoherent).toBe(true);
|
|
69
|
+
expect(result.contradictions).toHaveLength(0);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('contradictory notes', () => {
|
|
74
|
+
it('should detect "always use X" vs "never use X" contradiction', async () => {
|
|
75
|
+
const newNote = makeNote({
|
|
76
|
+
body: 'Always use semicolons in TypeScript code for consistency',
|
|
77
|
+
entities: ['typescript'],
|
|
78
|
+
domain: ['typescript'],
|
|
79
|
+
});
|
|
80
|
+
const existingNotes = [
|
|
81
|
+
makeNote({
|
|
82
|
+
body: 'Never use semicolons in TypeScript code — the parser handles it automatically',
|
|
83
|
+
entities: ['typescript'],
|
|
84
|
+
domain: ['typescript'],
|
|
85
|
+
}),
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const result = await checker.check(newNote, existingNotes);
|
|
89
|
+
|
|
90
|
+
expect(result.isCoherent).toBe(false);
|
|
91
|
+
expect(result.contradictions.length).toBeGreaterThan(0);
|
|
92
|
+
expect(result.contradictions[0].residualEnergy).toBeGreaterThan(0.2);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should detect "use X" vs "avoid X" contradiction', async () => {
|
|
96
|
+
const newNote = makeNote({
|
|
97
|
+
body: 'For TypeScript projects, use the any type when working with dynamic data structures',
|
|
98
|
+
entities: ['typescript'],
|
|
99
|
+
domain: ['typescript'],
|
|
100
|
+
});
|
|
101
|
+
const existingNotes = [
|
|
102
|
+
makeNote({
|
|
103
|
+
body: 'For TypeScript projects, avoid the any type when working with dynamic data structures',
|
|
104
|
+
entities: ['typescript'],
|
|
105
|
+
domain: ['typescript'],
|
|
106
|
+
}),
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
const result = await checker.check(newNote, existingNotes);
|
|
110
|
+
|
|
111
|
+
expect(result.isCoherent).toBe(false);
|
|
112
|
+
expect(result.contradictions.length).toBeGreaterThan(0);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should detect "do X" vs "don\'t X" contradiction', async () => {
|
|
116
|
+
const newNote = makeNote({
|
|
117
|
+
body: 'When configuring eslint rules for the project, do enable strict type checking',
|
|
118
|
+
entities: ['eslint'],
|
|
119
|
+
domain: ['tooling'],
|
|
120
|
+
});
|
|
121
|
+
const existingNotes = [
|
|
122
|
+
makeNote({
|
|
123
|
+
body: "When configuring eslint rules for the project, don't enable strict type checking",
|
|
124
|
+
entities: ['eslint'],
|
|
125
|
+
domain: ['tooling'],
|
|
126
|
+
}),
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
const result = await checker.check(newNote, existingNotes);
|
|
130
|
+
|
|
131
|
+
expect(result.isCoherent).toBe(false);
|
|
132
|
+
expect(result.contradictions.length).toBeGreaterThan(0);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('same-entity filtering', () => {
|
|
137
|
+
it('should compare notes with the same entities', async () => {
|
|
138
|
+
const newNote = makeNote({
|
|
139
|
+
body: 'Always use vitest for testing TypeScript projects',
|
|
140
|
+
entities: ['vitest'],
|
|
141
|
+
domain: ['testing'],
|
|
142
|
+
});
|
|
143
|
+
const existingNotes = [
|
|
144
|
+
makeNote({
|
|
145
|
+
body: 'Never use vitest for testing TypeScript projects — use jest instead',
|
|
146
|
+
entities: ['vitest'],
|
|
147
|
+
domain: ['testing'],
|
|
148
|
+
}),
|
|
149
|
+
makeNote({
|
|
150
|
+
body: 'Deploy applications to production every Friday',
|
|
151
|
+
entities: ['deployment'],
|
|
152
|
+
domain: ['devops'],
|
|
153
|
+
}),
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
const result = await checker.check(newNote, existingNotes);
|
|
157
|
+
|
|
158
|
+
// Should only find contradiction with vitest note, not deployment note
|
|
159
|
+
expect(result.isCoherent).toBe(false);
|
|
160
|
+
expect(result.contradictions.length).toBe(1);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe('global energy', () => {
|
|
165
|
+
it('should return 0 for a single note', () => {
|
|
166
|
+
const notes = [
|
|
167
|
+
makeNote({ body: 'TypeScript is great', domain: ['typescript'] }),
|
|
168
|
+
];
|
|
169
|
+
|
|
170
|
+
const energy = checker.computeGlobalEnergy(notes);
|
|
171
|
+
expect(energy).toBe(0);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should increase energy with more contradictions', () => {
|
|
175
|
+
const coherentNotes = [
|
|
176
|
+
makeNote({
|
|
177
|
+
body: 'Use TypeScript for type safety',
|
|
178
|
+
domain: ['typescript'],
|
|
179
|
+
entities: ['typescript'],
|
|
180
|
+
}),
|
|
181
|
+
makeNote({
|
|
182
|
+
body: 'TypeScript provides compile-time checking',
|
|
183
|
+
domain: ['typescript'],
|
|
184
|
+
entities: ['typescript'],
|
|
185
|
+
}),
|
|
186
|
+
];
|
|
187
|
+
|
|
188
|
+
const contradictoryNotes = [
|
|
189
|
+
makeNote({
|
|
190
|
+
body: 'Always use strict TypeScript types for safety',
|
|
191
|
+
domain: ['typescript'],
|
|
192
|
+
entities: ['typescript'],
|
|
193
|
+
}),
|
|
194
|
+
makeNote({
|
|
195
|
+
body: 'Never use strict TypeScript types — they slow development',
|
|
196
|
+
domain: ['typescript'],
|
|
197
|
+
entities: ['typescript'],
|
|
198
|
+
}),
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
const coherentEnergy = checker.computeGlobalEnergy(coherentNotes);
|
|
202
|
+
const contradictoryEnergy = checker.computeGlobalEnergy(contradictoryNotes);
|
|
203
|
+
|
|
204
|
+
expect(contradictoryEnergy).toBeGreaterThan(coherentEnergy);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe('configuration', () => {
|
|
209
|
+
it('should respect maxComparisons', async () => {
|
|
210
|
+
const checker2 = new CoherenceChecker({ maxComparisons: 1 });
|
|
211
|
+
const newNote = makeNote({
|
|
212
|
+
body: 'Always use semicolons for consistency',
|
|
213
|
+
entities: ['typescript'],
|
|
214
|
+
domain: ['typescript'],
|
|
215
|
+
});
|
|
216
|
+
// Create many existing notes — only 1 should be compared
|
|
217
|
+
const existingNotes = Array.from({ length: 10 }, (_, i) =>
|
|
218
|
+
makeNote({
|
|
219
|
+
id: `note-${i}`,
|
|
220
|
+
body: `Never use semicolons — note ${i} for consistency`,
|
|
221
|
+
entities: ['typescript'],
|
|
222
|
+
domain: ['typescript'],
|
|
223
|
+
})
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const result = await checker2.check(newNote, existingNotes);
|
|
227
|
+
|
|
228
|
+
// Should find at most 1 contradiction since maxComparisons=1
|
|
229
|
+
expect(result.contradictions.length).toBeLessThanOrEqual(1);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import { ExperienceMemory } from '../../src/memory/experience.js';
|
|
3
3
|
import { createExperience, type Experience } from '../../src/types/memory.js';
|
|
4
|
+
import { createSqlitePersistence } from '../../src/persistence/index.js';
|
|
4
5
|
import { mkdtemp, rm } from 'node:fs/promises';
|
|
5
6
|
import { join } from 'node:path';
|
|
6
7
|
import { tmpdir } from 'node:os';
|
|
@@ -8,15 +9,19 @@ import { tmpdir } from 'node:os';
|
|
|
8
9
|
describe('ExperienceMemory', () => {
|
|
9
10
|
let tempDir: string;
|
|
10
11
|
let memory: ExperienceMemory;
|
|
12
|
+
let persistence: any;
|
|
11
13
|
|
|
12
14
|
beforeEach(async () => {
|
|
13
15
|
tempDir = await mkdtemp(join(tmpdir(), 'atlas-test-'));
|
|
14
|
-
|
|
16
|
+
persistence = createSqlitePersistence({ baseDir: tempDir });
|
|
17
|
+
await persistence.init();
|
|
18
|
+
memory = new ExperienceMemory(persistence);
|
|
15
19
|
await memory.init();
|
|
16
20
|
});
|
|
17
21
|
|
|
18
22
|
afterEach(async () => {
|
|
19
23
|
await memory.close();
|
|
24
|
+
persistence.close();
|
|
20
25
|
await rm(tempDir, { recursive: true, force: true });
|
|
21
26
|
});
|
|
22
27
|
|
|
@@ -184,8 +189,8 @@ describe('ExperienceMemory', () => {
|
|
|
184
189
|
await memory.add(exp);
|
|
185
190
|
await memory.close();
|
|
186
191
|
|
|
187
|
-
// Create new memory instance
|
|
188
|
-
const memory2 = new ExperienceMemory(
|
|
192
|
+
// Create new memory instance from the same persistence (shared SQLite DB)
|
|
193
|
+
const memory2 = new ExperienceMemory(persistence);
|
|
189
194
|
await memory2.init();
|
|
190
195
|
|
|
191
196
|
const retrieved = await memory2.get(exp.id);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import { PlaybookLibrary, createPlaybookLibrary } from '../../src/memory/playbook.js';
|
|
3
3
|
import type { Playbook } from '../../src/types/playbook.js';
|
|
4
|
+
import { createSqlitePersistence } from '../../src/persistence/index.js';
|
|
4
5
|
import { mkdtemp, rm } from 'node:fs/promises';
|
|
5
6
|
import { join } from 'node:path';
|
|
6
7
|
import { tmpdir } from 'node:os';
|
|
@@ -8,15 +9,19 @@ import { tmpdir } from 'node:os';
|
|
|
8
9
|
describe('PlaybookLibrary', () => {
|
|
9
10
|
let tempDir: string;
|
|
10
11
|
let library: PlaybookLibrary;
|
|
12
|
+
let persistence: any;
|
|
11
13
|
|
|
12
14
|
beforeEach(async () => {
|
|
13
15
|
tempDir = await mkdtemp(join(tmpdir(), 'atlas-test-'));
|
|
14
|
-
|
|
16
|
+
persistence = createSqlitePersistence({ baseDir: tempDir });
|
|
17
|
+
await persistence.init();
|
|
18
|
+
library = createPlaybookLibrary(persistence);
|
|
15
19
|
await library.init();
|
|
16
20
|
});
|
|
17
21
|
|
|
18
22
|
afterEach(async () => {
|
|
19
23
|
await library.close();
|
|
24
|
+
persistence.close();
|
|
20
25
|
await rm(tempDir, { recursive: true, force: true });
|
|
21
26
|
});
|
|
22
27
|
|
|
@@ -322,6 +327,164 @@ describe('PlaybookLibrary', () => {
|
|
|
322
327
|
});
|
|
323
328
|
});
|
|
324
329
|
|
|
330
|
+
describe('stability-plasticity', () => {
|
|
331
|
+
it('should dampen confidence changes for high consolidationStrength', async () => {
|
|
332
|
+
// Create a highly consolidated playbook
|
|
333
|
+
const consolidated = createSamplePlaybook({
|
|
334
|
+
name: 'consolidated',
|
|
335
|
+
confidence: 0.7,
|
|
336
|
+
evolution: {
|
|
337
|
+
version: '1.0.0',
|
|
338
|
+
createdFrom: [],
|
|
339
|
+
failures: [],
|
|
340
|
+
refinements: [],
|
|
341
|
+
successCount: 50,
|
|
342
|
+
failureCount: 2,
|
|
343
|
+
consolidationStrength: 5,
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
await library.add(consolidated);
|
|
347
|
+
|
|
348
|
+
// Create a fresh playbook
|
|
349
|
+
const fresh = createSamplePlaybook({
|
|
350
|
+
name: 'fresh',
|
|
351
|
+
confidence: 0.7,
|
|
352
|
+
evolution: {
|
|
353
|
+
version: '1.0.0',
|
|
354
|
+
createdFrom: [],
|
|
355
|
+
failures: [],
|
|
356
|
+
refinements: [],
|
|
357
|
+
successCount: 0,
|
|
358
|
+
failureCount: 0,
|
|
359
|
+
consolidationStrength: 0,
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
await library.add(fresh);
|
|
363
|
+
|
|
364
|
+
// Apply failure to both
|
|
365
|
+
await library.recordFailure(consolidated.id, 'traj-1', 'test', 'test fail');
|
|
366
|
+
await library.recordFailure(fresh.id, 'traj-2', 'test', 'test fail');
|
|
367
|
+
|
|
368
|
+
const updatedConsolidated = await library.get(consolidated.id);
|
|
369
|
+
const updatedFresh = await library.get(fresh.id);
|
|
370
|
+
|
|
371
|
+
// Both should decrease, but consolidated should decrease less
|
|
372
|
+
const consolidatedDelta = 0.7 - updatedConsolidated!.confidence;
|
|
373
|
+
const freshDelta = 0.7 - updatedFresh!.confidence;
|
|
374
|
+
expect(consolidatedDelta).toBeLessThan(freshDelta);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('should behave as before when consolidationStrength is 0', async () => {
|
|
378
|
+
// A playbook with no consolidation should update like the original EMA
|
|
379
|
+
const playbook = createSamplePlaybook({
|
|
380
|
+
confidence: 0.5,
|
|
381
|
+
evolution: {
|
|
382
|
+
version: '1.0.0',
|
|
383
|
+
createdFrom: [],
|
|
384
|
+
failures: [],
|
|
385
|
+
refinements: [],
|
|
386
|
+
successCount: 0,
|
|
387
|
+
failureCount: 0,
|
|
388
|
+
consolidationStrength: 0,
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
await library.add(playbook);
|
|
392
|
+
|
|
393
|
+
await library.recordSuccess(playbook.id, 'traj-1');
|
|
394
|
+
|
|
395
|
+
const updated = await library.get(playbook.id);
|
|
396
|
+
// With cs=0: dampedDelta = rawDelta / (1 + 0) = rawDelta
|
|
397
|
+
// rawDelta = (1 - 0.5) * 0.1 = 0.05
|
|
398
|
+
// new confidence = 0.5 + 0.05 = 0.55
|
|
399
|
+
expect(updated!.confidence).toBeCloseTo(0.55, 2);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it('should grow consolidationStrength on success', async () => {
|
|
403
|
+
const playbook = createSamplePlaybook({
|
|
404
|
+
evolution: {
|
|
405
|
+
version: '1.0.0',
|
|
406
|
+
createdFrom: [],
|
|
407
|
+
failures: [],
|
|
408
|
+
refinements: [],
|
|
409
|
+
successCount: 0,
|
|
410
|
+
failureCount: 0,
|
|
411
|
+
consolidationStrength: 0,
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
await library.add(playbook);
|
|
415
|
+
|
|
416
|
+
await library.recordSuccess(playbook.id, 'traj-1');
|
|
417
|
+
const after1 = await library.get(playbook.id);
|
|
418
|
+
expect(after1!.evolution.consolidationStrength).toBeCloseTo(0.05, 3);
|
|
419
|
+
|
|
420
|
+
await library.recordSuccess(playbook.id, 'traj-2');
|
|
421
|
+
const after2 = await library.get(playbook.id);
|
|
422
|
+
expect(after2!.evolution.consolidationStrength).toBeCloseTo(0.10, 3);
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
it('should not reduce consolidationStrength on failure', async () => {
|
|
426
|
+
const playbook = createSamplePlaybook({
|
|
427
|
+
evolution: {
|
|
428
|
+
version: '1.0.0',
|
|
429
|
+
createdFrom: [],
|
|
430
|
+
failures: [],
|
|
431
|
+
refinements: [],
|
|
432
|
+
successCount: 10,
|
|
433
|
+
failureCount: 0,
|
|
434
|
+
consolidationStrength: 2.0,
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
await library.add(playbook);
|
|
438
|
+
|
|
439
|
+
await library.recordFailure(playbook.id, 'traj-1', 'test', 'failed');
|
|
440
|
+
const updated = await library.get(playbook.id);
|
|
441
|
+
// consolidationStrength should remain at 2.0 (failures don't reduce it)
|
|
442
|
+
expect(updated!.evolution.consolidationStrength).toBe(2.0);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
it('should cap consolidationStrength at 10', async () => {
|
|
446
|
+
const playbook = createSamplePlaybook({
|
|
447
|
+
evolution: {
|
|
448
|
+
version: '1.0.0',
|
|
449
|
+
createdFrom: [],
|
|
450
|
+
failures: [],
|
|
451
|
+
refinements: [],
|
|
452
|
+
successCount: 100,
|
|
453
|
+
failureCount: 0,
|
|
454
|
+
consolidationStrength: 9.98,
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
await library.add(playbook);
|
|
458
|
+
|
|
459
|
+
await library.recordSuccess(playbook.id, 'traj-1');
|
|
460
|
+
const updated = await library.get(playbook.id);
|
|
461
|
+
expect(updated!.evolution.consolidationStrength).toBeLessThanOrEqual(10);
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
it('should backward compat — missing consolidationStrength defaults to 0', async () => {
|
|
465
|
+
// Playbook without consolidationStrength field
|
|
466
|
+
const playbook = createSamplePlaybook({
|
|
467
|
+
confidence: 0.5,
|
|
468
|
+
evolution: {
|
|
469
|
+
version: '1.0.0',
|
|
470
|
+
createdFrom: [],
|
|
471
|
+
failures: [],
|
|
472
|
+
refinements: [],
|
|
473
|
+
successCount: 0,
|
|
474
|
+
failureCount: 0,
|
|
475
|
+
// No consolidationStrength or domainBreadth
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
await library.add(playbook);
|
|
479
|
+
|
|
480
|
+
await library.recordSuccess(playbook.id, 'traj-1');
|
|
481
|
+
const updated = await library.get(playbook.id);
|
|
482
|
+
// Should still work, same as cs=0
|
|
483
|
+
expect(updated!.confidence).toBeCloseTo(0.55, 2);
|
|
484
|
+
expect(updated!.evolution.consolidationStrength).toBeCloseTo(0.05, 3);
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
|
|
325
488
|
describe('count and getAll', () => {
|
|
326
489
|
it('should return correct counts', async () => {
|
|
327
490
|
expect(await library.count()).toBe(0);
|
|
@@ -335,4 +498,147 @@ describe('PlaybookLibrary', () => {
|
|
|
335
498
|
expect(all).toHaveLength(2);
|
|
336
499
|
});
|
|
337
500
|
});
|
|
501
|
+
|
|
502
|
+
describe('MMR diversity', () => {
|
|
503
|
+
it('should match pure relevance ranking when lambda=1.0', async () => {
|
|
504
|
+
await library.add(createSamplePlaybook({
|
|
505
|
+
name: 'pb-a',
|
|
506
|
+
applicability: {
|
|
507
|
+
situations: ['Fix TypeScript type errors in production code'],
|
|
508
|
+
triggers: ['TS2322'],
|
|
509
|
+
antiPatterns: [],
|
|
510
|
+
domains: ['typescript'],
|
|
511
|
+
},
|
|
512
|
+
guidance: {
|
|
513
|
+
strategy: 'Analyze and fix type mismatches',
|
|
514
|
+
tactics: [],
|
|
515
|
+
steps: [],
|
|
516
|
+
},
|
|
517
|
+
}));
|
|
518
|
+
await library.add(createSamplePlaybook({
|
|
519
|
+
name: 'pb-b',
|
|
520
|
+
applicability: {
|
|
521
|
+
situations: ['Fix TypeScript import errors'],
|
|
522
|
+
triggers: ['import'],
|
|
523
|
+
antiPatterns: [],
|
|
524
|
+
domains: ['typescript'],
|
|
525
|
+
},
|
|
526
|
+
guidance: {
|
|
527
|
+
strategy: 'Check and resolve import paths',
|
|
528
|
+
tactics: [],
|
|
529
|
+
steps: [],
|
|
530
|
+
},
|
|
531
|
+
}));
|
|
532
|
+
|
|
533
|
+
// lambda=1.0 should give same order as no MMR
|
|
534
|
+
const pureRelevance = await library.findMatching('TypeScript type errors', { k: 2 });
|
|
535
|
+
const mmr1 = await library.findMatching('TypeScript type errors', { k: 2, lambda: 1.0 });
|
|
536
|
+
|
|
537
|
+
expect(pureRelevance.length).toBe(mmr1.length);
|
|
538
|
+
// Same top result
|
|
539
|
+
expect(pureRelevance[0].playbook.name).toBe(mmr1[0].playbook.name);
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('should diversify results when lambda is low', async () => {
|
|
543
|
+
// Add two very similar playbooks and one different
|
|
544
|
+
await library.add(createSamplePlaybook({
|
|
545
|
+
name: 'similar-1',
|
|
546
|
+
applicability: {
|
|
547
|
+
situations: ['Debug TypeScript type error in code'],
|
|
548
|
+
triggers: ['type error'],
|
|
549
|
+
antiPatterns: [],
|
|
550
|
+
domains: ['typescript'],
|
|
551
|
+
},
|
|
552
|
+
guidance: {
|
|
553
|
+
strategy: 'Read the full error message and trace back to the source type declaration',
|
|
554
|
+
tactics: [],
|
|
555
|
+
steps: [],
|
|
556
|
+
},
|
|
557
|
+
}));
|
|
558
|
+
await library.add(createSamplePlaybook({
|
|
559
|
+
name: 'similar-2',
|
|
560
|
+
applicability: {
|
|
561
|
+
situations: ['Debug TypeScript type error in tests'],
|
|
562
|
+
triggers: ['type error'],
|
|
563
|
+
antiPatterns: [],
|
|
564
|
+
domains: ['typescript'],
|
|
565
|
+
},
|
|
566
|
+
guidance: {
|
|
567
|
+
strategy: 'Read the full error message and trace back to the source type declaration',
|
|
568
|
+
tactics: [],
|
|
569
|
+
steps: [],
|
|
570
|
+
},
|
|
571
|
+
}));
|
|
572
|
+
await library.add(createSamplePlaybook({
|
|
573
|
+
name: 'different',
|
|
574
|
+
applicability: {
|
|
575
|
+
situations: ['Debug TypeScript type error using alternative approach'],
|
|
576
|
+
triggers: ['type error'],
|
|
577
|
+
antiPatterns: [],
|
|
578
|
+
domains: ['typescript'],
|
|
579
|
+
},
|
|
580
|
+
guidance: {
|
|
581
|
+
strategy: 'Use the TypeScript compiler API to programmatically analyze types',
|
|
582
|
+
tactics: [],
|
|
583
|
+
steps: [],
|
|
584
|
+
},
|
|
585
|
+
}));
|
|
586
|
+
|
|
587
|
+
// With low lambda, MMR should prefer the diverse playbook over the near-duplicate
|
|
588
|
+
const diverseResults = await library.findMatching('TypeScript type error', {
|
|
589
|
+
k: 3,
|
|
590
|
+
lambda: 0.3,
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
expect(diverseResults.length).toBe(3);
|
|
594
|
+
// The "different" strategy playbook should appear in the top results
|
|
595
|
+
const names = diverseResults.map((r) => r.playbook.name);
|
|
596
|
+
expect(names).toContain('different');
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
it('should avoid returning near-duplicates with strong diversity bias', async () => {
|
|
600
|
+
// Add 3 playbooks with identical strategies
|
|
601
|
+
for (let i = 0; i < 3; i++) {
|
|
602
|
+
await library.add(createSamplePlaybook({
|
|
603
|
+
name: `clone-${i}`,
|
|
604
|
+
applicability: {
|
|
605
|
+
situations: ['Resolve eslint warnings in codebase'],
|
|
606
|
+
triggers: ['eslint warning'],
|
|
607
|
+
antiPatterns: [],
|
|
608
|
+
domains: ['typescript'],
|
|
609
|
+
},
|
|
610
|
+
guidance: {
|
|
611
|
+
strategy: 'Run eslint with auto-fix flag',
|
|
612
|
+
tactics: [],
|
|
613
|
+
steps: [],
|
|
614
|
+
},
|
|
615
|
+
}));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// Add one unique playbook
|
|
619
|
+
await library.add(createSamplePlaybook({
|
|
620
|
+
name: 'unique-lint',
|
|
621
|
+
applicability: {
|
|
622
|
+
situations: ['Resolve eslint warnings using custom rules'],
|
|
623
|
+
triggers: ['eslint warning'],
|
|
624
|
+
antiPatterns: [],
|
|
625
|
+
domains: ['typescript'],
|
|
626
|
+
},
|
|
627
|
+
guidance: {
|
|
628
|
+
strategy: 'Create custom eslint rule to prevent the warning pattern',
|
|
629
|
+
tactics: [],
|
|
630
|
+
steps: [],
|
|
631
|
+
},
|
|
632
|
+
}));
|
|
633
|
+
|
|
634
|
+
// With diversity bias, the unique one should appear by position 2
|
|
635
|
+
const results = await library.findMatching('eslint warnings', {
|
|
636
|
+
k: 2,
|
|
637
|
+
lambda: 0.3,
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
const names = results.map((r) => r.playbook.name);
|
|
641
|
+
expect(names).toContain('unique-lint');
|
|
642
|
+
});
|
|
643
|
+
});
|
|
338
644
|
});
|
|
@@ -3,6 +3,7 @@ import { PlaybookLibrary, createPlaybookLibrary } from '../../src/memory/playboo
|
|
|
3
3
|
import { loadCuratedPlaybooks, type CuratedPlaybookFile } from '../../src/memory/curated-loader.js';
|
|
4
4
|
import type { Playbook, PlaybookProvenance } from '../../src/types/playbook.js';
|
|
5
5
|
import { createPlaybook } from '../../src/types/playbook.js';
|
|
6
|
+
import { createSqlitePersistence } from '../../src/persistence/index.js';
|
|
6
7
|
import { mkdtemp, rm, mkdir, writeFile } from 'node:fs/promises';
|
|
7
8
|
import { join } from 'node:path';
|
|
8
9
|
import { tmpdir } from 'node:os';
|
|
@@ -10,15 +11,19 @@ import { tmpdir } from 'node:os';
|
|
|
10
11
|
describe('Playbook Provenance', () => {
|
|
11
12
|
let tempDir: string;
|
|
12
13
|
let library: PlaybookLibrary;
|
|
14
|
+
let persistence: any;
|
|
13
15
|
|
|
14
16
|
beforeEach(async () => {
|
|
15
17
|
tempDir = await mkdtemp(join(tmpdir(), 'atlas-prov-test-'));
|
|
16
|
-
|
|
18
|
+
persistence = createSqlitePersistence({ baseDir: tempDir });
|
|
19
|
+
await persistence.init();
|
|
20
|
+
library = createPlaybookLibrary(persistence);
|
|
17
21
|
await library.init();
|
|
18
22
|
});
|
|
19
23
|
|
|
20
24
|
afterEach(async () => {
|
|
21
25
|
await library.close();
|
|
26
|
+
persistence.close();
|
|
22
27
|
await rm(tempDir, { recursive: true, force: true });
|
|
23
28
|
});
|
|
24
29
|
|
|
@@ -373,17 +378,21 @@ describe('Curated Playbook Loader', () => {
|
|
|
373
378
|
let tempDir: string;
|
|
374
379
|
let curatedDir: string;
|
|
375
380
|
let library: PlaybookLibrary;
|
|
381
|
+
let persistence: any;
|
|
376
382
|
|
|
377
383
|
beforeEach(async () => {
|
|
378
384
|
tempDir = await mkdtemp(join(tmpdir(), 'atlas-curated-test-'));
|
|
379
385
|
curatedDir = join(tempDir, 'curated');
|
|
380
386
|
await mkdir(curatedDir, { recursive: true });
|
|
381
|
-
|
|
387
|
+
persistence = createSqlitePersistence({ baseDir: tempDir });
|
|
388
|
+
await persistence.init();
|
|
389
|
+
library = createPlaybookLibrary(persistence);
|
|
382
390
|
await library.init();
|
|
383
391
|
});
|
|
384
392
|
|
|
385
393
|
afterEach(async () => {
|
|
386
394
|
await library.close();
|
|
395
|
+
persistence.close();
|
|
387
396
|
await rm(tempDir, { recursive: true, force: true });
|
|
388
397
|
});
|
|
389
398
|
|