@soleri/core 2.1.0 → 2.5.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/brain.d.ts +10 -1
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +116 -13
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/intelligence.d.ts +36 -1
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +119 -14
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/types.d.ts +34 -2
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/cognee/client.d.ts +3 -0
- package/dist/cognee/client.d.ts.map +1 -1
- package/dist/cognee/client.js +17 -0
- package/dist/cognee/client.js.map +1 -1
- package/dist/cognee/sync-manager.d.ts +94 -0
- package/dist/cognee/sync-manager.d.ts.map +1 -0
- package/dist/cognee/sync-manager.js +293 -0
- package/dist/cognee/sync-manager.js.map +1 -0
- package/dist/control/identity-manager.d.ts +22 -0
- package/dist/control/identity-manager.d.ts.map +1 -0
- package/dist/control/identity-manager.js +233 -0
- package/dist/control/identity-manager.js.map +1 -0
- package/dist/control/intent-router.d.ts +32 -0
- package/dist/control/intent-router.d.ts.map +1 -0
- package/dist/control/intent-router.js +242 -0
- package/dist/control/intent-router.js.map +1 -0
- package/dist/control/types.d.ts +68 -0
- package/dist/control/types.d.ts.map +1 -0
- package/dist/control/types.js +9 -0
- package/dist/control/types.js.map +1 -0
- package/dist/curator/curator.d.ts +37 -1
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +199 -1
- package/dist/curator/curator.js.map +1 -1
- package/dist/errors/classify.d.ts +13 -0
- package/dist/errors/classify.d.ts.map +1 -0
- package/dist/errors/classify.js +97 -0
- package/dist/errors/classify.js.map +1 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +4 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/retry.d.ts +40 -0
- package/dist/errors/retry.d.ts.map +1 -0
- package/dist/errors/retry.js +97 -0
- package/dist/errors/retry.js.map +1 -0
- package/dist/errors/types.d.ts +48 -0
- package/dist/errors/types.d.ts.map +1 -0
- package/dist/errors/types.js +59 -0
- package/dist/errors/types.js.map +1 -0
- package/dist/facades/types.d.ts +1 -1
- package/dist/governance/governance.d.ts +42 -0
- package/dist/governance/governance.d.ts.map +1 -0
- package/dist/governance/governance.js +488 -0
- package/dist/governance/governance.js.map +1 -0
- package/dist/governance/index.d.ts +3 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +2 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/types.d.ts +102 -0
- package/dist/governance/types.d.ts.map +1 -0
- package/dist/governance/types.js +3 -0
- package/dist/governance/types.js.map +1 -0
- package/dist/index.d.ts +52 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -1
- package/dist/index.js.map +1 -1
- package/dist/intake/content-classifier.d.ts +14 -0
- package/dist/intake/content-classifier.d.ts.map +1 -0
- package/dist/intake/content-classifier.js +125 -0
- package/dist/intake/content-classifier.js.map +1 -0
- package/dist/intake/dedup-gate.d.ts +17 -0
- package/dist/intake/dedup-gate.d.ts.map +1 -0
- package/dist/intake/dedup-gate.js +66 -0
- package/dist/intake/dedup-gate.js.map +1 -0
- package/dist/intake/intake-pipeline.d.ts +63 -0
- package/dist/intake/intake-pipeline.d.ts.map +1 -0
- package/dist/intake/intake-pipeline.js +373 -0
- package/dist/intake/intake-pipeline.js.map +1 -0
- package/dist/intake/types.d.ts +65 -0
- package/dist/intake/types.d.ts.map +1 -0
- package/dist/intake/types.js +3 -0
- package/dist/intake/types.js.map +1 -0
- package/dist/intelligence/loader.js +1 -1
- package/dist/intelligence/loader.js.map +1 -1
- package/dist/intelligence/types.d.ts +3 -1
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/logging/logger.d.ts +37 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +145 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/types.d.ts +19 -0
- package/dist/logging/types.d.ts.map +1 -0
- package/dist/logging/types.js +2 -0
- package/dist/logging/types.js.map +1 -0
- package/dist/loop/loop-manager.d.ts +100 -0
- package/dist/loop/loop-manager.d.ts.map +1 -0
- package/dist/loop/loop-manager.js +379 -0
- package/dist/loop/loop-manager.js.map +1 -0
- package/dist/loop/types.d.ts +103 -0
- package/dist/loop/types.d.ts.map +1 -0
- package/dist/loop/types.js +11 -0
- package/dist/loop/types.js.map +1 -0
- package/dist/persistence/index.d.ts +3 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +2 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/sqlite-provider.d.ts +25 -0
- package/dist/persistence/sqlite-provider.d.ts.map +1 -0
- package/dist/persistence/sqlite-provider.js +59 -0
- package/dist/persistence/sqlite-provider.js.map +1 -0
- package/dist/persistence/types.d.ts +36 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +8 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/planning/gap-analysis.d.ts +72 -0
- package/dist/planning/gap-analysis.d.ts.map +1 -0
- package/dist/planning/gap-analysis.js +442 -0
- package/dist/planning/gap-analysis.js.map +1 -0
- package/dist/planning/gap-types.d.ts +29 -0
- package/dist/planning/gap-types.d.ts.map +1 -0
- package/dist/planning/gap-types.js +28 -0
- package/dist/planning/gap-types.js.map +1 -0
- package/dist/planning/planner.d.ts +421 -4
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +949 -21
- package/dist/planning/planner.js.map +1 -1
- package/dist/playbooks/generic/brainstorming.d.ts +9 -0
- package/dist/playbooks/generic/brainstorming.d.ts.map +1 -0
- package/dist/playbooks/generic/brainstorming.js +105 -0
- package/dist/playbooks/generic/brainstorming.js.map +1 -0
- package/dist/playbooks/generic/code-review.d.ts +11 -0
- package/dist/playbooks/generic/code-review.d.ts.map +1 -0
- package/dist/playbooks/generic/code-review.js +176 -0
- package/dist/playbooks/generic/code-review.js.map +1 -0
- package/dist/playbooks/generic/subagent-execution.d.ts +9 -0
- package/dist/playbooks/generic/subagent-execution.d.ts.map +1 -0
- package/dist/playbooks/generic/subagent-execution.js +68 -0
- package/dist/playbooks/generic/subagent-execution.js.map +1 -0
- package/dist/playbooks/generic/systematic-debugging.d.ts +9 -0
- package/dist/playbooks/generic/systematic-debugging.d.ts.map +1 -0
- package/dist/playbooks/generic/systematic-debugging.js +87 -0
- package/dist/playbooks/generic/systematic-debugging.js.map +1 -0
- package/dist/playbooks/generic/tdd.d.ts +9 -0
- package/dist/playbooks/generic/tdd.d.ts.map +1 -0
- package/dist/playbooks/generic/tdd.js +70 -0
- package/dist/playbooks/generic/tdd.js.map +1 -0
- package/dist/playbooks/generic/verification.d.ts +9 -0
- package/dist/playbooks/generic/verification.d.ts.map +1 -0
- package/dist/playbooks/generic/verification.js +74 -0
- package/dist/playbooks/generic/verification.js.map +1 -0
- package/dist/playbooks/index.d.ts +4 -0
- package/dist/playbooks/index.d.ts.map +1 -0
- package/dist/playbooks/index.js +5 -0
- package/dist/playbooks/index.js.map +1 -0
- package/dist/playbooks/playbook-registry.d.ts +42 -0
- package/dist/playbooks/playbook-registry.d.ts.map +1 -0
- package/dist/playbooks/playbook-registry.js +227 -0
- package/dist/playbooks/playbook-registry.js.map +1 -0
- package/dist/playbooks/playbook-seeder.d.ts +47 -0
- package/dist/playbooks/playbook-seeder.d.ts.map +1 -0
- package/dist/playbooks/playbook-seeder.js +104 -0
- package/dist/playbooks/playbook-seeder.js.map +1 -0
- package/dist/playbooks/playbook-types.d.ts +132 -0
- package/dist/playbooks/playbook-types.d.ts.map +1 -0
- package/dist/playbooks/playbook-types.js +12 -0
- package/dist/playbooks/playbook-types.js.map +1 -0
- package/dist/project/project-registry.d.ts +79 -0
- package/dist/project/project-registry.d.ts.map +1 -0
- package/dist/project/project-registry.js +274 -0
- package/dist/project/project-registry.js.map +1 -0
- package/dist/project/types.d.ts +28 -0
- package/dist/project/types.d.ts.map +1 -0
- package/dist/project/types.js +5 -0
- package/dist/project/types.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +3 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/parser.d.ts +17 -0
- package/dist/prompts/parser.d.ts.map +1 -0
- package/dist/prompts/parser.js +47 -0
- package/dist/prompts/parser.js.map +1 -0
- package/dist/prompts/template-manager.d.ts +25 -0
- package/dist/prompts/template-manager.d.ts.map +1 -0
- package/dist/prompts/template-manager.js +71 -0
- package/dist/prompts/template-manager.js.map +1 -0
- package/dist/prompts/types.d.ts +26 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +5 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/runtime/admin-extra-ops.d.ts +15 -0
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -0
- package/dist/runtime/admin-extra-ops.js +595 -0
- package/dist/runtime/admin-extra-ops.js.map +1 -0
- package/dist/runtime/admin-ops.d.ts +15 -0
- package/dist/runtime/admin-ops.d.ts.map +1 -0
- package/dist/runtime/admin-ops.js +329 -0
- package/dist/runtime/admin-ops.js.map +1 -0
- package/dist/runtime/capture-ops.d.ts +15 -0
- package/dist/runtime/capture-ops.d.ts.map +1 -0
- package/dist/runtime/capture-ops.js +363 -0
- package/dist/runtime/capture-ops.js.map +1 -0
- package/dist/runtime/cognee-sync-ops.d.ts +12 -0
- package/dist/runtime/cognee-sync-ops.d.ts.map +1 -0
- package/dist/runtime/cognee-sync-ops.js +55 -0
- package/dist/runtime/cognee-sync-ops.js.map +1 -0
- package/dist/runtime/core-ops.d.ts +9 -3
- package/dist/runtime/core-ops.d.ts.map +1 -1
- package/dist/runtime/core-ops.js +693 -10
- package/dist/runtime/core-ops.js.map +1 -1
- package/dist/runtime/curator-extra-ops.d.ts +9 -0
- package/dist/runtime/curator-extra-ops.d.ts.map +1 -0
- package/dist/runtime/curator-extra-ops.js +71 -0
- package/dist/runtime/curator-extra-ops.js.map +1 -0
- package/dist/runtime/domain-ops.d.ts.map +1 -1
- package/dist/runtime/domain-ops.js +61 -15
- package/dist/runtime/domain-ops.js.map +1 -1
- package/dist/runtime/grading-ops.d.ts +14 -0
- package/dist/runtime/grading-ops.d.ts.map +1 -0
- package/dist/runtime/grading-ops.js +105 -0
- package/dist/runtime/grading-ops.js.map +1 -0
- package/dist/runtime/intake-ops.d.ts +14 -0
- package/dist/runtime/intake-ops.d.ts.map +1 -0
- package/dist/runtime/intake-ops.js +110 -0
- package/dist/runtime/intake-ops.js.map +1 -0
- package/dist/runtime/loop-ops.d.ts +14 -0
- package/dist/runtime/loop-ops.d.ts.map +1 -0
- package/dist/runtime/loop-ops.js +251 -0
- package/dist/runtime/loop-ops.js.map +1 -0
- package/dist/runtime/memory-cross-project-ops.d.ts +12 -0
- package/dist/runtime/memory-cross-project-ops.d.ts.map +1 -0
- package/dist/runtime/memory-cross-project-ops.js +165 -0
- package/dist/runtime/memory-cross-project-ops.js.map +1 -0
- package/dist/runtime/memory-extra-ops.d.ts +13 -0
- package/dist/runtime/memory-extra-ops.d.ts.map +1 -0
- package/dist/runtime/memory-extra-ops.js +173 -0
- package/dist/runtime/memory-extra-ops.js.map +1 -0
- package/dist/runtime/orchestrate-ops.d.ts +17 -0
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -0
- package/dist/runtime/orchestrate-ops.js +246 -0
- package/dist/runtime/orchestrate-ops.js.map +1 -0
- package/dist/runtime/planning-extra-ops.d.ts +25 -0
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -0
- package/dist/runtime/planning-extra-ops.js +663 -0
- package/dist/runtime/planning-extra-ops.js.map +1 -0
- package/dist/runtime/playbook-ops.d.ts +14 -0
- package/dist/runtime/playbook-ops.d.ts.map +1 -0
- package/dist/runtime/playbook-ops.js +141 -0
- package/dist/runtime/playbook-ops.js.map +1 -0
- package/dist/runtime/project-ops.d.ts +15 -0
- package/dist/runtime/project-ops.d.ts.map +1 -0
- package/dist/runtime/project-ops.js +186 -0
- package/dist/runtime/project-ops.js.map +1 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +65 -3
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +29 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.d.ts +10 -0
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -0
- package/dist/runtime/vault-extra-ops.js +536 -0
- package/dist/runtime/vault-extra-ops.js.map +1 -0
- package/dist/telemetry/telemetry.d.ts +48 -0
- package/dist/telemetry/telemetry.d.ts.map +1 -0
- package/dist/telemetry/telemetry.js +87 -0
- package/dist/telemetry/telemetry.js.map +1 -0
- package/dist/vault/playbook.d.ts +34 -0
- package/dist/vault/playbook.d.ts.map +1 -0
- package/dist/vault/playbook.js +60 -0
- package/dist/vault/playbook.js.map +1 -0
- package/dist/vault/vault.d.ts +97 -4
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +424 -65
- package/dist/vault/vault.js.map +1 -1
- package/package.json +7 -3
- package/src/__tests__/admin-extra-ops.test.ts +467 -0
- package/src/__tests__/admin-ops.test.ts +271 -0
- package/src/__tests__/brain-intelligence.test.ts +205 -0
- package/src/__tests__/brain.test.ts +134 -3
- package/src/__tests__/capture-ops.test.ts +509 -0
- package/src/__tests__/cognee-integration.test.ts +80 -0
- package/src/__tests__/cognee-sync-manager.test.ts +103 -0
- package/src/__tests__/core-ops.test.ts +292 -2
- package/src/__tests__/curator-extra-ops.test.ts +381 -0
- package/src/__tests__/domain-ops.test.ts +66 -0
- package/src/__tests__/errors.test.ts +388 -0
- package/src/__tests__/governance.test.ts +522 -0
- package/src/__tests__/grading-ops.test.ts +361 -0
- package/src/__tests__/identity-manager.test.ts +243 -0
- package/src/__tests__/intake-pipeline.test.ts +162 -0
- package/src/__tests__/intent-router.test.ts +222 -0
- package/src/__tests__/logger.test.ts +200 -0
- package/src/__tests__/loop-ops.test.ts +469 -0
- package/src/__tests__/memory-cross-project-ops.test.ts +248 -0
- package/src/__tests__/memory-extra-ops.test.ts +352 -0
- package/src/__tests__/orchestrate-ops.test.ts +289 -0
- package/src/__tests__/persistence.test.ts +225 -0
- package/src/__tests__/planner.test.ts +416 -7
- package/src/__tests__/planning-extra-ops.test.ts +706 -0
- package/src/__tests__/playbook-registry.test.ts +326 -0
- package/src/__tests__/playbook-seeder.test.ts +163 -0
- package/src/__tests__/playbook.test.ts +389 -0
- package/src/__tests__/project-ops.test.ts +381 -0
- package/src/__tests__/template-manager.test.ts +222 -0
- package/src/__tests__/vault-extra-ops.test.ts +482 -0
- package/src/brain/brain.ts +185 -16
- package/src/brain/intelligence.ts +179 -10
- package/src/brain/types.ts +40 -2
- package/src/cognee/client.ts +18 -0
- package/src/cognee/sync-manager.ts +389 -0
- package/src/control/identity-manager.ts +354 -0
- package/src/control/intent-router.ts +326 -0
- package/src/control/types.ts +102 -0
- package/src/curator/curator.ts +295 -1
- package/src/errors/classify.ts +102 -0
- package/src/errors/index.ts +5 -0
- package/src/errors/retry.ts +132 -0
- package/src/errors/types.ts +81 -0
- package/src/governance/governance.ts +698 -0
- package/src/governance/index.ts +18 -0
- package/src/governance/types.ts +111 -0
- package/src/index.ts +213 -2
- package/src/intake/content-classifier.ts +146 -0
- package/src/intake/dedup-gate.ts +92 -0
- package/src/intake/intake-pipeline.ts +503 -0
- package/src/intake/types.ts +69 -0
- package/src/intelligence/loader.ts +1 -1
- package/src/intelligence/types.ts +3 -1
- package/src/logging/logger.ts +154 -0
- package/src/logging/types.ts +21 -0
- package/src/loop/loop-manager.ts +448 -0
- package/src/loop/types.ts +115 -0
- package/src/persistence/index.ts +7 -0
- package/src/persistence/sqlite-provider.ts +62 -0
- package/src/persistence/types.ts +44 -0
- package/src/planning/gap-analysis.ts +775 -0
- package/src/planning/gap-types.ts +61 -0
- package/src/planning/planner.ts +1273 -24
- package/src/playbooks/generic/brainstorming.ts +110 -0
- package/src/playbooks/generic/code-review.ts +181 -0
- package/src/playbooks/generic/subagent-execution.ts +74 -0
- package/src/playbooks/generic/systematic-debugging.ts +92 -0
- package/src/playbooks/generic/tdd.ts +75 -0
- package/src/playbooks/generic/verification.ts +79 -0
- package/src/playbooks/index.ts +27 -0
- package/src/playbooks/playbook-registry.ts +284 -0
- package/src/playbooks/playbook-seeder.ts +119 -0
- package/src/playbooks/playbook-types.ts +162 -0
- package/src/project/project-registry.ts +370 -0
- package/src/project/types.ts +31 -0
- package/src/prompts/index.ts +3 -0
- package/src/prompts/parser.ts +59 -0
- package/src/prompts/template-manager.ts +77 -0
- package/src/prompts/types.ts +28 -0
- package/src/runtime/admin-extra-ops.ts +652 -0
- package/src/runtime/admin-ops.ts +340 -0
- package/src/runtime/capture-ops.ts +404 -0
- package/src/runtime/cognee-sync-ops.ts +63 -0
- package/src/runtime/core-ops.ts +787 -9
- package/src/runtime/curator-extra-ops.ts +85 -0
- package/src/runtime/domain-ops.ts +67 -15
- package/src/runtime/grading-ops.ts +130 -0
- package/src/runtime/intake-ops.ts +126 -0
- package/src/runtime/loop-ops.ts +277 -0
- package/src/runtime/memory-cross-project-ops.ts +191 -0
- package/src/runtime/memory-extra-ops.ts +186 -0
- package/src/runtime/orchestrate-ops.ts +278 -0
- package/src/runtime/planning-extra-ops.ts +718 -0
- package/src/runtime/playbook-ops.ts +169 -0
- package/src/runtime/project-ops.ts +202 -0
- package/src/runtime/runtime.ts +77 -3
- package/src/runtime/types.ts +29 -0
- package/src/runtime/vault-extra-ops.ts +606 -0
- package/src/telemetry/telemetry.ts +118 -0
- package/src/vault/playbook.ts +87 -0
- package/src/vault/vault.ts +575 -98
package/src/brain/brain.ts
CHANGED
|
@@ -17,6 +17,9 @@ import type {
|
|
|
17
17
|
CaptureResult,
|
|
18
18
|
BrainStats,
|
|
19
19
|
QueryContext,
|
|
20
|
+
FeedbackInput,
|
|
21
|
+
FeedbackEntry,
|
|
22
|
+
FeedbackStats,
|
|
20
23
|
} from './types.js';
|
|
21
24
|
|
|
22
25
|
// Re-export types for backward compatibility
|
|
@@ -44,7 +47,7 @@ const DEFAULT_WEIGHTS: ScoringWeights = {
|
|
|
44
47
|
semantic: 0.4,
|
|
45
48
|
vector: 0.0,
|
|
46
49
|
severity: 0.15,
|
|
47
|
-
|
|
50
|
+
temporalDecay: 0.15,
|
|
48
51
|
tagOverlap: 0.15,
|
|
49
52
|
domainMatch: 0.15,
|
|
50
53
|
};
|
|
@@ -53,7 +56,7 @@ const COGNEE_WEIGHTS: ScoringWeights = {
|
|
|
53
56
|
semantic: 0.25,
|
|
54
57
|
vector: 0.35,
|
|
55
58
|
severity: 0.1,
|
|
56
|
-
|
|
59
|
+
temporalDecay: 0.1,
|
|
57
60
|
tagOverlap: 0.1,
|
|
58
61
|
domainMatch: 0.1,
|
|
59
62
|
};
|
|
@@ -268,14 +271,109 @@ export class Brain {
|
|
|
268
271
|
return result;
|
|
269
272
|
}
|
|
270
273
|
|
|
271
|
-
recordFeedback(query: string, entryId: string, action: 'accepted' | 'dismissed'): void
|
|
274
|
+
recordFeedback(query: string, entryId: string, action: 'accepted' | 'dismissed'): void;
|
|
275
|
+
recordFeedback(input: FeedbackInput): FeedbackEntry;
|
|
276
|
+
recordFeedback(
|
|
277
|
+
queryOrInput: string | FeedbackInput,
|
|
278
|
+
entryId?: string,
|
|
279
|
+
action?: 'accepted' | 'dismissed',
|
|
280
|
+
): void | FeedbackEntry {
|
|
272
281
|
const db = this.vault.getDb();
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
282
|
+
|
|
283
|
+
// Normalize to FeedbackInput
|
|
284
|
+
const input: FeedbackInput =
|
|
285
|
+
typeof queryOrInput === 'string'
|
|
286
|
+
? { query: queryOrInput, entryId: entryId!, action: action! }
|
|
287
|
+
: queryOrInput;
|
|
288
|
+
|
|
289
|
+
db.prepare(
|
|
290
|
+
`INSERT INTO brain_feedback (query, entry_id, action, source, confidence, duration, context, reason)
|
|
291
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
292
|
+
).run(
|
|
293
|
+
input.query,
|
|
294
|
+
input.entryId,
|
|
295
|
+
input.action,
|
|
296
|
+
input.source ?? 'search',
|
|
297
|
+
input.confidence ?? 0.6,
|
|
298
|
+
input.duration ?? null,
|
|
299
|
+
input.context ?? '{}',
|
|
300
|
+
input.reason ?? null,
|
|
277
301
|
);
|
|
278
302
|
this.recomputeWeights();
|
|
303
|
+
|
|
304
|
+
// Return FeedbackEntry only for the object overload
|
|
305
|
+
if (typeof queryOrInput !== 'string') {
|
|
306
|
+
const row = db
|
|
307
|
+
.prepare(
|
|
308
|
+
'SELECT * FROM brain_feedback WHERE query = ? AND entry_id = ? ORDER BY id DESC LIMIT 1',
|
|
309
|
+
)
|
|
310
|
+
.get(input.query, input.entryId) as {
|
|
311
|
+
id: number;
|
|
312
|
+
query: string;
|
|
313
|
+
entry_id: string;
|
|
314
|
+
action: string;
|
|
315
|
+
source: string;
|
|
316
|
+
confidence: number;
|
|
317
|
+
duration: number | null;
|
|
318
|
+
context: string;
|
|
319
|
+
reason: string | null;
|
|
320
|
+
created_at: number;
|
|
321
|
+
};
|
|
322
|
+
return {
|
|
323
|
+
id: row.id,
|
|
324
|
+
query: row.query,
|
|
325
|
+
entryId: row.entry_id,
|
|
326
|
+
action: row.action as FeedbackEntry['action'],
|
|
327
|
+
source: row.source as FeedbackEntry['source'],
|
|
328
|
+
confidence: row.confidence,
|
|
329
|
+
duration: row.duration,
|
|
330
|
+
context: row.context,
|
|
331
|
+
reason: row.reason,
|
|
332
|
+
createdAt: row.created_at,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
getFeedbackStats(): FeedbackStats {
|
|
338
|
+
const db = this.vault.getDb();
|
|
339
|
+
|
|
340
|
+
const total = (
|
|
341
|
+
db.prepare('SELECT COUNT(*) as count FROM brain_feedback').get() as { count: number }
|
|
342
|
+
).count;
|
|
343
|
+
|
|
344
|
+
const byAction: Record<string, number> = {};
|
|
345
|
+
const actionRows = db
|
|
346
|
+
.prepare('SELECT action, COUNT(*) as count FROM brain_feedback GROUP BY action')
|
|
347
|
+
.all() as Array<{ action: string; count: number }>;
|
|
348
|
+
for (const row of actionRows) {
|
|
349
|
+
byAction[row.action] = row.count;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const bySource: Record<string, number> = {};
|
|
353
|
+
const sourceRows = db
|
|
354
|
+
.prepare('SELECT source, COUNT(*) as count FROM brain_feedback GROUP BY source')
|
|
355
|
+
.all() as Array<{ source: string; count: number }>;
|
|
356
|
+
for (const row of sourceRows) {
|
|
357
|
+
bySource[row.source] = row.count;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const accepted = byAction['accepted'] ?? 0;
|
|
361
|
+
const acceptanceRate = total > 0 ? accepted / total : 0;
|
|
362
|
+
|
|
363
|
+
const avgConf =
|
|
364
|
+
(
|
|
365
|
+
db.prepare('SELECT AVG(confidence) as avg FROM brain_feedback').get() as {
|
|
366
|
+
avg: number | null;
|
|
367
|
+
}
|
|
368
|
+
).avg ?? 0;
|
|
369
|
+
|
|
370
|
+
return {
|
|
371
|
+
total,
|
|
372
|
+
byAction,
|
|
373
|
+
bySource,
|
|
374
|
+
acceptanceRate,
|
|
375
|
+
averageConfidence: avgConf,
|
|
376
|
+
};
|
|
279
377
|
}
|
|
280
378
|
|
|
281
379
|
async getRelevantPatterns(context: QueryContext): Promise<RankedResult[]> {
|
|
@@ -356,6 +454,42 @@ export class Brain {
|
|
|
356
454
|
return this.vocabulary.size;
|
|
357
455
|
}
|
|
358
456
|
|
|
457
|
+
async getDecayReport(
|
|
458
|
+
query: string,
|
|
459
|
+
limit: number = 10,
|
|
460
|
+
): Promise<
|
|
461
|
+
Array<{
|
|
462
|
+
id: string;
|
|
463
|
+
title: string;
|
|
464
|
+
decayScore: number;
|
|
465
|
+
validUntil: number | null;
|
|
466
|
+
status: 'active' | 'expiring' | 'expired';
|
|
467
|
+
}>
|
|
468
|
+
> {
|
|
469
|
+
const results = await this.intelligentSearch(query, { limit });
|
|
470
|
+
const now = Math.floor(Date.now() / 1000);
|
|
471
|
+
return results.map((r) => {
|
|
472
|
+
const validUntil = r.entry.validUntil ?? null;
|
|
473
|
+
let status: 'active' | 'expiring' | 'expired' = 'active';
|
|
474
|
+
if (validUntil) {
|
|
475
|
+
if (validUntil <= now) status = 'expired';
|
|
476
|
+
else {
|
|
477
|
+
const validFrom = r.entry.validFrom ?? now;
|
|
478
|
+
const totalWindow = validUntil - validFrom;
|
|
479
|
+
const remaining = validUntil - now;
|
|
480
|
+
if (remaining <= totalWindow * 0.25) status = 'expiring';
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return {
|
|
484
|
+
id: r.entry.id,
|
|
485
|
+
title: r.entry.title,
|
|
486
|
+
decayScore: r.breakdown.temporalDecay,
|
|
487
|
+
validUntil,
|
|
488
|
+
status,
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
359
493
|
// ─── Private methods ─────────────────────────────────────────────
|
|
360
494
|
|
|
361
495
|
private scoreEntry(
|
|
@@ -385,9 +519,7 @@ export class Brain {
|
|
|
385
519
|
|
|
386
520
|
const severity = SEVERITY_SCORES[entry.severity] ?? 0.4;
|
|
387
521
|
|
|
388
|
-
const
|
|
389
|
-
const halfLifeSeconds = RECENCY_HALF_LIFE_DAYS * 86400;
|
|
390
|
-
const recency = entryAge > 0 ? Math.exp((-Math.LN2 * entryAge) / halfLifeSeconds) : 1;
|
|
522
|
+
const temporalDecay = computeTemporalDecay(entry, now);
|
|
391
523
|
|
|
392
524
|
const tagOverlap = queryTags.length > 0 ? jaccardSimilarity(queryTags, entry.tags) : 0;
|
|
393
525
|
|
|
@@ -399,11 +531,11 @@ export class Brain {
|
|
|
399
531
|
w.semantic * semantic +
|
|
400
532
|
w.vector * vector +
|
|
401
533
|
w.severity * severity +
|
|
402
|
-
w.
|
|
534
|
+
w.temporalDecay * temporalDecay +
|
|
403
535
|
w.tagOverlap * tagOverlap +
|
|
404
536
|
w.domainMatch * domainMatch;
|
|
405
537
|
|
|
406
|
-
return { semantic, vector, severity,
|
|
538
|
+
return { semantic, vector, severity, temporalDecay, tagOverlap, domainMatch, total };
|
|
407
539
|
}
|
|
408
540
|
|
|
409
541
|
private generateTags(title: string, description: string, context?: string): string[] {
|
|
@@ -503,8 +635,11 @@ export class Brain {
|
|
|
503
635
|
|
|
504
636
|
private recomputeWeights(): void {
|
|
505
637
|
const db = this.vault.getDb();
|
|
638
|
+
// Exclude 'failed' from weight computation — system errors don't indicate relevance
|
|
506
639
|
const feedbackCount = (
|
|
507
|
-
db.prepare(
|
|
640
|
+
db.prepare("SELECT COUNT(*) as count FROM brain_feedback WHERE action != 'failed'").get() as {
|
|
641
|
+
count: number;
|
|
642
|
+
}
|
|
508
643
|
).count;
|
|
509
644
|
if (feedbackCount < FEEDBACK_THRESHOLD) {
|
|
510
645
|
this.weights = { ...DEFAULT_WEIGHTS };
|
|
@@ -516,7 +651,13 @@ export class Brain {
|
|
|
516
651
|
.prepare("SELECT COUNT(*) as count FROM brain_feedback WHERE action = 'accepted'")
|
|
517
652
|
.get() as { count: number }
|
|
518
653
|
).count;
|
|
519
|
-
|
|
654
|
+
// 'modified' counts as 0.5 positive — user adjusted but didn't dismiss
|
|
655
|
+
const modified = (
|
|
656
|
+
db
|
|
657
|
+
.prepare("SELECT COUNT(*) as count FROM brain_feedback WHERE action = 'modified'")
|
|
658
|
+
.get() as { count: number }
|
|
659
|
+
).count;
|
|
660
|
+
const acceptRate = feedbackCount > 0 ? (accepted + modified * 0.5) / feedbackCount : 0.5;
|
|
520
661
|
|
|
521
662
|
const semanticDelta = (acceptRate - 0.5) * WEIGHT_BOUND * 2;
|
|
522
663
|
|
|
@@ -533,12 +674,12 @@ export class Brain {
|
|
|
533
674
|
const remaining = 1.0 - newWeights.semantic - newWeights.vector;
|
|
534
675
|
const otherSum =
|
|
535
676
|
DEFAULT_WEIGHTS.severity +
|
|
536
|
-
DEFAULT_WEIGHTS.
|
|
677
|
+
DEFAULT_WEIGHTS.temporalDecay +
|
|
537
678
|
DEFAULT_WEIGHTS.tagOverlap +
|
|
538
679
|
DEFAULT_WEIGHTS.domainMatch;
|
|
539
680
|
const scale = remaining / otherSum;
|
|
540
681
|
newWeights.severity = DEFAULT_WEIGHTS.severity * scale;
|
|
541
|
-
newWeights.
|
|
682
|
+
newWeights.temporalDecay = DEFAULT_WEIGHTS.temporalDecay * scale;
|
|
542
683
|
newWeights.tagOverlap = DEFAULT_WEIGHTS.tagOverlap * scale;
|
|
543
684
|
newWeights.domainMatch = DEFAULT_WEIGHTS.domainMatch * scale;
|
|
544
685
|
|
|
@@ -546,6 +687,34 @@ export class Brain {
|
|
|
546
687
|
}
|
|
547
688
|
}
|
|
548
689
|
|
|
690
|
+
function computeTemporalDecay(entry: IntelligenceEntry, now: number): number {
|
|
691
|
+
const entryRecord = entry as unknown as {
|
|
692
|
+
created_at?: number;
|
|
693
|
+
updated_at?: number;
|
|
694
|
+
valid_until?: number;
|
|
695
|
+
valid_from?: number;
|
|
696
|
+
};
|
|
697
|
+
const validUntil = entry.validUntil ?? entryRecord.valid_until;
|
|
698
|
+
|
|
699
|
+
if (!validUntil) {
|
|
700
|
+
// No expiry — use existing age-based exponential decay
|
|
701
|
+
const updatedAt = entryRecord.updated_at ?? entryRecord.created_at ?? now;
|
|
702
|
+
const ageSeconds = now - updatedAt;
|
|
703
|
+
const halfLifeSeconds = RECENCY_HALF_LIFE_DAYS * 86400;
|
|
704
|
+
return ageSeconds > 0 ? Math.exp((-Math.LN2 * ageSeconds) / halfLifeSeconds) : 1;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// With valid_until: linear ramp-down in last 25% of validity window
|
|
708
|
+
const validFrom = entry.validFrom ?? entryRecord.valid_from ?? entryRecord.created_at ?? now;
|
|
709
|
+
const totalWindow = validUntil - validFrom;
|
|
710
|
+
const remaining = validUntil - now;
|
|
711
|
+
if (remaining <= 0) return 0; // expired
|
|
712
|
+
if (totalWindow <= 0) return 1; // edge case: bad data
|
|
713
|
+
const decayZone = totalWindow * 0.25;
|
|
714
|
+
if (remaining > decayZone) return 1.0; // fully valid
|
|
715
|
+
return remaining / decayZone; // linear decay in last quarter
|
|
716
|
+
}
|
|
717
|
+
|
|
549
718
|
function clamp(value: number, min: number, max: number): number {
|
|
550
719
|
return Math.max(min, Math.min(max, value));
|
|
551
720
|
}
|
|
@@ -77,7 +77,8 @@ export class BrainIntelligence {
|
|
|
77
77
|
tools_used TEXT NOT NULL DEFAULT '[]',
|
|
78
78
|
files_modified TEXT NOT NULL DEFAULT '[]',
|
|
79
79
|
plan_id TEXT,
|
|
80
|
-
plan_outcome TEXT
|
|
80
|
+
plan_outcome TEXT,
|
|
81
|
+
extracted_at TEXT
|
|
81
82
|
);
|
|
82
83
|
|
|
83
84
|
CREATE TABLE IF NOT EXISTS brain_proposals (
|
|
@@ -161,9 +162,34 @@ export class BrainIntelligence {
|
|
|
161
162
|
values.push(sessionId);
|
|
162
163
|
db.prepare(`UPDATE brain_sessions SET ${updates.join(', ')} WHERE id = ?`).run(...values);
|
|
163
164
|
|
|
165
|
+
// Auto-extract knowledge if session has enough signal
|
|
166
|
+
this.autoExtractIfReady(this.getSession(sessionId)!);
|
|
167
|
+
|
|
168
|
+
// Return fresh session (extractedAt may have been set by auto-extract)
|
|
164
169
|
return this.getSession(sessionId)!;
|
|
165
170
|
}
|
|
166
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Attempt auto-extraction after session end if the session has enough signal.
|
|
174
|
+
* Gate: at least 1 tool used OR 1 file modified OR a plan was associated.
|
|
175
|
+
* Silently skips if already extracted or insufficient data.
|
|
176
|
+
*/
|
|
177
|
+
private autoExtractIfReady(session: BrainSession): void {
|
|
178
|
+
if (!session.endedAt) return;
|
|
179
|
+
if (session.extractedAt) return;
|
|
180
|
+
|
|
181
|
+
const hasSignal =
|
|
182
|
+
session.toolsUsed.length > 0 || session.filesModified.length > 0 || session.planId !== null;
|
|
183
|
+
|
|
184
|
+
if (!hasSignal) return;
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
this.extractKnowledge(session.id);
|
|
188
|
+
} catch {
|
|
189
|
+
// Non-critical — don't break session end
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
167
193
|
getSessionContext(limit = 10): SessionContext {
|
|
168
194
|
const db = this.vault.getDb();
|
|
169
195
|
|
|
@@ -179,6 +205,7 @@ export class BrainIntelligence {
|
|
|
179
205
|
files_modified: string;
|
|
180
206
|
plan_id: string | null;
|
|
181
207
|
plan_outcome: string | null;
|
|
208
|
+
extracted_at: string | null;
|
|
182
209
|
}>;
|
|
183
210
|
|
|
184
211
|
const sessions = rows.map((r) => this.rowToSession(r));
|
|
@@ -230,6 +257,8 @@ export class BrainIntelligence {
|
|
|
230
257
|
COUNT(*) as total,
|
|
231
258
|
SUM(CASE WHEN action = 'accepted' THEN 1 ELSE 0 END) as accepted,
|
|
232
259
|
SUM(CASE WHEN action = 'dismissed' THEN 1 ELSE 0 END) as dismissed,
|
|
260
|
+
SUM(CASE WHEN action = 'modified' THEN 1 ELSE 0 END) as modified,
|
|
261
|
+
SUM(CASE WHEN action = 'failed' THEN 1 ELSE 0 END) as failed,
|
|
233
262
|
MAX(created_at) as last_used
|
|
234
263
|
FROM brain_feedback
|
|
235
264
|
GROUP BY entry_id`,
|
|
@@ -239,6 +268,8 @@ export class BrainIntelligence {
|
|
|
239
268
|
total: number;
|
|
240
269
|
accepted: number;
|
|
241
270
|
dismissed: number;
|
|
271
|
+
modified: number;
|
|
272
|
+
failed: number;
|
|
242
273
|
last_used: string;
|
|
243
274
|
}>;
|
|
244
275
|
|
|
@@ -265,7 +296,10 @@ export class BrainIntelligence {
|
|
|
265
296
|
const spreadScore = Math.min(25, (uniqueContexts / SPREAD_MAX) * 25);
|
|
266
297
|
|
|
267
298
|
// Success score: 25 * successRate
|
|
268
|
-
|
|
299
|
+
// modified = 0.5 positive, failed = excluded (system error, not relevance)
|
|
300
|
+
const relevantTotal = row.total - row.failed;
|
|
301
|
+
const successRate =
|
|
302
|
+
relevantTotal > 0 ? (row.accepted + row.modified * 0.5) / relevantTotal : 0;
|
|
269
303
|
const successScore = 25 * successRate;
|
|
270
304
|
|
|
271
305
|
// Recency score: max(0, 25 * (1 - daysSince / RECENCY_DECAY_DAYS))
|
|
@@ -364,12 +398,17 @@ export class BrainIntelligence {
|
|
|
364
398
|
}));
|
|
365
399
|
}
|
|
366
400
|
|
|
367
|
-
recommend(context: {
|
|
401
|
+
recommend(context: {
|
|
402
|
+
domain?: string;
|
|
403
|
+
task?: string;
|
|
404
|
+
source?: string;
|
|
405
|
+
limit?: number;
|
|
406
|
+
}): PatternStrength[] {
|
|
368
407
|
const limit = context.limit ?? 5;
|
|
369
408
|
const strengths = this.getStrengths({
|
|
370
409
|
domain: context.domain,
|
|
371
410
|
minStrength: 30,
|
|
372
|
-
limit: limit *
|
|
411
|
+
limit: limit * 3,
|
|
373
412
|
});
|
|
374
413
|
|
|
375
414
|
// If task context provided, boost patterns with matching terms
|
|
@@ -383,9 +422,36 @@ export class BrainIntelligence {
|
|
|
383
422
|
(s as { strength: number }).strength += overlap * 5;
|
|
384
423
|
}
|
|
385
424
|
}
|
|
386
|
-
strengths.sort((a, b) => b.strength - a.strength);
|
|
387
425
|
}
|
|
388
426
|
|
|
427
|
+
// Boost patterns with high source-specific acceptance rates
|
|
428
|
+
if (context.source) {
|
|
429
|
+
const db = this.vault.getDb();
|
|
430
|
+
for (const s of strengths) {
|
|
431
|
+
const row = db
|
|
432
|
+
.prepare(
|
|
433
|
+
`SELECT COUNT(*) as total,
|
|
434
|
+
SUM(CASE WHEN action = 'accepted' THEN 1 ELSE 0 END) as accepted,
|
|
435
|
+
SUM(CASE WHEN action = 'modified' THEN 1 ELSE 0 END) as modified
|
|
436
|
+
FROM brain_feedback
|
|
437
|
+
WHERE entry_id = (SELECT id FROM entries WHERE title = ? LIMIT 1)
|
|
438
|
+
AND source = ?`,
|
|
439
|
+
)
|
|
440
|
+
.get(s.pattern, context.source) as {
|
|
441
|
+
total: number;
|
|
442
|
+
accepted: number;
|
|
443
|
+
modified: number;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
if (row.total >= 3) {
|
|
447
|
+
const sourceRate = (row.accepted + row.modified * 0.5) / row.total;
|
|
448
|
+
// Boost up to +10 points for high source-specific acceptance
|
|
449
|
+
(s as { strength: number }).strength += sourceRate * 10;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
strengths.sort((a, b) => b.strength - a.strength);
|
|
389
455
|
return strengths.slice(0, limit);
|
|
390
456
|
}
|
|
391
457
|
|
|
@@ -510,6 +576,11 @@ export class BrainIntelligence {
|
|
|
510
576
|
}
|
|
511
577
|
}
|
|
512
578
|
|
|
579
|
+
// Mark session as extracted
|
|
580
|
+
db.prepare("UPDATE brain_sessions SET extracted_at = datetime('now') WHERE id = ?").run(
|
|
581
|
+
sessionId,
|
|
582
|
+
);
|
|
583
|
+
|
|
513
584
|
return {
|
|
514
585
|
sessionId,
|
|
515
586
|
proposals,
|
|
@@ -517,6 +588,37 @@ export class BrainIntelligence {
|
|
|
517
588
|
};
|
|
518
589
|
}
|
|
519
590
|
|
|
591
|
+
resetExtracted(options?: { sessionId?: string; since?: string; all?: boolean }): {
|
|
592
|
+
reset: number;
|
|
593
|
+
} {
|
|
594
|
+
const db = this.vault.getDb();
|
|
595
|
+
|
|
596
|
+
if (options?.sessionId) {
|
|
597
|
+
const info = db
|
|
598
|
+
.prepare(
|
|
599
|
+
'UPDATE brain_sessions SET extracted_at = NULL WHERE id = ? AND extracted_at IS NOT NULL',
|
|
600
|
+
)
|
|
601
|
+
.run(options.sessionId);
|
|
602
|
+
return { reset: info.changes };
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
if (options?.since) {
|
|
606
|
+
const info = db
|
|
607
|
+
.prepare('UPDATE brain_sessions SET extracted_at = NULL WHERE extracted_at >= ?')
|
|
608
|
+
.run(options.since);
|
|
609
|
+
return { reset: info.changes };
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
if (options?.all) {
|
|
613
|
+
const info = db
|
|
614
|
+
.prepare('UPDATE brain_sessions SET extracted_at = NULL WHERE extracted_at IS NOT NULL')
|
|
615
|
+
.run();
|
|
616
|
+
return { reset: info.changes };
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
return { reset: 0 };
|
|
620
|
+
}
|
|
621
|
+
|
|
520
622
|
getProposals(options?: {
|
|
521
623
|
sessionId?: string;
|
|
522
624
|
promoted?: boolean;
|
|
@@ -556,10 +658,36 @@ export class BrainIntelligence {
|
|
|
556
658
|
return rows.map((r) => this.rowToProposal(r));
|
|
557
659
|
}
|
|
558
660
|
|
|
559
|
-
promoteProposals(
|
|
661
|
+
promoteProposals(
|
|
662
|
+
proposalIds: string[],
|
|
663
|
+
governanceGate?: {
|
|
664
|
+
evaluateCapture: (
|
|
665
|
+
projectPath: string,
|
|
666
|
+
entry: { type: string; category: string; title?: string },
|
|
667
|
+
) => { action: string; reason?: string };
|
|
668
|
+
propose: (
|
|
669
|
+
projectPath: string,
|
|
670
|
+
entryData: {
|
|
671
|
+
entryId?: string;
|
|
672
|
+
title: string;
|
|
673
|
+
type: string;
|
|
674
|
+
category: string;
|
|
675
|
+
data?: Record<string, unknown>;
|
|
676
|
+
},
|
|
677
|
+
source?: string,
|
|
678
|
+
) => number;
|
|
679
|
+
},
|
|
680
|
+
projectPath?: string,
|
|
681
|
+
): {
|
|
682
|
+
promoted: number;
|
|
683
|
+
failed: string[];
|
|
684
|
+
gated: Array<{ id: string; action: string; reason?: string }>;
|
|
685
|
+
} {
|
|
560
686
|
const db = this.vault.getDb();
|
|
561
687
|
let promoted = 0;
|
|
562
688
|
const failed: string[] = [];
|
|
689
|
+
const gated: Array<{ id: string; action: string; reason?: string }> = [];
|
|
690
|
+
const pp = projectPath ?? '.';
|
|
563
691
|
|
|
564
692
|
for (const id of proposalIds) {
|
|
565
693
|
const row = db.prepare('SELECT * FROM brain_proposals WHERE id = ?').get(id) as
|
|
@@ -583,10 +711,46 @@ export class BrainIntelligence {
|
|
|
583
711
|
|
|
584
712
|
if (row.promoted) continue; // Already promoted
|
|
585
713
|
|
|
586
|
-
//
|
|
714
|
+
// Map type for vault
|
|
587
715
|
const rawType = row.type;
|
|
588
716
|
const vaultType: 'pattern' | 'anti-pattern' | 'rule' =
|
|
589
717
|
rawType === 'anti-pattern' ? 'anti-pattern' : 'pattern';
|
|
718
|
+
|
|
719
|
+
// Governance gate (when provided)
|
|
720
|
+
if (governanceGate) {
|
|
721
|
+
const decision = governanceGate.evaluateCapture(pp, {
|
|
722
|
+
type: vaultType,
|
|
723
|
+
category: 'brain-intelligence',
|
|
724
|
+
title: row.title,
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
if (decision.action === 'propose') {
|
|
728
|
+
governanceGate.propose(
|
|
729
|
+
pp,
|
|
730
|
+
{
|
|
731
|
+
entryId: `proposal-${id}`,
|
|
732
|
+
title: row.title,
|
|
733
|
+
type: vaultType,
|
|
734
|
+
category: 'brain-intelligence',
|
|
735
|
+
data: {
|
|
736
|
+
severity: 'suggestion',
|
|
737
|
+
description: row.description,
|
|
738
|
+
tags: ['auto-extracted', row.rule],
|
|
739
|
+
},
|
|
740
|
+
},
|
|
741
|
+
'brain-promote',
|
|
742
|
+
);
|
|
743
|
+
gated.push({ id, action: 'propose', reason: decision.reason });
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
if (decision.action !== 'capture') {
|
|
748
|
+
gated.push({ id, action: decision.action, reason: decision.reason });
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Capture into vault
|
|
590
754
|
this.brain.enrichAndCapture({
|
|
591
755
|
id: `proposal-${id}`,
|
|
592
756
|
type: vaultType,
|
|
@@ -601,7 +765,7 @@ export class BrainIntelligence {
|
|
|
601
765
|
promoted++;
|
|
602
766
|
}
|
|
603
767
|
|
|
604
|
-
return { promoted, failed };
|
|
768
|
+
return { promoted, failed, gated };
|
|
605
769
|
}
|
|
606
770
|
|
|
607
771
|
// ─── Intelligence Pipeline ────────────────────────────────────────
|
|
@@ -725,6 +889,7 @@ export class BrainIntelligence {
|
|
|
725
889
|
files_modified: string;
|
|
726
890
|
plan_id: string | null;
|
|
727
891
|
plan_outcome: string | null;
|
|
892
|
+
extracted_at: string | null;
|
|
728
893
|
}>;
|
|
729
894
|
const sessions = sessionRows.map((r) => this.rowToSession(r));
|
|
730
895
|
|
|
@@ -790,8 +955,8 @@ export class BrainIntelligence {
|
|
|
790
955
|
// Import sessions
|
|
791
956
|
const insertSession = db.prepare(
|
|
792
957
|
`INSERT OR IGNORE INTO brain_sessions
|
|
793
|
-
(id, started_at, ended_at, domain, context, tools_used, files_modified, plan_id, plan_outcome)
|
|
794
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
958
|
+
(id, started_at, ended_at, domain, context, tools_used, files_modified, plan_id, plan_outcome, extracted_at)
|
|
959
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
795
960
|
);
|
|
796
961
|
for (const s of data.sessions) {
|
|
797
962
|
const changes = insertSession.run(
|
|
@@ -804,6 +969,7 @@ export class BrainIntelligence {
|
|
|
804
969
|
JSON.stringify(s.filesModified),
|
|
805
970
|
s.planId,
|
|
806
971
|
s.planOutcome,
|
|
972
|
+
s.extractedAt ?? null,
|
|
807
973
|
);
|
|
808
974
|
if (changes.changes > 0) result.imported.sessions++;
|
|
809
975
|
}
|
|
@@ -883,6 +1049,7 @@ export class BrainIntelligence {
|
|
|
883
1049
|
files_modified: string;
|
|
884
1050
|
plan_id: string | null;
|
|
885
1051
|
plan_outcome: string | null;
|
|
1052
|
+
extracted_at: string | null;
|
|
886
1053
|
}
|
|
887
1054
|
| undefined;
|
|
888
1055
|
|
|
@@ -900,6 +1067,7 @@ export class BrainIntelligence {
|
|
|
900
1067
|
files_modified: string;
|
|
901
1068
|
plan_id: string | null;
|
|
902
1069
|
plan_outcome: string | null;
|
|
1070
|
+
extracted_at: string | null;
|
|
903
1071
|
}): BrainSession {
|
|
904
1072
|
return {
|
|
905
1073
|
id: row.id,
|
|
@@ -911,6 +1079,7 @@ export class BrainIntelligence {
|
|
|
911
1079
|
filesModified: JSON.parse(row.files_modified) as string[],
|
|
912
1080
|
planId: row.plan_id,
|
|
913
1081
|
planOutcome: row.plan_outcome,
|
|
1082
|
+
extractedAt: row.extracted_at,
|
|
914
1083
|
};
|
|
915
1084
|
}
|
|
916
1085
|
|
package/src/brain/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface ScoringWeights {
|
|
|
6
6
|
semantic: number;
|
|
7
7
|
vector: number;
|
|
8
8
|
severity: number;
|
|
9
|
-
|
|
9
|
+
temporalDecay: number;
|
|
10
10
|
tagOverlap: number;
|
|
11
11
|
domainMatch: number;
|
|
12
12
|
}
|
|
@@ -15,7 +15,7 @@ export interface ScoreBreakdown {
|
|
|
15
15
|
semantic: number;
|
|
16
16
|
vector: number;
|
|
17
17
|
severity: number;
|
|
18
|
-
|
|
18
|
+
temporalDecay: number;
|
|
19
19
|
tagOverlap: number;
|
|
20
20
|
domainMatch: number;
|
|
21
21
|
total: number;
|
|
@@ -55,6 +55,43 @@ export interface QueryContext {
|
|
|
55
55
|
tags?: string[];
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// ─── Feedback Types ───────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
export type FeedbackType = 'accepted' | 'dismissed' | 'modified' | 'failed';
|
|
61
|
+
export type FeedbackSource = 'search' | 'recommendation' | 'tool-execution' | 'explicit';
|
|
62
|
+
|
|
63
|
+
export interface FeedbackInput {
|
|
64
|
+
query: string;
|
|
65
|
+
entryId: string;
|
|
66
|
+
action: FeedbackType;
|
|
67
|
+
source?: FeedbackSource;
|
|
68
|
+
confidence?: number;
|
|
69
|
+
duration?: number;
|
|
70
|
+
context?: string;
|
|
71
|
+
reason?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface FeedbackEntry {
|
|
75
|
+
id: number;
|
|
76
|
+
query: string;
|
|
77
|
+
entryId: string;
|
|
78
|
+
action: FeedbackType;
|
|
79
|
+
source: FeedbackSource;
|
|
80
|
+
confidence: number;
|
|
81
|
+
duration: number | null;
|
|
82
|
+
context: string;
|
|
83
|
+
reason: string | null;
|
|
84
|
+
createdAt: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface FeedbackStats {
|
|
88
|
+
total: number;
|
|
89
|
+
byAction: Record<string, number>;
|
|
90
|
+
bySource: Record<string, number>;
|
|
91
|
+
acceptanceRate: number;
|
|
92
|
+
averageConfidence: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
58
95
|
// ─── Brain Intelligence Types ──────────────────────────────────────
|
|
59
96
|
|
|
60
97
|
export interface PatternStrength {
|
|
@@ -87,6 +124,7 @@ export interface BrainSession {
|
|
|
87
124
|
filesModified: string[];
|
|
88
125
|
planId: string | null;
|
|
89
126
|
planOutcome: string | null;
|
|
127
|
+
extractedAt: string | null;
|
|
90
128
|
}
|
|
91
129
|
|
|
92
130
|
export interface SessionLifecycleInput {
|