autosnippet 3.3.4 → 3.3.6

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.
Files changed (221) hide show
  1. package/README.md +174 -83
  2. package/config/constitution.yaml +2 -0
  3. package/dashboard/dist/assets/icons-D1aVZYFW.js +1 -0
  4. package/dashboard/dist/assets/index-CxHOu8Hd.css +1 -0
  5. package/dashboard/dist/assets/index-DDdAOpYT.js +128 -0
  6. package/dashboard/dist/index.html +3 -3
  7. package/dist/bin/api-server.js +1 -0
  8. package/dist/bin/cli.d.ts +1 -0
  9. package/dist/bin/cli.js +136 -9
  10. package/dist/lib/agent/AgentFactory.d.ts +0 -17
  11. package/dist/lib/agent/AgentFactory.js +1 -25
  12. package/dist/lib/agent/capabilities.d.ts +11 -0
  13. package/dist/lib/agent/capabilities.js +29 -5
  14. package/dist/lib/agent/context/ExplorationTracker.js +10 -1
  15. package/dist/lib/agent/context/exploration/ExplorationStrategies.d.ts +2 -0
  16. package/dist/lib/agent/context/exploration/ExplorationStrategies.js +2 -2
  17. package/dist/lib/agent/domain/insight-analyst.d.ts +47 -3
  18. package/dist/lib/agent/domain/insight-analyst.js +111 -11
  19. package/dist/lib/agent/domain/insight-evolver.d.ts +69 -0
  20. package/dist/lib/agent/domain/insight-evolver.js +230 -0
  21. package/dist/lib/agent/domain/insight-gate.d.ts +42 -0
  22. package/dist/lib/agent/domain/insight-gate.js +41 -0
  23. package/dist/lib/agent/domain/insight-producer.d.ts +27 -2
  24. package/dist/lib/agent/domain/insight-producer.js +60 -5
  25. package/dist/lib/agent/domain/scan-prompts.js +10 -7
  26. package/dist/lib/agent/memory/ActiveContext.d.ts +2 -28
  27. package/dist/lib/agent/memory/MemoryCoordinator.d.ts +2 -2
  28. package/dist/lib/agent/memory/SessionStore.d.ts +6 -12
  29. package/dist/lib/agent/memory/SessionStore.js +9 -15
  30. package/dist/lib/agent/memory/memory-flush-contract.d.ts +49 -0
  31. package/dist/lib/agent/memory/memory-flush-contract.js +16 -0
  32. package/dist/lib/agent/memory/session-store-schema.d.ts +20 -0
  33. package/dist/lib/agent/memory/session-store-schema.js +41 -0
  34. package/dist/lib/agent/presets.d.ts +89 -1
  35. package/dist/lib/agent/presets.js +53 -5
  36. package/dist/lib/agent/tools/_shared.d.ts +7 -15
  37. package/dist/lib/agent/tools/_shared.js +20 -21
  38. package/dist/lib/agent/tools/composite.d.ts +25 -22
  39. package/dist/lib/agent/tools/composite.js +108 -109
  40. package/dist/lib/agent/tools/evolution-tools.d.ts +145 -0
  41. package/dist/lib/agent/tools/evolution-tools.js +161 -0
  42. package/dist/lib/agent/tools/index.d.ts +163 -92
  43. package/dist/lib/agent/tools/index.js +9 -1
  44. package/dist/lib/agent/tools/lifecycle.d.ts +7 -1
  45. package/dist/lib/agent/tools/lifecycle.js +59 -75
  46. package/dist/lib/cli/AiScanService.js +1 -1
  47. package/dist/lib/cli/KnowledgeSyncService.d.ts +5 -1
  48. package/dist/lib/cli/KnowledgeSyncService.js +6 -3
  49. package/dist/lib/core/AstAnalyzer.d.ts +1 -0
  50. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.d.ts → domain/dimension/DimensionCopy.d.ts} +2 -2
  51. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.js → domain/dimension/DimensionCopy.js} +22 -72
  52. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +54 -0
  53. package/dist/lib/domain/dimension/DimensionRegistry.js +620 -0
  54. package/dist/lib/domain/dimension/DimensionSop.d.ts +55 -0
  55. package/dist/lib/domain/dimension/DimensionSop.js +1604 -0
  56. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +61 -0
  57. package/dist/lib/domain/dimension/UnifiedDimension.js +53 -0
  58. package/dist/lib/domain/dimension/index.d.ts +10 -0
  59. package/dist/lib/domain/dimension/index.js +9 -0
  60. package/dist/lib/domain/knowledge/FieldSpec.d.ts +1 -1
  61. package/dist/lib/domain/knowledge/FieldSpec.js +29 -16
  62. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +33 -111
  63. package/dist/lib/domain/knowledge/KnowledgeEntry.js +27 -6
  64. package/dist/lib/domain/knowledge/KnowledgeRepository.d.ts +1 -0
  65. package/dist/lib/domain/knowledge/KnowledgeRepository.js +3 -0
  66. package/dist/lib/domain/knowledge/Lifecycle.js +1 -1
  67. package/dist/lib/domain/knowledge/StyleGuide.d.ts +1 -1
  68. package/dist/lib/domain/knowledge/StyleGuide.js +1 -1
  69. package/dist/lib/domain/knowledge/UnifiedValidator.js +15 -0
  70. package/dist/lib/domain/knowledge/values/Stats.d.ts +1 -1
  71. package/dist/lib/domain/knowledge/values/Stats.js +2 -2
  72. package/dist/lib/external/mcp/McpServer.js +4 -0
  73. package/dist/lib/external/mcp/handlers/TargetClassifier.d.ts +1 -1
  74. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.d.ts +8 -16
  75. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +10 -10
  76. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.d.ts +7 -0
  77. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +20 -0
  78. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +52 -132
  79. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +204 -17
  80. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.d.ts +11 -75
  81. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.js +40 -191
  82. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.d.ts +13 -78
  83. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.js +30 -52
  84. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.d.ts +0 -1
  85. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.d.ts +99 -12
  86. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +172 -161
  87. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +7 -17
  88. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.d.ts +46 -0
  89. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.js +58 -0
  90. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.d.ts +25 -0
  91. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.js +47 -0
  92. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +50 -12
  93. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +30 -10
  94. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-text.js +1 -1
  95. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.d.ts +24 -0
  96. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.js +14 -0
  97. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.d.ts +14 -0
  98. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.js +48 -0
  99. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.d.ts +21 -0
  100. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.js +45 -0
  101. package/dist/lib/external/mcp/handlers/bootstrap/shared/skill-generator.d.ts +1 -1
  102. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.d.ts +27 -0
  103. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.js +44 -0
  104. package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +14 -10
  105. package/dist/lib/external/mcp/handlers/bootstrap-external.js +39 -51
  106. package/dist/lib/external/mcp/handlers/bootstrap-internal.d.ts +2 -0
  107. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +115 -82
  108. package/dist/lib/external/mcp/handlers/consolidated.d.ts +4 -4
  109. package/dist/lib/external/mcp/handlers/consolidated.js +115 -162
  110. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +69 -1
  111. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +54 -0
  112. package/dist/lib/external/mcp/handlers/evolve-external.js +226 -0
  113. package/dist/lib/external/mcp/handlers/knowledge.js +26 -2
  114. package/dist/lib/external/mcp/handlers/rescan-external.d.ts +76 -0
  115. package/dist/lib/external/mcp/handlers/rescan-external.js +335 -0
  116. package/dist/lib/external/mcp/handlers/rescan-internal.d.ts +120 -0
  117. package/dist/lib/external/mcp/handlers/rescan-internal.js +359 -0
  118. package/dist/lib/external/mcp/handlers/search.d.ts +6 -5
  119. package/dist/lib/external/mcp/handlers/search.js +6 -5
  120. package/dist/lib/external/mcp/handlers/types.d.ts +2 -1
  121. package/dist/lib/external/mcp/handlers/wiki-external.js +2 -2
  122. package/dist/lib/external/mcp/tools.d.ts +8 -18
  123. package/dist/lib/external/mcp/tools.js +60 -3
  124. package/dist/lib/http/routes/knowledge.js +122 -1
  125. package/dist/lib/http/routes/modules.js +25 -3
  126. package/dist/lib/http/routes/panorama.js +16 -4
  127. package/dist/lib/infrastructure/cache/CacheCoordinator.d.ts +41 -0
  128. package/dist/lib/infrastructure/cache/CacheCoordinator.js +105 -0
  129. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.d.ts +7 -0
  130. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.js +28 -0
  131. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +1 -1
  132. package/dist/lib/injection/ServiceContainer.js +55 -0
  133. package/dist/lib/injection/ServiceMap.d.ts +8 -1
  134. package/dist/lib/injection/modules/InfraModule.js +4 -1
  135. package/dist/lib/injection/modules/KnowledgeModule.js +38 -1
  136. package/dist/lib/repository/evolution/ProposalRepository.d.ts +99 -0
  137. package/dist/lib/repository/evolution/ProposalRepository.js +255 -0
  138. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +4 -0
  139. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +16 -1
  140. package/dist/lib/service/bootstrap/BootstrapEventEmitter.d.ts +3 -2
  141. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +1 -1
  142. package/dist/lib/service/bootstrap/DeliveryVerifier.d.ts +51 -0
  143. package/dist/lib/service/bootstrap/DeliveryVerifier.js +163 -0
  144. package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +22 -4
  145. package/dist/lib/service/bootstrap/UiStartupTasks.js +73 -5
  146. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +54 -0
  147. package/dist/lib/service/bootstrap/bootstrap-event-types.js +10 -0
  148. package/dist/lib/service/cleanup/CleanupService.d.ts +85 -0
  149. package/dist/lib/service/cleanup/CleanupService.js +324 -0
  150. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +39 -43
  151. package/dist/lib/service/delivery/FileProtection.d.ts +20 -0
  152. package/dist/lib/service/delivery/FileProtection.js +54 -0
  153. package/dist/lib/service/delivery/SkillsSyncer.js +16 -21
  154. package/dist/lib/service/evolution/ContentPatcher.d.ts +44 -0
  155. package/dist/lib/service/evolution/ContentPatcher.js +310 -0
  156. package/dist/lib/service/evolution/DecayDetector.d.ts +4 -3
  157. package/dist/lib/service/evolution/DecayDetector.js +97 -22
  158. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -2
  159. package/dist/lib/service/evolution/KnowledgeMetabolism.js +29 -2
  160. package/dist/lib/service/evolution/ProposalExecutor.d.ts +66 -0
  161. package/dist/lib/service/evolution/ProposalExecutor.js +424 -0
  162. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +64 -0
  163. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +458 -0
  164. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +89 -0
  165. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +492 -0
  166. package/dist/lib/service/evolution/StagingManager.js +5 -3
  167. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +44 -0
  168. package/dist/lib/service/evolution/createSupersedeProposal.js +81 -0
  169. package/dist/lib/service/guard/ComplianceReporter.d.ts +4 -0
  170. package/dist/lib/service/guard/ComplianceReporter.js +51 -0
  171. package/dist/lib/service/guard/GuardCheckEngine.js +5 -4
  172. package/dist/lib/service/guard/GuardCrossFileChecks.js +2 -0
  173. package/dist/lib/service/guard/ReverseGuard.d.ts +1 -1
  174. package/dist/lib/service/guard/ReverseGuard.js +32 -2
  175. package/dist/lib/service/knowledge/ConfidenceRouter.js +1 -1
  176. package/dist/lib/service/knowledge/KnowledgeService.d.ts +11 -1
  177. package/dist/lib/service/knowledge/KnowledgeService.js +44 -4
  178. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +225 -0
  179. package/dist/lib/service/knowledge/RecipeProductionGateway.js +384 -0
  180. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +2 -0
  181. package/dist/lib/service/knowledge/SourceRefReconciler.js +48 -0
  182. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +3 -2
  183. package/dist/lib/service/panorama/DimensionAnalyzer.js +15 -140
  184. package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
  185. package/dist/lib/service/search/SearchEngine.d.ts +11 -10
  186. package/dist/lib/service/search/SearchEngine.js +38 -36
  187. package/dist/lib/service/search/SearchTypes.d.ts +14 -8
  188. package/dist/lib/service/search/SearchTypes.js +1 -1
  189. package/dist/lib/service/search/tokenizer.d.ts +1 -1
  190. package/dist/lib/service/search/tokenizer.js +2 -2
  191. package/dist/lib/shared/schemas/common.d.ts +4 -4
  192. package/dist/lib/shared/schemas/http-requests.d.ts +12 -1
  193. package/dist/lib/shared/schemas/http-requests.js +8 -0
  194. package/dist/lib/shared/schemas/mcp-tools.d.ts +33 -2
  195. package/dist/lib/shared/schemas/mcp-tools.js +42 -0
  196. package/dist/lib/types/evolution.d.ts +135 -0
  197. package/dist/lib/types/evolution.js +6 -0
  198. package/dist/lib/types/graph-shared.d.ts +25 -0
  199. package/dist/lib/types/graph-shared.js +7 -0
  200. package/dist/lib/types/knowledge-wire.d.ts +131 -0
  201. package/dist/lib/types/knowledge-wire.js +7 -0
  202. package/dist/lib/types/project-snapshot-builder.d.ts +19 -0
  203. package/dist/lib/types/project-snapshot-builder.js +189 -0
  204. package/dist/lib/types/project-snapshot.d.ts +399 -0
  205. package/dist/lib/types/project-snapshot.js +17 -0
  206. package/dist/lib/types/search-wire.d.ts +46 -0
  207. package/dist/lib/types/search-wire.js +7 -0
  208. package/dist/lib/types/snapshot-views.d.ts +58 -0
  209. package/dist/lib/types/snapshot-views.js +103 -0
  210. package/package.json +1 -1
  211. package/skills/autosnippet-recipes/SKILL.md +1 -1
  212. package/templates/instructions/agent-static.md +2 -0
  213. package/templates/instructions/conventions.md +3 -1
  214. package/templates/recipes-setup/README.md +2 -2
  215. package/dashboard/dist/assets/icons-BJ2mUBi8.js +0 -1
  216. package/dashboard/dist/assets/index-B659K9t5.js +0 -128
  217. package/dashboard/dist/assets/index-NCm40PMD.css +0 -1
  218. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.d.ts +0 -169
  219. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.js +0 -727
  220. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.d.ts +0 -370
  221. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +0 -821
@@ -23,16 +23,17 @@ export const PRODUCER_SYSTEM_PROMPT = `你是知识管理专家。你会收到
23
23
  核心原则: 分析文本已经包含了所有发现,你的唯一工作是将它们格式化为 submit_knowledge 调用。
24
24
 
25
25
  每个候选必须:
26
- 1. 有清晰的标题 (描述知识点的核心,使用项目真实类名)
26
+ 1. 有清晰的标题 (描述知识点的核心,使用项目真实类名,不以项目名开头)
27
27
  2. 有项目特写风格的正文 (content.markdown 字段,结合代码展示)
28
- 3. 标注相关文件路径
28
+ 3. 标注相关文件的完整相对路径 + 行号(从项目根目录开始,如 Packages/AOXNetworkKit/Sources/.../NetworkClient.swift:42)
29
29
  4. 选择正确的 kind (rule/pattern/fact)
30
30
  5. 提供完整的 Cursor 交付字段 (trigger, doClause, whenClause 等)
31
+ 6. 标注所属模块/包名(如「所属模块: AOXNetworkKit」),特别是来自本地子包的知识
31
32
 
32
33
  工作流程:
33
34
  1. 阅读分析文本,识别每个独立的知识点/发现
34
35
  2. 用 read_project_file 批量获取关键代码片段:
35
- read_project_file({ filePaths: ["FileA.m", "FileB.m"], maxLines: 80 })
36
+ read_project_file({ filePaths: ["Full/Path/To/FileA.swift", "Full/Path/To/FileB.swift"], maxLines: 80 })
36
37
  3. 立刻调用 submit_knowledge 提交
37
38
  4. 重复直到分析中的所有知识点都已提交
38
39
 
@@ -40,9 +41,11 @@ export const PRODUCER_SYSTEM_PROMPT = `你是知识管理专家。你会收到
40
41
  - 分析中的每个要点/段落都应转化为至少一个候选
41
42
  - read_project_file 支持 filePaths 数组批量读取多个文件,一次调用完成
42
43
  - read_project_file 时读取足够多的行数(startLine + maxLines 至少 30 行)
43
- - reasoning.sources 必须是非空数组,填写相关文件路径如 ["FileName.m"]
44
+ - reasoning.sources 必须是非空数组,填写文件的完整相对路径如 ["Packages/AOXNetworkKit/Sources/AOXNetworkKit/Client/NetworkClient.swift"](禁止只写文件名)
45
+ - content.markdown 中的来源标注必须使用完整相对路径+行号: (来源: Full/Path/FileName.ext:行号)
44
46
  - 如果分析提到了 3 个模式,就应该提交 3 个候选,不要合并
45
47
  - 禁止: 不要搜索新文件、不要做额外分析,专注于格式化和提交
48
+ - 【跨维度去重】每条候选必须聚焦当前维度独有的视角,不得将同一知识点换个说法重复提交。相同的类/模式只在最相关的维度出现一次,宁可少提交也不要充数
46
49
 
47
50
  容错规则:
48
51
  - 如果 read_project_file 返回"文件不存在"或错误,不要重试同一文件的其他路径变体
@@ -99,8 +102,10 @@ export function buildProducerPrompt(analysisReport, dimConfig, projectInfo) {
99
102
  * - §3 结构化发现 (findings)
100
103
  * - §4 代码证据 (evidenceMap → code context)
101
104
  * - §5 负空间信号
105
+ * - §9 (可选) Rescan 模式约束
106
+ * - §M1 (可选) 全景上下文
102
107
  */
103
- export function buildProducerPromptV2(artifact, dimConfig, projectInfo) {
108
+ export function buildProducerPromptV2(artifact, dimConfig, projectInfo, rescanContext, panorama) {
104
109
  const parts = [];
105
110
  parts.push(`将以下对 ${projectInfo.name} 项目 "${dimConfig.label}" 维度的分析,转化为知识候选:`);
106
111
  parts.push(`---\n${artifact.analysisText}\n---`);
@@ -144,6 +149,56 @@ export function buildProducerPromptV2(artifact, dimConfig, projectInfo) {
144
149
  // §8 写作指南 + 提交要求
145
150
  parts.push(STYLE_GUIDE);
146
151
  parts.push(SUBMIT_REQUIREMENTS);
152
+ // §M1 全景上下文 — 帮助 Producer 理解模块定位
153
+ if (panorama) {
154
+ const pLines = [];
155
+ if (panorama.moduleRole) {
156
+ pLines.push(`模块角色: ${panorama.moduleRole}${panorama.moduleLayer !== null ? ` (L${panorama.moduleLayer})` : ''}`);
157
+ }
158
+ if (panorama.layerContext) {
159
+ pLines.push(`架构层级: ${panorama.layerContext}`);
160
+ }
161
+ if (panorama.knownGaps.length > 0) {
162
+ pLines.push(`知识空白区: ${panorama.knownGaps.join(', ')} — 优先为这些方向创建候选。`);
163
+ }
164
+ if (pLines.length > 0) {
165
+ parts.push(`## 🏗️ 项目全景\n${pLines.join('\n')}`);
166
+ }
167
+ }
168
+ // §9a Rescan 模式约束 — 限制提交数量,避免重复
169
+ if (rescanContext && rescanContext.gap > 0) {
170
+ const lines = [
171
+ '## ⚠️ 增量扫描模式 — 补齐约束',
172
+ `本维度已有 ${rescanContext.existing} 个有效知识,需补齐 **${rescanContext.gap}** 个。`,
173
+ `**提交上限: ${rescanContext.gap} 个候选**。达到目标后立即停止,不要多提交。`,
174
+ ];
175
+ if (rescanContext.occupiedTriggers.length > 0) {
176
+ lines.push(`已占用的 trigger: ${rescanContext.occupiedTriggers.slice(0, 15).join(', ')}`);
177
+ lines.push('禁止使用上述已占用的 trigger,必须为新模式创建新 trigger。');
178
+ }
179
+ if (rescanContext.existingRecipes.length > 0) {
180
+ lines.push('已有知识标题 (禁止重复):');
181
+ for (const r of rescanContext.existingRecipes.slice(0, 8)) {
182
+ lines.push(`- "${r.title}"`);
183
+ }
184
+ }
185
+ parts.push(lines.join('\n'));
186
+ }
187
+ // §9b 衰退 Recipe — 可用 supersedes 替换
188
+ if (rescanContext?.decayingRecipes && rescanContext.decayingRecipes.length > 0) {
189
+ const dLines = [
190
+ '## 🔄 可替换的衰退知识',
191
+ '以下 Recipe 正在衰退,如果 Analyst 发现了更新版本的模式,',
192
+ '你可以用 `supersedes` 参数提交替代版本:',
193
+ ];
194
+ for (const r of rescanContext.decayingRecipes.slice(0, 5)) {
195
+ dLines.push(`- [${r.id || '?'}] "${r.title}" — ${r.decayReason || '衰退中'}`);
196
+ dLines.push(` → 替换方式: submit_knowledge({ ...newRecipe, supersedes: "${r.id || ''}" })`);
197
+ }
198
+ dLines.push('注意: supersedes 提交会创建观察窗口(72h),不是立即替换。');
199
+ dLines.push('替换的新 Recipe 必须基于当前代码,不要复制旧 Recipe 内容。');
200
+ parts.push(dLines.join('\n'));
201
+ }
147
202
  return parts.join('\n\n');
148
203
  }
149
204
  // ──────────────────────────────────────────────────────────────────
@@ -30,32 +30,35 @@ export const SCAN_TASK_CONFIGS = {
30
30
  核心原则: 分析文本已经包含了所有发现,你的唯一工作是将它们格式化为 collect_scan_recipe 调用。
31
31
 
32
32
  每个候选必须:
33
- 1. 有清晰的标题 (描述知识点的核心,使用项目真实类名)
33
+ 1. 有清晰的标题 (描述知识点的核心,使用项目真实类名,不以项目名开头)
34
34
  2. 有项目特写风格的正文 (content.markdown 字段,结合代码展示)
35
- 3. 标注相关文件路径 (reasoning.sources)
35
+ 3. 标注相关文件的完整相对路径 + 行号 (reasoning.sources,如 ["Packages/ModuleName/Sources/.../FileName.swift"])
36
36
  4. 选择正确的 kind (rule/pattern/fact)
37
37
  5. 提供完整的 Cursor 交付字段 (trigger, doClause, whenClause 等)
38
+ 6. 标注所属模块/包名(特别是来自本地子包的知识)
38
39
 
39
40
  ## 「项目特写」写作要求(content.markdown)
40
41
  content.markdown 字段必须是「项目特写」:
41
42
  1. **项目选择了什么** — 采用了哪种写法/模式/约定
42
43
  2. **为什么这样选** — 统计分布、占比、历史决策
43
44
  3. **项目禁止什么** — 反模式、已废弃写法
44
- 4. **新代码怎么写** — 可直接复制使用的代码模板 + 来源标注 (来源: FileName.ext:行号)
45
+ 4. **新代码怎么写** — 可直接复制使用的代码模板 + 来源标注 (来源: Full/Relative/Path/FileName.ext:行号)
45
46
 
46
47
  ## 工作流程
47
48
  1. 阅读分析文本,识别每个独立的知识点/发现
48
49
  2. 用 read_project_file 批量获取关键代码片段:
49
- read_project_file({ filePaths: ["FileA.m", "FileB.m"], maxLines: 80 })
50
+ read_project_file({ filePaths: ["Full/Path/To/FileA.swift", "Full/Path/To/FileB.swift"], maxLines: 80 })
50
51
  3. 立刻调用 collect_scan_recipe 提交
51
52
  4. 重复直到分析中的所有知识点都已提交
52
53
 
53
54
  ## 关键规则
54
55
  - 分析中的每个要点/段落都应转化为至少一个候选
55
56
  - read_project_file 支持 filePaths 数组批量读取多个文件,一次调用完成
56
- - reasoning.sources 必须是非空数组,填写相关文件路径如 ["FileName.m"]
57
+ - reasoning.sources 必须是非空数组,填写文件的完整相对路径(从项目根目录开始),禁止只写文件名
58
+ - content.markdown 中的来源标注必须使用完整相对路径: (来源: Full/Path/FileName.ext:行号)
57
59
  - 如果分析提到了 3 个模式,就应该提交 3 个候选,不要合并
58
60
  - 禁止: 不要搜索新文件、不要做额外分析,专注于格式化和提交
61
+ - 【跨维度去重】每条候选必须聚焦当前维度独有的视角,不得将同一知识点换个说法重复提交到不同维度。宁可少提交也不要充数
59
62
 
60
63
  容错规则:
61
64
  - 如果 read_project_file 返回"文件不存在"或错误,不要重试同一文件的其他路径变体
@@ -71,7 +74,7 @@ content.markdown 字段必须是「项目特写」:
71
74
  核心原则: 分析文本已经包含了所有发现,你的唯一工作是将它们格式化为 collect_scan_recipe 调用。
72
75
 
73
76
  这是单文件/代码片段的深度分析,提交一个(或少量)高质量的知识候选:
74
- 1. 清晰的标题(描述代码的核心功能,使用项目真实类名)
77
+ 1. 清晰的标题(描述代码的核心功能,使用项目真实类名,不以项目名开头)
75
78
  2. 完整的技术文档正文(content.markdown 字段,≥200 字符)
76
79
  3. 实用的使用指南(usageGuide 字段,含示例)
77
80
  4. 准确的分类(category)和标签(tags)
@@ -206,7 +209,7 @@ export function buildScanPipelineStages({ task, producePrompt, analyzeCaps, prod
206
209
  2. content.markdown 字段 ≥ 200 字符,含代码块 (\`\`\`)
207
210
  3. content.rationale 必填 — 设计原理说明
208
211
  4. reasoning.sources 必须是非空数组
209
- 5. 标题使用项目真实类名
212
+ 5. 标题使用项目真实类名,不以项目名开头
210
213
  6. 必填: trigger (@kebab-case)、kind (rule/pattern/fact)、doClause (英文祈使句)`;
211
214
  },
212
215
  skipOnDegrade: true,
@@ -21,6 +21,7 @@
21
21
  *
22
22
  * @module ActiveContext
23
23
  */
24
+ import type { DistilledContext } from './memory-flush-contract.js';
24
25
  interface ActiveContextOptions {
25
26
  maxRecentRounds?: number;
26
27
  lightweight?: boolean;
@@ -189,34 +190,7 @@ export declare class ActiveContext {
189
190
  * 蒸馏 ActiveContext 为结构化报告
190
191
  * 在 Agent execute 结束时调用,结果写入 SessionStore
191
192
  */
192
- distill(): {
193
- keyFindings: {
194
- finding: string;
195
- evidence: string;
196
- importance: number;
197
- }[];
198
- toolCallSummary: string[];
199
- stats: {
200
- totalRounds: number;
201
- thoughtCount: number;
202
- totalActions: number;
203
- totalObservations: number;
204
- reflectionCount: number;
205
- totalDurationMs: number;
206
- };
207
- plan: {
208
- steps: {
209
- description: string;
210
- status: string;
211
- keywords: string[];
212
- }[];
213
- text: string;
214
- createdAtIteration: number;
215
- lastUpdatedAtIteration: number;
216
- } | null;
217
- totalObservations: number;
218
- compressedCount: number;
219
- };
193
+ distill(): DistilledContext;
220
194
  /**
221
195
  * 获取所有有 Thought 的轮次
222
196
  * @returns >}
@@ -14,7 +14,7 @@
14
14
  * @module MemoryCoordinator
15
15
  */
16
16
  import { ActiveContext } from './ActiveContext.js';
17
- import type { SessionStore } from './SessionStore.js';
17
+ import type { DimensionReportInput, SessionStore } from './SessionStore.js';
18
18
  /** PersistentMemory 接口 (声明式) */
19
19
  interface PersistentMemoryLike {
20
20
  toPromptSection(opts: {
@@ -153,7 +153,7 @@ export declare class MemoryCoordinator {
153
153
  * 完成维度: 蒸馏 + 存储到 SessionStore
154
154
  * @param [report] 附加报告数据
155
155
  */
156
- completeDimension(scopeId: string, report?: Record<string, unknown>): void;
156
+ completeDimension(scopeId: string, report?: DimensionReportInput): void;
157
157
  /**
158
158
  * 完成会话: 触发 Consolidator
159
159
  * @returns |null>}
@@ -22,6 +22,7 @@
22
22
  *
23
23
  * @module SessionStore
24
24
  */
25
+ import type { SessionStoreSerialized } from './session-store-schema.js';
25
26
  /** Finding 结构 */
26
27
  export interface Finding {
27
28
  finding: string;
@@ -59,7 +60,10 @@ export interface WorkingMemoryDistilled {
59
60
  tool: string;
60
61
  summary: string;
61
62
  }>;
62
- [key: string]: unknown;
63
+ stats?: Record<string, number>;
64
+ plan?: Record<string, unknown> | null;
65
+ totalObservations?: number;
66
+ compressedCount?: number;
63
67
  }
64
68
  /** 维度摘要 */
65
69
  export interface DimensionDigest {
@@ -168,17 +172,7 @@ export declare class SessionStore {
168
172
  set(toolName: string, args: ToolArgs, result: unknown): void;
169
173
  saveCheckpoint(projectRoot: string): Promise<void>;
170
174
  loadCheckpoint(projectRoot: string): Promise<boolean>;
171
- toJSON(): {
172
- dimensionReports: {
173
- [k: string]: DimensionReport;
174
- };
175
- crossReferences: CrossReference[];
176
- tierReflections: TierReflection[];
177
- submittedCandidates: {
178
- [k: string]: CandidateSummary[];
179
- };
180
- projectContext: Record<string, unknown>;
181
- };
175
+ toJSON(): SessionStoreSerialized;
182
176
  static fromJSON(json: Record<string, unknown>): SessionStore;
183
177
  /** 获取所有已引用文件 (去重, F10) */
184
178
  getAllReferencedFiles(): Set<string>;
@@ -26,6 +26,7 @@ import fs from 'node:fs';
26
26
  import path from 'node:path';
27
27
  import Logger from '#infra/logging/Logger.js';
28
28
  import { CACHE } from '#shared/constants.js';
29
+ import { validateSessionStoreShape } from './session-store-schema.js';
29
30
  // ── 类型定义 ──
30
31
  /** 副作用工具 — 不缓存结果 (B3 fix) */
31
32
  const NON_CACHEABLE = new Set([
@@ -570,24 +571,17 @@ export class SessionStore {
570
571
  };
571
572
  }
572
573
  static fromJSON(json) {
574
+ const validated = validateSessionStoreShape(json);
573
575
  const store = new SessionStore({
574
- projectContext: json.projectContext || {},
576
+ projectContext: validated.projectContext,
575
577
  });
576
- if (json.dimensionReports) {
577
- for (const [k, v] of Object.entries(json.dimensionReports)) {
578
- store.#dimensionReports.set(k, v);
579
- }
580
- }
581
- if (json.crossReferences) {
582
- store.#crossReferences = json.crossReferences;
578
+ for (const [k, v] of Object.entries(validated.dimensionReports)) {
579
+ store.#dimensionReports.set(k, v);
583
580
  }
584
- if (json.tierReflections) {
585
- store.#tierReflections = json.tierReflections;
586
- }
587
- if (json.submittedCandidates) {
588
- for (const [k, v] of Object.entries(json.submittedCandidates)) {
589
- store.#submittedCandidates.set(k, v);
590
- }
581
+ store.#crossReferences = validated.crossReferences;
582
+ store.#tierReflections = validated.tierReflections;
583
+ for (const [k, v] of Object.entries(validated.submittedCandidates)) {
584
+ store.#submittedCandidates.set(k, v);
591
585
  }
592
586
  return store;
593
587
  }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * §11.3 H3: MemoryFlushContract — 层级数据流转规约
3
+ *
4
+ * 定义 completeDimension() 保存数据的显式检查表,
5
+ * 确保 distill() 的结果在 ActiveContext.clear() 之前完整提取。
6
+ */
7
+ import type { Finding } from './SessionStore.js';
8
+ /** ActiveContext.distill() 的结构化返回类型 */
9
+ export interface DistilledContext {
10
+ keyFindings: Array<{
11
+ finding: string;
12
+ evidence: string;
13
+ importance: number;
14
+ }>;
15
+ toolCallSummary: string[];
16
+ stats: {
17
+ totalRounds: number;
18
+ thoughtCount: number;
19
+ totalActions: number;
20
+ totalObservations: number;
21
+ reflectionCount: number;
22
+ totalDurationMs: number;
23
+ };
24
+ plan: {
25
+ text: string;
26
+ steps: Array<{
27
+ description: string;
28
+ status: string;
29
+ keywords: string[];
30
+ }>;
31
+ createdAtIteration: number;
32
+ lastUpdatedAtIteration: number;
33
+ } | null;
34
+ totalObservations: number;
35
+ compressedCount: number;
36
+ }
37
+ /** completeDimension() 执行数据保存时使用的结构化清单 */
38
+ export interface DimensionFlushManifest {
39
+ /** distill() 的结果 — 总是存入 SessionStore */
40
+ distilled: DistilledContext;
41
+ /** 原始 scratchpad findings — 重要性 >= threshold 的需要转发 */
42
+ highPriorityFindings: Finding[];
43
+ /** 工具调用统计 — 用于 SessionStore.toolCallLog */
44
+ toolCallSummary: string[];
45
+ /** 是否触发向 PersistentMemory 的异步 consolidation */
46
+ shouldConsolidate: boolean;
47
+ }
48
+ /** 从 DistilledContext 提取高优先级 findings (importance >= threshold) */
49
+ export declare function extractHighPriorityFindings(distilled: DistilledContext, threshold?: number): Finding[];
@@ -0,0 +1,16 @@
1
+ /**
2
+ * §11.3 H3: MemoryFlushContract — 层级数据流转规约
3
+ *
4
+ * 定义 completeDimension() 保存数据的显式检查表,
5
+ * 确保 distill() 的结果在 ActiveContext.clear() 之前完整提取。
6
+ */
7
+ /** 从 DistilledContext 提取高优先级 findings (importance >= threshold) */
8
+ export function extractHighPriorityFindings(distilled, threshold = 7) {
9
+ return distilled.keyFindings
10
+ .filter((f) => f.importance >= threshold)
11
+ .map((f) => ({
12
+ finding: f.finding,
13
+ evidence: f.evidence,
14
+ importance: f.importance,
15
+ }));
16
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * SessionStore 序列化校验
3
+ *
4
+ * `SessionStore.fromJSON()` 的反序列化入口,对边界数据做轻量类型校验。
5
+ *
6
+ * @module agent/memory/session-store-schema
7
+ */
8
+ import type { CandidateSummary, CrossReference, DimensionReport, TierReflection, WorkingMemoryDistilled } from './SessionStore.js';
9
+ export interface SessionStoreSerialized {
10
+ dimensionReports: Record<string, DimensionReport>;
11
+ crossReferences: CrossReference[];
12
+ tierReflections: TierReflection[];
13
+ submittedCandidates: Record<string, CandidateSummary[]>;
14
+ projectContext: Record<string, unknown>;
15
+ workingMemory?: WorkingMemoryDistilled;
16
+ }
17
+ /**
18
+ * 校验反序列化数据的关键字段类型,返回类型安全的结构。
19
+ */
20
+ export declare function validateSessionStoreShape(raw: Record<string, unknown>): SessionStoreSerialized;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * SessionStore 序列化校验
3
+ *
4
+ * `SessionStore.fromJSON()` 的反序列化入口,对边界数据做轻量类型校验。
5
+ *
6
+ * @module agent/memory/session-store-schema
7
+ */
8
+ // ── Helpers ──────────────────────────────────────────────────
9
+ function isRecord(val) {
10
+ return val !== null && typeof val === 'object' && !Array.isArray(val);
11
+ }
12
+ // ── Public API ───────────────────────────────────────────────
13
+ /**
14
+ * 校验反序列化数据的关键字段类型,返回类型安全的结构。
15
+ */
16
+ export function validateSessionStoreShape(raw) {
17
+ if (raw.dimensionReports !== undefined && !isRecord(raw.dimensionReports)) {
18
+ throw new Error('SessionStore schema: dimensionReports must be a Record');
19
+ }
20
+ if (raw.crossReferences !== undefined && !Array.isArray(raw.crossReferences)) {
21
+ throw new Error('SessionStore schema: crossReferences must be an array');
22
+ }
23
+ if (raw.tierReflections !== undefined && !Array.isArray(raw.tierReflections)) {
24
+ throw new Error('SessionStore schema: tierReflections must be an array');
25
+ }
26
+ if (raw.submittedCandidates !== undefined && !isRecord(raw.submittedCandidates)) {
27
+ throw new Error('SessionStore schema: submittedCandidates must be a Record');
28
+ }
29
+ return {
30
+ dimensionReports: raw.dimensionReports ?? {},
31
+ crossReferences: raw.crossReferences ?? [],
32
+ tierReflections: raw.tierReflections ?? [],
33
+ submittedCandidates: raw.submittedCandidates ?? {},
34
+ projectContext: isRecord(raw.projectContext)
35
+ ? raw.projectContext
36
+ : {},
37
+ workingMemory: isRecord(raw.workingMemory)
38
+ ? raw.workingMemory
39
+ : undefined,
40
+ };
41
+ }
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * @module presets
21
21
  */
22
- import { insightGateEvaluator } from './domain/insight-gate.js';
22
+ import { evolutionGateEvaluator, insightGateEvaluator } from './domain/insight-gate.js';
23
23
  import { producerRejectionGateEvaluator } from './domain/insight-producer.js';
24
24
  import { BudgetPolicy, QualityGatePolicy, SafetyPolicy } from './policies.js';
25
25
  import { type Strategy } from './strategies.js';
@@ -168,6 +168,50 @@ export declare const PRESETS: Readonly<{
168
168
  enabled: boolean;
169
169
  };
170
170
  };
171
+ evolution: {
172
+ name: string;
173
+ description: string;
174
+ capabilities: string[];
175
+ strategy: {
176
+ type: string;
177
+ maxRetries: number;
178
+ stages: ({
179
+ name: string;
180
+ capabilities: string[];
181
+ budget: {
182
+ temperature: number;
183
+ timeoutMs: number;
184
+ maxIterations: number;
185
+ searchBudget: number;
186
+ searchBudgetGrace: number;
187
+ maxSubmits: number;
188
+ softSubmitLimit: number;
189
+ idleRoundsToExit: number;
190
+ };
191
+ systemPrompt: string;
192
+ promptBuilder: (ctx: Record<string, unknown>) => string;
193
+ gate?: undefined;
194
+ } | {
195
+ name: string;
196
+ gate: {
197
+ evaluator: typeof evolutionGateEvaluator;
198
+ maxRetries: number;
199
+ };
200
+ capabilities?: undefined;
201
+ budget?: undefined;
202
+ systemPrompt?: undefined;
203
+ promptBuilder?: undefined;
204
+ })[];
205
+ };
206
+ policies: ((config?: PolicyFactoryConfig) => BudgetPolicy)[];
207
+ persona: {
208
+ role: string;
209
+ description: string;
210
+ };
211
+ memory: {
212
+ enabled: boolean;
213
+ };
214
+ };
171
215
  lark: {
172
216
  name: string;
173
217
  description: string;
@@ -323,6 +367,50 @@ declare const _default: {
323
367
  enabled: boolean;
324
368
  };
325
369
  };
370
+ evolution: {
371
+ name: string;
372
+ description: string;
373
+ capabilities: string[];
374
+ strategy: {
375
+ type: string;
376
+ maxRetries: number;
377
+ stages: ({
378
+ name: string;
379
+ capabilities: string[];
380
+ budget: {
381
+ temperature: number;
382
+ timeoutMs: number;
383
+ maxIterations: number;
384
+ searchBudget: number;
385
+ searchBudgetGrace: number;
386
+ maxSubmits: number;
387
+ softSubmitLimit: number;
388
+ idleRoundsToExit: number;
389
+ };
390
+ systemPrompt: string;
391
+ promptBuilder: (ctx: Record<string, unknown>) => string;
392
+ gate?: undefined;
393
+ } | {
394
+ name: string;
395
+ gate: {
396
+ evaluator: typeof evolutionGateEvaluator;
397
+ maxRetries: number;
398
+ };
399
+ capabilities?: undefined;
400
+ budget?: undefined;
401
+ systemPrompt?: undefined;
402
+ promptBuilder?: undefined;
403
+ })[];
404
+ };
405
+ policies: ((config?: PolicyFactoryConfig) => BudgetPolicy)[];
406
+ persona: {
407
+ role: string;
408
+ description: string;
409
+ };
410
+ memory: {
411
+ enabled: boolean;
412
+ };
413
+ };
326
414
  lark: {
327
415
  name: string;
328
416
  description: string;
@@ -21,7 +21,8 @@
21
21
  */
22
22
  // v3.0: 导入 Insight 领域函数 (domain/ 模块)
23
23
  import { ANALYST_BUDGET, ANALYST_SYSTEM_PROMPT, buildAnalystPrompt, } from './domain/insight-analyst.js';
24
- import { buildRetryPrompt, insightGateEvaluator } from './domain/insight-gate.js';
24
+ import { buildEvolverPrompt, EVOLVER_BUDGET, EVOLVER_SYSTEM_PROMPT, } from './domain/insight-evolver.js';
25
+ import { buildRetryPrompt, evolutionGateEvaluator, insightGateEvaluator, } from './domain/insight-gate.js';
25
26
  import { buildProducerPromptV2, PRODUCER_BUDGET, PRODUCER_SYSTEM_PROMPT, producerRejectionGateEvaluator, } from './domain/insight-producer.js';
26
27
  import { PipelineStrategy } from './PipelineStrategy.js';
27
28
  import { BudgetPolicy, QualityGatePolicy, SafetyPolicy } from './policies.js';
@@ -81,7 +82,7 @@ export const PRESETS = Object.freeze({
81
82
  timeoutMs: 300_000,
82
83
  },
83
84
  systemPrompt: ANALYST_SYSTEM_PROMPT,
84
- promptBuilder: (ctx) => buildAnalystPrompt(ctx.dimConfig, ctx.projectInfo, ctx.dimContext, ctx.sessionStore, ctx.semanticMemory, ctx.codeEntityGraph),
85
+ promptBuilder: (ctx) => buildAnalystPrompt(ctx.dimConfig, ctx.projectInfo, ctx.dimContext, ctx.sessionStore, ctx.semanticMemory, ctx.codeEntityGraph, ctx.rescanContext, ctx.panorama, ctx.evidenceStarters, ctx.gateArtifact),
85
86
  retryPromptBuilder: (retryCtx, _origPrompt, prev) => {
86
87
  const prevAnalysis = prev.analyze?.reply || '';
87
88
  const retryHint = buildRetryPrompt(retryCtx.reason ?? '');
@@ -106,7 +107,7 @@ export const PRESETS = Object.freeze({
106
107
  budget: { ...PRODUCER_BUDGET, temperature: 0.3, timeoutMs: 180_000 },
107
108
  systemPrompt: PRODUCER_SYSTEM_PROMPT,
108
109
  promptBuilder: (ctx) => buildProducerPromptV2(ctx.gateArtifact, // 来自 quality_gate 的 AnalysisArtifact
109
- ctx.dimConfig, ctx.projectInfo),
110
+ ctx.dimConfig, ctx.projectInfo, ctx.rescanContext, ctx.panorama),
110
111
  // 拒绝率过高时: 缩减预算 + 特定修复 prompt (对齐旧 ProducerAgent 的 rejection retry)
111
112
  retryBudget: { maxIterations: 5, temperature: 0.3, timeoutMs: 120_000 },
112
113
  retryPromptBuilder: (retryCtx, _origPrompt, prev) => {
@@ -129,7 +130,7 @@ export const PRESETS = Object.freeze({
129
130
  2. content.markdown 字段 ≥ 200 字符,含代码块 (\`\`\`)
130
131
  3. content.rationale 必填 — 设计原理说明(为什么这样设计)
131
132
  4. 包含来源标注 (来源: FileName.m:行号)
132
- 5. 标题使用项目真实类名
133
+ 5. 标题使用项目真实类名,不以项目名开头
133
134
  6. 必填: trigger (@kebab-case)、kind (rule/pattern/fact)、doClause (英文祈使句)`;
134
135
  },
135
136
  skipOnDegrade: true,
@@ -150,7 +151,7 @@ export const PRESETS = Object.freeze({
150
151
  maxIterations: config?.maxIterations ?? 24,
151
152
  maxTokens: config?.maxTokens ?? 4096,
152
153
  temperature: config?.temperature ?? 0.3,
153
- timeoutMs: config?.timeoutMs ?? 600_000,
154
+ timeoutMs: config?.timeoutMs ?? 3_600_000,
154
155
  }),
155
156
  (config) => new QualityGatePolicy({
156
157
  minEvidenceLength: config?.minEvidenceLength ?? 500,
@@ -166,6 +167,53 @@ export const PRESETS = Object.freeze({
166
167
  enabled: false, // 无状态 worker
167
168
  },
168
169
  },
170
+ // ─── evolution: 衰退 Recipe 进化决策 ─────────
171
+ evolution: {
172
+ name: '进化',
173
+ description: '审查衰退 Recipe,决定进化(supersede)、废弃或跳过。Evolve→EvolutionGate。',
174
+ capabilities: ['evolution_analysis'],
175
+ strategy: {
176
+ type: 'pipeline',
177
+ maxRetries: 1,
178
+ stages: [
179
+ // ── Phase 1: Evolver ──
180
+ {
181
+ name: 'evolve',
182
+ capabilities: ['evolution_analysis'],
183
+ budget: {
184
+ ...EVOLVER_BUDGET,
185
+ temperature: 0.3,
186
+ timeoutMs: 180_000,
187
+ },
188
+ systemPrompt: EVOLVER_SYSTEM_PROMPT,
189
+ promptBuilder: (ctx) => buildEvolverPrompt(null, null, ctx),
190
+ },
191
+ // ── Phase 2: Evolution Gate ──
192
+ {
193
+ name: 'evolution_gate',
194
+ gate: {
195
+ evaluator: evolutionGateEvaluator,
196
+ maxRetries: 1,
197
+ },
198
+ },
199
+ ],
200
+ },
201
+ policies: [
202
+ (config) => new BudgetPolicy({
203
+ maxIterations: config?.maxIterations ?? 16,
204
+ maxTokens: config?.maxTokens ?? 4096,
205
+ temperature: config?.temperature ?? 0.3,
206
+ timeoutMs: config?.timeoutMs ?? 180_000,
207
+ }),
208
+ ],
209
+ persona: {
210
+ role: 'analyst',
211
+ description: '知识进化专家',
212
+ },
213
+ memory: {
214
+ enabled: false,
215
+ },
216
+ },
169
217
  // ─── lark: 飞书知识管理对话 ─────────────
170
218
  lark: {
171
219
  name: '飞书对话',