soloforge 1.2.20 → 1.3.1

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 (688) hide show
  1. package/README.md +150 -3
  2. package/dist/adapters/claude_code/claude_md.d.ts +1 -2
  3. package/dist/adapters/claude_code/claude_md.d.ts.map +1 -1
  4. package/dist/adapters/claude_code/claude_md.js +47 -4
  5. package/dist/adapters/claude_code/claude_md.js.map +1 -1
  6. package/dist/adapters/claude_code/hooks.d.ts.map +1 -1
  7. package/dist/adapters/claude_code/hooks.js +2 -1
  8. package/dist/adapters/claude_code/hooks.js.map +1 -1
  9. package/dist/adapters/claude_code/server.js +4 -3
  10. package/dist/adapters/claude_code/server.js.map +1 -1
  11. package/dist/adapters/claude_code/tools.d.ts +282 -1
  12. package/dist/adapters/claude_code/tools.d.ts.map +1 -1
  13. package/dist/adapters/claude_code/tools.js +1366 -40
  14. package/dist/adapters/claude_code/tools.js.map +1 -1
  15. package/dist/adapters/codex/codex_config.d.ts.map +1 -1
  16. package/dist/adapters/codex/codex_config.js +3 -2
  17. package/dist/adapters/codex/codex_config.js.map +1 -1
  18. package/dist/adapters/codex/codex_rules.d.ts.map +1 -1
  19. package/dist/adapters/codex/codex_rules.js +2 -1
  20. package/dist/adapters/codex/codex_rules.js.map +1 -1
  21. package/dist/adapters/shared/workflow_template.d.ts.map +1 -1
  22. package/dist/adapters/shared/workflow_template.js +8 -1
  23. package/dist/adapters/shared/workflow_template.js.map +1 -1
  24. package/dist/adapters/trae/trae_config.d.ts +0 -5
  25. package/dist/adapters/trae/trae_config.d.ts.map +1 -1
  26. package/dist/adapters/trae/trae_config.js +2 -1
  27. package/dist/adapters/trae/trae_config.js.map +1 -1
  28. package/dist/adapters/trae/trae_rules.d.ts.map +1 -1
  29. package/dist/adapters/trae/trae_rules.js +2 -1
  30. package/dist/adapters/trae/trae_rules.js.map +1 -1
  31. package/dist/bin/config_commands.d.ts.map +1 -1
  32. package/dist/bin/config_commands.js +34 -33
  33. package/dist/bin/config_commands.js.map +1 -1
  34. package/dist/bin/soloforge.d.ts.map +1 -1
  35. package/dist/bin/soloforge.js +1256 -160
  36. package/dist/bin/soloforge.js.map +1 -1
  37. package/dist/engine/adapter_prompt_contract.d.ts +60 -0
  38. package/dist/engine/adapter_prompt_contract.d.ts.map +1 -0
  39. package/dist/engine/adapter_prompt_contract.js +163 -0
  40. package/dist/engine/adapter_prompt_contract.js.map +1 -0
  41. package/dist/engine/architecture_decision_workshop.d.ts +58 -0
  42. package/dist/engine/architecture_decision_workshop.d.ts.map +1 -0
  43. package/dist/engine/architecture_decision_workshop.js +118 -0
  44. package/dist/engine/architecture_decision_workshop.js.map +1 -0
  45. package/dist/engine/architecture_design_contract.d.ts +49 -0
  46. package/dist/engine/architecture_design_contract.d.ts.map +1 -0
  47. package/dist/engine/architecture_design_contract.js +169 -0
  48. package/dist/engine/architecture_design_contract.js.map +1 -0
  49. package/dist/engine/artifact_contract_registry.d.ts.map +1 -1
  50. package/dist/engine/artifact_contract_registry.js +7 -14
  51. package/dist/engine/artifact_contract_registry.js.map +1 -1
  52. package/dist/engine/{batch1_manifest.d.ts → asset_manifest.d.ts} +8 -8
  53. package/dist/engine/asset_manifest.d.ts.map +1 -0
  54. package/dist/engine/{batch1_manifest.js → asset_manifest.js} +63 -9
  55. package/dist/engine/asset_manifest.js.map +1 -0
  56. package/dist/engine/audit_pool.d.ts.map +1 -1
  57. package/dist/engine/audit_pool.js +5 -4
  58. package/dist/engine/audit_pool.js.map +1 -1
  59. package/dist/engine/audit_sampler.d.ts.map +1 -1
  60. package/dist/engine/audit_sampler.js +2 -1
  61. package/dist/engine/audit_sampler.js.map +1 -1
  62. package/dist/engine/audit_verifier.d.ts.map +1 -1
  63. package/dist/engine/audit_verifier.js +5 -4
  64. package/dist/engine/audit_verifier.js.map +1 -1
  65. package/dist/engine/brainstorm_contract.d.ts +46 -0
  66. package/dist/engine/brainstorm_contract.d.ts.map +1 -0
  67. package/dist/engine/brainstorm_contract.js +136 -0
  68. package/dist/engine/brainstorm_contract.js.map +1 -0
  69. package/dist/engine/capability_action_advisor.d.ts.map +1 -1
  70. package/dist/engine/capability_action_advisor.js +8 -7
  71. package/dist/engine/capability_action_advisor.js.map +1 -1
  72. package/dist/engine/capability_registry.d.ts.map +1 -1
  73. package/dist/engine/capability_registry.js +0 -7
  74. package/dist/engine/capability_registry.js.map +1 -1
  75. package/dist/engine/capability_state_store.d.ts.map +1 -1
  76. package/dist/engine/capability_state_store.js +7 -6
  77. package/dist/engine/capability_state_store.js.map +1 -1
  78. package/dist/engine/change_coordinator.d.ts.map +1 -1
  79. package/dist/engine/change_coordinator.js +4 -3
  80. package/dist/engine/change_coordinator.js.map +1 -1
  81. package/dist/engine/chinese_semantic_priority.d.ts +62 -0
  82. package/dist/engine/chinese_semantic_priority.d.ts.map +1 -0
  83. package/dist/engine/chinese_semantic_priority.js +153 -0
  84. package/dist/engine/chinese_semantic_priority.js.map +1 -0
  85. package/dist/engine/coding_readiness_gate.d.ts +46 -0
  86. package/dist/engine/coding_readiness_gate.d.ts.map +1 -0
  87. package/dist/engine/coding_readiness_gate.js +175 -0
  88. package/dist/engine/coding_readiness_gate.js.map +1 -0
  89. package/dist/engine/cognitive_anchor.d.ts.map +1 -1
  90. package/dist/engine/cognitive_anchor.js +7 -6
  91. package/dist/engine/cognitive_anchor.js.map +1 -1
  92. package/dist/engine/command_execution_contract.d.ts.map +1 -1
  93. package/dist/engine/command_execution_contract.js +13 -12
  94. package/dist/engine/command_execution_contract.js.map +1 -1
  95. package/dist/engine/confidence_scorer.d.ts.map +1 -1
  96. package/dist/engine/confidence_scorer.js +2 -1
  97. package/dist/engine/confidence_scorer.js.map +1 -1
  98. package/dist/engine/config_precedence_contract.d.ts.map +1 -1
  99. package/dist/engine/config_precedence_contract.js +9 -8
  100. package/dist/engine/config_precedence_contract.js.map +1 -1
  101. package/dist/engine/conflict_gate.d.ts.map +1 -1
  102. package/dist/engine/conflict_gate.js +4 -3
  103. package/dist/engine/conflict_gate.js.map +1 -1
  104. package/dist/engine/consumable_asset_registry.d.ts +4 -0
  105. package/dist/engine/consumable_asset_registry.d.ts.map +1 -1
  106. package/dist/engine/consumable_asset_registry.js +370 -0
  107. package/dist/engine/consumable_asset_registry.js.map +1 -1
  108. package/dist/engine/consumption_trace_store.d.ts +50 -0
  109. package/dist/engine/consumption_trace_store.d.ts.map +1 -0
  110. package/dist/engine/consumption_trace_store.js +84 -0
  111. package/dist/engine/consumption_trace_store.js.map +1 -0
  112. package/dist/engine/contract_guard.d.ts.map +1 -1
  113. package/dist/engine/contract_guard.js +7 -6
  114. package/dist/engine/contract_guard.js.map +1 -1
  115. package/dist/engine/contract_registry.d.ts +1 -1
  116. package/dist/engine/contract_registry.d.ts.map +1 -1
  117. package/dist/engine/contract_registry.js +511 -38
  118. package/dist/engine/contract_registry.js.map +1 -1
  119. package/dist/engine/convention_detector.d.ts.map +1 -1
  120. package/dist/engine/convention_detector.js +4 -3
  121. package/dist/engine/convention_detector.js.map +1 -1
  122. package/dist/engine/core_engineering_principles.d.ts.map +1 -1
  123. package/dist/engine/core_engineering_principles.js +4 -14
  124. package/dist/engine/core_engineering_principles.js.map +1 -1
  125. package/dist/engine/core_experience_principle.d.ts +194 -0
  126. package/dist/engine/core_experience_principle.d.ts.map +1 -0
  127. package/dist/engine/core_experience_principle.js +349 -0
  128. package/dist/engine/core_experience_principle.js.map +1 -0
  129. package/dist/engine/debt_reporter.d.ts.map +1 -1
  130. package/dist/engine/debt_reporter.js +3 -2
  131. package/dist/engine/debt_reporter.js.map +1 -1
  132. package/dist/engine/debt_tracker.d.ts.map +1 -1
  133. package/dist/engine/debt_tracker.js +8 -7
  134. package/dist/engine/debt_tracker.js.map +1 -1
  135. package/dist/engine/debug_log.d.ts +4 -1
  136. package/dist/engine/debug_log.d.ts.map +1 -1
  137. package/dist/engine/debug_log.js +4 -6
  138. package/dist/engine/debug_log.js.map +1 -1
  139. package/dist/engine/debugger.d.ts.map +1 -1
  140. package/dist/engine/debugger.js +5 -4
  141. package/dist/engine/debugger.js.map +1 -1
  142. package/dist/engine/decision_contract.d.ts.map +1 -1
  143. package/dist/engine/decision_contract.js +4 -3
  144. package/dist/engine/decision_contract.js.map +1 -1
  145. package/dist/engine/delivery.d.ts.map +1 -1
  146. package/dist/engine/delivery.js +16 -15
  147. package/dist/engine/delivery.js.map +1 -1
  148. package/dist/engine/delivery_readiness.d.ts +5 -1
  149. package/dist/engine/delivery_readiness.d.ts.map +1 -1
  150. package/dist/engine/delivery_readiness.js +24 -2
  151. package/dist/engine/delivery_readiness.js.map +1 -1
  152. package/dist/engine/dependency_scanner.d.ts.map +1 -1
  153. package/dist/engine/dependency_scanner.js +6 -5
  154. package/dist/engine/dependency_scanner.js.map +1 -1
  155. package/dist/engine/design_artifact_pack.d.ts +44 -0
  156. package/dist/engine/design_artifact_pack.d.ts.map +1 -0
  157. package/dist/engine/design_artifact_pack.js +167 -0
  158. package/dist/engine/design_artifact_pack.js.map +1 -0
  159. package/dist/engine/detail_discipline.d.ts +40 -0
  160. package/dist/engine/detail_discipline.d.ts.map +1 -0
  161. package/dist/engine/detail_discipline.js +107 -0
  162. package/dist/engine/detail_discipline.js.map +1 -0
  163. package/dist/engine/developer_sovereignty.d.ts.map +1 -1
  164. package/dist/engine/developer_sovereignty.js +6 -5
  165. package/dist/engine/developer_sovereignty.js.map +1 -1
  166. package/dist/engine/diff_ownership.d.ts.map +1 -1
  167. package/dist/engine/diff_ownership.js +9 -8
  168. package/dist/engine/diff_ownership.js.map +1 -1
  169. package/dist/engine/diff_ownership_store.d.ts.map +1 -1
  170. package/dist/engine/diff_ownership_store.js +8 -7
  171. package/dist/engine/diff_ownership_store.js.map +1 -1
  172. package/dist/engine/documentation_governance.d.ts +55 -0
  173. package/dist/engine/documentation_governance.d.ts.map +1 -0
  174. package/dist/engine/documentation_governance.js +249 -0
  175. package/dist/engine/documentation_governance.js.map +1 -0
  176. package/dist/engine/dual_layer_mechanism_registry.d.ts +6 -4
  177. package/dist/engine/dual_layer_mechanism_registry.d.ts.map +1 -1
  178. package/dist/engine/dual_layer_mechanism_registry.js +851 -11
  179. package/dist/engine/dual_layer_mechanism_registry.js.map +1 -1
  180. package/dist/engine/enforcement_guard.d.ts.map +1 -1
  181. package/dist/engine/enforcement_guard.js +14 -0
  182. package/dist/engine/enforcement_guard.js.map +1 -1
  183. package/dist/engine/escape_report.d.ts.map +1 -1
  184. package/dist/engine/escape_report.js +4 -3
  185. package/dist/engine/escape_report.js.map +1 -1
  186. package/dist/engine/evidence_grounding_contract.d.ts +137 -0
  187. package/dist/engine/evidence_grounding_contract.d.ts.map +1 -0
  188. package/dist/engine/evidence_grounding_contract.js +410 -0
  189. package/dist/engine/evidence_grounding_contract.js.map +1 -0
  190. package/dist/engine/evolution_regression_gate.d.ts +42 -0
  191. package/dist/engine/evolution_regression_gate.d.ts.map +1 -0
  192. package/dist/engine/evolution_regression_gate.js +159 -0
  193. package/dist/engine/evolution_regression_gate.js.map +1 -0
  194. package/dist/engine/existing_system_analysis.d.ts +37 -0
  195. package/dist/engine/existing_system_analysis.d.ts.map +1 -0
  196. package/dist/engine/existing_system_analysis.js +151 -0
  197. package/dist/engine/existing_system_analysis.js.map +1 -0
  198. package/dist/engine/exploration.d.ts.map +1 -1
  199. package/dist/engine/exploration.js +7 -6
  200. package/dist/engine/exploration.js.map +1 -1
  201. package/dist/engine/extension_contract.d.ts +50 -0
  202. package/dist/engine/extension_contract.d.ts.map +1 -0
  203. package/dist/engine/extension_contract.js +158 -0
  204. package/dist/engine/extension_contract.js.map +1 -0
  205. package/dist/engine/extension_platform_contracts.d.ts +712 -0
  206. package/dist/engine/extension_platform_contracts.d.ts.map +1 -0
  207. package/dist/engine/extension_platform_contracts.js +42 -0
  208. package/dist/engine/extension_platform_contracts.js.map +1 -0
  209. package/dist/engine/extension_scenario_registry.d.ts +30 -0
  210. package/dist/engine/extension_scenario_registry.d.ts.map +1 -0
  211. package/dist/engine/extension_scenario_registry.js +976 -0
  212. package/dist/engine/extension_scenario_registry.js.map +1 -0
  213. package/dist/engine/failure_classifier.d.ts.map +1 -1
  214. package/dist/engine/failure_classifier.js +9 -8
  215. package/dist/engine/failure_classifier.js.map +1 -1
  216. package/dist/engine/feasibility_checker.d.ts.map +1 -1
  217. package/dist/engine/feasibility_checker.js +5 -4
  218. package/dist/engine/feasibility_checker.js.map +1 -1
  219. package/dist/engine/first_principles.d.ts +35 -0
  220. package/dist/engine/first_principles.d.ts.map +1 -0
  221. package/dist/engine/first_principles.js +128 -0
  222. package/dist/engine/first_principles.js.map +1 -0
  223. package/dist/engine/{batch1_scenario_registry.d.ts → foundation_scenario_registry.d.ts} +15 -15
  224. package/dist/engine/foundation_scenario_registry.d.ts.map +1 -0
  225. package/dist/engine/{batch1_scenario_registry.js → foundation_scenario_registry.js} +22 -25
  226. package/dist/engine/foundation_scenario_registry.js.map +1 -0
  227. package/dist/engine/{batch1_scenario_runners.d.ts → foundation_scenario_runners.d.ts} +1 -1
  228. package/dist/engine/foundation_scenario_runners.d.ts.map +1 -0
  229. package/dist/engine/{batch1_scenario_runners.js → foundation_scenario_runners.js} +8 -7
  230. package/dist/engine/foundation_scenario_runners.js.map +1 -0
  231. package/dist/engine/git_deps.d.ts.map +1 -1
  232. package/dist/engine/git_deps.js +2 -1
  233. package/dist/engine/git_deps.js.map +1 -1
  234. package/dist/engine/governance_report.d.ts.map +1 -1
  235. package/dist/engine/governance_report.js +10 -9
  236. package/dist/engine/governance_report.js.map +1 -1
  237. package/dist/engine/impact_analyzer.d.ts.map +1 -1
  238. package/dist/engine/impact_analyzer.js +5 -4
  239. package/dist/engine/impact_analyzer.js.map +1 -1
  240. package/dist/engine/implementation_roadmap_registry.d.ts +1 -1
  241. package/dist/engine/implementation_roadmap_registry.d.ts.map +1 -1
  242. package/dist/engine/implementation_roadmap_registry.js +348 -82
  243. package/dist/engine/implementation_roadmap_registry.js.map +1 -1
  244. package/dist/engine/input_material_contract_registry.d.ts.map +1 -1
  245. package/dist/engine/input_material_contract_registry.js +4 -3
  246. package/dist/engine/input_material_contract_registry.js.map +1 -1
  247. package/dist/engine/instruction_contract.d.ts +75 -0
  248. package/dist/engine/instruction_contract.d.ts.map +1 -0
  249. package/dist/engine/instruction_contract.js +185 -0
  250. package/dist/engine/instruction_contract.js.map +1 -0
  251. package/dist/engine/intent_expander.d.ts.map +1 -1
  252. package/dist/engine/intent_expander.js +353 -1
  253. package/dist/engine/intent_expander.js.map +1 -1
  254. package/dist/engine/intent_router.d.ts +11 -2
  255. package/dist/engine/intent_router.d.ts.map +1 -1
  256. package/dist/engine/intent_router.js +121 -1
  257. package/dist/engine/intent_router.js.map +1 -1
  258. package/dist/engine/intent_signal_extractor.d.ts +3 -0
  259. package/dist/engine/intent_signal_extractor.d.ts.map +1 -1
  260. package/dist/engine/intent_signal_extractor.js +49 -0
  261. package/dist/engine/intent_signal_extractor.js.map +1 -1
  262. package/dist/engine/io_controller.d.ts.map +1 -1
  263. package/dist/engine/io_controller.js +8 -7
  264. package/dist/engine/io_controller.js.map +1 -1
  265. package/dist/engine/java_quality_guard.d.ts.map +1 -1
  266. package/dist/engine/java_quality_guard.js +5 -18
  267. package/dist/engine/java_quality_guard.js.map +1 -1
  268. package/dist/engine/job_manager.d.ts.map +1 -1
  269. package/dist/engine/job_manager.js +8 -7
  270. package/dist/engine/job_manager.js.map +1 -1
  271. package/dist/engine/knowledge_acceptance_registry.d.ts +35 -0
  272. package/dist/engine/knowledge_acceptance_registry.d.ts.map +1 -0
  273. package/dist/engine/knowledge_acceptance_registry.js +271 -0
  274. package/dist/engine/knowledge_acceptance_registry.js.map +1 -0
  275. package/dist/engine/knowledge_asset_audit.d.ts +65 -0
  276. package/dist/engine/knowledge_asset_audit.d.ts.map +1 -0
  277. package/dist/engine/knowledge_asset_audit.js +230 -0
  278. package/dist/engine/knowledge_asset_audit.js.map +1 -0
  279. package/dist/engine/knowledge_asset_consumer.d.ts +150 -0
  280. package/dist/engine/knowledge_asset_consumer.d.ts.map +1 -0
  281. package/dist/engine/knowledge_asset_consumer.js +279 -0
  282. package/dist/engine/knowledge_asset_consumer.js.map +1 -0
  283. package/dist/engine/knowledge_asset_generation_gate.d.ts +38 -0
  284. package/dist/engine/knowledge_asset_generation_gate.d.ts.map +1 -0
  285. package/dist/engine/knowledge_asset_generation_gate.js +131 -0
  286. package/dist/engine/knowledge_asset_generation_gate.js.map +1 -0
  287. package/dist/engine/knowledge_asset_migration.d.ts +117 -0
  288. package/dist/engine/knowledge_asset_migration.d.ts.map +1 -0
  289. package/dist/engine/knowledge_asset_migration.js +204 -0
  290. package/dist/engine/knowledge_asset_migration.js.map +1 -0
  291. package/dist/engine/knowledge_asset_schema.d.ts +97 -0
  292. package/dist/engine/knowledge_asset_schema.d.ts.map +1 -0
  293. package/dist/engine/knowledge_asset_schema.js +413 -0
  294. package/dist/engine/knowledge_asset_schema.js.map +1 -0
  295. package/dist/engine/knowledge_config_loader.d.ts.map +1 -1
  296. package/dist/engine/knowledge_config_loader.js +5 -4
  297. package/dist/engine/knowledge_config_loader.js.map +1 -1
  298. package/dist/engine/knowledge_consumption_snapshot.d.ts +91 -0
  299. package/dist/engine/knowledge_consumption_snapshot.d.ts.map +1 -0
  300. package/dist/engine/knowledge_consumption_snapshot.js +113 -0
  301. package/dist/engine/knowledge_consumption_snapshot.js.map +1 -0
  302. package/dist/engine/knowledge_evolution.d.ts +82 -0
  303. package/dist/engine/knowledge_evolution.d.ts.map +1 -0
  304. package/dist/engine/knowledge_evolution.js +272 -0
  305. package/dist/engine/knowledge_evolution.js.map +1 -0
  306. package/dist/engine/knowledge_lifecycle.d.ts +70 -10
  307. package/dist/engine/knowledge_lifecycle.d.ts.map +1 -1
  308. package/dist/engine/knowledge_lifecycle.js +238 -4
  309. package/dist/engine/knowledge_lifecycle.js.map +1 -1
  310. package/dist/engine/knowledge_manager.d.ts.map +1 -1
  311. package/dist/engine/knowledge_manager.js +9 -8
  312. package/dist/engine/knowledge_manager.js.map +1 -1
  313. package/dist/engine/knowledge_scenario_registry.d.ts +21 -0
  314. package/dist/engine/knowledge_scenario_registry.d.ts.map +1 -0
  315. package/dist/engine/knowledge_scenario_registry.js +337 -0
  316. package/dist/engine/knowledge_scenario_registry.js.map +1 -0
  317. package/dist/engine/knowledge_sovereignty.d.ts.map +1 -1
  318. package/dist/engine/knowledge_sovereignty.js +5 -4
  319. package/dist/engine/knowledge_sovereignty.js.map +1 -1
  320. package/dist/engine/knowledge_template_contracts.d.ts +244 -0
  321. package/dist/engine/knowledge_template_contracts.d.ts.map +1 -0
  322. package/dist/engine/knowledge_template_contracts.js +26 -0
  323. package/dist/engine/knowledge_template_contracts.js.map +1 -0
  324. package/dist/engine/language_policy.d.ts +69 -12
  325. package/dist/engine/language_policy.d.ts.map +1 -1
  326. package/dist/engine/language_policy.js +129 -8
  327. package/dist/engine/language_policy.js.map +1 -1
  328. package/dist/engine/llm_gateway.d.ts.map +1 -1
  329. package/dist/engine/llm_gateway.js +10 -9
  330. package/dist/engine/llm_gateway.js.map +1 -1
  331. package/dist/engine/local_docker_acceptance.d.ts +94 -0
  332. package/dist/engine/local_docker_acceptance.d.ts.map +1 -0
  333. package/dist/engine/local_docker_acceptance.js +312 -0
  334. package/dist/engine/local_docker_acceptance.js.map +1 -0
  335. package/dist/engine/logger.d.ts +64 -0
  336. package/dist/engine/logger.d.ts.map +1 -0
  337. package/dist/engine/logger.js +115 -0
  338. package/dist/engine/logger.js.map +1 -0
  339. package/dist/engine/main_path_integration_contract.d.ts.map +1 -1
  340. package/dist/engine/main_path_integration_contract.js +43 -42
  341. package/dist/engine/main_path_integration_contract.js.map +1 -1
  342. package/dist/engine/mechanism_contract_registry.d.ts.map +1 -1
  343. package/dist/engine/mechanism_contract_registry.js +514 -17
  344. package/dist/engine/mechanism_contract_registry.js.map +1 -1
  345. package/dist/engine/metric_governance.d.ts +51 -0
  346. package/dist/engine/metric_governance.d.ts.map +1 -0
  347. package/dist/engine/metric_governance.js +138 -0
  348. package/dist/engine/metric_governance.js.map +1 -0
  349. package/dist/engine/migration_guard.d.ts.map +1 -1
  350. package/dist/engine/migration_guard.js +6 -5
  351. package/dist/engine/migration_guard.js.map +1 -1
  352. package/dist/engine/mutation_audit.d.ts.map +1 -1
  353. package/dist/engine/mutation_audit.js +6 -5
  354. package/dist/engine/mutation_audit.js.map +1 -1
  355. package/dist/engine/observability.d.ts +11 -0
  356. package/dist/engine/observability.d.ts.map +1 -1
  357. package/dist/engine/observability.js +60 -8
  358. package/dist/engine/observability.js.map +1 -1
  359. package/dist/engine/onboarding.d.ts.map +1 -1
  360. package/dist/engine/onboarding.js +17 -16
  361. package/dist/engine/onboarding.js.map +1 -1
  362. package/dist/engine/plan_proposal_gate.d.ts +131 -0
  363. package/dist/engine/plan_proposal_gate.d.ts.map +1 -0
  364. package/dist/engine/plan_proposal_gate.js +340 -0
  365. package/dist/engine/plan_proposal_gate.js.map +1 -0
  366. package/dist/engine/platform_context.d.ts +44 -0
  367. package/dist/engine/platform_context.d.ts.map +1 -0
  368. package/dist/engine/platform_context.js +169 -0
  369. package/dist/engine/platform_context.js.map +1 -0
  370. package/dist/engine/policy_drift_detector.d.ts.map +1 -1
  371. package/dist/engine/policy_drift_detector.js +8 -7
  372. package/dist/engine/policy_drift_detector.js.map +1 -1
  373. package/dist/engine/regression_matrix.d.ts.map +1 -1
  374. package/dist/engine/regression_matrix.js +15 -14
  375. package/dist/engine/regression_matrix.js.map +1 -1
  376. package/dist/engine/release_compatibility.d.ts +62 -0
  377. package/dist/engine/release_compatibility.d.ts.map +1 -0
  378. package/dist/engine/release_compatibility.js +145 -0
  379. package/dist/engine/release_compatibility.js.map +1 -0
  380. package/dist/engine/release_gate.d.ts +29 -0
  381. package/dist/engine/release_gate.d.ts.map +1 -0
  382. package/dist/engine/release_gate.js +675 -0
  383. package/dist/engine/release_gate.js.map +1 -0
  384. package/dist/engine/release_gate_scenario_registry.d.ts +65 -0
  385. package/dist/engine/release_gate_scenario_registry.d.ts.map +1 -0
  386. package/dist/engine/release_gate_scenario_registry.js +717 -0
  387. package/dist/engine/release_gate_scenario_registry.js.map +1 -0
  388. package/dist/engine/release_readiness_gate.d.ts +44 -0
  389. package/dist/engine/release_readiness_gate.d.ts.map +1 -0
  390. package/dist/engine/release_readiness_gate.js +1660 -0
  391. package/dist/engine/release_readiness_gate.js.map +1 -0
  392. package/dist/engine/risk_sampler.d.ts.map +1 -1
  393. package/dist/engine/risk_sampler.js +4 -3
  394. package/dist/engine/risk_sampler.js.map +1 -1
  395. package/dist/engine/runtime_safety.d.ts.map +1 -1
  396. package/dist/engine/runtime_safety.js +18 -17
  397. package/dist/engine/runtime_safety.js.map +1 -1
  398. package/dist/engine/scaffolder.d.ts.map +1 -1
  399. package/dist/engine/scaffolder.js +4 -3
  400. package/dist/engine/scaffolder.js.map +1 -1
  401. package/dist/engine/scope_lease.d.ts.map +1 -1
  402. package/dist/engine/scope_lease.js +4 -3
  403. package/dist/engine/scope_lease.js.map +1 -1
  404. package/dist/engine/semantic_evidence.d.ts.map +1 -1
  405. package/dist/engine/semantic_evidence.js +4 -3
  406. package/dist/engine/semantic_evidence.js.map +1 -1
  407. package/dist/engine/state_fact_classifier.d.ts +47 -0
  408. package/dist/engine/state_fact_classifier.d.ts.map +1 -0
  409. package/dist/engine/state_fact_classifier.js +158 -0
  410. package/dist/engine/state_fact_classifier.js.map +1 -0
  411. package/dist/engine/task_context.d.ts +34 -5
  412. package/dist/engine/task_context.d.ts.map +1 -1
  413. package/dist/engine/task_context.js +175 -49
  414. package/dist/engine/task_context.js.map +1 -1
  415. package/dist/engine/task_planner.d.ts.map +1 -1
  416. package/dist/engine/task_planner.js +6 -5
  417. package/dist/engine/task_planner.js.map +1 -1
  418. package/dist/engine/team_awareness.d.ts.map +1 -1
  419. package/dist/engine/team_awareness.js +2 -1
  420. package/dist/engine/team_awareness.js.map +1 -1
  421. package/dist/engine/technology_decision.d.ts +38 -0
  422. package/dist/engine/technology_decision.d.ts.map +1 -0
  423. package/dist/engine/technology_decision.js +120 -0
  424. package/dist/engine/technology_decision.js.map +1 -0
  425. package/dist/engine/template_manifest_io.d.ts +47 -0
  426. package/dist/engine/template_manifest_io.d.ts.map +1 -0
  427. package/dist/engine/template_manifest_io.js +151 -0
  428. package/dist/engine/template_manifest_io.js.map +1 -0
  429. package/dist/engine/template_mechanism_auditor.d.ts.map +1 -1
  430. package/dist/engine/template_mechanism_auditor.js +5 -4
  431. package/dist/engine/template_mechanism_auditor.js.map +1 -1
  432. package/dist/engine/template_sync.d.ts +98 -0
  433. package/dist/engine/template_sync.d.ts.map +1 -0
  434. package/dist/engine/template_sync.js +355 -0
  435. package/dist/engine/template_sync.js.map +1 -0
  436. package/dist/engine/test_generator.d.ts.map +1 -1
  437. package/dist/engine/test_generator.js +5 -4
  438. package/dist/engine/test_generator.js.map +1 -1
  439. package/dist/engine/test_quality.d.ts.map +1 -1
  440. package/dist/engine/test_quality.js +5 -4
  441. package/dist/engine/test_quality.js.map +1 -1
  442. package/dist/engine/tool_invocation_contract_registry.d.ts.map +1 -1
  443. package/dist/engine/tool_invocation_contract_registry.js +32 -31
  444. package/dist/engine/tool_invocation_contract_registry.js.map +1 -1
  445. package/dist/engine/traceability.d.ts.map +1 -1
  446. package/dist/engine/traceability.js +6 -5
  447. package/dist/engine/traceability.js.map +1 -1
  448. package/dist/engine/user_feedback_contract.d.ts.map +1 -1
  449. package/dist/engine/user_feedback_contract.js +81 -19
  450. package/dist/engine/user_feedback_contract.js.map +1 -1
  451. package/dist/engine/user_promise.d.ts +67 -0
  452. package/dist/engine/user_promise.d.ts.map +1 -0
  453. package/dist/engine/user_promise.js +436 -0
  454. package/dist/engine/user_promise.js.map +1 -0
  455. package/dist/engine/verifier.d.ts +6 -10
  456. package/dist/engine/verifier.d.ts.map +1 -1
  457. package/dist/engine/verifier.js +112 -1
  458. package/dist/engine/verifier.js.map +1 -1
  459. package/dist/engine/workflow_contract_registry.d.ts.map +1 -1
  460. package/dist/engine/workflow_contract_registry.js +128 -10
  461. package/dist/engine/workflow_contract_registry.js.map +1 -1
  462. package/dist/engine/workflow_template_pack.d.ts +71 -0
  463. package/dist/engine/workflow_template_pack.d.ts.map +1 -0
  464. package/dist/engine/workflow_template_pack.js +246 -0
  465. package/dist/engine/workflow_template_pack.js.map +1 -0
  466. package/dist/engine/workspace_resumer.d.ts.map +1 -1
  467. package/dist/engine/workspace_resumer.js +9 -8
  468. package/dist/engine/workspace_resumer.js.map +1 -1
  469. package/dist/engine/zero_config_init.d.ts.map +1 -1
  470. package/dist/engine/zero_config_init.js +16 -15
  471. package/dist/engine/zero_config_init.js.map +1 -1
  472. package/dist/git/operations.d.ts.map +1 -1
  473. package/dist/git/operations.js +18 -17
  474. package/dist/git/operations.js.map +1 -1
  475. package/dist/index.js +10 -9
  476. package/dist/index.js.map +1 -1
  477. package/dist/knowledge/conflict_detector.d.ts.map +1 -1
  478. package/dist/knowledge/conflict_detector.js +2 -1
  479. package/dist/knowledge/conflict_detector.js.map +1 -1
  480. package/dist/knowledge/health_checker.d.ts.map +1 -1
  481. package/dist/knowledge/health_checker.js +5 -4
  482. package/dist/knowledge/health_checker.js.map +1 -1
  483. package/dist/knowledge/index_manager.js +4 -4
  484. package/dist/knowledge/index_manager.js.map +1 -1
  485. package/dist/knowledge/loader.d.ts.map +1 -1
  486. package/dist/knowledge/loader.js +20 -14
  487. package/dist/knowledge/loader.js.map +1 -1
  488. package/dist/knowledge/writer.d.ts.map +1 -1
  489. package/dist/knowledge/writer.js +7 -6
  490. package/dist/knowledge/writer.js.map +1 -1
  491. package/dist/types.d.ts +40 -8
  492. package/dist/types.d.ts.map +1 -1
  493. package/package.json +14 -5
  494. package/templates/knowledge/acceptance_templates/API/346/216/245/345/217/243/350/247/204/346/240/274/346/226/207/346/241/243/346/250/241/347/211/210.md +74 -0
  495. package/templates/knowledge/acceptance_templates/Bug/345/210/206/346/236/220/346/250/241/347/211/210.md +27 -3
  496. package/templates/knowledge/acceptance_templates/POC/347/273/223/350/256/272/346/250/241/347/211/210.md +27 -3
  497. package/templates/knowledge/acceptance_templates//345/211/215/347/253/257/351/241/265/351/235/242/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -3
  498. package/templates/knowledge/acceptance_templates//345/216/237/345/236/213/350/257/264/346/230/216/346/250/241/347/211/210.md +31 -3
  499. package/templates/knowledge/acceptance_templates//345/220/216/347/253/257API/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -3
  500. package/templates/knowledge/acceptance_templates//345/256/211/345/205/250/345/256/241/350/256/241/346/250/241/347/211/210.md +27 -3
  501. package/templates/knowledge/acceptance_templates//346/200/247/350/203/275/345/210/206/346/236/220/346/250/241/347/211/210.md +27 -3
  502. package/templates/knowledge/acceptance_templates//346/212/200/346/234/257/351/200/211/345/236/213/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -3
  503. package/templates/knowledge/acceptance_templates//346/216/245/345/217/243/345/257/271/346/216/245/346/226/271/346/241/210/346/250/241/347/211/210.md +26 -3
  504. package/templates/knowledge/acceptance_templates//346/216/245/345/217/243/350/256/276/350/256/241/346/250/241/347/211/210.md +27 -3
  505. package/templates/knowledge/acceptance_templates//346/225/205/351/232/234/345/244/215/347/233/230/346/250/241/347/211/210.md +28 -3
  506. package/templates/knowledge/acceptance_templates//346/225/260/346/215/256/345/272/223/345/217/230/346/233/264/346/226/271/346/241/210/346/250/241/347/211/210.md +26 -3
  507. package/templates/knowledge/acceptance_templates//346/225/260/346/215/256/345/272/223/345/217/230/346/233/264/351/252/214/346/224/266/346/270/205/345/215/225.md +31 -3
  508. package/templates/knowledge/acceptance_templates//346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/346/226/207/346/241/243/346/250/241/347/211/210.md +59 -0
  509. package/templates/knowledge/acceptance_templates//346/236/266/346/236/204/350/256/276/350/256/241/346/250/241/347/211/210.md +54 -10
  510. package/templates/knowledge/acceptance_templates//346/265/213/350/257/225/350/256/241/345/210/222/346/250/241/347/211/210.md +27 -3
  511. package/templates/knowledge/acceptance_templates//350/256/276/350/256/241/344/270/200/350/207/264/346/200/247/351/252/214/346/224/266/346/212/245/345/221/212/346/250/241/347/211/210.md +47 -0
  512. package/templates/knowledge/acceptance_templates//350/257/246/347/273/206/350/256/276/350/256/241/346/250/241/347/211/210.md +26 -3
  513. package/templates/knowledge/acceptance_templates//350/277/201/347/247/273/350/257/204/344/274/260/346/250/241/347/211/210.md +27 -3
  514. package/templates/knowledge/acceptance_templates//351/200/232/347/224/250/350/264/250/351/207/217/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -3
  515. package/templates/knowledge/acceptance_templates//351/207/215/346/236/204/346/226/271/346/241/210/346/250/241/347/211/210.md +27 -3
  516. package/templates/knowledge/acceptance_templates//351/234/200/346/261/202/345/210/206/346/236/220/346/250/241/347/211/210.md +27 -3
  517. package/templates/knowledge/checklists//344/270/273/351/223/276/350/267/257/346/216/245/345/205/245/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -0
  518. package/templates/knowledge/checklists//344/274/232/350/257/235/346/201/242/345/244/215.md +30 -8
  519. package/templates/knowledge/checklists//345/267/245/344/275/234/346/265/201/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -0
  520. package/templates/knowledge/checklists//346/240/270/345/277/203/345/267/245/347/250/213/346/211/247/350/241/214/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -0
  521. package/templates/knowledge/checklists//347/237/245/350/257/206/346/263/250/345/205/245/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -0
  522. package/templates/knowledge/checklists//351/232/220/347/247/201/345/256/241/346/237/245/346/270/205/345/215/225.md +29 -0
  523. package/templates/knowledge/checklists//351/252/214/350/257/201/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -0
  524. package/templates/knowledge/domain//345/244/232/347/247/237/346/210/267.md +28 -3
  525. package/templates/knowledge/domain//345/256/241/350/256/241/346/227/245/345/277/227.md +27 -3
  526. package/templates/knowledge/domain//345/257/274/345/205/245/345/257/274/345/207/272/350/247/204/345/210/231.md +30 -3
  527. package/templates/knowledge/domain//345/267/245/344/275/234/346/265/201/345/274/225/346/223/216.md +32 -3
  528. package/templates/knowledge/domain//346/212/245/350/241/250/347/273/237/350/256/241.md +31 -3
  529. package/templates/knowledge/domain//346/224/257/344/273/230/350/247/204/345/210/231.md +31 -3
  530. package/templates/knowledge/domain//346/225/260/346/215/256/346/235/203/351/231/220.md +28 -3
  531. package/templates/knowledge/domain//351/200/232/347/224/250/346/234/272/346/242/260/346/235/241/346/254/276.md +30 -3
  532. package/templates/knowledge/domain//351/200/232/347/237/245/350/247/204/345/210/231.md +31 -3
  533. package/templates/knowledge/patterns/core/Diff/345/275/222/345/261/236/350/277/275/350/270/252.md +24 -7
  534. package/templates/knowledge/patterns/core/Java/350/264/250/351/207/217/351/227/250/347/246/201.md +25 -7
  535. package/templates/knowledge/patterns/core/LLM/351/242/204/347/256/227/347/275/221/345/205/263.md +24 -7
  536. package/templates/knowledge/patterns/core//344/273/273/345/212/241/344/270/212/344/270/213/346/226/207/347/224/237/345/221/275/345/221/250/346/234/237.md +24 -7
  537. package/templates/knowledge/patterns/core//344/273/273/345/212/241/347/256/241/347/220/206/345/231/250.md +25 -7
  538. package/templates/knowledge/patterns/core//344/275/234/347/224/250/345/237/237/344/270/216/345/257/206/351/222/245/346/213/246/346/210/252.md +24 -7
  539. package/templates/knowledge/patterns/core//344/275/234/347/224/250/345/237/237/347/247/237/347/272/246.md +25 -7
  540. package/templates/knowledge/patterns/core//345/206/262/347/252/201/351/227/250/347/246/201.md +24 -7
  541. package/templates/knowledge/patterns/core//345/206/263/347/255/226/347/275/221/345/205/263.md +26 -7
  542. package/templates/knowledge/patterns/core//345/217/230/345/274/202/345/256/241/350/256/241.md +25 -7
  543. package/templates/knowledge/patterns/core//345/233/236/345/275/222/347/237/251/351/230/265.md +24 -7
  544. package/templates/knowledge/patterns/core//345/267/245/344/275/234/345/214/272/344/272/222/346/226/245/351/224/201.md +24 -7
  545. package/templates/knowledge/patterns/core//345/267/245/344/275/234/345/214/272/345/224/244/351/206/222.md +24 -7
  546. package/templates/knowledge/patterns/core//345/271/266/345/217/221/351/224/201.md +26 -7
  547. package/templates/knowledge/patterns/core//345/274/200/345/217/221/350/200/205/345/256/252/346/263/225.md +26 -7
  548. package/templates/knowledge/patterns/core//346/225/217/346/204/237/344/277/241/346/201/257/346/211/253/346/217/217.md +24 -7
  549. package/templates/knowledge/patterns/core//346/262/273/347/220/206/350/277/220/350/241/214/346/227/266/345/276/252/347/216/257.md +25 -7
  550. package/templates/knowledge/patterns/core//346/265/201/345/274/217/345/277/203/350/267/263.md +25 -7
  551. package/templates/knowledge/patterns/core//347/237/245/350/257/206/344/270/273/346/235/203.md +25 -7
  552. package/templates/knowledge/patterns/core//350/257/255/344/271/211/350/257/201/346/215/256.md +24 -7
  553. package/templates/knowledge/patterns/core//350/277/220/350/241/214/345/256/211/345/205/250/345/214/205.md +25 -7
  554. package/templates/knowledge/patterns/core//351/233/266/351/205/215/347/275/256/345/210/235/345/247/213/345/214/226.md +24 -7
  555. package/templates/knowledge/patterns/core//351/252/214/350/257/201/345/221/275/344/273/244/347/224/237/346/210/220.md +24 -7
  556. package/templates/knowledge/procedures/Schema/345/217/230/346/233/264/346/265/201/346/260/264/347/272/277.md +29 -3
  557. package/templates/knowledge/procedures//344/270/273/351/223/276/350/267/257/346/216/245/345/205/245/351/252/214/350/257/201/346/265/201/347/250/213.md +33 -0
  558. package/templates/knowledge/procedures//344/273/243/347/240/201/351/227/250/347/246/201/346/265/201/347/250/213.md +30 -3
  559. package/templates/knowledge/procedures//344/273/273/345/212/241/346/213/206/350/247/243/346/265/201/347/250/213.md +30 -3
  560. package/templates/knowledge/procedures//345/212/237/350/203/275/345/274/200/345/217/221/346/265/201/347/250/213.md +30 -3
  561. package/templates/knowledge/procedures//345/221/275/344/273/244/346/211/247/350/241/214/346/265/201/347/250/213.md +34 -0
  562. package/templates/knowledge/procedures//345/256/211/345/205/250/345/212/240/345/233/272/346/265/201/346/260/264/347/272/277.md +30 -3
  563. package/templates/knowledge/procedures//345/267/245/345/205/267/350/260/203/347/224/250/346/265/201/347/250/213.md +34 -0
  564. package/templates/knowledge/procedures//346/200/247/350/203/275/346/265/201/346/260/264/347/272/277.md +30 -3
  565. package/templates/knowledge/procedures//346/204/217/345/233/276/350/267/257/347/224/261/346/265/201/347/250/213.md +34 -0
  566. package/templates/knowledge/procedures//346/216/245/345/217/243/351/233/206/346/210/220/346/265/201/346/260/264/347/272/277.md +30 -3
  567. package/templates/knowledge/procedures//346/225/260/346/215/256/345/272/223/350/277/201/347/247/273/346/265/201/347/250/213.md +29 -3
  568. package/templates/knowledge/procedures//346/234/254/345/234/260/346/265/217/350/247/210/345/231/250/351/252/214/346/224/266/345/267/245/344/275/234/346/265/201.md +99 -0
  569. package/templates/knowledge/procedures//346/236/266/346/236/204/345/206/263/347/255/226/347/240/224/350/256/250/345/267/245/344/275/234/346/265/201.md +51 -0
  570. package/templates/knowledge/procedures//346/236/266/346/236/204/350/256/276/350/256/241/345/267/245/344/275/234/346/265/201.md +104 -0
  571. package/templates/knowledge/procedures//346/236/266/346/236/204/350/256/276/350/256/241/346/265/201/347/250/213.md +30 -3
  572. package/templates/knowledge/procedures//346/246/202/345/277/265/351/252/214/350/257/201/346/265/201/346/260/264/347/272/277.md +30 -3
  573. package/templates/knowledge/procedures//346/265/213/350/257/225/344/274/230/345/205/210/347/274/226/347/240/201/345/267/245/344/275/234/346/265/201.md +91 -0
  574. package/templates/knowledge/procedures//346/272/220/347/240/201/345/216/237/345/236/213/344/272/244/344/273/230/346/265/201/347/250/213.md +30 -3
  575. package/templates/knowledge/procedures//347/216/260/346/234/211/347/263/273/347/273/237/345/267/256/350/267/235/345/210/206/346/236/220/345/267/245/344/275/234/346/265/201.md +97 -0
  576. package/templates/knowledge/procedures//347/237/245/350/257/206/347/273/264/346/212/244/346/265/201/346/260/264/347/272/277.md +30 -3
  577. package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +30 -3
  578. package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/347/250/213.md +30 -3
  579. package/templates/knowledge/procedures//347/274/226/347/240/201/345/211/215/346/276/204/346/270/205/346/265/201/347/250/213.md +33 -0
  580. package/templates/knowledge/procedures//347/274/272/351/231/267/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +30 -3
  581. package/templates/knowledge/procedures//350/207/252/344/270/273/351/200/211/345/236/213/346/265/201/347/250/213.md +30 -3
  582. package/templates/knowledge/procedures//350/256/276/350/256/241/344/272/247/347/211/251/347/224/237/346/210/220/344/270/216/345/244/215/351/252/214/345/267/245/344/275/234/346/265/201.md +45 -0
  583. package/templates/knowledge/procedures//350/257/246/347/273/206/350/256/276/350/256/241/346/265/201/347/250/213.md +30 -3
  584. package/templates/knowledge/procedures//350/260/203/350/257/225/346/216/222/346/237/245/346/265/201/347/250/213.md +30 -3
  585. package/templates/knowledge/procedures//350/277/201/347/247/273/346/265/201/346/260/264/347/272/277.md +30 -3
  586. package/templates/knowledge/procedures//351/203/250/347/275/262/345/217/221/345/270/203/346/265/201/347/250/213.md +30 -3
  587. package/templates/knowledge/procedures//351/207/215/346/236/204/346/265/201/346/260/264/347/272/277.md +30 -3
  588. package/templates/knowledge/procedures//351/233/206/346/210/220/351/252/214/350/257/201/346/265/201/347/250/213.md +30 -3
  589. package/templates/knowledge/procedures//351/234/200/346/261/202/346/276/204/346/270/205/346/265/201/347/250/213.md +30 -3
  590. package/templates/knowledge/procedures//351/252/214/346/224/266/346/265/213/350/257/225/350/247/204/345/210/222.md +30 -3
  591. package/templates/knowledge/procedures//351/252/214/350/257/201/350/256/241/345/210/222/346/265/201/347/250/213.md +30 -3
  592. package/templates/knowledge/review_rules//344/272/244/344/273/230/345/256/214/345/244/207/346/200/247/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  593. package/templates/knowledge/review_rules//345/256/211/345/205/250/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  594. package/templates/knowledge/review_rules//345/271/266/345/217/221/345/256/241/346/237/245/350/247/204/345/210/231.md +23 -3
  595. package/templates/knowledge/review_rules//346/200/247/350/203/275/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  596. package/templates/knowledge/review_rules//346/216/245/345/217/243/345/245/221/347/272/246/345/256/241/346/237/245/350/247/204/345/210/231.md +23 -3
  597. package/templates/knowledge/review_rules//346/236/266/346/236/204/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  598. package/templates/knowledge/review_rules//350/264/250/351/207/217/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  599. package/templates/knowledge/rules//344/272/247/347/211/251/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  600. package/templates/knowledge/rules//344/273/273/345/212/241/344/270/212/344/270/213/346/226/207/347/224/237/345/221/275/345/221/250/346/234/237/350/247/204/345/210/231.md +65 -0
  601. package/templates/knowledge/rules//345/221/275/344/273/244/346/211/247/350/241/214/350/247/204/345/210/231.md +36 -0
  602. package/templates/knowledge/rules//345/267/245/344/275/234/346/265/201/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  603. package/templates/knowledge/rules//345/267/245/344/275/234/346/265/201/346/250/241/346/235/277/345/214/205/350/247/204/345/210/231.md +48 -0
  604. package/templates/knowledge/rules//345/267/245/345/205/267/350/260/203/347/224/250/350/247/204/345/210/231.md +36 -0
  605. package/templates/knowledge/rules//346/204/217/345/233/276/350/267/257/347/224/261/350/247/204/345/210/231.md +36 -0
  606. package/templates/knowledge/rules//346/211/247/350/241/214/345/256/210/345/215/253/350/257/204/344/274/260/350/247/204/345/210/231.md +36 -0
  607. package/templates/knowledge/rules//346/211/251/345/261/225/347/224/237/345/221/275/345/221/250/346/234/237/350/247/204/345/210/231.md +48 -0
  608. package/templates/knowledge/rules//346/212/200/346/234/257/345/206/263/347/255/226/344/270/273/346/235/203/350/247/204/345/210/231.md +64 -0
  609. package/templates/knowledge/rules//346/225/217/346/204/237/344/277/241/346/201/257/345/244/204/347/220/206/350/247/204/345/210/231.md +36 -0
  610. package/templates/knowledge/rules//346/226/275/345/267/245/346/214/207/344/273/244/345/245/221/347/272/246/350/247/204/345/210/231.md +78 -0
  611. package/templates/knowledge/rules//346/236/266/346/236/204/345/206/263/347/255/226/347/240/224/350/256/250/350/247/204/345/210/231.md +49 -0
  612. package/templates/knowledge/rules//346/240/270/345/277/203/344/275/223/351/252/214/345/216/237/345/210/231.md +50 -0
  613. package/templates/knowledge/rules//346/240/270/345/277/203/345/267/245/347/250/213/346/211/247/350/241/214/345/216/237/345/210/231.md +35 -0
  614. package/templates/knowledge/rules//346/263/250/345/206/214/350/241/250/345/237/272/347/241/200/350/256/276/346/226/275/350/247/204/345/210/231.md +36 -0
  615. package/templates/knowledge/rules//346/274/224/350/277/233/345/233/236/345/275/222/350/247/204/345/210/231.md +51 -0
  616. package/templates/knowledge/rules//346/274/224/350/277/233/345/233/236/345/275/222/351/227/250/346/216/247/350/247/204/345/210/231.md +74 -0
  617. package/templates/knowledge/rules//347/224/250/346/210/267/345/217/215/351/246/210/345/245/221/347/272/246/350/247/204/345/210/231.md +35 -0
  618. package/templates/knowledge/rules//347/237/245/350/257/206/346/263/250/345/205/245/350/276/271/347/225/214/350/247/204/345/210/231.md +36 -0
  619. package/templates/knowledge/rules//347/237/245/350/257/206/350/265/204/344/272/247/346/262/273/347/220/206/350/247/204/345/210/231.md +61 -0
  620. package/templates/knowledge/rules//347/254/254/344/270/200/346/200/247/345/216/237/347/220/206/346/216/250/347/220/206/350/247/204/345/210/231.md +73 -0
  621. package/templates/knowledge/rules//347/273/206/350/212/202/347/272/252/345/276/213/350/247/204/345/210/231.md +67 -0
  622. package/templates/knowledge/rules//350/204/221/346/232/264/344/270/216/346/226/271/346/241/210/346/216/242/347/264/242/350/247/204/345/210/231.md +66 -0
  623. package/templates/knowledge/rules//350/256/241/345/210/222/345/211/215/347/275/256/351/227/250/350/247/204/345/210/231.md +59 -0
  624. package/templates/knowledge/rules//350/256/276/350/256/241/344/272/247/347/211/251/345/214/205/350/247/204/345/210/231.md +55 -0
  625. package/templates/knowledge/rules//350/257/201/346/215/256/351/251/261/345/212/250/344/270/216/345/217/215/345/271/273/350/247/211/350/247/204/345/210/231.md +75 -0
  626. package/templates/knowledge/rules//350/267/250/345/271/263/345/217/260/350/267/257/345/276/204/345/256/211/345/205/250/350/247/204/345/210/231.md +48 -0
  627. package/templates/knowledge/rules//350/276/223/345/205/245/346/235/220/346/226/231/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  628. package/templates/knowledge/rules//351/205/215/347/275/256/344/274/230/345/205/210/347/272/247/350/247/204/345/210/231.md +35 -0
  629. package/templates/knowledge/rules//351/230/262/345/255/244/345/262/233/345/256/236/347/216/260/350/247/204/345/210/231.md +36 -0
  630. package/templates/knowledge/rules//351/233/266/351/205/215/347/275/256/345/210/235/345/247/213/345/214/226/350/247/204/345/210/231.md +36 -0
  631. package/templates/knowledge/rules//351/252/214/350/257/201/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  632. package/templates/knowledge/templates//345/256/241/346/237/245/346/221/230/350/246/201.md +26 -7
  633. package/templates/patterns/API/350/256/276/350/256/241/350/247/204/350/214/203.md +30 -3
  634. package/templates/patterns/Docker/351/203/250/347/275/262/350/247/204/350/214/203.md +29 -3
  635. package/templates/patterns/Git/346/223/215/344/275/234/350/247/204/350/214/203.md +33 -3
  636. package/templates/patterns/N/345/212/2401/346/237/245/350/257/242/350/247/204/350/214/203.md +31 -3
  637. package/templates/patterns/React/345/210/227/350/241/250/350/241/250/346/240/274/350/247/204/350/214/203.md +30 -3
  638. package/templates/patterns/React/346/216/245/345/217/243/351/233/206/346/210/220/350/247/204/350/214/203.md +31 -3
  639. package/templates/patterns/React/347/212/266/346/200/201/347/256/241/347/220/206/350/247/204/350/214/203.md +31 -3
  640. package/templates/patterns/React/347/273/204/344/273/266/350/247/204/350/214/203.md +30 -3
  641. package/templates/patterns/React/350/241/250/345/215/225/350/247/204/350/214/203.md +30 -3
  642. package/templates/patterns/React/350/267/257/347/224/261/350/247/204/350/214/203.md +31 -3
  643. package/templates/patterns/Schema/345/205/274/345/256/271/350/247/204/350/214/203.md +30 -3
  644. package/templates/patterns/Vue/347/212/266/346/200/201/347/256/241/347/220/206/350/247/204/350/214/203.md +29 -3
  645. package/templates/patterns/Vue/347/273/204/344/273/266/350/247/204/350/214/203.md +33 -3
  646. package/templates/patterns/Vue/350/267/257/347/224/261/350/247/204/350/214/203.md +28 -3
  647. package/templates/patterns//344/272/213/344/273/266/351/251/261/345/212/250/350/247/204/350/214/203.md +32 -3
  648. package/templates/patterns//344/272/213/345/212/241/346/250/241/345/274/217/350/247/204/350/214/203.md +31 -3
  649. package/templates/patterns//344/274/230/351/233/205/345/201/234/346/234/272/350/247/204/350/214/203.md +31 -3
  650. package/templates/patterns//345/205/250/346/240/210/346/265/201/347/250/213/344/277/256/345/244/215.md +30 -3
  651. package/templates/patterns//345/210/206/351/241/265/346/237/245/350/257/242/350/247/204/350/214/203.md +34 -3
  652. package/templates/patterns//345/211/215/347/253/257/346/200/247/350/203/275/350/247/204/350/214/203.md +32 -3
  653. package/templates/patterns//345/221/275/345/220/215/350/247/204/350/214/203.md +30 -3
  654. package/templates/patterns//345/233/275/351/231/205/345/214/226/350/247/204/350/214/203.md +31 -3
  655. package/templates/patterns//345/242/236/345/210/240/346/224/271/346/237/245/350/247/204/350/214/203.md +31 -3
  656. package/templates/patterns//345/244/226/351/203/250/344/276/235/350/265/226/350/247/204/350/214/203.md +31 -3
  657. package/templates/patterns//345/245/221/347/272/246/345/205/274/345/256/271/350/247/204/350/214/203.md +28 -3
  658. package/templates/patterns//345/256/232/346/227/266/344/273/273/345/212/241/350/247/204/350/214/203.md +32 -3
  659. package/templates/patterns//345/256/236/346/227/266/346/216/250/351/200/201/350/247/204/350/214/203.md +31 -3
  660. package/templates/patterns//345/267/245/347/250/213/347/272/252/345/276/213.md +30 -3
  661. package/templates/patterns//345/271/266/345/217/221/346/216/247/345/210/266/350/247/204/350/214/203.md +34 -3
  662. package/templates/patterns//345/274/202/346/255/245/345/257/274/345/207/272/350/247/204/350/214/203.md +31 -3
  663. package/templates/patterns//346/216/245/345/217/243/345/245/221/347/272/246/350/247/204/350/214/203.md +29 -3
  664. package/templates/patterns//346/220/234/347/264/242/346/250/241/345/274/217/350/247/204/350/214/203.md +33 -3
  665. package/templates/patterns//346/225/260/346/215/256/351/232/220/347/247/201/350/247/204/350/214/203.md +34 -3
  666. package/templates/patterns//346/226/207/344/273/266/344/270/212/344/274/240/350/247/204/350/214/203.md +30 -3
  667. package/templates/patterns//346/227/240/351/232/234/347/242/215/350/247/204/350/214/203.md +30 -3
  668. package/templates/patterns//346/227/245/345/277/227/350/247/204/350/214/203.md +31 -3
  669. package/templates/patterns//346/235/203/351/231/220/350/256/244/350/257/201/350/247/204/350/214/203.md +34 -3
  670. package/templates/patterns//346/236/266/346/236/204/347/272/242/347/272/277.md +28 -3
  671. package/templates/patterns//346/265/213/350/257/225/350/264/250/351/207/217/350/247/204/350/214/203.md +30 -3
  672. package/templates/patterns//347/206/224/346/226/255/351/231/215/347/272/247/350/247/204/350/214/203.md +32 -3
  673. package/templates/patterns//347/212/266/346/200/201/346/265/201/350/275/254/350/247/204/350/214/203.md +29 -3
  674. package/templates/patterns//347/272/246/346/235/237/345/256/236/347/216/260/350/247/204/350/214/203.md +32 -3
  675. package/templates/patterns//347/274/223/345/255/230/347/255/226/347/225/245/350/247/204/350/214/203.md +31 -3
  676. package/templates/patterns//347/274/226/347/240/201/350/264/250/351/207/217/350/247/204/350/214/203.md +30 -3
  677. package/templates/patterns//347/274/272/351/231/267/347/256/241/347/220/206/350/247/204/350/214/203.md +29 -3
  678. package/templates/patterns//350/260/203/350/257/225/346/226/271/346/263/225/350/256/272.md +30 -3
  679. package/templates/patterns//350/276/223/345/205/245/346/240/241/351/252/214/350/247/204/350/214/203.md +31 -3
  680. package/templates/patterns//351/224/231/350/257/257/345/244/204/347/220/206/350/247/204/350/214/203.md +31 -3
  681. package/templates/patterns//351/224/231/350/257/257/350/276/271/347/225/214/350/247/204/350/214/203.md +33 -3
  682. package/templates/patterns//351/242/206/345/237/237/351/251/261/345/212/250/350/256/276/350/256/241/350/247/204/350/214/203.md +30 -3
  683. package/dist/engine/batch1_manifest.d.ts.map +0 -1
  684. package/dist/engine/batch1_manifest.js.map +0 -1
  685. package/dist/engine/batch1_scenario_registry.d.ts.map +0 -1
  686. package/dist/engine/batch1_scenario_registry.js.map +0 -1
  687. package/dist/engine/batch1_scenario_runners.d.ts.map +0 -1
  688. package/dist/engine/batch1_scenario_runners.js.map +0 -1
@@ -16,10 +16,11 @@ import { cmdConfigResolve, cmdConfigExplain, cmdConfigConfirm, cmdConfigUnset, l
16
16
  import { resolveCurrentProjectConfigReports, validateConfigPrecedence, } from "../engine/config_precedence_contract.js";
17
17
  import { isReadForbidden } from "../engine/privacy_secret_contract.js";
18
18
  import { routeIntent } from "../engine/intent_router.js";
19
- import { debugLog } from "../engine/debug_log.js";
19
+ import { debugLog, debug, userInfo, userWarn, userError, internalWarn, jsonSafeError, initLoggerFromEnv } from "../engine/logger.js";
20
20
  const command = process.argv[2];
21
21
  const args = process.argv.slice(3);
22
22
  async function main() {
23
+ initLoggerFromEnv();
23
24
  switch (command) {
24
25
  case "init":
25
26
  if (args.includes("--auto")) {
@@ -59,8 +60,38 @@ async function main() {
59
60
  case "audit-template-mechanisms":
60
61
  await cmdAuditTemplateMechanisms();
61
62
  break;
63
+ case "audit-design-artifacts":
64
+ await cmdAuditDesignArtifacts();
65
+ break;
66
+ case "upgrade-design-artifacts":
67
+ await cmdUpgradeDesignArtifacts();
68
+ break;
62
69
  case "validate-batch1":
63
- await cmdValidateBatch1();
70
+ userWarn("⚠️ validate-batch1 是历史施工命令,不代表正式发布通过。请使用 validate-release。");
71
+ await cmdValidateFoundation();
72
+ break;
73
+ case "validate-batch3":
74
+ userWarn("⚠️ validate-batch3 是历史施工命令,不代表正式发布通过。请使用 validate-release。");
75
+ await cmdValidateKnowledge();
76
+ break;
77
+ case "validate-batch5":
78
+ userWarn("⚠️ validate-batch5 是历史施工命令,不代表正式发布通过。请使用 validate-release。");
79
+ await cmdValidateReleaseGate();
80
+ break;
81
+ case "validate-release":
82
+ await cmdValidateReleaseGate();
83
+ break;
84
+ case "sync-templates":
85
+ await cmdSyncTemplates();
86
+ break;
87
+ case "sync-adapters":
88
+ await cmdSyncAdapters();
89
+ break;
90
+ case "migrate":
91
+ await cmdMigrate();
92
+ break;
93
+ case "validate-new-issue":
94
+ await cmdValidateNewIssue();
64
95
  break;
65
96
  case "generate-trae":
66
97
  await cmdGenerateTrae();
@@ -89,20 +120,23 @@ async function main() {
89
120
  await cmdConfigUnset();
90
121
  break;
91
122
  default:
92
- console.log("用法: soloforge config <resolve|explain|confirm|unset> [options]");
93
- console.log("");
94
- console.log(" resolve 解析配置字段优先级(只读,显示所有候选来源)");
95
- console.log(" explain 解释指定字段的来源和优先级(只读,中文输出)");
96
- console.log(" confirm 确认配置字段值(写入 config + evidence)");
97
- console.log(" unset 移除指定字段的确认配置和 evidence");
123
+ userInfo("用法: soloforge config <resolve|explain|confirm|unset> [options]");
124
+ userInfo("");
125
+ userInfo(" resolve 解析配置字段优先级(只读,显示所有候选来源)");
126
+ userInfo(" explain 解释指定字段的来源和优先级(只读,中文输出)");
127
+ userInfo(" confirm 确认配置字段值(写入 config + evidence)");
128
+ userInfo(" unset 移除指定字段的确认配置和 evidence");
98
129
  }
99
130
  break;
100
131
  }
101
132
  case "status":
102
133
  await cmdStatus();
103
134
  break;
135
+ case "cleanup":
136
+ await cmdCleanup();
137
+ break;
104
138
  default:
105
- console.log(`SoloForge CLI
139
+ userInfo(`SoloForge CLI
106
140
 
107
141
  用法: soloforge <命令>
108
142
 
@@ -121,17 +155,27 @@ async function main() {
121
155
  validate 验证项目配置和知识文件(config.yaml 可选,缺失时自动推断)
122
156
  validate-mechanisms 验证双层机制承载模型完整性(模板层 + 机制层)
123
157
  audit-template-mechanisms 扫描模板与机制注册表交叉校验(--json 输出完整报告,--changed-only 仅检查变更文件)
158
+ audit-design-artifacts 审计架构/数据库/API 设计产物包(只读,--json 输出报告)
159
+ upgrade-design-artifacts 生成存量设计资产升级计划(默认 dry-run,--apply --confirm 仅建立已归档迁移基线)
160
+ validate-release 验证发布门禁(契约、场景矩阵、消费 trace、双层机制、回归基线)
161
+ validate-batch1 [历史] 仅基础契约验证,不代表正式发布通过
162
+ validate-batch3 [历史] 仅知识模板验证,不代表正式发布通过
163
+ validate-batch5 [历史] 仅发布门禁验证,不代表正式发布通过
164
+ sync-templates 同步模板到项目(默认 dry-run,--apply 需 --confirm)
165
+ sync-adapters 同步适配器 Prompt(默认 dry-run,--apply 需 --confirm)
166
+ migrate 迁移项目 .soloforge/(默认 dry-run,--apply 需确认)
124
167
  version 显示 SoloForge 版本信息
125
168
  config resolve 解析配置字段优先级(只读)
126
169
  config explain 解释配置字段来源(只读,中文)
127
170
  config confirm <field> <value> 确认配置字段(写入 config + evidence)
128
171
  config unset <field> 移除确认配置
129
172
  status 显示当前项目的 SoloForge 状态
173
+ cleanup 清理过期任务和 evidence(默认 dry-run,--apply 执行实际清理)
130
174
  `);
131
175
  }
132
176
  }
133
177
  async function cmdInitAuto() {
134
- console.error("[soloForge] CLI: 执行 cmdInitAuto");
178
+ debug("CLI", "执行 cmdInitAuto");
135
179
  const dryRun = args.includes("--dry-run");
136
180
  const projectPathArg = getArgValue("--project-path");
137
181
  const projectPath = projectPathArg ? path.resolve(projectPathArg) : process.cwd();
@@ -142,50 +186,50 @@ async function cmdInitAuto() {
142
186
  // 层 3: 字段级 evidence
143
187
  const evidence = generateConfigEvidence(fp, draft, "auto");
144
188
  // 展示探测结果 + evidence
145
- console.log("\nSoloForge 自动配置探测结果:");
146
- console.log("=".repeat(50));
189
+ userInfo("\nSoloForge 自动配置探测结果:");
190
+ userInfo("=".repeat(50));
147
191
  for (const [key, field] of Object.entries(evidence.fields)) {
148
192
  const icon = field.confidence === "high" ? "✅" : field.confidence === "medium" ? "⚠️" : "❓";
149
193
  const valStr = typeof field.value === "object" ? JSON.stringify(field.value) : String(field.value);
150
- console.log(` ${icon} ${key}: ${valStr} (${field.confidence}, ${field.confidence_source})`);
151
- console.log(` 证据: ${field.evidence.join(", ")}`);
194
+ userInfo(` ${icon} ${key}: ${valStr} (${field.confidence}, ${field.confidence_source})`);
195
+ userInfo(` 证据: ${field.evidence.join(", ")}`);
152
196
  }
153
- console.log("=".repeat(50));
154
- console.log(`综合置信度: ${draft.confidence}`);
197
+ userInfo("=".repeat(50));
198
+ userInfo(`综合置信度: ${draft.confidence}`);
155
199
  if (draft.advisory_notes.length > 0) {
156
- console.log("建议:");
200
+ userInfo("建议:");
157
201
  for (const note of draft.advisory_notes) {
158
- console.log(` - ${note}`);
202
+ userInfo(` - ${note}`);
159
203
  }
160
204
  }
161
205
  // Schema 校验 (advisory)
162
206
  const validation = validateConfigDraft(draft);
163
207
  if (validation.warnings.length > 0) {
164
- console.log("\nschema 建议:");
208
+ userInfo("\nschema 建议:");
165
209
  for (const w of validation.warnings) {
166
- console.log(` ⚠️ ${w}`);
210
+ userInfo(` ⚠️ ${w}`);
167
211
  }
168
212
  }
169
213
  if (!validation.valid) {
170
- console.log("\nschema 错误:");
214
+ userInfo("\nschema 错误:");
171
215
  for (const e of validation.errors) {
172
- console.log(` ❌ ${e}`);
216
+ userInfo(` ❌ ${e}`);
173
217
  }
174
- console.log("\n配置校验失败,请手动运行 `soloforge init --interactive`。");
218
+ userInfo("\n配置校验失败,请手动运行 `soloforge init --interactive`。");
175
219
  return;
176
220
  }
177
221
  if (dryRun) {
178
- console.log("\n[dry-run] 不写入文件。使用不带 --dry-run 的命令执行写入。");
222
+ userInfo("\n[dry-run] 不写入文件。使用不带 --dry-run 的命令执行写入。");
179
223
  return;
180
224
  }
181
225
  // 写入门禁: 所有必要字段必须 high confidence + detected/user_declared/confirmed
182
226
  const gate = canAutoWrite(evidence);
183
227
  if (!gate.allowed) {
184
- console.log(`\n⚠️ 存在低/中置信度配置项,拒绝写入:`);
228
+ userInfo(`\n⚠️ 存在低/中置信度配置项,拒绝写入:`);
185
229
  for (const f of gate.blockedFields) {
186
- console.log(` - ${f}`);
230
+ userInfo(` - ${f}`);
187
231
  }
188
- console.log("请使用 `soloforge init --interactive` 或 `soloforge init --blueprint \"...\"` 生成配置。");
232
+ userInfo("请使用 `soloforge init --interactive` 或 `soloforge init --blueprint \"...\"` 生成配置。");
189
233
  return;
190
234
  }
191
235
  // 写入配置 + evidence
@@ -245,9 +289,9 @@ function writeConfigWithEvidence(projectPath, draft, evidence) {
245
289
  fss.writeFileSync(evidencePath, JSON.stringify(existing, null, 2), "utf-8");
246
290
  }
247
291
  catch (e) {
248
- console.error(`[soloForge] 更新 evidence 文件失败: ${e instanceof Error ? e.message : String(e)}`);
292
+ internalWarn("CLI", `更新 evidence 文件失败: ${e instanceof Error ? e.message : String(e)}`);
249
293
  }
250
- console.log(`\n✅ .soloforge/config.yaml + config.evidence.json created`);
294
+ userInfo(`\n✅ .soloforge/config.yaml + config.evidence.json created`);
251
295
  }
252
296
  function hashConfigValue(str) {
253
297
  return crypto.createHash("sha256").update(str).digest("hex").slice(0, 16);
@@ -261,18 +305,18 @@ function mapLegacySource(source) {
261
305
  }
262
306
  }
263
307
  async function cmdInitBlueprint() {
264
- console.error("[soloForge] CLI: 执行 cmdInitBlueprint");
308
+ debug("CLI", "执行 cmdInitBlueprint");
265
309
  const blueprintText = getArgValue("--blueprint");
266
310
  if (!blueprintText) {
267
- console.error("❌ --blueprint 需要提供描述文本,例如: soloforge init --blueprint \"Spring Boot + React 的 B2B 内部管理系统\"");
311
+ userError("❌ --blueprint 需要提供描述文本,例如: soloforge init --blueprint \"Spring Boot + React 的 B2B 内部管理系统\"");
268
312
  return;
269
313
  }
270
314
  const projectPathArg = getArgValue("--project-path");
271
315
  const projectPath = projectPathArg ? path.resolve(projectPathArg) : process.cwd();
272
316
  const parsed = parseBlueprint(blueprintText);
273
317
  if (!parsed.parsed) {
274
- console.log("⚠️ 无法从蓝图文本解析技术栈,请使用 --interactive。");
275
- console.log("支持的框架关键词: Spring Boot, Go, Rust, Gradle, React, Vue, Angular, Next.js, Nuxt");
318
+ userInfo("⚠️ 无法从蓝图文本解析技术栈,请使用 --interactive。");
319
+ userInfo("支持的框架关键词: Spring Boot, Go, Rust, Gradle, React, Vue, Angular, Next.js, Nuxt");
276
320
  return;
277
321
  }
278
322
  // 从解析的蓝图构建草稿
@@ -335,7 +379,7 @@ function blueprintFrontendCommands(framework) {
335
379
  }
336
380
  }
337
381
  async function cmdInit() {
338
- console.error("[soloForge] CLI: 执行 cmdInit");
382
+ debug("CLI", "执行 cmdInit");
339
383
  const interactive = args.includes("--interactive");
340
384
  const adapter = getArgValue("--adapter") || "claude-code";
341
385
  const projectPathArg = getArgValue("--project-path");
@@ -368,7 +412,7 @@ async function cmdInit() {
368
412
  writeConfigWithEvidence(projectPath, config.draft, config.evidence);
369
413
  }
370
414
  else if (!process.stdin.isTTY) {
371
- console.log("⚠️ interactive requires TTY. 请使用 --auto 或 --blueprint。");
415
+ userInfo("⚠️ interactive requires TTY. 请使用 --auto 或 --blueprint。");
372
416
  }
373
417
  }
374
418
  // 生成 .mcp.json(SoloForge + Playwright)
@@ -389,7 +433,7 @@ async function cmdInit() {
389
433
  },
390
434
  };
391
435
  fss.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
392
- console.log("✅ .mcp.json 已创建(soloforge + playwright)");
436
+ userInfo("✅ .mcp.json 已创建(soloforge + playwright)");
393
437
  }
394
438
  // 生成 hooks
395
439
  await cmdGenerateHooks(projectPath);
@@ -399,7 +443,7 @@ async function cmdInit() {
399
443
  // 生成 Trae IDE 配置
400
444
  if (adapter === "trae" || adapter === "all") {
401
445
  await cmdGenerateTraeInner(projectPath);
402
- console.log("💡 提示: 使用项目级 .trae/ 配置需在 Trae 中开启 beta flag");
446
+ userInfo("💡 提示: 使用项目级 .trae/ 配置需在 Trae 中开启 beta flag");
403
447
  }
404
448
  // 生成 Codex App 配置
405
449
  if (adapter === "codex" || adapter === "all") {
@@ -410,7 +454,7 @@ async function cmdInit() {
410
454
  await copyKnowledgeTemplates(projectPath);
411
455
  // 确保 .gitignore 包含必要条目
412
456
  ensureGitignore(projectPath);
413
- console.log(`\n✅ SoloForge 初始化完成 (适配器: ${adapter})。${adapter === "trae" ? "请打开 Trae IDE 开始使用。" :
457
+ userInfo(`\n✅ SoloForge 初始化完成 (适配器: ${adapter})。${adapter === "trae" ? "请打开 Trae IDE 开始使用。" :
414
458
  adapter === "codex" ? "请打开 Codex App 开始使用。" :
415
459
  adapter === "all" ? "可在 Claude Code、Trae IDE 或 Codex App 中使用。" :
416
460
  "请打开 Claude Code 开始使用。"}`);
@@ -421,14 +465,25 @@ async function copyGlobalPatterns(projectPath) {
421
465
  const templatesDir = path.resolve(import.meta.dirname, "..", "..", "templates", "patterns");
422
466
  if (fss.existsSync(templatesDir)) {
423
467
  const files = fss.readdirSync(templatesDir).filter((f) => f.endsWith(".md"));
468
+ let copiedCount = 0;
469
+ let skippedCount = 0;
424
470
  for (const f of files) {
425
471
  const src = path.join(templatesDir, f);
426
472
  const dest = path.join(globalDir, f);
427
473
  if (!fss.existsSync(dest)) {
428
474
  fss.copyFileSync(src, dest);
475
+ copiedCount++;
476
+ }
477
+ else {
478
+ skippedCount++;
429
479
  }
430
480
  }
431
- console.log(`✅ ${files.length} 个默认模板已复制到 ~/.soloforge/patterns/`);
481
+ const parts = [];
482
+ if (copiedCount > 0)
483
+ parts.push(`新增 ${copiedCount} 个`);
484
+ if (skippedCount > 0)
485
+ parts.push(`跳过 ${skippedCount} 个(已存在)`);
486
+ userInfo(`✅ 全局模板 ~/.soloforge/patterns/: ${parts.length > 0 ? parts.join(",") : `${files.length} 个(已全部存在)`}`);
432
487
  }
433
488
  }
434
489
  async function copyKnowledgeTemplates(projectPath) {
@@ -453,7 +508,7 @@ async function copyKnowledgeTemplates(projectPath) {
453
508
  }
454
509
  }
455
510
  if (copiedCount > 0) {
456
- console.log(`✅ ${copiedCount} 个知识模板已复制到 .soloforge/knowledge/`);
511
+ userInfo(`✅ ${copiedCount} 个知识模板已复制到 .soloforge/knowledge/`);
457
512
  }
458
513
  }
459
514
  }
@@ -468,7 +523,7 @@ async function generateAdapterConfigs(projectPath, adapter) {
468
523
  },
469
524
  };
470
525
  fss.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
471
- console.log("✅ .mcp.json 已创建(soloforge + playwright)");
526
+ userInfo("✅ .mcp.json 已创建(soloforge + playwright)");
472
527
  }
473
528
  await cmdGenerateHooks(projectPath);
474
529
  await cmdGenerateClaudeMdInner(projectPath);
@@ -486,7 +541,7 @@ function ensureGitignore(projectPath) {
486
541
  if (missing.length > 0) {
487
542
  const addition = (content.endsWith("\n") ? "" : "\n") + missing.join("\n") + "\n";
488
543
  fss.appendFileSync(gitignorePath, addition, "utf-8");
489
- console.log(`✅ .gitignore 已更新: ${missing.join(", ")}`);
544
+ userInfo(`✅ .gitignore 已更新: ${missing.join(", ")}`);
490
545
  }
491
546
  }
492
547
  async function cmdGenerateHooks(projectPath) {
@@ -507,7 +562,7 @@ async function cmdGenerateHooks(projectPath) {
507
562
  // 仅 merge hooks 字段,保留用户的 permissions/env 等设置
508
563
  existing.hooks = hooksConfig.hooks;
509
564
  fss.writeFileSync(settingsPath, JSON.stringify(existing, null, 2), "utf-8");
510
- console.log("✅ .claude/settings.json 已更新 hooks 配置");
565
+ userInfo("✅ .claude/settings.json 已更新 hooks 配置");
511
566
  }
512
567
  async function cmdGenerateClaudeMd() {
513
568
  await cmdGenerateClaudeMdInner(process.cwd());
@@ -524,16 +579,16 @@ async function cmdGenerateCodexInner(projectPath) {
524
579
  fss.mkdirSync(codexDir, { recursive: true });
525
580
  const tomlContent = generateCodexMcpConfig(projectPath);
526
581
  fss.writeFileSync(path.join(codexDir, "config.toml"), tomlContent, "utf-8");
527
- console.log("✅ .codex/config.toml 已创建");
582
+ userInfo("✅ .codex/config.toml 已创建");
528
583
  // 生成 .codex/hooks.json
529
584
  const hooksContent = generateCodexHooksConfig();
530
585
  fss.writeFileSync(path.join(codexDir, "hooks.json"), hooksContent, "utf-8");
531
- console.log("✅ .codex/hooks.json 已创建");
586
+ userInfo("✅ .codex/hooks.json 已创建");
532
587
  // 生成 AGENTS.md
533
588
  const { config } = await resolveProjectConfig(projectPath);
534
589
  const agentsContent = generateCodexAgentsMd(config);
535
590
  fss.writeFileSync(path.join(projectPath, "AGENTS.md"), agentsContent, "utf-8");
536
- console.log("✅ AGENTS.md 已创建");
591
+ userInfo("✅ AGENTS.md 已创建");
537
592
  }
538
593
  async function cmdGenerateTraeInner(projectPath) {
539
594
  // 生成 .trae/mcp.json
@@ -542,20 +597,20 @@ async function cmdGenerateTraeInner(projectPath) {
542
597
  const traeMcpPath = path.join(traeDir, "mcp.json");
543
598
  const traeMcpConfig = generateTraeMcpConfig(projectPath);
544
599
  fss.writeFileSync(traeMcpPath, JSON.stringify(traeMcpConfig, null, 2), "utf-8");
545
- console.log("✅ .trae/mcp.json created");
600
+ userInfo("✅ .trae/mcp.json created");
546
601
  // 生成 .trae/rules/project_rules.md
547
602
  const rulesDir = path.join(traeDir, "rules");
548
603
  fss.mkdirSync(rulesDir, { recursive: true });
549
604
  const { config } = await resolveProjectConfig(projectPath);
550
605
  const rulesContent = generateTraeRules(config);
551
606
  fss.writeFileSync(path.join(rulesDir, "project_rules.md"), rulesContent, "utf-8");
552
- console.log("✅ .trae/rules/project_rules.md created");
607
+ userInfo("✅ .trae/rules/project_rules.md created");
553
608
  }
554
609
  async function cmdGenerateClaudeMdInner(projectPath) {
555
610
  const { config } = await resolveProjectConfig(projectPath);
556
611
  const content = generateClaudeMd(config);
557
612
  fss.writeFileSync(path.join(projectPath, "CLAUDE.md"), content, "utf-8");
558
- console.log("✅ CLAUDE.md created");
613
+ userInfo("✅ CLAUDE.md created");
559
614
  }
560
615
  async function cmdCheckWrite() {
561
616
  debugLog("CLI: 执行 cmdCheckWrite");
@@ -591,16 +646,24 @@ async function cmdCheckWrite() {
591
646
  }
592
647
  // 加载配置
593
648
  const projectPath = resolveProjectPath();
594
- const { config } = await resolveProjectConfig(projectPath);
649
+ const { config, source } = await resolveProjectConfig(projectPath);
595
650
  // 从配置中收集所有允许路径
596
- const allowedPaths = [
651
+ let allowedPaths = [
597
652
  ...(config.scope.backend || []),
598
653
  ...(config.scope.frontend || []),
599
654
  ...config.repos.flatMap((r) => r.scope || []),
600
655
  ].map((p) => path.resolve(projectPath, p));
656
+ if (source === "inferred" || allowedPaths.length === 0) {
657
+ allowedPaths = [...new Set([...allowedPaths, projectPath])];
658
+ }
601
659
  // 使用 scope_controller 统一检查
602
660
  const { checkScope } = await import("../engine/scope_controller.js");
603
- const result = checkScope(filePath, allowedPaths, content || undefined);
661
+ const rawTargetFilePath = path.isAbsolute(filePath) ? filePath : path.resolve(projectPath, filePath);
662
+ const projectRealPath = fss.realpathSync(projectPath);
663
+ const targetFilePath = rawTargetFilePath === projectPath || rawTargetFilePath.startsWith(projectPath + path.sep)
664
+ ? path.join(projectRealPath, path.relative(projectPath, rawTargetFilePath))
665
+ : rawTargetFilePath;
666
+ const result = checkScope(targetFilePath, allowedPaths, content || undefined);
604
667
  // 隐私/秘密契约:禁止读取的模式
605
668
  if (isReadForbidden(filePath)) {
606
669
  process.stdout.write(JSON.stringify({
@@ -624,12 +687,37 @@ async function cmdCheckWrite() {
624
687
  process.exit(0);
625
688
  }
626
689
  if (result.severity === "warning") {
627
- console.error(JSON.stringify(result));
690
+ jsonSafeError(JSON.stringify(result));
691
+ }
692
+ // 问题六十二: Claude Code 直接 Edit/Write 也必须遵守设计产物就绪门。
693
+ // 设计资产本身允许继续修订;非设计文件在产物包复验通过前禁止写入。
694
+ const relativeFilePath = path.relative(projectRealPath, targetFilePath).replaceAll(path.sep, "/");
695
+ const isDesignArtifactFile = /^docs\/architecture\//.test(relativeFilePath) ||
696
+ /^docs\/api\/openapi\.(?:ya?ml|json)$/.test(relativeFilePath) ||
697
+ /^db\/(?:migrations|schema)\//.test(relativeFilePath);
698
+ if (!isDesignArtifactFile) {
699
+ const { TaskContextManager } = await import("../engine/task_context.js");
700
+ const stateDir = path.join(projectPath, ".soloforge", "state");
701
+ if (fss.existsSync(stateDir)) {
702
+ const manager = new TaskContextManager(stateDir);
703
+ const currentTask = await manager.getCurrentTask();
704
+ const designPack = currentTask?.design_artifact_pack;
705
+ if (designPack && designPack.status !== "implementation_ready") {
706
+ process.stdout.write(JSON.stringify({
707
+ hookSpecificOutput: {
708
+ hookEventName: "PreToolUse",
709
+ permissionDecision: "deny",
710
+ permissionDecisionReason: `设计产物包状态为 ${designPack.status},请先完善 docs/architecture、docs/api/openapi 或 db/migrations|schema 并通过复验,再写入业务实现`,
711
+ },
712
+ }));
713
+ process.exit(0);
714
+ }
715
+ }
628
716
  }
629
717
  process.exit(0); // 允许
630
718
  }
631
719
  catch (e) {
632
- console.error(`SoloForge 写入检查错误: ${e instanceof Error ? e.message : String(e)}`);
720
+ userError(`SoloForge 写入检查错误: ${e instanceof Error ? e.message : String(e)}`);
633
721
  process.exit(1);
634
722
  }
635
723
  }
@@ -639,16 +727,20 @@ function resolveProjectPath() {
639
727
  try {
640
728
  const stat = fss.statSync(envPath);
641
729
  if (!stat.isDirectory()) {
642
- console.error(`⚠️ SOLOFORGE_PROJECT (${envPath}) 不是目录,回退到 cwd`);
730
+ userWarn(`⚠️ SOLOFORGE_PROJECT (${envPath}) 不是目录,回退到 cwd`);
643
731
  return process.cwd();
644
732
  }
645
733
  return envPath;
646
734
  }
647
735
  catch {
648
- console.error(`⚠️ SOLOFORGE_PROJECT (${envPath}) 路径不存在,回退到 cwd`);
736
+ userWarn(`⚠️ SOLOFORGE_PROJECT (${envPath}) 路径不存在,回退到 cwd`);
649
737
  return process.cwd();
650
738
  }
651
739
  }
740
+ const projectPathArg = getArgValue("--project-path");
741
+ if (projectPathArg) {
742
+ return path.resolve(projectPathArg);
743
+ }
652
744
  return process.cwd();
653
745
  }
654
746
  async function cmdPostBash() {
@@ -699,12 +791,12 @@ async function cmdPrePrompt() {
699
791
  }
700
792
  }
701
793
  catch (e) {
702
- console.error("[soloForge] pre-prompt hook 错误:", e);
794
+ internalWarn("CLI", "pre-prompt hook 错误:", e);
703
795
  }
704
796
  process.exit(0);
705
797
  }
706
798
  async function checkEvidenceWarnings(projectPath) {
707
- console.error("[soloForge] CLI: 执行 checkEvidenceWarnings — " + projectPath);
799
+ debug("CLI", "执行 checkEvidenceWarnings —", projectPath);
708
800
  const warnings = [];
709
801
  const configPath = path.join(projectPath, ".soloforge", "config.yaml");
710
802
  const evidencePath = path.join(projectPath, ".soloforge", "config.evidence.json");
@@ -773,16 +865,16 @@ function getConfigFieldValue(config, key) {
773
865
  return obj;
774
866
  }
775
867
  async function cmdValidate() {
776
- console.error("[soloForge] CLI: 执行 cmdValidate");
777
- const projectPath = process.cwd();
868
+ debug("CLI", "执行 cmdValidate");
869
+ const projectPath = resolveProjectPath();
778
870
  try {
779
871
  const { config, source } = await resolveProjectConfig(projectPath);
780
872
  if (source === "inferred") {
781
- console.log("ℹ️ 未找到 .soloforge/config.yaml — 使用自动推断的配置。");
782
- console.log(" 运行 'soloforge init --auto' 可持久化。");
873
+ userInfo("ℹ️ 未找到 .soloforge/config.yaml — 使用自动推断的配置。");
874
+ userInfo(" 运行 'soloforge init --auto' 可持久化。");
783
875
  }
784
876
  else {
785
- console.log("✅ config.yaml 有效");
877
+ userInfo("✅ config.yaml 有效");
786
878
  }
787
879
  // 使用共享函数验证配置优先级
788
880
  let hasHardFail = false;
@@ -793,43 +885,122 @@ async function cmdValidate() {
793
885
  const advisory = findings.filter(f => f.severity === "advisory");
794
886
  if (hardFails.length > 0) {
795
887
  hasHardFail = true;
796
- console.log(`❌ 配置优先级: ${hardFails.length} hard_fail`);
888
+ userInfo(`❌ 配置优先级: ${hardFails.length} hard_fail`);
797
889
  for (const f of hardFails) {
798
- console.log(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
890
+ userInfo(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
799
891
  }
800
892
  }
801
893
  if (advisory.length > 0) {
802
- console.log(`⚠️ 配置优先级: ${advisory.length} advisory`);
894
+ userInfo(`⚠️ 配置优先级: ${advisory.length} advisory`);
803
895
  for (const f of advisory) {
804
- console.log(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
896
+ userInfo(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
805
897
  }
806
898
  }
807
899
  if (hardFails.length === 0 && advisory.length === 0) {
808
- console.log("✅ 配置优先级验证通过");
900
+ userInfo("✅ 配置优先级验证通过");
809
901
  }
810
902
  }
811
903
  catch { }
812
904
  // Evidence 检查
813
905
  const evidenceWarnings = await checkEvidenceWarnings(projectPath);
814
906
  for (const w of evidenceWarnings) {
815
- console.log(`⚠️ evidence: ${w}`);
907
+ userInfo(`⚠️ evidence: ${w}`);
816
908
  }
817
909
  // 检查知识文件
818
910
  const knowledgeDir = getProjectKnowledgeDir(config);
819
911
  if (fss.existsSync(knowledgeDir)) {
820
912
  const { KnowledgeIndexManager } = await import("../knowledge/index_manager.js");
821
- const index = new KnowledgeIndexManager(config);
822
- await index.build();
823
- const entries = index.getAllEntries();
824
- console.log(`✅ ${entries.project.length} 条项目知识已索引`);
825
- const issues = await index.checkHealth();
826
- if (issues.length > 0) {
827
- console.log(`⚠️ ${issues.length} 个健康问题:`);
828
- for (const { entry, issue } of issues) {
829
- console.log(` - ${entry.name}: ${issue}`);
913
+ const index = new KnowledgeIndexManager(config, { watch: false });
914
+ try {
915
+ await index.build();
916
+ const entries = index.getAllEntries();
917
+ userInfo(`✅ ${entries.project.length} 条项目知识已索引`);
918
+ const issues = await index.checkHealth();
919
+ if (issues.length > 0) {
920
+ userInfo(`⚠️ ${issues.length} 个健康问题:`);
921
+ for (const { entry, issue } of issues) {
922
+ userInfo(` - ${entry.name}: ${issue}`);
923
+ }
924
+ }
925
+ }
926
+ finally {
927
+ await index.close();
928
+ }
929
+ }
930
+ // 扩展清单校验 (problem-39: validateExtensionManifest)
931
+ try {
932
+ const { validateExtensionManifest } = await import("../engine/extension_contract.js");
933
+ const extResult = validateExtensionManifest({ extension_id: "soloforge-cli-validate", name: "SoloForge CLI 验证", version: "1.0.0", provider: "soloforge", extension_type: "workflow", contract_ids: [], capability_ids: [], permissions: ["read_project"], entrypoints: [], outputs: [], default_state: "disabled", compatibility: { min_soloforge_version: "1.0.0" } }, { extension_id: "soloforge-cli-validate", claimed_capabilities: [], claimed_enforcement: "advisory", third_party: false });
934
+ if (extResult.violations.length > 0) {
935
+ userInfo(" ✗ 扩展清单校验失败:");
936
+ for (const v of extResult.violations)
937
+ userInfo(` - ${v}`);
938
+ hasHardFail = true;
939
+ }
940
+ else {
941
+ userInfo(" ✓ 扩展清单校验通过");
942
+ }
943
+ }
944
+ catch (e) {
945
+ userInfo(` ⚠ 扩展清单校验异常: ${e instanceof Error ? e.message : String(e)}`);
946
+ }
947
+ // 平台兼容性检查 (problem-40: normalizePathRef via generatePlatformReport)
948
+ try {
949
+ const { generatePlatformReport } = await import("../engine/platform_context.js");
950
+ const platform = {
951
+ os: process.platform,
952
+ arch: process.arch,
953
+ shell: (process.env.SHELL?.includes("zsh") ? "zsh" : process.env.SHELL?.includes("fish") ? "fish" : "bash"),
954
+ path_case_sensitive: process.platform !== "darwin" && process.platform !== "win32",
955
+ path_separator: process.platform === "win32" ? "\\" : "/",
956
+ line_ending: process.platform === "win32" ? "crlf" : "lf",
957
+ supports_symlink: process.platform !== "win32",
958
+ workspace_realpath: projectPath,
959
+ };
960
+ const platformReport = generatePlatformReport(platform, ["package.json", "tsconfig.json"], process.cwd());
961
+ if (platformReport.platform_compatibility_status === "blocked") {
962
+ userInfo(` ✗ 平台兼容性阻断: ${platformReport.issues_found.join(", ")}`);
963
+ hasHardFail = true;
964
+ }
965
+ else {
966
+ userInfo(` ✓ 平台兼容性检查: ${platformReport.platform_compatibility_status}`);
967
+ }
968
+ }
969
+ catch (e) {
970
+ userInfo(` ⚠ 平台兼容性检查异常: ${e instanceof Error ? e.message : String(e)}`);
971
+ }
972
+ // README 命令漂移检测 (problem-30: detectReadmeDrift via validateUserPromise)
973
+ try {
974
+ const { validateUserPromise, getCliCommandContracts } = await import("../engine/user_promise.js");
975
+ const { extractReadmeCommands } = await import("../engine/knowledge_scenario_registry.js");
976
+ const fs = await import("node:fs");
977
+ const pathMod = await import("node:path");
978
+ const readmePath = pathMod.join(projectPath, "README.md");
979
+ if (fs.existsSync(readmePath)) {
980
+ const readmeContent = fs.readFileSync(readmePath, "utf-8");
981
+ const readmeCommands = extractReadmeCommands(readmeContent);
982
+ const promiseResult = validateUserPromise(readmeCommands, getCliCommandContracts());
983
+ const hardFails = promiseResult.findings.filter(f => f.severity === "hard_fail");
984
+ const warnings = promiseResult.findings.filter(f => f.severity === "warning");
985
+ if (hardFails.length > 0) {
986
+ userInfo(" ✗ README 命令漂移:");
987
+ for (const hf of hardFails)
988
+ userInfo(` - ${hf.message_zh}`);
989
+ hasHardFail = true;
990
+ }
991
+ else if (warnings.length > 0) {
992
+ userInfo(" ⚠ README 命令漂移警告:");
993
+ for (const w of warnings)
994
+ userInfo(` - ${w.message_zh}`);
995
+ }
996
+ else {
997
+ userInfo(" ✓ README 命令一致性检查通过");
830
998
  }
831
999
  }
832
1000
  }
1001
+ catch (e) {
1002
+ userInfo(` ⚠ README 命令漂移检测异常: ${e instanceof Error ? e.message : String(e)}`);
1003
+ }
833
1004
  // 双层机制验证 (仅限 SoloForge 自身源码目录)
834
1005
  if (fss.existsSync(path.join(projectPath, "src", "engine", "dual_layer_mechanism_registry.ts"))) {
835
1006
  const { validateMechanismLayerMaps } = await import("../engine/dual_layer_mechanism_registry.js");
@@ -837,29 +1008,78 @@ async function cmdValidate() {
837
1008
  const dlHard = dlFindings.filter((f) => f.severity === "hard_fail");
838
1009
  const dlAdvisory = dlFindings.filter((f) => f.severity === "advisory");
839
1010
  if (dlHard.length > 0) {
840
- console.log(`❌ 双层机制验证: ${dlHard.length} hard_fail`);
1011
+ userInfo(`❌ 双层机制验证: ${dlHard.length} hard_fail`);
841
1012
  for (const f of dlHard) {
842
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1013
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
843
1014
  }
844
- console.error(`❌ validate 失败: 双层机制存在 ${dlHard.length} hard_fail`);
1015
+ userError(`❌ validate 失败: 双层机制存在 ${dlHard.length} hard_fail`);
845
1016
  process.exit(1);
846
1017
  }
847
1018
  else {
848
- console.log(`✅ 双层机制验证: ${dlAdvisory.length} advisory, 0 hard_fail`);
1019
+ userInfo(`✅ 双层机制验证: ${dlAdvisory.length} advisory, 0 hard_fail`);
1020
+ }
1021
+ // problem-34: 测试策略覆盖验证 — 从 contract_registry 真实元数据构建
1022
+ try {
1023
+ const { validateTestStrategy } = await import("../engine/test_strategy.js");
1024
+ const { getAllContracts } = await import("../engine/contract_registry.js");
1025
+ const enforcedContracts = getAllContracts().filter((c) => c.state === "enforced");
1026
+ let tsHardFail = false;
1027
+ let tsChecked = 0;
1028
+ let tsPending = 0;
1029
+ for (const c of enforcedContracts) {
1030
+ const hasTests = c.test_files && c.test_files.length > 0;
1031
+ const hasLifecycle = c.lifecycle_test_files && c.lifecycle_test_files.length > 0;
1032
+ if (!hasTests) {
1033
+ // enforced 契约无测试文件元数据 → hard_fail,不得用 required_test_types:[] 掩盖
1034
+ userInfo(`❌ 测试策略: ${c.contract_id} — enforced 契约缺少 test_files 元数据,无法验证覆盖`);
1035
+ tsHardFail = true;
1036
+ tsPending++;
1037
+ continue;
1038
+ }
1039
+ const coverage = {
1040
+ contract_id: c.contract_id,
1041
+ required_test_types: ["unit"],
1042
+ coverage_status: hasLifecycle ? "satisfied" : "partial",
1043
+ satisfied_types: ["unit"],
1044
+ missing_types: hasLifecycle ? [] : ["lifecycle"],
1045
+ test_files: c.test_files || [],
1046
+ has_lifecycle_test: hasLifecycle,
1047
+ has_must_fail_case: false,
1048
+ };
1049
+ const tsErrors = validateTestStrategy(c.contract_id, true, coverage);
1050
+ tsChecked++;
1051
+ for (const e of tsErrors) {
1052
+ if (e.severity === "hard_fail") {
1053
+ tsHardFail = true;
1054
+ userInfo(`❌ 测试策略: ${c.contract_id} — ${e.error}`);
1055
+ }
1056
+ }
1057
+ }
1058
+ if (tsHardFail) {
1059
+ userError(`❌ 测试策略覆盖验证失败: ${tsChecked} 个已检查, ${tsPending} 个元数据缺失`);
1060
+ hasHardFail = true;
1061
+ }
1062
+ else {
1063
+ userInfo(`✅ 测试策略覆盖: 已检查 ${tsChecked} 个 enforced 契约`);
1064
+ }
1065
+ }
1066
+ catch (e) {
1067
+ userError(`❌ 测试策略验证异常: ${e.message}`);
1068
+ hasHardFail = true;
849
1069
  }
850
1070
  } // 双层机制检查结束
851
1071
  if (hasHardFail) {
852
- console.error("❌ validate 失败: 配置优先级存在 hard_fail");
1072
+ userError("❌ validate 失败: 配置优先级存在 hard_fail");
853
1073
  process.exit(1);
854
1074
  }
855
1075
  }
856
1076
  catch (e) {
857
- console.error(`❌ 验证失败: ${e.message}`);
1077
+ userError(`❌ 验证失败: ${e.message}`);
858
1078
  process.exit(1);
859
1079
  }
860
1080
  }
861
1081
  async function cmdValidateMechanisms() {
862
- console.error("[soloForge] CLI: 执行 cmdValidateMechanisms");
1082
+ debug("CLI", "执行 cmdValidateMechanisms");
863
1083
  // 从编译后的二进制位置推导根目录: dist/bin/soloforge.js -> 项目根
864
1084
  const soloforgeRoot = path.resolve(import.meta.dirname, "..", "..");
865
1085
  const projectPath = fss.existsSync(path.join(soloforgeRoot, "src", "engine"))
@@ -871,47 +1091,68 @@ async function cmdValidateMechanisms() {
871
1091
  const hardFails = findings.filter((f) => f.severity === "hard_fail");
872
1092
  const advisory = findings.filter((f) => f.severity === "advisory");
873
1093
  if (findings.length === 0) {
874
- console.log("✅ 所有双层机制映射验证通过,无发现。");
1094
+ userInfo("✅ 所有双层机制映射验证通过,无发现。");
875
1095
  process.exit(0);
876
1096
  return;
877
1097
  }
878
1098
  if (advisory.length > 0) {
879
- console.log(`⚠️ advisory findings (${advisory.length}):`);
1099
+ userInfo(`⚠️ advisory findings (${advisory.length}):`);
880
1100
  for (const f of advisory) {
881
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1101
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
882
1102
  }
883
1103
  }
884
1104
  if (hardFails.length > 0) {
885
- console.log(`❌ hard_fail findings (${hardFails.length}):`);
1105
+ userInfo(`❌ hard_fail findings (${hardFails.length}):`);
886
1106
  for (const f of hardFails) {
887
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1107
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1108
+ }
1109
+ userInfo(`\n❌ 双层机制验证失败: ${hardFails.length} hard_fail`);
1110
+ process.exit(1);
1111
+ }
1112
+ userInfo(`\n✅ 双层机制验证通过,${advisory.length} advisory findings`);
1113
+ // problem-15: 机制族实现一致性验证
1114
+ try {
1115
+ const { validateMechanismFamilies } = await import("../engine/mechanism_family_registry.js");
1116
+ const familyFindings = validateMechanismFamilies();
1117
+ const familyHardFails = familyFindings.filter((f) => f.severity === "hard_fail");
1118
+ if (familyHardFails.length > 0) {
1119
+ userInfo(`\n❌ 机制族验证失败 (${familyHardFails.length} hard_fail):`);
1120
+ for (const f of familyHardFails)
1121
+ userInfo(` - ${f.mechanism_id}: ${f.message_zh}`);
1122
+ process.exit(1);
1123
+ }
1124
+ else if (familyFindings.length > 0) {
1125
+ userInfo(`\n📊 机制族验证: ${familyFindings.length} advisory`);
888
1126
  }
889
- console.log(`\n❌ 双层机制验证失败: ${hardFails.length} hard_fail`);
1127
+ }
1128
+ catch (e) {
1129
+ userError(`❌ 机制族验证异常: ${e.message}`);
890
1130
  process.exit(1);
891
1131
  }
892
- console.log(`\n✅ 双层机制验证通过,${advisory.length} advisory findings`);
893
1132
  // 审计摘要
894
1133
  try {
895
1134
  const { auditTemplateMechanisms } = await import("../engine/template_mechanism_auditor.js");
896
1135
  const audit = auditTemplateMechanisms(projectPath);
897
1136
  if (audit.hard_fail_count > 0) {
898
- console.log(`\n⚠️ 模板审计摘要: ${audit.hard_fail_count} hard_fail, ${audit.unmapped_template_assets.length} unmapped`);
1137
+ userInfo(`\n模板审计摘要: ${audit.hard_fail_count} hard_fail, ${audit.unmapped_template_assets.length} unmapped`);
1138
+ process.exit(1);
899
1139
  }
900
1140
  else {
901
- console.log(`\n📊 模板审计: ${audit.total_template_files} 文件, ${audit.unmapped_template_assets.length} unmapped, ${audit.advisory_count} advisory`);
1141
+ userInfo(`\n📊 模板审计: ${audit.total_template_files} 文件, ${audit.unmapped_template_assets.length} unmapped, ${audit.advisory_count} advisory`);
902
1142
  }
903
1143
  }
904
- catch {
905
- // 审计仅为建议,不阻断
1144
+ catch (e) {
1145
+ userError(`❌ 模板审计异常: ${e.message}`);
1146
+ process.exit(1);
906
1147
  }
907
1148
  }
908
1149
  catch (e) {
909
- console.error(`❌ validate-mechanisms 失败: ${e.message}`);
1150
+ userError(`❌ validate-mechanisms 失败: ${e.message}`);
910
1151
  process.exit(1);
911
1152
  }
912
1153
  }
913
1154
  async function cmdAuditTemplateMechanisms() {
914
- console.error("[soloForge] CLI: 执行 cmdAuditTemplateMechanisms");
1155
+ debug("CLI", "执行 cmdAuditTemplateMechanisms");
915
1156
  const asJson = args.includes("--json");
916
1157
  const changedOnly = args.includes("--changed-only");
917
1158
  // 从编译后的二进制位置推导根目录
@@ -923,108 +1164,718 @@ async function cmdAuditTemplateMechanisms() {
923
1164
  const { auditTemplateMechanisms } = await import("../engine/template_mechanism_auditor.js");
924
1165
  const report = auditTemplateMechanisms(projectPath);
925
1166
  if (asJson) {
926
- console.log(JSON.stringify(report, null, 2));
1167
+ userInfo(JSON.stringify(report, null, 2));
927
1168
  if (report.hard_fail_count > 0) {
928
1169
  process.exit(1);
929
1170
  }
930
1171
  return;
931
1172
  }
932
1173
  // 人类可读输出
933
- console.log(`模板-机制审计报告 (${report.generated_at})`);
934
- console.log(` 模板文件: ${report.total_template_files}`);
935
- console.log(` 注册资产: ${report.total_registered_assets}`);
936
- console.log(` 机制总数: ${report.total_mechanisms}`);
937
- console.log("");
1174
+ userInfo(`模板-机制审计报告 (${report.generated_at})`);
1175
+ userInfo(` 模板文件: ${report.total_template_files}`);
1176
+ userInfo(` 注册资产: ${report.total_registered_assets}`);
1177
+ userInfo(` 机制总数: ${report.total_mechanisms}`);
1178
+ userInfo("");
938
1179
  if (report.unmapped_template_assets.length > 0) {
939
- console.log(`⚠️ 未注册模板 (${report.unmapped_template_assets.length}):`);
1180
+ userInfo(`⚠️ 未注册模板 (${report.unmapped_template_assets.length}):`);
940
1181
  for (const u of report.unmapped_template_assets) {
941
- console.log(` - ${u.path}`);
1182
+ userInfo(` - ${u.path}`);
942
1183
  }
943
1184
  }
944
1185
  if (report.unconsumed_template_assets.length > 0) {
945
- console.log(`⚠️ 未消费资产 (${report.unconsumed_template_assets.length}):`);
1186
+ userInfo(`⚠️ 未消费资产 (${report.unconsumed_template_assets.length}):`);
946
1187
  for (const u of report.unconsumed_template_assets) {
947
- console.log(` - ${u.path} (mode=${u.consumption_mode})`);
1188
+ userInfo(` - ${u.path} (mode=${u.consumption_mode})`);
948
1189
  }
949
1190
  }
950
1191
  if (report.code_only_mechanisms.length > 0) {
951
- console.log(`⚠️ 仅代码机制 (无模板层):`);
1192
+ userInfo(`⚠️ 仅代码机制 (无模板层):`);
952
1193
  for (const m of report.code_only_mechanisms) {
953
- console.log(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
1194
+ userInfo(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
954
1195
  }
955
1196
  }
956
1197
  if (report.template_only_mechanisms.length > 0) {
957
- console.log(`⚠️ 仅模板机制 (无代码层):`);
1198
+ userInfo(`⚠️ 仅模板机制 (无代码层):`);
958
1199
  for (const m of report.template_only_mechanisms) {
959
- console.log(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
1200
+ userInfo(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
960
1201
  }
961
1202
  }
962
1203
  if (report.required_assets_without_enforcer.length > 0) {
963
- console.log(`❌ Required 资产无 enforcer (${report.required_assets_without_enforcer.length}):`);
1204
+ userInfo(`❌ Required 资产无 enforcer (${report.required_assets_without_enforcer.length}):`);
964
1205
  for (const r of report.required_assets_without_enforcer) {
965
- console.log(` - ${r.path} (mechanism=${r.owner_mechanism_id})`);
1206
+ userInfo(` - ${r.path} (mechanism=${r.owner_mechanism_id})`);
966
1207
  }
967
1208
  }
968
1209
  if (report.overpromised_adapter_rules.length > 0) {
969
- console.log(`❌ 适配器过度承诺 (${report.overpromised_adapter_rules.length}):`);
1210
+ userInfo(`❌ 适配器过度承诺 (${report.overpromised_adapter_rules.length}):`);
970
1211
  for (const o of report.overpromised_adapter_rules) {
971
- console.log(` - ${o.source_file}: ${o.promised_mechanism_id} (${o.promise_keywords.join(",")})`);
1212
+ userInfo(` - ${o.source_file}: ${o.promised_mechanism_id} (${o.promise_keywords.join(",")})`);
972
1213
  }
973
1214
  }
974
1215
  if (report.deprecated_assets_injected.length > 0) {
975
- console.log(`⚠️ Deprecated 资产仍被注入:`);
1216
+ userInfo(`⚠️ Deprecated 资产仍被注入:`);
976
1217
  for (const d of report.deprecated_assets_injected) {
977
- console.log(` - ${d.path}`);
1218
+ userInfo(` - ${d.path}`);
978
1219
  }
979
1220
  }
980
1221
  if (report.template_mechanism_drift.length > 0) {
981
1222
  const driftHard = report.template_mechanism_drift.filter((f) => f.severity === "hard_fail");
982
1223
  const driftAdvisory = report.template_mechanism_drift.filter((f) => f.severity === "advisory");
983
1224
  if (driftAdvisory.length > 0) {
984
- console.log(`⚠️ 漂移 advisory (${driftAdvisory.length}):`);
1225
+ userInfo(`⚠️ 漂移 advisory (${driftAdvisory.length}):`);
985
1226
  for (const f of driftAdvisory) {
986
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1227
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
987
1228
  }
988
1229
  }
989
1230
  if (driftHard.length > 0) {
990
- console.log(`❌ 漂移 hard_fail (${driftHard.length}):`);
1231
+ userInfo(`❌ 漂移 hard_fail (${driftHard.length}):`);
991
1232
  for (const f of driftHard) {
992
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1233
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
993
1234
  }
994
1235
  }
995
1236
  }
996
- console.log("");
1237
+ userInfo("");
997
1238
  if (report.hard_fail_count > 0) {
998
- console.log(`❌ 审计失败: ${report.hard_fail_count} hard_fail, ${report.advisory_count} advisory`);
999
- process.exit(1);
1239
+ userInfo(`❌ 审计失败: ${report.hard_fail_count} hard_fail, ${report.advisory_count} advisory`);
1000
1240
  }
1001
1241
  else {
1002
- console.log(`✅ 审计通过: 0 hard_fail, ${report.advisory_count} advisory`);
1242
+ userInfo(`✅ 审计通过: 0 hard_fail, ${report.advisory_count} advisory`);
1243
+ }
1244
+ // problem-57: 知识资产 schema 审计
1245
+ try {
1246
+ const { auditKnowledgeAssets, parseAssetFile } = await import("../engine/knowledge_asset_audit.js");
1247
+ const knowledgeDirs = [
1248
+ path.join(projectPath, "templates", "knowledge", "procedures"),
1249
+ path.join(projectPath, "templates", "knowledge", "rules"),
1250
+ path.join(projectPath, "templates", "knowledge", "checklists"),
1251
+ path.join(projectPath, "templates", "knowledge", "acceptance_templates"),
1252
+ path.join(projectPath, "templates", "knowledge", "review_rules"),
1253
+ path.join(projectPath, "templates", "knowledge", "workflow_templates"),
1254
+ ];
1255
+ const assets = [];
1256
+ for (const dir of knowledgeDirs) {
1257
+ if (!fss.existsSync(dir))
1258
+ continue;
1259
+ for (const entry of fss.readdirSync(dir).filter((f) => f.endsWith(".md"))) {
1260
+ const fp = path.join(dir, entry);
1261
+ const content = fss.readFileSync(fp, "utf-8");
1262
+ assets.push(parseAssetFile(fp, content));
1263
+ }
1264
+ }
1265
+ if (assets.length > 0) {
1266
+ const kaReport = auditKnowledgeAssets(assets);
1267
+ userInfo("");
1268
+ userInfo("知识资产审计:");
1269
+ userInfo(` 资产数: ${kaReport.total_assets}`);
1270
+ userInfo(` 通过: ${kaReport.passed ? "✓" : "✗"}`);
1271
+ userInfo(` hard_fail: ${kaReport.hard_fail_count}, warning: ${kaReport.warning_count}`);
1272
+ for (const f of kaReport.findings) {
1273
+ const icon = f.severity === "hard_fail" ? "❌" : "⚠️";
1274
+ userInfo(` ${icon} ${f.asset_id ?? f.file_path}: ${f.detail} (${f.kind})`);
1275
+ }
1276
+ if (kaReport.hard_fail_count > 0) {
1277
+ userInfo(`❌ 知识资产审计有 ${kaReport.hard_fail_count} hard_fail`);
1278
+ process.exit(1);
1279
+ }
1280
+ }
1281
+ }
1282
+ catch (e) {
1283
+ userError(`❌ 知识资产审计异常: ${e.message}`);
1284
+ process.exit(1);
1285
+ }
1286
+ if (report.hard_fail_count > 0) {
1287
+ process.exit(1);
1003
1288
  }
1004
1289
  }
1005
1290
  catch (e) {
1006
- console.error(`❌ audit-template-mechanisms 失败: ${e.message}`);
1291
+ userError(`❌ audit-template-mechanisms 失败: ${e.message}`);
1292
+ process.exit(1);
1293
+ }
1294
+ }
1295
+ async function cmdAuditDesignArtifacts() {
1296
+ debug("CLI", "执行 cmdAuditDesignArtifacts");
1297
+ const isJson = args.includes("--json");
1298
+ const projectPath = resolveProjectPath();
1299
+ const { createDesignArtifactPack, verifyDesignArtifactPack } = await import("../engine/design_artifact_pack.js");
1300
+ const contract = createDesignArtifactPack("design-artifact-audit-cli");
1301
+ const result = verifyDesignArtifactPack(projectPath, contract);
1302
+ if (isJson) {
1303
+ userInfo(JSON.stringify({ command: "audit-design-artifacts", project_path: projectPath, ...result }, null, 2));
1304
+ }
1305
+ else {
1306
+ userInfo(`设计产物包审计: ${projectPath}`);
1307
+ userInfo(` 状态: ${result.status}`);
1308
+ userInfo(` 已检查文件: ${result.checked_files.length}`);
1309
+ userInfo(` hard_fail: ${result.findings.filter((finding) => finding.severity === "hard_fail").length}`);
1310
+ for (const finding of result.findings) {
1311
+ userInfo(` ${finding.severity === "hard_fail" ? "❌" : "⚠️"} [${finding.code}] ${finding.message_zh}`);
1312
+ }
1313
+ if (result.passed)
1314
+ userInfo("✅ 设计产物包复验通过,可作为后续实现输入");
1315
+ }
1316
+ if (!result.passed)
1317
+ process.exit(1);
1318
+ }
1319
+ /**
1320
+ * 存量设计资产升级只负责安全建立复验基线与归档原文。
1321
+ * 修正文档内容仍须经 AI 草案和用户确认后写入,再由 audit 命令真实复验。
1322
+ */
1323
+ async function cmdUpgradeDesignArtifacts() {
1324
+ debug("CLI", "执行 cmdUpgradeDesignArtifacts");
1325
+ const apply = args.includes("--apply");
1326
+ const confirm = args.includes("--confirm");
1327
+ const isJson = args.includes("--json");
1328
+ const projectPath = resolveProjectPath();
1329
+ const { createDesignArtifactPack, verifyDesignArtifactPack } = await import("../engine/design_artifact_pack.js");
1330
+ const contract = createDesignArtifactPack("design-artifact-upgrade-cli");
1331
+ const audit = verifyDesignArtifactPack(projectPath, contract);
1332
+ const presentFiles = audit.checked_files.filter((relativePath) => fss.existsSync(path.join(projectPath, relativePath)));
1333
+ const output = {
1334
+ command: "upgrade-design-artifacts",
1335
+ mode: apply ? "apply" : "dry_run",
1336
+ status: audit.passed ? "implementation_ready" : "needs_revalidation",
1337
+ present_files: presentFiles,
1338
+ findings: audit.findings,
1339
+ next_steps: audit.passed
1340
+ ? ["设计产物已符合当前标准,无需覆盖现有文件"]
1341
+ : ["保留原文归档", "基于 findings 生成修订草案", "用户确认后写入修订文档/OpenAPI/SQL", "重新执行 audit-design-artifacts"],
1342
+ };
1343
+ if (!apply) {
1344
+ if (isJson)
1345
+ userInfo(JSON.stringify(output, null, 2));
1346
+ else {
1347
+ userInfo("设计产物升级计划: dry-run(不会修改现有文档)");
1348
+ userInfo(` 当前状态: ${output.status}`);
1349
+ userInfo(` 已发现现有资产: ${presentFiles.length}`);
1350
+ userInfo(` 待修复项: ${audit.findings.length}`);
1351
+ userInfo(" 使用 --apply --confirm 仅归档现有基线并登记 needs_revalidation;修订内容仍须用户确认。");
1352
+ }
1353
+ return;
1354
+ }
1355
+ if (!confirm) {
1356
+ userError("❌ upgrade-design-artifacts --apply 必须同时提供 --confirm,禁止静默改写或归档现有设计文档");
1357
+ process.exit(1);
1358
+ }
1359
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
1360
+ const archiveDir = path.join(projectPath, ".soloforge", "design-artifacts", "archive", timestamp);
1361
+ fss.mkdirSync(archiveDir, { recursive: true });
1362
+ for (const relativePath of presentFiles) {
1363
+ const target = path.join(archiveDir, relativePath);
1364
+ fss.mkdirSync(path.dirname(target), { recursive: true });
1365
+ fss.copyFileSync(path.join(projectPath, relativePath), target);
1366
+ }
1367
+ const contractDir = path.join(projectPath, ".soloforge", "design-artifacts");
1368
+ fss.mkdirSync(contractDir, { recursive: true });
1369
+ fss.writeFileSync(path.join(contractDir, "upgrade-contract.json"), JSON.stringify({
1370
+ ...contract,
1371
+ status: audit.passed ? "implementation_ready" : "needs_revalidation",
1372
+ baseline_hashes: audit.hashes,
1373
+ findings: audit.findings,
1374
+ verified_at: new Date().toISOString(),
1375
+ archive_dir: path.relative(projectPath, archiveDir),
1376
+ write_policy: "原文仅归档;修订文档须由用户确认后另行写入并重新复验",
1377
+ }, null, 2), "utf-8");
1378
+ const appliedOutput = { ...output, archive_dir: path.relative(projectPath, archiveDir), original_documents_overwritten: false };
1379
+ if (isJson)
1380
+ userInfo(JSON.stringify(appliedOutput, null, 2));
1381
+ else {
1382
+ userInfo(`✅ 已归档现有设计基线: ${appliedOutput.archive_dir}`);
1383
+ userInfo(" 未覆盖现有设计文档;请确认修订草案后重新执行复验。");
1384
+ }
1385
+ }
1386
+ async function cmdValidateKnowledge() {
1387
+ debug("CLI", "执行 cmdValidateKnowledge");
1388
+ const { validateContractRegistry } = await import("../engine/contract_registry.js");
1389
+ const { listProblemsByBatch } = await import("../engine/implementation_roadmap_registry.js");
1390
+ const { runAllKnowledgeScenarios, extractReadmeCommands } = await import("../engine/knowledge_scenario_registry.js");
1391
+ const { listKnowledgeIssueDetailAcceptances, validateKnowledgeIssueDetailAcceptance, } = await import("../engine/knowledge_acceptance_registry.js");
1392
+ const isJson = args.includes("--json");
1393
+ const cwd = process.cwd();
1394
+ const fs = await import("node:fs");
1395
+ const pathModule = await import("node:path");
1396
+ // 收集项目文件集合
1397
+ const existingFiles = new Set();
1398
+ function walkDir(dir, prefix) {
1399
+ try {
1400
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
1401
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
1402
+ if (entry.isDirectory()) {
1403
+ walkDir(pathModule.join(dir, entry.name), rel);
1404
+ }
1405
+ else {
1406
+ existingFiles.add(rel);
1407
+ }
1408
+ }
1409
+ }
1410
+ catch { /* 忽略不存在目录 */ }
1411
+ }
1412
+ walkDir(pathModule.join(cwd, "src"), "src");
1413
+ walkDir(pathModule.join(cwd, "tests"), "tests");
1414
+ // 验证契约注册表
1415
+ const contractFindings = validateContractRegistry(existingFiles);
1416
+ const hardFails = contractFindings.filter((f) => f.severity === "hard_fail");
1417
+ // 验证 知识模板问题状态
1418
+ const knowledgeProblems = listProblemsByBatch("batch-3");
1419
+ const allImplemented = knowledgeProblems.every((p) => p.status === "implemented_verified");
1420
+ // 读取真实 README 并提取命令
1421
+ let readmeCommands;
1422
+ try {
1423
+ const readmeContent = fs.readFileSync(pathModule.join(cwd, "README.md"), "utf-8");
1424
+ readmeCommands = extractReadmeCommands(readmeContent);
1425
+ }
1426
+ catch { /* README 不存在时跳过 */ }
1427
+ // 运行真实场景矩阵
1428
+ const scenarioResults = runAllKnowledgeScenarios(readmeCommands);
1429
+ const scenariosPass = scenarioResults.every((s) => s.status === "PASS");
1430
+ // 验证 IssueDetailAcceptance 注册表
1431
+ const acceptances = listKnowledgeIssueDetailAcceptances();
1432
+ const acceptanceFindings = acceptances.flatMap((a) => validateKnowledgeIssueDetailAcceptance(a));
1433
+ const acceptanceHardFails = acceptanceFindings.filter((f) => f.severity === "hard_fail");
1434
+ const result = {
1435
+ knowledge_problems: knowledgeProblems.length,
1436
+ all_implemented_verified: allImplemented,
1437
+ contract_hard_fails: hardFails.length,
1438
+ issue_acceptances: acceptances.length,
1439
+ acceptance_hard_fails: acceptanceHardFails.length,
1440
+ scenarios_pass: scenariosPass,
1441
+ scenario_results: scenarioResults.map((s) => ({
1442
+ scenario_id: s.scenario_id,
1443
+ scenario_name: s.scenario_name,
1444
+ status: s.status,
1445
+ evidence: s.evidence,
1446
+ failures: s.failures.length,
1447
+ })),
1448
+ };
1449
+ if (isJson) {
1450
+ userInfo(JSON.stringify(result, null, 2));
1451
+ }
1452
+ else {
1453
+ userInfo("═══ Batch 3 验证 ═══");
1454
+ userInfo(` 问题数: ${knowledgeProblems.length}`);
1455
+ userInfo(` 全部 implemented_verified: ${allImplemented ? "✓" : "✗"}`);
1456
+ userInfo(` 契约 hard_fail: ${hardFails.length}`);
1457
+ for (const f of hardFails) {
1458
+ userInfo(` ✗ ${f.contract_id}: ${f.message_zh}`);
1459
+ }
1460
+ userInfo(` IssueDetailAcceptance: ${acceptances.length} 条, hard_fail: ${acceptanceHardFails.length}`);
1461
+ for (const f of acceptanceHardFails) {
1462
+ userInfo(` ✗ ${f.issue_id}: ${f.message_zh}`);
1463
+ }
1464
+ userInfo(` 场景矩阵:`);
1465
+ for (const s of scenarioResults) {
1466
+ const icon = s.status === "PASS" ? "✓" : "✗";
1467
+ userInfo(` ${icon} ${s.scenario_id}: ${s.scenario_name} — ${s.status}`);
1468
+ for (const ev of s.evidence) {
1469
+ userInfo(` ✓ ${ev}`);
1470
+ }
1471
+ for (const fl of s.failures) {
1472
+ userInfo(` ✗ ${fl}`);
1473
+ }
1474
+ }
1475
+ const overallPass = allImplemented && hardFails.length === 0 && scenariosPass && acceptanceHardFails.length === 0;
1476
+ userInfo(overallPass ? "\n✅ Batch 3 验证通过" : "\n❌ Batch 3 验证失败");
1477
+ }
1478
+ const overallPass = allImplemented && hardFails.length === 0 && scenariosPass && acceptanceHardFails.length === 0;
1479
+ process.exit(overallPass ? 0 : 1);
1480
+ }
1481
+ async function cmdSyncTemplates() {
1482
+ debug("CLI", "执行 cmdSyncTemplates");
1483
+ const apply = args.includes("--apply");
1484
+ const confirm = args.includes("--confirm");
1485
+ const isJson = args.includes("--json");
1486
+ const { executeSync, validateSyncSafety, computeTemplateAssetVersions } = await import("../engine/template_sync.js");
1487
+ const { validateWorkflowTemplatePack, createWorkflowTemplatePackContract, createWorkflowTemplateEntry, createTemplateConsumptionEvidence, } = await import("../engine/workflow_template_pack.js");
1488
+ const { buildTemplateManifestFromSource, computeFileHashes, loadProjectManifest, saveProjectManifest, writeFileSyncRecursive, sha256Hex, hashFile, } = await import("../engine/template_manifest_io.js");
1489
+ const projectPath = process.cwd();
1490
+ const packageRoot = path.resolve(import.meta.dirname, "..", "..");
1491
+ const sourceDir = args.find((a) => a.startsWith("--source="))?.slice("--source=".length) ?? path.join(packageRoot, "templates");
1492
+ // 读取当前包版本
1493
+ let packageVersion = "0.0.0";
1494
+ try {
1495
+ const pkgJson = JSON.parse(fss.readFileSync(path.join(packageRoot, "package.json"), "utf-8"));
1496
+ packageVersion = pkgJson.version;
1497
+ }
1498
+ catch { /* 回退 */ }
1499
+ // 构建源清单(真实模板文件)
1500
+ const sourceManifest = buildTemplateManifestFromSource(sourceDir, packageVersion);
1501
+ // 加载已安装清单
1502
+ const installedManifest = loadProjectManifest(projectPath) ?? [];
1503
+ // 计算哈希(Map key 用相对路径,与 computeTemplateAssetVersions 查找键一致)
1504
+ const sourceHashes = new Map();
1505
+ for (const e of sourceManifest) {
1506
+ const h = hashFile(path.join(packageRoot, e.source_path));
1507
+ if (h !== null)
1508
+ sourceHashes.set(e.source_path, h);
1509
+ }
1510
+ const baseManifest = installedManifest.length > 0 ? installedManifest : sourceManifest;
1511
+ const currentHashes = new Map();
1512
+ for (const e of baseManifest) {
1513
+ const h = hashFile(path.join(projectPath, e.target_path));
1514
+ if (h !== null)
1515
+ currentHashes.set(e.target_path, h);
1516
+ }
1517
+ // 计算差异(首次安装用 sourceManifest 作为基准,全部为 missing)
1518
+ const assets = computeTemplateAssetVersions(baseManifest, currentHashes, sourceHashes);
1519
+ // problem-53: 工作流模板包完整性校验 — 用真实 manifest 数据构建 pack
1520
+ const wfPackEntries = sourceManifest
1521
+ .filter(e => e.asset_kind === "workflow_template")
1522
+ .map(e => createWorkflowTemplateEntry("architecture_design", e.target_path));
1523
+ const wfConsumptionEvidences = assets
1524
+ .filter(a => wfPackEntries.some(w => w.template_path === a.target_path))
1525
+ .map(a => createTemplateConsumptionEvidence(a.target_path));
1526
+ if (wfPackEntries.length > 0) {
1527
+ const wfPack = createWorkflowTemplatePackContract({
1528
+ workflows: wfPackEntries,
1529
+ mechanism_consumption_map: sourceManifest
1530
+ .filter(e => e.asset_kind === "workflow_template")
1531
+ .map(e => ({ template_path: e.target_path, consumed_mechanism_id: `mc-${e.asset_id}`, consumption_type: "route_trigger", evidence_required: true })),
1532
+ });
1533
+ const wfResult = validateWorkflowTemplatePack(wfPack, wfConsumptionEvidences);
1534
+ if (!wfResult.valid && !isJson) {
1535
+ userInfo(` ⚠ 工作流模板包校验: ${wfResult.violations.length} 个违规`);
1536
+ for (const v of wfResult.violations)
1537
+ userInfo(` - ${v}`);
1538
+ }
1539
+ if (!wfResult.valid && apply) {
1540
+ // 校验失败阻断 apply
1541
+ internalWarn("CLI", `工作流模板包校验失败,apply 已阻断。违规: ${wfResult.violations.join("; ")}`);
1542
+ process.exit(1);
1543
+ }
1544
+ }
1545
+ const safeCheck = validateSyncSafety(assets);
1546
+ const syncResult = executeSync({ dry_run: !apply, apply, confirm, project_path: projectPath, source_path: sourceDir }, assets, sourceManifest);
1547
+ // apply 模式:真实文件复制
1548
+ if (apply && confirm && syncResult.success && syncResult.backup_path) {
1549
+ const backupDir = syncResult.backup_path;
1550
+ fss.mkdirSync(backupDir, { recursive: true });
1551
+ const assetMap = new Map(assets.map((a) => [a.asset_id, a]));
1552
+ const updatedManifest = [...sourceManifest];
1553
+ for (const assetId of [...syncResult.report.added, ...syncResult.report.updated]) {
1554
+ const asset = assetMap.get(assetId);
1555
+ if (!asset)
1556
+ continue;
1557
+ const srcAbs = path.join(packageRoot, asset.source_path);
1558
+ const tgtAbs = path.join(projectPath, asset.target_path);
1559
+ // 备份已有文件
1560
+ if (fss.existsSync(tgtAbs)) {
1561
+ const backupFile = path.join(backupDir, path.basename(tgtAbs));
1562
+ fss.copyFileSync(tgtAbs, backupFile);
1563
+ }
1564
+ // 复制源文件到目标
1565
+ writeFileSyncRecursive(tgtAbs, fss.readFileSync(srcAbs));
1566
+ // 更新清单中的 installed_hash
1567
+ const idx = updatedManifest.findIndex((e) => e.asset_id === assetId);
1568
+ if (idx >= 0) {
1569
+ updatedManifest[idx] = {
1570
+ ...updatedManifest[idx],
1571
+ installed_hash: asset.source_hash,
1572
+ installed_at: new Date().toISOString(),
1573
+ };
1574
+ }
1575
+ }
1576
+ // 持久化清单
1577
+ saveProjectManifest(projectPath, updatedManifest);
1578
+ }
1579
+ if (isJson) {
1580
+ userInfo(JSON.stringify({
1581
+ command: "sync-templates",
1582
+ mode: apply ? "apply" : "dry_run",
1583
+ total_assets: assets.length,
1584
+ safe: safeCheck.safe,
1585
+ result: syncResult.success,
1586
+ dry_run: syncResult.dry_run,
1587
+ report: syncResult.report,
1588
+ }, null, 2));
1589
+ }
1590
+ else {
1591
+ userInfo(apply ? "模板同步: apply 模式" : "模板同步: dry-run 模式(不写入文件)");
1592
+ userInfo(` 资产总数: ${assets.length}`);
1593
+ userInfo(` 安全检查: ${safeCheck.safe ? "✓" : "✗"}`);
1594
+ userInfo(` 结果: ${syncResult.success ? "成功" : "失败"}`);
1595
+ userInfo(` 新增: ${syncResult.report.added.length}`);
1596
+ userInfo(` 更新: ${syncResult.report.updated.length}`);
1597
+ userInfo(` 跳过(用户修改): ${syncResult.report.skipped_user_modified.length}`);
1598
+ userInfo(` 废弃: ${syncResult.report.deprecated.length}`);
1599
+ if (!apply)
1600
+ userInfo(" 使用 --apply --confirm 应用同步");
1601
+ }
1602
+ if (!syncResult.success)
1007
1603
  process.exit(1);
1604
+ }
1605
+ async function cmdSyncAdapters() {
1606
+ debug("CLI", "执行 cmdSyncAdapters");
1607
+ const apply = args.includes("--apply");
1608
+ const confirm = args.includes("--confirm");
1609
+ const isJson = args.includes("--json");
1610
+ const { syncAdapterPrompts, validateAdapterPrompt, REQUIRED_ADAPTER_SECTIONS, } = await import("../engine/adapter_prompt_contract.js");
1611
+ const { writeFileSyncRecursive, sha256Hex, hashFile, } = await import("../engine/template_manifest_io.js");
1612
+ const projectPath = process.cwd();
1613
+ // 加载项目配置(回退到默认)
1614
+ let config;
1615
+ try {
1616
+ const resolved = await resolveProjectConfig(projectPath);
1617
+ config = resolved.config;
1618
+ }
1619
+ catch {
1620
+ config = {
1621
+ name: "default", tech_stack: { backend: { lang: "", framework: "", version: "" }, frontend: { lang: "", framework: "", version: "" } },
1622
+ product_profile: "general", repos: [], build_commands: { backend: {}, frontend: {} }, scope: { backend: [], frontend: [] },
1623
+ };
1624
+ }
1625
+ // 适配器生成器
1626
+ const { generateClaudeMd } = await import("../adapters/claude_code/claude_md.js");
1627
+ const { generateCodexAgentsMd } = await import("../adapters/codex/codex_rules.js");
1628
+ const { generateTraeRules } = await import("../adapters/trae/trae_rules.js");
1629
+ const sections = [...REQUIRED_ADAPTER_SECTIONS];
1630
+ // 适配器 installed hash 记录文件
1631
+ const ADAPTER_HASH_FILE = ".soloforge/adapter_hashes.json";
1632
+ // 加载已安装的适配器 hash 记录
1633
+ let installedAdapterHashes = {};
1634
+ try {
1635
+ const hashContent = fss.readFileSync(path.join(projectPath, ADAPTER_HASH_FILE), "utf-8");
1636
+ installedAdapterHashes = JSON.parse(hashContent);
1637
+ }
1638
+ catch { /* 首次无记录 */ }
1639
+ const adapterContracts = [
1640
+ {
1641
+ adapter_id: "claude-code", host_type: "claude_code",
1642
+ prompt_path: "CLAUDE.md",
1643
+ generated_from_contract_version: "1",
1644
+ required_sections: sections,
1645
+ forbidden_claims: [],
1646
+ sync_required: true,
1647
+ next_allowed_tools: ["sf_classify", "sf_expand", "sf_verify", "sf_learn", "sf_deliver", "sf_review"],
1648
+ },
1649
+ {
1650
+ adapter_id: "codex", host_type: "codex",
1651
+ prompt_path: "AGENTS.md",
1652
+ generated_from_contract_version: "1",
1653
+ required_sections: sections,
1654
+ forbidden_claims: [],
1655
+ sync_required: true,
1656
+ next_allowed_tools: ["sf_classify", "sf_expand", "sf_verify", "sf_learn"],
1657
+ },
1658
+ {
1659
+ adapter_id: "trae", host_type: "cursor",
1660
+ prompt_path: ".trae/rules/project_rules.md",
1661
+ generated_from_contract_version: "1",
1662
+ required_sections: sections,
1663
+ forbidden_claims: [],
1664
+ sync_required: true,
1665
+ next_allowed_tools: ["sf_classify", "sf_expand", "sf_verify", "sf_learn"],
1666
+ },
1667
+ ];
1668
+ // 验证所有适配器
1669
+ const validations = syncAdapterPrompts(adapterContracts, { dry_run: !apply, apply, confirm });
1670
+ // 适配器内容生成
1671
+ const generators = {
1672
+ "claude-code": () => generateClaudeMd(config),
1673
+ "codex": () => generateCodexAgentsMd(config),
1674
+ "trae": () => generateTraeRules(config),
1675
+ };
1676
+ // apply 模式:写入合规的适配器文件
1677
+ const writtenFiles = [];
1678
+ const skippedFiles = [];
1679
+ if (apply && confirm) {
1680
+ const updatedHashes = { ...installedAdapterHashes };
1681
+ for (const contract of adapterContracts) {
1682
+ const validation = validations.find((v) => v.adapter_id === contract.adapter_id);
1683
+ if (!validation?.compliant) {
1684
+ skippedFiles.push(`${contract.adapter_id}: 不合规,跳过`);
1685
+ continue;
1686
+ }
1687
+ const targetPath = path.join(projectPath, contract.prompt_path);
1688
+ const generator = generators[contract.adapter_id];
1689
+ if (!generator)
1690
+ continue;
1691
+ const content = generator();
1692
+ const generatedHash = sha256Hex(content);
1693
+ // 用户修改检测:文件存在且 hash 与已安装 hash 不一致
1694
+ if (fss.existsSync(targetPath)) {
1695
+ const diskHash = hashFile(targetPath);
1696
+ const installedHash = installedAdapterHashes[contract.adapter_id];
1697
+ if (diskHash && installedHash && diskHash !== installedHash) {
1698
+ // 文件被用户修改,不得覆盖
1699
+ skippedFiles.push(`${contract.adapter_id}: 用户已修改,跳过`);
1700
+ continue;
1701
+ }
1702
+ }
1703
+ // 首次安装或内容有变化:写入
1704
+ writeFileSyncRecursive(targetPath, content);
1705
+ writtenFiles.push(contract.prompt_path);
1706
+ updatedHashes[contract.adapter_id] = generatedHash;
1707
+ }
1708
+ // 持久化 hash 记录
1709
+ writeFileSyncRecursive(path.join(projectPath, ADAPTER_HASH_FILE), JSON.stringify(updatedHashes, null, 2));
1710
+ }
1711
+ if (isJson) {
1712
+ userInfo(JSON.stringify({
1713
+ command: "sync-adapters",
1714
+ mode: apply ? "apply" : "dry_run",
1715
+ adapter_count: adapterContracts.length,
1716
+ validations,
1717
+ written: writtenFiles,
1718
+ skipped: skippedFiles,
1719
+ }, null, 2));
1720
+ }
1721
+ else {
1722
+ userInfo(apply ? "适配器同步: apply 模式" : "适配器同步: dry-run 模式(不写入文件)");
1723
+ userInfo(` 适配器数量: ${adapterContracts.length}`);
1724
+ for (const v of validations) {
1725
+ const icon = v.compliant ? "✓" : "✗";
1726
+ userInfo(` ${icon} ${v.adapter_id}: ${v.compliant ? "合规" : "不合规"}`);
1727
+ for (const f of v.findings) {
1728
+ if (f.severity !== "info")
1729
+ userInfo(` ${f.severity === "critical" ? "✗" : "⚠"} ${f.message_zh}`);
1730
+ }
1731
+ }
1732
+ if (writtenFiles.length > 0) {
1733
+ userInfo(` 已写入: ${writtenFiles.join(", ")}`);
1734
+ }
1735
+ if (skippedFiles.length > 0) {
1736
+ userInfo(` 已跳过: ${skippedFiles.join("; ")}`);
1737
+ }
1738
+ if (!apply)
1739
+ userInfo(" 使用 --apply --confirm 应用同步");
1740
+ }
1741
+ }
1742
+ async function cmdMigrate() {
1743
+ debug("CLI", "执行 cmdMigrate");
1744
+ const apply = args.includes("--apply");
1745
+ const confirm = args.includes("--confirm");
1746
+ const isJson = args.includes("--json");
1747
+ const { createMigrationPlan, getCurrentCompatibility, validateMigrationSafety, generateVersionFile } = await import("../engine/release_compatibility.js");
1748
+ const { loadProjectVersion, saveProjectVersion, writeFileSyncRecursive } = await import("../engine/template_manifest_io.js");
1749
+ const projectPath = process.cwd();
1750
+ const compat = getCurrentCompatibility();
1751
+ const toVersion = compat.package_version;
1752
+ // 读取项目已安装版本,不存在视为首次
1753
+ const installed = loadProjectVersion(projectPath);
1754
+ const fromVersion = installed?.soloforge_package_version ?? "0.0.0";
1755
+ // 版本相同,无需迁移
1756
+ if (fromVersion === toVersion) {
1757
+ if (isJson) {
1758
+ userInfo(JSON.stringify({
1759
+ command: "migrate",
1760
+ mode: "noop",
1761
+ success: true,
1762
+ dry_run: !apply,
1763
+ safe: true,
1764
+ message: `已是最新版本 ${toVersion}`,
1765
+ from_version: fromVersion,
1766
+ to_version: toVersion,
1767
+ }, null, 2));
1768
+ }
1769
+ else {
1770
+ userInfo(`项目迁移: 已是最新版本 ${toVersion}`);
1771
+ userInfo(` 当前版本: ${fromVersion}`);
1772
+ }
1773
+ return;
1774
+ }
1775
+ // 先生成真实迁移计划
1776
+ const plan = createMigrationPlan({ dry_run: !apply, apply, confirm, project_path: projectPath, from_version: fromVersion, to_version: toVersion }, compat);
1777
+ // 基于真实 plan 做安全检查
1778
+ const safetyCheck = validateMigrationSafety(plan.plan, apply, !!confirm);
1779
+ // apply --confirm 模式且安全通过时:创建备份 + 写入 version.json
1780
+ if (apply && confirm && plan.success && safetyCheck.safe && plan.backup_path) {
1781
+ const backupDir = path.join(projectPath, plan.backup_path);
1782
+ fss.mkdirSync(backupDir, { recursive: true });
1783
+ // 备份已有 version.json
1784
+ const versionPath = path.join(projectPath, ".soloforge/version.json");
1785
+ if (fss.existsSync(versionPath)) {
1786
+ fss.copyFileSync(versionPath, path.join(backupDir, "version.json"));
1787
+ }
1788
+ // 写入新版本文件
1789
+ const versionContent = generateVersionFile(toVersion, compat.contract_registry_version);
1790
+ // 合并 created_at(首次用新时间,升级保留原时间)
1791
+ if (installed?.created_at) {
1792
+ versionContent.created_at = installed.created_at;
1793
+ }
1794
+ saveProjectVersion(projectPath, versionContent);
1795
+ }
1796
+ const success = plan.success && safetyCheck.safe;
1797
+ if (isJson) {
1798
+ userInfo(JSON.stringify({
1799
+ command: "migrate",
1800
+ mode: apply ? "apply" : "dry_run",
1801
+ success,
1802
+ dry_run: plan.dry_run,
1803
+ safe: safetyCheck.safe,
1804
+ from_version: fromVersion,
1805
+ to_version: toVersion,
1806
+ plan: plan.plan,
1807
+ backup_path: plan.backup_path,
1808
+ }, null, 2));
1008
1809
  }
1810
+ else {
1811
+ userInfo(apply ? "项目迁移: apply 模式" : "项目迁移: dry-run 模式(不写入文件)");
1812
+ userInfo(` 结果: ${success ? "成功" : "失败"}`);
1813
+ userInfo(` 从版本: ${fromVersion}`);
1814
+ userInfo(` 到版本: ${toVersion}`);
1815
+ userInfo(` 安全检查: ${safetyCheck.safe ? "✓" : "✗"}`);
1816
+ userInfo(` 需迁移: ${plan.plan.required_migrations.length}`);
1817
+ userInfo(` 自动应用: ${plan.plan.auto_applicable.length}`);
1818
+ userInfo(` 需人工: ${plan.plan.requires_human.length}`);
1819
+ if (!apply)
1820
+ userInfo(" 使用 --apply --confirm 执行迁移");
1821
+ }
1822
+ if (!success)
1823
+ process.exit(1);
1009
1824
  }
1010
- async function cmdValidateBatch1() {
1011
- console.error("[soloForge] CLI: 执行 cmdValidateBatch1");
1825
+ async function cmdValidateReleaseGate() {
1826
+ const isJson = args.includes("--json");
1827
+ debug("CLI", "执行 cmdValidateReleaseGate");
1828
+ const { runReleaseReadinessGate } = await import("../engine/release_readiness_gate.js");
1829
+ const result = await runReleaseReadinessGate(process.cwd());
1830
+ if (isJson) {
1831
+ userInfo(JSON.stringify({
1832
+ passed: result.passed,
1833
+ hard_fail_count: result.hard_fail_count,
1834
+ hard_fails: result.hard_fails,
1835
+ phases: result.phases,
1836
+ }, null, 2));
1837
+ }
1838
+ else {
1839
+ userInfo("══════════════════════════════════════════════════════════════");
1840
+ userInfo(`发布结论: ${result.passed ? "PASS" : "FAIL"}`);
1841
+ userInfo(`hard_fail 数量: ${result.hard_fail_count}`);
1842
+ userInfo("══════════════════════════════════════════════════════════════");
1843
+ userInfo();
1844
+ for (const p of result.phases) {
1845
+ userInfo(` ${p.hard_fail_count === 0 ? "[PASS]" : "[FAIL]"} ${p.name} — ${p.hard_fail_count} hard_fail`);
1846
+ }
1847
+ if (result.hard_fails.length > 0) {
1848
+ userInfo();
1849
+ userInfo("━━━ hard_fail 明细 ━━━");
1850
+ for (let i = 0; i < result.hard_fails.length; i++) {
1851
+ const hf = result.hard_fails[i];
1852
+ userInfo(`[${i + 1}] ${hf.code}: ${hf.message}`);
1853
+ userInfo(` 涉及: ${hf.files.join(", ")}`);
1854
+ userInfo(` 下一步: ${hf.nextStep}`);
1855
+ }
1856
+ }
1857
+ }
1858
+ if (!result.passed)
1859
+ process.exit(1);
1860
+ }
1861
+ async function cmdValidateFoundation() {
1862
+ debug("CLI", "执行 cmdValidateFoundation");
1012
1863
  const { validateMechanismLayerMaps, listMechanismLayerMaps } = await import("../engine/dual_layer_mechanism_registry.js");
1013
1864
  const { auditTemplateMechanisms } = await import("../engine/template_mechanism_auditor.js");
1014
- const { validateBatch1Scenarios, validateBatch1ProblemMatrix } = await import("../engine/batch1_scenario_registry.js");
1865
+ const { validateFoundationScenarios, validateFoundationProblemMatrix } = await import("../engine/foundation_scenario_registry.js");
1015
1866
  const cwd = process.cwd();
1016
1867
  const maps = listMechanismLayerMaps();
1017
1868
  const mechFindings = validateMechanismLayerMaps(maps, cwd);
1018
1869
  const mechanismsPass = mechFindings.filter((f) => f.severity === "hard_fail").length === 0;
1019
1870
  const auditReport = auditTemplateMechanisms(cwd);
1020
1871
  const auditPass = auditReport.hard_fail_count === 0;
1021
- const scenarioResults = await validateBatch1Scenarios(mechanismsPass, auditPass, true);
1872
+ const scenarioResults = await validateFoundationScenarios(mechanismsPass, auditPass, true);
1022
1873
  const allPass = scenarioResults.every((s) => s.status === "PASS");
1023
1874
  const isJson = process.argv.includes("--json");
1024
1875
  if (isJson) {
1025
- const problemMatrix = validateBatch1ProblemMatrix(cwd);
1876
+ const problemMatrix = validateFoundationProblemMatrix(cwd);
1026
1877
  const problemAllPass = problemMatrix.every((p) => Object.values(p.dimensions).every((d) => d.status === "PASS"));
1027
- console.log(JSON.stringify({
1878
+ userInfo(JSON.stringify({
1028
1879
  mechanisms_pass: mechanismsPass,
1029
1880
  audit_pass: auditPass,
1030
1881
  all_pass: allPass && problemAllPass,
@@ -1036,71 +1887,173 @@ async function cmdValidateBatch1() {
1036
1887
  else {
1037
1888
  for (const s of scenarioResults) {
1038
1889
  const icon = s.status === "PASS" ? "✓" : "✗";
1039
- console.log(`${icon} ${s.scenario_id}: ${s.scenario_name} — ${s.status}`);
1890
+ userInfo(`${icon} ${s.scenario_id}: ${s.scenario_name} — ${s.status}`);
1040
1891
  for (const r of s.rules) {
1041
1892
  const ri = r.status === "PASS" ? " ✓" : " ✗";
1042
- console.log(`${ri} ${r.rule}: ${r.evidence}`);
1893
+ userInfo(`${ri} ${r.rule}: ${r.evidence}`);
1043
1894
  }
1044
1895
  }
1045
- console.log(allPass ? "\n所有场景通过" : "\n部分场景失败");
1896
+ userInfo(allPass ? "\n所有场景通过" : "\n部分场景失败");
1046
1897
  }
1047
1898
  process.exit(allPass ? 0 : 1);
1048
1899
  }
1900
+ /**
1901
+ * 新增问题/issue 演进门控 — problem-54 真实消费入口。
1902
+ * 用法: soloforge validate-new-issue --title="问题标题" --batch=2 [--json]
1903
+ */
1904
+ async function cmdValidateNewIssue() {
1905
+ debug("CLI", "执行 cmdValidateNewIssue");
1906
+ const title = getArgValue("--title") ?? "";
1907
+ const batchStr = getArgValue("--batch");
1908
+ const batch = batchStr ? parseInt(batchStr, 10) : 0;
1909
+ const isJson = args.includes("--json");
1910
+ if (!title) {
1911
+ userError("❌ 错误: --title 必须提供");
1912
+ process.exit(1);
1913
+ }
1914
+ const { performEvolutionGate, checkDuplicateIssue, createNewIssueRegressionGate, } = await import("../engine/evolution_regression_gate.js");
1915
+ // 从 implementation_roadmap_registry 加载真实已有问题
1916
+ const { listAllProblems } = await import("../engine/implementation_roadmap_registry.js");
1917
+ const allProblems = listAllProblems();
1918
+ // 精确重复检测: label 精确匹配(不子串),title 语义包含,id 精确匹配
1919
+ const lower = title.toLowerCase();
1920
+ const matchedProblemMap = new Map();
1921
+ for (const p of allProblems) {
1922
+ let matched = false;
1923
+ // id 精确匹配
1924
+ if (p.id.toLowerCase() === lower)
1925
+ matched = true;
1926
+ // label 精确匹配
1927
+ if (p.label.toLowerCase() === lower)
1928
+ matched = true;
1929
+ // label 前缀匹配: "问题四十一" 匹配 "问题四十一(Brainstorm)"
1930
+ if (p.label.toLowerCase().startsWith(lower + "("))
1931
+ matched = true;
1932
+ // 完整 title 的包含匹配(title 是长描述,子串匹配合理)
1933
+ if (lower.length >= 2 && p.title.toLowerCase().includes(lower))
1934
+ matched = true;
1935
+ // 输入包含完整 title(输入更长时)
1936
+ if (lower.length >= 4 && p.title.length >= 4 && lower.includes(p.title.toLowerCase()))
1937
+ matched = true;
1938
+ if (matched) {
1939
+ matchedProblemMap.set(p.id, { id: p.id, label: p.label, title: p.title });
1940
+ }
1941
+ }
1942
+ const deduplicatedIds = [...matchedProblemMap.keys()];
1943
+ const matchedDetails = [...matchedProblemMap.values()];
1944
+ // 稳定 slug: 基于标题哈希而非 Date.now
1945
+ const titleSlug = title
1946
+ .toLowerCase()
1947
+ .replace(/[^a-z0-9一-鿿]+/g, "-")
1948
+ .replace(/^-|-$/g, "")
1949
+ .slice(0, 40);
1950
+ const hashSuffix = crypto.createHash("sha256").update(title).digest("hex").slice(0, 8);
1951
+ const candidateId = `problem-new-${titleSlug}-${hashSuffix}`;
1952
+ const gate = createNewIssueRegressionGate({
1953
+ issue_candidate_id: candidateId,
1954
+ candidate_title: title,
1955
+ });
1956
+ // 重复检测 — 写入去重后的 ID 列表
1957
+ gate.duplicate_check.possible_duplicates = deduplicatedIds;
1958
+ // 演进门控
1959
+ const result = performEvolutionGate(gate);
1960
+ const output = {
1961
+ title,
1962
+ batch,
1963
+ candidate_id: candidateId,
1964
+ existing_issues_checked: allProblems.length,
1965
+ duplicate_detected: gate.duplicate_check.possible_duplicates.length > 0,
1966
+ duplicates: [...new Set(gate.duplicate_check.possible_duplicates)],
1967
+ matched_duplicate_details: matchedDetails,
1968
+ gate_status: result.gate_status,
1969
+ can_proceed: result.allowed,
1970
+ reasons: result.reasons,
1971
+ };
1972
+ if (isJson) {
1973
+ userInfo(JSON.stringify(output, null, 2));
1974
+ }
1975
+ else {
1976
+ userInfo(`问题演进门控: ${output.gate_status}`);
1977
+ userInfo(` 已检查 ${allProblems.length} 个既有问题`);
1978
+ if (output.duplicate_detected) {
1979
+ userInfo(` ⚠ 重复检测: 发现 ${output.duplicates.join(", ")}`);
1980
+ for (const d of matchedDetails) {
1981
+ userInfo(` - ${d.id}: ${d.label} — ${d.title}`);
1982
+ }
1983
+ }
1984
+ if (result.reasons.length > 0) {
1985
+ userInfo(` 原因:`);
1986
+ for (const r of result.reasons)
1987
+ userInfo(` - ${r}`);
1988
+ }
1989
+ if (output.can_proceed) {
1990
+ userInfo(` ✓ 可继续: 问题新增已通过演进门控 (候选ID: ${candidateId})`);
1991
+ }
1992
+ }
1993
+ if (!output.can_proceed) {
1994
+ process.exit(1);
1995
+ }
1996
+ }
1049
1997
  async function cmdStatus() {
1050
- console.error("[soloForge] CLI: 执行 cmdStatus");
1051
- const projectPath = process.cwd();
1052
- console.log(`SoloForge 状态: ${projectPath}`);
1998
+ debug("CLI", "执行 cmdStatus");
1999
+ const projectPath = resolveProjectPath();
2000
+ userInfo(`SoloForge 状态: ${projectPath}`);
1053
2001
  const { config, source } = await resolveProjectConfig(projectPath);
1054
- console.log(` 配置来源: ${source === "config_file" ? "config.yaml" : "自动推断"}`);
1055
- console.log(` 产品: ${config.product_profile}`);
1056
- console.log(` 后端: ${config.tech_stack.backend.framework || "未配置"}`);
1057
- console.log(` 前端: ${config.tech_stack.frontend.framework || "未配置"}`);
2002
+ userInfo(` 配置来源: ${source === "config_file" ? "config.yaml" : "自动推断"}`);
2003
+ userInfo(` 产品: ${config.product_profile}`);
2004
+ userInfo(` 后端: ${config.tech_stack.backend.framework || "未配置"}`);
2005
+ userInfo(` 前端: ${config.tech_stack.frontend.framework || "未配置"}`);
1058
2006
  // 逐字段配置优先级状态
1059
2007
  try {
1060
2008
  const { resolutions, entries } = await resolveCurrentProjectConfigReports(projectPath);
1061
2009
  if (resolutions.length > 0) {
1062
- console.log("");
1063
- console.log(" 字段解析状态:");
2010
+ userInfo("");
2011
+ userInfo(" 字段解析状态:");
1064
2012
  for (const r of resolutions) {
1065
2013
  const stale = r.stale_warning ? " ⚠️ stale" : "";
1066
2014
  const conflict = r.conflict_report ? " ⚠️ conflict" : "";
1067
- console.log(` ${r.field_path}: ${JSON.stringify(r.resolved_value)} (${r.source}${stale}${conflict})`);
2015
+ userInfo(` ${r.field_path}: ${JSON.stringify(r.resolved_value)} (${r.source}${stale}${conflict})`);
1068
2016
  }
1069
2017
  }
1070
2018
  const schemaPath = path.join(projectPath, ".soloforge", "config.evidence.json");
1071
2019
  if (fss.existsSync(schemaPath)) {
1072
2020
  try {
1073
2021
  const raw = JSON.parse(fss.readFileSync(schemaPath, "utf-8"));
1074
- console.log(` evidence: schema_version=${raw.schema_version ?? 1}, ${entries.length} 条`);
2022
+ userInfo(` evidence: schema_version=${raw.schema_version ?? 1}, ${entries.length} 条`);
1075
2023
  }
1076
2024
  catch {
1077
- console.log(" evidence: 无法解析");
2025
+ userInfo(" evidence: 无法解析");
1078
2026
  }
1079
2027
  }
1080
2028
  else if (source === "config_file") {
1081
- console.log(" evidence: ⚠️ config.evidence.json 缺失");
2029
+ userInfo(" evidence: ⚠️ config.evidence.json 缺失");
1082
2030
  }
1083
2031
  }
1084
2032
  catch { }
1085
2033
  // Evidence 警告
1086
2034
  const evidenceWarnings = await checkEvidenceWarnings(projectPath);
1087
2035
  for (const w of evidenceWarnings) {
1088
- console.log(` ⚠️ evidence: ${w}`);
2036
+ userInfo(` ⚠️ evidence: ${w}`);
1089
2037
  }
1090
2038
  const knowledgeDir = getProjectKnowledgeDir(config);
1091
2039
  if (fss.existsSync(knowledgeDir)) {
1092
2040
  const { KnowledgeIndexManager } = await import("../knowledge/index_manager.js");
1093
- const index = new KnowledgeIndexManager(config);
1094
- await index.build();
1095
- const entries = index.getAllEntries();
1096
- console.log(` 知识: ${entries.global.length} 全局 + ${entries.project.length} 项目`);
2041
+ const index = new KnowledgeIndexManager(config, { watch: false });
2042
+ try {
2043
+ await index.build();
2044
+ const entries = index.getAllEntries();
2045
+ userInfo(` 知识: ${entries.global.length} 全局 + ${entries.project.length} 项目`);
2046
+ }
2047
+ finally {
2048
+ await index.close();
2049
+ }
1097
2050
  }
1098
2051
  else {
1099
- console.log(" 知识: 未初始化");
2052
+ userInfo(" 知识: 未初始化");
1100
2053
  }
1101
2054
  }
1102
2055
  async function interactiveConfig(projectPath) {
1103
- console.error("[soloForge] CLI: 执行 interactiveConfig");
2056
+ debug("CLI", "执行 interactiveConfig");
1104
2057
  if (!process.stdin.isTTY)
1105
2058
  return undefined;
1106
2059
  const readline = await import("node:readline");
@@ -1146,22 +2099,165 @@ async function interactiveConfig(projectPath) {
1146
2099
  return { draft, evidence };
1147
2100
  }
1148
2101
  function cmdVersion() {
1149
- console.error("[soloForge] CLI: 执行 cmdVersion");
2102
+ debug("CLI", "执行 cmdVersion");
1150
2103
  // dist/bin/soloforge.js → dist/package.json (local) 或 package.json (global npm)
1151
2104
  const pkgPath = path.resolve(import.meta.dirname, "..", "package.json");
1152
2105
  try {
1153
2106
  const pkg = JSON.parse(fss.readFileSync(pkgPath, "utf-8"));
1154
- console.log("SoloForge v" + pkg.version);
2107
+ userInfo("SoloForge v" + pkg.version);
1155
2108
  }
1156
2109
  catch {
1157
2110
  // 回退: 从 dist 同级目录查找
1158
2111
  const altPath = path.resolve(import.meta.dirname, "..", "..", "package.json");
1159
2112
  const pkg = JSON.parse(fss.readFileSync(altPath, "utf-8"));
1160
- console.log("SoloForge v" + pkg.version);
2113
+ userInfo("SoloForge v" + pkg.version);
1161
2114
  }
1162
2115
  }
1163
- main().catch((e) => { console.error(e); process.exit(1); });
2116
+ async function cmdCleanup() {
2117
+ debug("CLI", "执行 cmdCleanup");
2118
+ const dryRun = !args.includes("--apply");
2119
+ const projectPath = process.cwd();
2120
+ const stateDir = path.join(projectPath, ".soloforge", "state");
2121
+ let hasError = false;
2122
+ userInfo(`SoloForge 清理: ${projectPath}`);
2123
+ userInfo(` 模式: ${dryRun ? "dry-run(仅评估)" : "⚠️ 实际清理"}`);
2124
+ // 收集所有 evidence 引用来源:task-*.json 中的 evidence 文件名 / evidence id
2125
+ const referencedEvidenceIds = new Set();
2126
+ // 扫描 task context 文件中的 evidence 引用
2127
+ if (fss.existsSync(stateDir)) {
2128
+ for (const f of fss.readdirSync(stateDir).filter((f) => f.startsWith("task-") && f.endsWith(".json"))) {
2129
+ try {
2130
+ const content = fss.readFileSync(path.join(stateDir, f), "utf-8");
2131
+ const ctx = JSON.parse(content);
2132
+ // 从 verification_evidence 收集引用
2133
+ if (ctx.verification_evidence && typeof ctx.verification_evidence === "object") {
2134
+ for (const [key, val] of Object.entries(ctx.verification_evidence)) {
2135
+ if (typeof val === "string")
2136
+ referencedEvidenceIds.add(val);
2137
+ referencedEvidenceIds.add(key);
2138
+ }
2139
+ }
2140
+ // 从 artifacts 的 evidence_refs 收集
2141
+ if (Array.isArray(ctx.output_artifacts)) {
2142
+ for (const art of ctx.output_artifacts) {
2143
+ if (art.evidence_refs && Array.isArray(art.evidence_refs)) {
2144
+ for (const ref of art.evidence_refs)
2145
+ referencedEvidenceIds.add(ref);
2146
+ }
2147
+ if (art.artifact_id)
2148
+ referencedEvidenceIds.add(art.artifact_id);
2149
+ }
2150
+ }
2151
+ // 从 delivery_report 收集
2152
+ if (ctx.delivery_report && typeof ctx.delivery_report === "object") {
2153
+ const dr = ctx.delivery_report;
2154
+ if (dr.evidence_refs && Array.isArray(dr.evidence_refs)) {
2155
+ for (const ref of dr.evidence_refs)
2156
+ referencedEvidenceIds.add(ref);
2157
+ }
2158
+ }
2159
+ // 从 governance_report 收集
2160
+ if (ctx.governance_report && typeof ctx.governance_report === "string") {
2161
+ referencedEvidenceIds.add(ctx.governance_report);
2162
+ }
2163
+ }
2164
+ catch {
2165
+ // 跳过不可解析文件
2166
+ }
2167
+ }
2168
+ }
2169
+ // 1. TaskContext 清理(使用 retention_policy)
2170
+ if (fss.existsSync(stateDir)) {
2171
+ try {
2172
+ const { TaskContextManager } = await import("../engine/task_context.js");
2173
+ const mgr = new TaskContextManager(stateDir);
2174
+ const result = await mgr.cleanup(dryRun);
2175
+ userInfo("");
2176
+ userInfo(" TaskContext 清理:");
2177
+ userInfo(` 已清理: ${result.removed} 条`);
2178
+ userInfo(` 受保护(被引用不可删除): ${result.protected} 条`);
2179
+ userInfo(` 禁止内容检出: ${result.forbidden_content_hits.length > 0 ? result.forbidden_content_hits.join("; ") : "无"}`);
2180
+ userInfo(` dry_run: ${result.dry_run}`);
2181
+ if (result.forbidden_content_hits.length > 0) {
2182
+ userError(` ❌ TaskContext 包含禁止内容,清理中止`);
2183
+ hasError = true;
2184
+ }
2185
+ }
2186
+ catch (e) {
2187
+ userError(` ❌ TaskContext 清理失败: ${e.message}`);
2188
+ process.exit(1);
2189
+ }
2190
+ }
2191
+ else {
2192
+ userInfo(" TaskContext: 状态目录不存在,跳过");
2193
+ }
2194
+ // 2. Evidence 文件清理(真实引用扫描)
2195
+ const evidenceDir = path.join(projectPath, ".soloforge");
2196
+ if (fss.existsSync(evidenceDir)) {
2197
+ try {
2198
+ const { evaluateCleanup, checkForbiddenContent } = await import("../engine/retention_policy.js");
2199
+ const evidenceFiles = fss.readdirSync(evidenceDir)
2200
+ .filter((f) => f.endsWith(".json") && !f.startsWith("config."))
2201
+ .map((f) => {
2202
+ const fp = path.join(evidenceDir, f);
2203
+ const stat = fss.statSync(fp);
2204
+ const ageDays = Math.max(0, (Date.now() - stat.mtimeMs) / (24 * 60 * 60 * 1000));
2205
+ const content = fss.readFileSync(fp, "utf-8");
2206
+ const forbiddenHits = checkForbiddenContent("evidence", content);
2207
+ // 真实引用检查: evidence 文件名或内容中的 id 出现在引用集合中
2208
+ const isReferenced = referencedEvidenceIds.has(f) || referencedEvidenceIds.has(f.replace(/\.json$/, ""));
2209
+ return { name: f, age_days: ageDays, is_referenced: isReferenced, forbidden: forbiddenHits };
2210
+ });
2211
+ const records = evidenceFiles.map(e => ({ id: e.name, age_days: e.age_days, is_referenced: e.is_referenced }));
2212
+ const result = evaluateCleanup("evidence", records, dryRun);
2213
+ userInfo("");
2214
+ userInfo(" Evidence 清理:");
2215
+ userInfo(` 总文件: ${result.total_records}`);
2216
+ userInfo(` 可清理: ${result.eligible_for_cleanup}`);
2217
+ userInfo(` 受保护: ${result.protected_records}`);
2218
+ userInfo(` dry_run: ${result.dry_run}`);
2219
+ if (result.cleanup_candidates.length > 0) {
2220
+ userInfo(` 清理候选: ${result.cleanup_candidates.join(", ")}`);
2221
+ }
2222
+ const forbiddenFiles = evidenceFiles.filter(e => e.forbidden.length > 0);
2223
+ if (forbiddenFiles.length > 0) {
2224
+ userInfo(" ❌ 禁止内容检出:");
2225
+ for (const f of forbiddenFiles) {
2226
+ userInfo(` ${f.name}: ${f.forbidden.join(", ")}`);
2227
+ }
2228
+ hasError = true;
2229
+ }
2230
+ }
2231
+ catch (e) {
2232
+ userError(` ❌ Evidence 清理失败: ${e.message}`);
2233
+ process.exit(1);
2234
+ }
2235
+ }
2236
+ // 3. 列出所有保留策略
2237
+ try {
2238
+ const { listRetentionPolicies } = await import("../engine/retention_policy.js");
2239
+ const policies = listRetentionPolicies();
2240
+ userInfo("");
2241
+ userInfo(" 保留策略:");
2242
+ for (const p of policies) {
2243
+ userInfo(` ${p.policy_id}: ${p.record_type}, 最大 ${p.max_age_days} 天 / ${p.max_count} 条, dry_run_default=${p.dry_run_default}`);
2244
+ }
2245
+ }
2246
+ catch (e) {
2247
+ userError(` ❌ 保留策略加载失败: ${e.message}`);
2248
+ process.exit(1);
2249
+ }
2250
+ if (hasError)
2251
+ process.exit(1);
2252
+ }
2253
+ main().catch((e) => { internalWarn("CLI", "启动失败:", e); process.exit(1); });
1164
2254
  function getArgValue(flag) {
2255
+ // 支持 --flag=value 格式
2256
+ const eqPrefix = flag + "=";
2257
+ const eqIdx = args.findIndex((a) => a.startsWith(eqPrefix));
2258
+ if (eqIdx !== -1) {
2259
+ return args[eqIdx].slice(eqPrefix.length) || undefined;
2260
+ }
1165
2261
  const idx = args.indexOf(flag);
1166
2262
  if (idx === -1 || idx + 1 >= args.length)
1167
2263
  return undefined;