autosnippet 3.3.7 → 3.3.8
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/README.md +1 -0
- package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
- package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
- package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.js +7 -4
- package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
- package/dist/lib/agent/core/LoopContext.d.ts +1 -0
- package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
- package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
- package/dist/lib/agent/memory/ActiveContext.js +0 -2
- package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
- package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
- package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
- package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
- package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
- package/dist/lib/agent/memory/MemoryStore.js +196 -261
- package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
- package/dist/lib/agent/memory/PersistentMemory.js +4 -5
- package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
- package/dist/lib/agent/memory/SessionStore.js +0 -2
- package/dist/lib/agent/tools/ast-graph.js +21 -19
- package/dist/lib/agent/tools/infrastructure.js +3 -2
- package/dist/lib/agent/tools/project-access.d.ts +2 -2
- package/dist/lib/agent/tools/project-access.js +5 -4
- package/dist/lib/bootstrap.js +2 -1
- package/dist/lib/cli/AiScanService.js +4 -17
- package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
- package/dist/lib/cli/KnowledgeSyncService.js +23 -51
- package/dist/lib/core/ast/ProjectGraph.js +5 -27
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
- package/dist/lib/domain/dimension/DimensionSop.js +44 -33
- package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
- package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
- package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
- package/dist/lib/domain/knowledge/index.d.ts +2 -1
- package/dist/lib/domain/knowledge/index.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/panorama.js +9 -9
- package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
- package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
- package/dist/lib/external/mcp/handlers/search.js +3 -1
- package/dist/lib/external/mcp/handlers/skill.js +4 -4
- package/dist/lib/external/mcp/handlers/structure.js +8 -12
- package/dist/lib/external/mcp/handlers/system.js +10 -34
- package/dist/lib/http/routes/ai.js +11 -13
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +59 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
- package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
- package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
- package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
- package/dist/lib/injection/ServiceContainer.js +7 -4
- package/dist/lib/injection/ServiceMap.d.ts +20 -0
- package/dist/lib/injection/modules/AppModule.js +2 -1
- package/dist/lib/injection/modules/GuardModule.js +5 -5
- package/dist/lib/injection/modules/InfraModule.js +60 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
- package/dist/lib/injection/modules/PanoramaModule.js +16 -10
- package/dist/lib/injection/modules/VectorModule.js +3 -0
- package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
- package/dist/lib/repository/audit/AuditRepository.js +272 -0
- package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
- package/dist/lib/repository/base/RepositoryBase.js +32 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
- package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
- package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
- package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
- package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
- package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
- package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
- package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
- package/dist/lib/repository/memory/MemoryRepository.js +260 -0
- package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
- package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
- package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
- package/dist/lib/repository/session/SessionRepository.js +110 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
- package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
- package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
- package/dist/lib/service/cleanup/CleanupService.js +8 -4
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
- package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
- package/dist/lib/service/evolution/ContentPatcher.js +48 -19
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
- package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
- package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
- package/dist/lib/service/evolution/DecayDetector.js +63 -57
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
- package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
- package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
- package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
- package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
- package/dist/lib/service/evolution/StagingManager.js +37 -95
- package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
- package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
- package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
- package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
- package/dist/lib/service/guard/ReverseGuard.js +21 -31
- package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
- package/dist/lib/service/guard/ViolationsStore.js +75 -69
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
- package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
- package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
- package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
- package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
- package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
- package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
- package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
- package/dist/lib/service/panorama/LayerInferrer.js +1 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
- package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
- package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +41 -66
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
- package/dist/lib/service/panorama/RoleRefiner.js +52 -283
- package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
- package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
- package/dist/lib/service/quality/QualityScorer.js +157 -83
- package/dist/lib/service/search/SearchEngine.d.ts +1 -0
- package/dist/lib/service/search/SearchEngine.js +32 -37
- package/dist/lib/service/signal/HitRecorder.js +5 -5
- package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
- package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
- package/dist/lib/service/skills/SignalCollector.js +28 -55
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
- package/dist/lib/service/vector/SyncCoordinator.js +25 -3
- package/dist/lib/service/vector/VectorService.d.ts +2 -0
- package/dist/lib/service/vector/VectorService.js +3 -0
- package/dist/lib/service/wiki/WikiGenerator.js +1 -1
- package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
- package/dist/lib/shared/LanguageProfiles.js +939 -0
- package/dist/lib/shared/LanguageService.d.ts +6 -0
- package/dist/lib/shared/LanguageService.js +16 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
- package/dist/lib/types/project-snapshot-builder.js +0 -1
- package/dist/lib/types/project-snapshot.d.ts +0 -1
- package/dist/lib/types/project-snapshot.js +0 -1
- package/dist/lib/types/snapshot-views.d.ts +0 -2
- package/dist/lib/types/snapshot-views.js +0 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
- package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
- package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import { randomUUID } from 'node:crypto';
|
|
20
20
|
import { isValidTransition } from '../../domain/knowledge/Lifecycle.js';
|
|
21
21
|
import Logger from '../../infrastructure/logging/Logger.js';
|
|
22
|
+
/* ────────────────────── Types ────────────────────── */
|
|
22
23
|
/* ────────────────────── Constants ────────────────────── */
|
|
23
24
|
/** 中间态超时配置(毫秒) */
|
|
24
25
|
const TIMEOUT_MS = {
|
|
@@ -50,11 +51,15 @@ const ENTRY_META_KEYS = {
|
|
|
50
51
|
};
|
|
51
52
|
/* ────────────────────── Class ────────────────────── */
|
|
52
53
|
export class RecipeLifecycleSupervisor {
|
|
53
|
-
#
|
|
54
|
+
#knowledgeRepo;
|
|
55
|
+
#proposalRepo;
|
|
56
|
+
#lifecycleEventRepo;
|
|
54
57
|
#signalBus;
|
|
55
58
|
#logger = Logger.getInstance();
|
|
56
|
-
constructor(
|
|
57
|
-
this.#
|
|
59
|
+
constructor(knowledgeRepo, options = {}) {
|
|
60
|
+
this.#knowledgeRepo = knowledgeRepo;
|
|
61
|
+
this.#proposalRepo = options.proposalRepo ?? null;
|
|
62
|
+
this.#lifecycleEventRepo = options.lifecycleEventRepo ?? null;
|
|
58
63
|
this.#signalBus = options.signalBus ?? null;
|
|
59
64
|
}
|
|
60
65
|
/* ═══════════════════ Core Transition ═══════════════════ */
|
|
@@ -69,11 +74,11 @@ export class RecipeLifecycleSupervisor {
|
|
|
69
74
|
* 6. 记录 TransitionEvent
|
|
70
75
|
* 7. 发射信号
|
|
71
76
|
*/
|
|
72
|
-
transition(request) {
|
|
77
|
+
async transition(request) {
|
|
73
78
|
const { recipeId, targetState, trigger, evidence, proposalId, operatorId } = request;
|
|
74
79
|
const opId = operatorId ?? 'system';
|
|
75
80
|
// 1. 获取当前状态
|
|
76
|
-
const current = this.#getRecipeState(recipeId);
|
|
81
|
+
const current = await this.#getRecipeState(recipeId);
|
|
77
82
|
if (!current) {
|
|
78
83
|
return {
|
|
79
84
|
success: false,
|
|
@@ -94,14 +99,12 @@ export class RecipeLifecycleSupervisor {
|
|
|
94
99
|
};
|
|
95
100
|
}
|
|
96
101
|
// 3. Exit Action
|
|
97
|
-
this.#executeExitAction(recipeId, fromState);
|
|
102
|
+
await this.#executeExitAction(recipeId, fromState);
|
|
98
103
|
// 4. 更新 lifecycle
|
|
99
104
|
const now = Date.now();
|
|
100
|
-
this.#
|
|
101
|
-
.prepare(`UPDATE knowledge_entries SET lifecycle = ?, updatedAt = ? WHERE id = ?`)
|
|
102
|
-
.run(targetState, now, recipeId);
|
|
105
|
+
await this.#knowledgeRepo.updateLifecycle(recipeId, targetState);
|
|
103
106
|
// 5. Entry Action
|
|
104
|
-
this.#executeEntryAction(recipeId, targetState, now, proposalId);
|
|
107
|
+
await this.#executeEntryAction(recipeId, targetState, now, proposalId);
|
|
105
108
|
// 6. 记录 TransitionEvent
|
|
106
109
|
const event = this.#recordEvent({
|
|
107
110
|
recipeId,
|
|
@@ -126,7 +129,7 @@ export class RecipeLifecycleSupervisor {
|
|
|
126
129
|
* - evolving > 7d → active(回退)
|
|
127
130
|
* - decaying > 30d → deprecated
|
|
128
131
|
*/
|
|
129
|
-
checkTimeouts() {
|
|
132
|
+
async checkTimeouts() {
|
|
130
133
|
const result = { timedOut: [], checked: 0 };
|
|
131
134
|
const now = Date.now();
|
|
132
135
|
for (const [state, timeoutMs] of Object.entries(TIMEOUT_MS)) {
|
|
@@ -134,19 +137,16 @@ export class RecipeLifecycleSupervisor {
|
|
|
134
137
|
continue;
|
|
135
138
|
}
|
|
136
139
|
const targetState = TIMEOUT_TARGET[state];
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
for (const row of rows) {
|
|
142
|
-
const stats = safeJsonParse(row.stats, {});
|
|
140
|
+
const entries = await this.#knowledgeRepo.findAllByLifecycles([state]);
|
|
141
|
+
result.checked += entries.length;
|
|
142
|
+
for (const entry of entries) {
|
|
143
|
+
const stats = (entry.stats ?? {});
|
|
143
144
|
const entryKey = ENTRY_META_KEYS[state];
|
|
144
145
|
const enteredAt = (entryKey ? stats[entryKey] : null);
|
|
145
|
-
|
|
146
|
-
const stateAge = enteredAt ? now - enteredAt : this.#getRecipeAge(row.id, now);
|
|
146
|
+
const stateAge = enteredAt ? now - enteredAt : await this.#getRecipeAge(entry.id, now);
|
|
147
147
|
if (stateAge > timeoutMs) {
|
|
148
|
-
const transitionResult = this.transition({
|
|
149
|
-
recipeId:
|
|
148
|
+
const transitionResult = await this.transition({
|
|
149
|
+
recipeId: entry.id,
|
|
150
150
|
targetState,
|
|
151
151
|
trigger: 'timeout-recovery',
|
|
152
152
|
evidence: {
|
|
@@ -155,7 +155,7 @@ export class RecipeLifecycleSupervisor {
|
|
|
155
155
|
});
|
|
156
156
|
if (transitionResult.success) {
|
|
157
157
|
result.timedOut.push({
|
|
158
|
-
recipeId:
|
|
158
|
+
recipeId: entry.id,
|
|
159
159
|
fromState: state,
|
|
160
160
|
toState: targetState,
|
|
161
161
|
age: stateAge,
|
|
@@ -175,15 +175,10 @@ export class RecipeLifecycleSupervisor {
|
|
|
175
175
|
*/
|
|
176
176
|
getTransitionHistory(recipeId, limit = 50) {
|
|
177
177
|
try {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
WHERE recipe_id = ?
|
|
183
|
-
ORDER BY created_at DESC
|
|
184
|
-
LIMIT ?`)
|
|
185
|
-
.all(recipeId, limit);
|
|
186
|
-
return rows.map((row) => this.#rowToEvent(row));
|
|
178
|
+
if (!this.#lifecycleEventRepo) {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
return this.#lifecycleEventRepo.getHistory(recipeId, limit);
|
|
187
182
|
}
|
|
188
183
|
catch {
|
|
189
184
|
// 表可能不存在(migration 未运行)
|
|
@@ -193,16 +188,14 @@ export class RecipeLifecycleSupervisor {
|
|
|
193
188
|
/**
|
|
194
189
|
* 获取全局状态健康摘要
|
|
195
190
|
*/
|
|
196
|
-
getHealthSummary() {
|
|
191
|
+
async getHealthSummary() {
|
|
197
192
|
const now = Date.now();
|
|
198
|
-
|
|
199
|
-
const stateDistribution = this.#getStateDistribution();
|
|
200
|
-
// 中间态卡死检测
|
|
193
|
+
const stateDistribution = await this.#getStateDistribution();
|
|
201
194
|
const intermediateStates = {
|
|
202
|
-
stuckEvolving: this.#getStuckInfo('evolving', STUCK_THRESHOLD_MS.evolving, now),
|
|
203
|
-
stuckDecaying: this.#getStuckInfo('decaying', STUCK_THRESHOLD_MS.decaying, now),
|
|
204
|
-
stuckStaging: this.#getStuckInfo('staging', STUCK_THRESHOLD_MS.staging, now),
|
|
205
|
-
stuckPending: this.#getStuckInfo('pending', STUCK_THRESHOLD_MS.pending, now),
|
|
195
|
+
stuckEvolving: await this.#getStuckInfo('evolving', STUCK_THRESHOLD_MS.evolving, now),
|
|
196
|
+
stuckDecaying: await this.#getStuckInfo('decaying', STUCK_THRESHOLD_MS.decaying, now),
|
|
197
|
+
stuckStaging: await this.#getStuckInfo('staging', STUCK_THRESHOLD_MS.staging, now),
|
|
198
|
+
stuckPending: await this.#getStuckInfo('pending', STUCK_THRESHOLD_MS.pending, now),
|
|
206
199
|
};
|
|
207
200
|
// 最近转移统计
|
|
208
201
|
const recentTransitions = this.#getRecentTransitionStats(now);
|
|
@@ -211,21 +204,18 @@ export class RecipeLifecycleSupervisor {
|
|
|
211
204
|
return { stateDistribution, intermediateStates, recentTransitions, proposalMetrics };
|
|
212
205
|
}
|
|
213
206
|
/* ═══════════════════ Entry/Exit Actions ═══════════════════ */
|
|
214
|
-
#executeEntryAction(recipeId, state, now, proposalId) {
|
|
207
|
+
async #executeEntryAction(recipeId, state, now, proposalId) {
|
|
215
208
|
const metaKey = ENTRY_META_KEYS[state];
|
|
216
209
|
if (!metaKey) {
|
|
217
210
|
return;
|
|
218
211
|
}
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
.get(recipeId);
|
|
222
|
-
const stats = safeJsonParse(statsRow?.stats, {});
|
|
212
|
+
const entry = await this.#knowledgeRepo.findById(recipeId);
|
|
213
|
+
const stats = (entry?.stats ?? {});
|
|
223
214
|
stats[metaKey] = now;
|
|
224
215
|
if (state === 'evolving' && proposalId) {
|
|
225
216
|
stats.evolvingProposalId = proposalId;
|
|
226
217
|
}
|
|
227
218
|
if (state === 'active') {
|
|
228
|
-
// 清除中间态元数据
|
|
229
219
|
delete stats.evolvingStartedAt;
|
|
230
220
|
delete stats.evolvingProposalId;
|
|
231
221
|
delete stats.decayStartedAt;
|
|
@@ -233,23 +223,15 @@ export class RecipeLifecycleSupervisor {
|
|
|
233
223
|
if (state === 'deprecated') {
|
|
234
224
|
stats.deprecatedAt = now;
|
|
235
225
|
}
|
|
236
|
-
this.#
|
|
237
|
-
.prepare(`UPDATE knowledge_entries SET stats = ? WHERE id = ?`)
|
|
238
|
-
.run(JSON.stringify(stats), recipeId);
|
|
226
|
+
await this.#knowledgeRepo.update(recipeId, { stats });
|
|
239
227
|
}
|
|
240
|
-
#executeExitAction(recipeId, state) {
|
|
228
|
+
async #executeExitAction(recipeId, state) {
|
|
241
229
|
if (state === 'active') {
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
.prepare(`SELECT stats FROM knowledge_entries WHERE id = ?`)
|
|
245
|
-
.get(recipeId);
|
|
246
|
-
const stats = safeJsonParse(statsRow?.stats, {});
|
|
230
|
+
const entry = await this.#knowledgeRepo.findById(recipeId);
|
|
231
|
+
const stats = (entry?.stats ?? {});
|
|
247
232
|
stats.lastActiveAt = Date.now();
|
|
248
|
-
this.#
|
|
249
|
-
.prepare(`UPDATE knowledge_entries SET stats = ? WHERE id = ?`)
|
|
250
|
-
.run(JSON.stringify(stats), recipeId);
|
|
233
|
+
await this.#knowledgeRepo.update(recipeId, { stats });
|
|
251
234
|
}
|
|
252
|
-
// staging exit: 清除 staging 元数据(由 StagingManager 自行处理)
|
|
253
235
|
}
|
|
254
236
|
/* ═══════════════════ Event Recording ═══════════════════ */
|
|
255
237
|
#recordEvent(params) {
|
|
@@ -266,11 +248,21 @@ export class RecipeLifecycleSupervisor {
|
|
|
266
248
|
createdAt: params.createdAt,
|
|
267
249
|
};
|
|
268
250
|
try {
|
|
269
|
-
this.#
|
|
270
|
-
.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
251
|
+
if (!this.#lifecycleEventRepo) {
|
|
252
|
+
this.#logger.warn(`[Supervisor] No lifecycleEventRepo available, cannot record transition event`);
|
|
253
|
+
return event;
|
|
254
|
+
}
|
|
255
|
+
this.#lifecycleEventRepo.record({
|
|
256
|
+
id,
|
|
257
|
+
recipeId: params.recipeId,
|
|
258
|
+
fromState: params.fromState,
|
|
259
|
+
toState: params.toState,
|
|
260
|
+
trigger: params.trigger,
|
|
261
|
+
operatorId: params.operatorId,
|
|
262
|
+
evidence: params.evidence,
|
|
263
|
+
proposalId: params.proposalId,
|
|
264
|
+
createdAt: params.createdAt,
|
|
265
|
+
});
|
|
274
266
|
}
|
|
275
267
|
catch {
|
|
276
268
|
// lifecycle_transition_events 表可能不存在(降级容忍)
|
|
@@ -279,7 +271,7 @@ export class RecipeLifecycleSupervisor {
|
|
|
279
271
|
return event;
|
|
280
272
|
}
|
|
281
273
|
/* ═══════════════════ Health Queries ═══════════════════ */
|
|
282
|
-
#getStateDistribution() {
|
|
274
|
+
async #getStateDistribution() {
|
|
283
275
|
const dist = {
|
|
284
276
|
pending: 0,
|
|
285
277
|
staging: 0,
|
|
@@ -289,11 +281,9 @@ export class RecipeLifecycleSupervisor {
|
|
|
289
281
|
deprecated: 0,
|
|
290
282
|
};
|
|
291
283
|
try {
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
for (const row of rows) {
|
|
296
|
-
dist[row.lifecycle] = row.cnt;
|
|
284
|
+
const grouped = await this.#knowledgeRepo.countGroupByLifecycle();
|
|
285
|
+
for (const [lifecycle, cnt] of Object.entries(grouped)) {
|
|
286
|
+
dist[lifecycle] = cnt;
|
|
297
287
|
}
|
|
298
288
|
}
|
|
299
289
|
catch {
|
|
@@ -301,18 +291,16 @@ export class RecipeLifecycleSupervisor {
|
|
|
301
291
|
}
|
|
302
292
|
return dist;
|
|
303
293
|
}
|
|
304
|
-
#getStuckInfo(state, thresholdMs, now) {
|
|
294
|
+
async #getStuckInfo(state, thresholdMs, now) {
|
|
305
295
|
try {
|
|
306
|
-
const
|
|
307
|
-
.prepare(`SELECT id, stats, updatedAt FROM knowledge_entries WHERE lifecycle = ?`)
|
|
308
|
-
.all(state);
|
|
296
|
+
const entries = await this.#knowledgeRepo.findAllByLifecycles([state]);
|
|
309
297
|
let count = 0;
|
|
310
298
|
let oldestAge = 0;
|
|
311
|
-
for (const
|
|
312
|
-
const stats =
|
|
299
|
+
for (const entry of entries) {
|
|
300
|
+
const stats = (entry.stats ?? {});
|
|
313
301
|
const metaKey = ENTRY_META_KEYS[state];
|
|
314
302
|
const enteredAt = (metaKey ? stats[metaKey] : null);
|
|
315
|
-
const age = enteredAt ? now - enteredAt : now - (
|
|
303
|
+
const age = enteredAt ? now - enteredAt : now - (entry.updatedAt || now);
|
|
316
304
|
if (age > thresholdMs) {
|
|
317
305
|
count++;
|
|
318
306
|
if (age > oldestAge) {
|
|
@@ -328,25 +316,13 @@ export class RecipeLifecycleSupervisor {
|
|
|
328
316
|
}
|
|
329
317
|
#getRecentTransitionStats(now) {
|
|
330
318
|
try {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
.prepare(`SELECT trigger, COUNT(*) as cnt
|
|
339
|
-
FROM lifecycle_transition_events
|
|
340
|
-
WHERE created_at > ?
|
|
341
|
-
GROUP BY trigger
|
|
342
|
-
ORDER BY cnt DESC
|
|
343
|
-
LIMIT 5`)
|
|
344
|
-
.all(now - 7 * 24 * 60 * 60 * 1000);
|
|
345
|
-
return {
|
|
346
|
-
last24h: last24hCount,
|
|
347
|
-
last7d: last7dCount,
|
|
348
|
-
topTriggers: triggerRows.map((r) => ({ trigger: r.trigger, count: r.cnt })),
|
|
349
|
-
};
|
|
319
|
+
if (!this.#lifecycleEventRepo) {
|
|
320
|
+
return { last24h: 0, last7d: 0, topTriggers: [] };
|
|
321
|
+
}
|
|
322
|
+
const last24hCount = this.#lifecycleEventRepo.countSince(now - 24 * 60 * 60 * 1000);
|
|
323
|
+
const last7dCount = this.#lifecycleEventRepo.countSince(now - 7 * 24 * 60 * 60 * 1000);
|
|
324
|
+
const topTriggers = this.#lifecycleEventRepo.topTriggersSince(now - 7 * 24 * 60 * 60 * 1000, 5);
|
|
325
|
+
return { last24h: last24hCount, last7d: last7dCount, topTriggers };
|
|
350
326
|
}
|
|
351
327
|
catch {
|
|
352
328
|
return { last24h: 0, last7d: 0, topTriggers: [] };
|
|
@@ -354,33 +330,25 @@ export class RecipeLifecycleSupervisor {
|
|
|
354
330
|
}
|
|
355
331
|
#getProposalMetrics() {
|
|
356
332
|
try {
|
|
357
|
-
const
|
|
358
|
-
.
|
|
359
|
-
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const
|
|
365
|
-
const observing = map.observing ?? 0;
|
|
366
|
-
const executed = map.executed ?? 0;
|
|
367
|
-
const rejected = map.rejected ?? 0;
|
|
368
|
-
const expired = map.expired ?? 0;
|
|
333
|
+
const statusMap = this.#proposalRepo
|
|
334
|
+
? this.#proposalRepo.stats()
|
|
335
|
+
: {};
|
|
336
|
+
const pending = statusMap.pending ?? 0;
|
|
337
|
+
const observing = statusMap.observing ?? 0;
|
|
338
|
+
const executed = statusMap.executed ?? 0;
|
|
339
|
+
const rejected = statusMap.rejected ?? 0;
|
|
340
|
+
const expired = statusMap.expired ?? 0;
|
|
369
341
|
const total = executed + rejected + expired;
|
|
370
|
-
// contentPatchRate: 有 patch 的事件 / 总 proposal-execution 事件
|
|
371
342
|
let contentPatchRate = 0;
|
|
372
343
|
try {
|
|
373
|
-
|
|
374
|
-
.
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
const patchCount = patchEvents?.cnt ?? 0;
|
|
382
|
-
const execCount = execEvents?.cnt ?? 0;
|
|
383
|
-
contentPatchRate = execCount > 0 ? patchCount / execCount : 0;
|
|
344
|
+
if (this.#lifecycleEventRepo) {
|
|
345
|
+
const patchCount = this.#lifecycleEventRepo.countByTrigger('content-patch-complete');
|
|
346
|
+
const execCount = this.#lifecycleEventRepo.countByTriggers([
|
|
347
|
+
'proposal-execution',
|
|
348
|
+
'proposal-attach',
|
|
349
|
+
]);
|
|
350
|
+
contentPatchRate = execCount > 0 ? patchCount / execCount : 0;
|
|
351
|
+
}
|
|
384
352
|
}
|
|
385
353
|
catch {
|
|
386
354
|
// table may not exist yet
|
|
@@ -389,7 +357,7 @@ export class RecipeLifecycleSupervisor {
|
|
|
389
357
|
pendingCount: pending,
|
|
390
358
|
observingCount: observing,
|
|
391
359
|
executionRate: total > 0 ? executed / total : 0,
|
|
392
|
-
avgObservationDays: 0,
|
|
360
|
+
avgObservationDays: 0,
|
|
393
361
|
contentPatchRate,
|
|
394
362
|
};
|
|
395
363
|
}
|
|
@@ -404,30 +372,13 @@ export class RecipeLifecycleSupervisor {
|
|
|
404
372
|
}
|
|
405
373
|
}
|
|
406
374
|
/* ═══════════════════ DB Helpers ═══════════════════ */
|
|
407
|
-
#getRecipeState(recipeId) {
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
.get(recipeId);
|
|
411
|
-
return row ?? null;
|
|
412
|
-
}
|
|
413
|
-
#getRecipeAge(recipeId, now) {
|
|
414
|
-
const row = this.#db
|
|
415
|
-
.prepare(`SELECT updatedAt FROM knowledge_entries WHERE id = ?`)
|
|
416
|
-
.get(recipeId);
|
|
417
|
-
return row ? now - row.updatedAt : 0;
|
|
375
|
+
async #getRecipeState(recipeId) {
|
|
376
|
+
const entry = await this.#knowledgeRepo.findById(recipeId);
|
|
377
|
+
return entry ? { lifecycle: entry.lifecycle } : null;
|
|
418
378
|
}
|
|
419
|
-
#
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
recipeId: row.recipe_id,
|
|
423
|
-
fromState: row.from_state,
|
|
424
|
-
toState: row.to_state,
|
|
425
|
-
trigger: row.trigger,
|
|
426
|
-
evidence: row.evidence_json ? safeJsonParse(row.evidence_json, null) : null,
|
|
427
|
-
proposalId: row.proposal_id ?? null,
|
|
428
|
-
operatorId: row.operator_id,
|
|
429
|
-
createdAt: row.created_at,
|
|
430
|
-
};
|
|
379
|
+
async #getRecipeAge(recipeId, now) {
|
|
380
|
+
const entry = await this.#knowledgeRepo.findById(recipeId);
|
|
381
|
+
return entry ? now - (entry.updatedAt || now) : 0;
|
|
431
382
|
}
|
|
432
383
|
/* ═══════════════════ Signal ═══════════════════ */
|
|
433
384
|
#emitSignal(recipeId, fromState, toState, trigger) {
|
|
@@ -444,15 +395,3 @@ export class RecipeLifecycleSupervisor {
|
|
|
444
395
|
});
|
|
445
396
|
}
|
|
446
397
|
}
|
|
447
|
-
/* ────────────────────── Util ────────────────────── */
|
|
448
|
-
function safeJsonParse(json, fallback) {
|
|
449
|
-
if (!json) {
|
|
450
|
-
return fallback;
|
|
451
|
-
}
|
|
452
|
-
try {
|
|
453
|
-
return JSON.parse(json);
|
|
454
|
-
}
|
|
455
|
-
catch {
|
|
456
|
-
return fallback;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
*
|
|
19
19
|
* @module service/evolution/RecipeRelevanceAuditor
|
|
20
20
|
*/
|
|
21
|
+
import type { ProposalRepository } from '../../repository/evolution/ProposalRepository.js';
|
|
22
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
21
23
|
/** Logger 接口 */
|
|
22
24
|
interface AuditorLogger {
|
|
23
25
|
info(msg: string, meta?: Record<string, unknown>): void;
|
|
@@ -78,7 +80,8 @@ export interface RelevanceAuditSummary {
|
|
|
78
80
|
export declare class RecipeRelevanceAuditor {
|
|
79
81
|
#private;
|
|
80
82
|
constructor(opts: {
|
|
81
|
-
|
|
83
|
+
knowledgeRepo: KnowledgeRepositoryImpl;
|
|
84
|
+
proposalRepo?: ProposalRepository;
|
|
82
85
|
logger?: AuditorLogger;
|
|
83
86
|
});
|
|
84
87
|
/**
|
|
@@ -59,11 +59,12 @@ const GRACE_PERIOD_DECAY = 7 * 24 * 60 * 60 * 1000; // 7d
|
|
|
59
59
|
const GRACE_PERIOD_SEVERE = 3 * 24 * 60 * 60 * 1000; // 3d
|
|
60
60
|
// ── RecipeRelevanceAuditor ──────────────────────────────────
|
|
61
61
|
export class RecipeRelevanceAuditor {
|
|
62
|
-
#
|
|
62
|
+
#knowledgeRepo;
|
|
63
|
+
#proposalRepo;
|
|
63
64
|
#logger;
|
|
64
65
|
constructor(opts) {
|
|
65
|
-
|
|
66
|
-
this.#
|
|
66
|
+
this.#knowledgeRepo = opts.knowledgeRepo;
|
|
67
|
+
this.#proposalRepo = opts.proposalRepo ?? null;
|
|
67
68
|
this.#logger = opts.logger || { info() { }, warn() { } };
|
|
68
69
|
}
|
|
69
70
|
/**
|
|
@@ -90,11 +91,11 @@ export class RecipeRelevanceAuditor {
|
|
|
90
91
|
depModules.add(edge.to.toLowerCase());
|
|
91
92
|
}
|
|
92
93
|
for (const recipe of recipes) {
|
|
93
|
-
const fullRecipe = this.#loadFullRecipe(recipe.id);
|
|
94
|
+
const fullRecipe = await this.#loadFullRecipe(recipe.id);
|
|
94
95
|
if (!fullRecipe) {
|
|
95
96
|
continue;
|
|
96
97
|
}
|
|
97
|
-
const result = this.#computeRelevanceScore(fullRecipe, {
|
|
98
|
+
const result = await this.#computeRelevanceScore(fullRecipe, {
|
|
98
99
|
fileSet,
|
|
99
100
|
entityNames,
|
|
100
101
|
depModules,
|
|
@@ -105,7 +106,7 @@ export class RecipeRelevanceAuditor {
|
|
|
105
106
|
summary.results.push(result);
|
|
106
107
|
// 执行衰退状态转换
|
|
107
108
|
if (result.verdict === 'dead' || result.verdict === 'severe' || result.verdict === 'decay') {
|
|
108
|
-
const executed = this.#executeDecay(result);
|
|
109
|
+
const executed = await this.#executeDecay(result);
|
|
109
110
|
if (result.verdict === 'dead') {
|
|
110
111
|
summary.immediateDeprecated += executed ? 1 : 0;
|
|
111
112
|
}
|
|
@@ -126,21 +127,28 @@ export class RecipeRelevanceAuditor {
|
|
|
126
127
|
}
|
|
127
128
|
// ─── 内部方法 ─────────────────────────────────────────
|
|
128
129
|
/** 从 DB 加载完整 Recipe 数据 */
|
|
129
|
-
#loadFullRecipe(id) {
|
|
130
|
+
async #loadFullRecipe(id) {
|
|
130
131
|
try {
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
const entry = await this.#knowledgeRepo.findById(id);
|
|
133
|
+
if (!entry) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
id: entry.id,
|
|
138
|
+
title: entry.title,
|
|
139
|
+
trigger: entry.trigger ?? '',
|
|
140
|
+
category: entry.category ?? '',
|
|
141
|
+
content: JSON.stringify(entry.content?.toJSON?.() ?? entry.content ?? {}),
|
|
142
|
+
doClause: entry.doClause ?? null,
|
|
143
|
+
coreCode: entry.coreCode ?? null,
|
|
144
|
+
};
|
|
137
145
|
}
|
|
138
146
|
catch {
|
|
139
147
|
return null;
|
|
140
148
|
}
|
|
141
149
|
}
|
|
142
150
|
/** 计算单个 Recipe 的 relevanceScore */
|
|
143
|
-
#computeRelevanceScore(recipe, ctx) {
|
|
151
|
+
async #computeRelevanceScore(recipe, ctx) {
|
|
144
152
|
const category = recipe.category || '';
|
|
145
153
|
const weights = {
|
|
146
154
|
...DEFAULT_WEIGHTS,
|
|
@@ -173,7 +181,7 @@ export class RecipeRelevanceAuditor {
|
|
|
173
181
|
}
|
|
174
182
|
}
|
|
175
183
|
// 4. 源代码文件存活率(来自 reasoning.sources + content.codeChanges)
|
|
176
|
-
const codeFiles = this.#extractCodeFiles(recipe);
|
|
184
|
+
const codeFiles = await this.#extractCodeFiles(recipe);
|
|
177
185
|
let codeFilesExist = 1.0;
|
|
178
186
|
if (codeFiles.length > 0) {
|
|
179
187
|
const existCount = codeFiles.filter((f) => ctx.fileSet.has(f.toLowerCase())).length;
|
|
@@ -362,7 +370,7 @@ export class RecipeRelevanceAuditor {
|
|
|
362
370
|
return [...new Set(modules)];
|
|
363
371
|
}
|
|
364
372
|
/** 从 Recipe 中提取 codeChanges 引用的文件路径 */
|
|
365
|
-
#extractCodeFiles(recipe) {
|
|
373
|
+
async #extractCodeFiles(recipe) {
|
|
366
374
|
const files = [];
|
|
367
375
|
try {
|
|
368
376
|
const content = JSON.parse(recipe.content || '{}');
|
|
@@ -374,18 +382,15 @@ export class RecipeRelevanceAuditor {
|
|
|
374
382
|
}
|
|
375
383
|
}
|
|
376
384
|
}
|
|
377
|
-
// reasoning.sources 在 content 外层,由下方独立查询处理
|
|
378
385
|
}
|
|
379
386
|
catch {
|
|
380
387
|
/* invalid JSON */
|
|
381
388
|
}
|
|
382
|
-
//
|
|
389
|
+
// reasoning.sources 在 entry 的 reasoning 属性中
|
|
383
390
|
try {
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if (row?.reasoning) {
|
|
388
|
-
const reasoning = JSON.parse(row.reasoning);
|
|
391
|
+
const entry = await this.#knowledgeRepo.findById(recipe.id);
|
|
392
|
+
if (entry?.reasoning) {
|
|
393
|
+
const reasoning = (typeof entry.reasoning === 'object' ? entry.reasoning : {});
|
|
389
394
|
if (Array.isArray(reasoning.sources)) {
|
|
390
395
|
for (const src of reasoning.sources) {
|
|
391
396
|
if (typeof src === 'string') {
|
|
@@ -402,22 +407,18 @@ export class RecipeRelevanceAuditor {
|
|
|
402
407
|
}
|
|
403
408
|
}
|
|
404
409
|
catch {
|
|
405
|
-
/*
|
|
410
|
+
/* entry not found */
|
|
406
411
|
}
|
|
407
412
|
return [...new Set(files)];
|
|
408
413
|
}
|
|
409
414
|
/** 执行衰退状态转换 */
|
|
410
|
-
#executeDecay(result) {
|
|
415
|
+
async #executeDecay(result) {
|
|
411
416
|
try {
|
|
412
417
|
const now = Date.now();
|
|
413
418
|
switch (result.verdict) {
|
|
414
419
|
case 'dead': {
|
|
415
|
-
|
|
416
|
-
this.#
|
|
417
|
-
.prepare(`UPDATE knowledge_entries SET lifecycle = 'deprecated', updatedAt = ? WHERE id = ?`)
|
|
418
|
-
.run(now, result.recipeId);
|
|
419
|
-
// 记录已执行的 proposal(审计追溯)
|
|
420
|
-
this.#createProposal({
|
|
420
|
+
await this.#knowledgeRepo.updateLifecycle(result.recipeId, 'deprecated');
|
|
421
|
+
await this.#createProposal({
|
|
421
422
|
targetRecipeId: result.recipeId,
|
|
422
423
|
type: 'deprecate',
|
|
423
424
|
source: 'rescan-relevance-audit',
|
|
@@ -430,11 +431,8 @@ export class RecipeRelevanceAuditor {
|
|
|
430
431
|
return true;
|
|
431
432
|
}
|
|
432
433
|
case 'severe': {
|
|
433
|
-
|
|
434
|
-
this.#
|
|
435
|
-
.prepare(`UPDATE knowledge_entries SET lifecycle = 'decaying', updatedAt = ? WHERE id = ?`)
|
|
436
|
-
.run(now, result.recipeId);
|
|
437
|
-
this.#createProposal({
|
|
434
|
+
await this.#knowledgeRepo.updateLifecycle(result.recipeId, 'decaying');
|
|
435
|
+
await this.#createProposal({
|
|
438
436
|
targetRecipeId: result.recipeId,
|
|
439
437
|
type: 'deprecate',
|
|
440
438
|
source: 'rescan-relevance-audit',
|
|
@@ -447,11 +445,8 @@ export class RecipeRelevanceAuditor {
|
|
|
447
445
|
return true;
|
|
448
446
|
}
|
|
449
447
|
case 'decay': {
|
|
450
|
-
|
|
451
|
-
this.#
|
|
452
|
-
.prepare(`UPDATE knowledge_entries SET lifecycle = 'decaying', updatedAt = ? WHERE id = ?`)
|
|
453
|
-
.run(now, result.recipeId);
|
|
454
|
-
this.#createProposal({
|
|
448
|
+
await this.#knowledgeRepo.updateLifecycle(result.recipeId, 'decaying');
|
|
449
|
+
await this.#createProposal({
|
|
455
450
|
targetRecipeId: result.recipeId,
|
|
456
451
|
type: 'deprecate',
|
|
457
452
|
source: 'rescan-relevance-audit',
|
|
@@ -474,15 +469,21 @@ export class RecipeRelevanceAuditor {
|
|
|
474
469
|
}
|
|
475
470
|
}
|
|
476
471
|
/** 创建 evolution proposal */
|
|
477
|
-
#createProposal(input) {
|
|
472
|
+
async #createProposal(input) {
|
|
478
473
|
try {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
474
|
+
if (this.#proposalRepo) {
|
|
475
|
+
this.#proposalRepo.create({
|
|
476
|
+
type: input.type,
|
|
477
|
+
targetRecipeId: input.targetRecipeId,
|
|
478
|
+
relatedRecipeIds: [],
|
|
479
|
+
confidence: 0.95,
|
|
480
|
+
source: input.source,
|
|
481
|
+
description: input.description,
|
|
482
|
+
evidence: [input.evidence],
|
|
483
|
+
status: input.status,
|
|
484
|
+
expiresAt: input.expiresAt,
|
|
485
|
+
});
|
|
486
|
+
}
|
|
486
487
|
}
|
|
487
488
|
catch (err) {
|
|
488
489
|
const msg = err instanceof Error ? err.message : String(err);
|