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
@@ -0,0 +1,1660 @@
1
+ /**
2
+ * 发布就绪门禁 — CLI 和 npm 共用的正式发布检查逻辑。
3
+ *
4
+ * 本模块是 validate-release 的唯一正式入口。
5
+ * 旧 validate-batch* gate 仅代表历史施工检查,不代表正式发布通过。
6
+ *
7
+ * 检查项:
8
+ * 0. dist 旧产物风险
9
+ * 1. Batch 施工痕迹泄漏
10
+ * 2. 双层模型语义归位
11
+ * 3. 主链路真实消费
12
+ * 4. 模板/adapter 更新空洞
13
+ * 5. 旧 gate 误导标记
14
+ * 6. 测试污染初筛
15
+ * 7. Batch 问题文档格式一致性
16
+ * 8. 关键问题消费验证
17
+ * 9. 机制身份一致性
18
+ * 10. P0/P1 知识资产 schema
19
+ * 11. engine console.log 检查
20
+ * 12. 中文注释检查
21
+ * 13. 第五批一致性校验
22
+ * 14. 依赖漏洞扫描
23
+ * 15. Batch6 架构决策与设计产物真实消费
24
+ */
25
+ import fs from "node:fs";
26
+ import path from "node:path";
27
+ // ── 辅助函数 ──
28
+ function safeRead(filePath) {
29
+ try {
30
+ return fs.readFileSync(filePath, "utf8");
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ function safeReadLines(filePath) {
37
+ const content = safeRead(filePath);
38
+ return content ? content.split("\n") : [];
39
+ }
40
+ // ── 0. dist 旧产物风险 ──
41
+ function checkDistFreshness(rootDir, hardFail) {
42
+ const srcDir = path.join(rootDir, "src");
43
+ const distDir = path.join(rootDir, "dist");
44
+ if (!fs.existsSync(distDir)) {
45
+ hardFail("DIST_STALE", "dist/ 目录不存在,请先 npm run build", ["dist/"], "构建系统", "旧 gate 不检查 dist 是否存在", "构建");
46
+ return;
47
+ }
48
+ let latestSrc = new Date(0);
49
+ function findLatestSrc(dir) {
50
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
51
+ for (const entry of entries) {
52
+ const full = path.join(dir, entry.name);
53
+ if (entry.isDirectory()) {
54
+ if (entry.name === "node_modules")
55
+ continue;
56
+ findLatestSrc(full);
57
+ }
58
+ else if (entry.isFile() && entry.name.endsWith(".ts")) {
59
+ const stat = fs.statSync(full);
60
+ if (stat.mtime > latestSrc)
61
+ latestSrc = stat.mtime;
62
+ }
63
+ }
64
+ }
65
+ findLatestSrc(srcDir);
66
+ let oldestDist = new Date(Infinity);
67
+ let distFileCount = 0;
68
+ function findOldestDist(dir) {
69
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
70
+ for (const entry of entries) {
71
+ const full = path.join(dir, entry.name);
72
+ if (entry.isDirectory()) {
73
+ findOldestDist(full);
74
+ }
75
+ else if (entry.isFile() && entry.name.endsWith(".js")) {
76
+ distFileCount++;
77
+ const stat = fs.statSync(full);
78
+ if (stat.mtime < oldestDist)
79
+ oldestDist = stat.mtime;
80
+ }
81
+ }
82
+ }
83
+ findOldestDist(distDir);
84
+ if (distFileCount === 0) {
85
+ hardFail("DIST_STALE", "dist/ 中无 .js 文件,请先 npm run build", ["dist/"], "构建系统", "旧 gate 不检查 dist 是否为空", "构建");
86
+ }
87
+ else if (oldestDist < latestSrc) {
88
+ hardFail("DIST_STALE", `dist/ 最旧文件 (${oldestDist.toISOString()}) 早于 src/ 最新文件 (${latestSrc.toISOString()}),存在过期风险`, ["dist/", "src/"], "构建系统", "旧 gate 不检查 dist 与 src 的时间一致性", "构建");
89
+ }
90
+ }
91
+ // ── 1. Batch 施工痕迹泄漏 ──
92
+ function checkBatchTraceLeakage(rootDir, hardFail, _info) {
93
+ const srcDir = path.join(rootDir, "src");
94
+ const batchRegex = /\b(batch[1-5]|batch_[1-5])\b/i;
95
+ // 白名单: 仅允许 @deprecated 标记和类型中的迁移兼容字段
96
+ const allowedPatterns = [/deprecated/i, /@deprecated/, /迁移兼容/];
97
+ const findings = [];
98
+ function scanDir(dir) {
99
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
100
+ for (const entry of entries) {
101
+ const full = path.join(dir, entry.name);
102
+ if (entry.isDirectory()) {
103
+ if (entry.name === "node_modules" || entry.name === "dist")
104
+ continue;
105
+ scanDir(full);
106
+ }
107
+ else if (entry.isFile() && entry.name.endsWith(".ts")) {
108
+ const lines = safeReadLines(full);
109
+ const rel = path.relative(rootDir, full);
110
+ for (let i = 0; i < lines.length; i++) {
111
+ const line = lines[i];
112
+ if (!batchRegex.test(line))
113
+ continue;
114
+ if (allowedPatterns.some(p => p.test(line)))
115
+ continue;
116
+ findings.push({ file: rel, line: i + 1, content: line.trim() });
117
+ }
118
+ }
119
+ }
120
+ }
121
+ scanDir(srcDir);
122
+ if (findings.length > 0) {
123
+ const criticalFindings = findings.filter(f => {
124
+ if (f.file.startsWith("src/engine/") && !f.content.startsWith("//") && !f.content.startsWith("*"))
125
+ return true;
126
+ return false;
127
+ });
128
+ for (const f of criticalFindings) {
129
+ hardFail("BATCH_TRACE_LEAK", `正式代码中发现 batch 施工痕迹: ${f.content}`, [f.file], `${f.file}:${f.line}`, "旧 validate-batch* gate 只检查文件是否存在和测试是否通过,不检查 batch 命名是否泄漏到正式 runtime", "清理");
130
+ }
131
+ const nonCritical = findings.filter(f => !criticalFindings.includes(f));
132
+ for (const f of nonCritical) {
133
+ _info(` [注意] batch 引用在: ${f.file}:${f.line} — ${f.content}`);
134
+ }
135
+ }
136
+ }
137
+ // ── 2. 双层模型语义归位 ──
138
+ async function checkDualLayerSemantics(rootDir, hardFail, _info) {
139
+ const registryPath = path.join(rootDir, "dist", "engine", "dual_layer_mechanism_registry.js");
140
+ const consumablePath = path.join(rootDir, "dist", "engine", "consumable_asset_registry.js");
141
+ if (!fs.existsSync(registryPath)) {
142
+ hardFail("REGISTRY_NOT_BUILT", "dual_layer_mechanism_registry.js 未编译,请先 npm run build", ["dist/engine/dual_layer_mechanism_registry.js"], "构建系统", "旧 gate 只检查源文件存在,不检查是否可运行", "构建");
143
+ return;
144
+ }
145
+ let mechanisms = [];
146
+ let consumableAssets = [];
147
+ try {
148
+ const reg = await import(registryPath);
149
+ mechanisms = reg.listMechanismLayerMaps ? reg.listMechanismLayerMaps() : [];
150
+ }
151
+ catch (e) {
152
+ hardFail("REGISTRY_LOAD_FAIL", `无法加载 dual_layer_mechanism_registry: ${e.message}`, ["dist/engine/dual_layer_mechanism_registry.js"], "构建系统", "旧 gate 只检查源文件存在,不检查运行时可加载", "修复");
153
+ return;
154
+ }
155
+ try {
156
+ const con = await import(consumablePath);
157
+ consumableAssets = con.listBuiltinConsumableAssets ? con.listBuiltinConsumableAssets() : [];
158
+ }
159
+ catch (e) {
160
+ _info(` [警告] 无法加载 consumable_asset_registry: ${e.message}`);
161
+ }
162
+ const enforced = mechanisms.filter((m) => m.status === "dual_layer_enforced");
163
+ for (const mech of enforced) {
164
+ const assets = mech.template_assets || [];
165
+ if (assets.length > 0 && assets.every((a) => a.consumption_mode === "supporting")) {
166
+ hardFail("ALL_SUPPORTING_ASSETS", `机制 ${mech.mechanism_id} 的所有模板资产都是 supporting 模式,无 required 资产: ${assets.map((a) => a.path).join(", ")}`, assets.map((a) => a.path), mech.mechanism_id, "旧 gate 用 template_assets.length > 0 判断模板层通过,不区分 required/supporting", "修复语义归位");
167
+ continue;
168
+ }
169
+ for (const asset of assets) {
170
+ const inConsumable = consumableAssets.find((ca) => ca.path === asset.path && ca.owner_mechanism_id === mech.mechanism_id);
171
+ if (!inConsumable) {
172
+ const assetBasename = path.basename(asset.path, ".md");
173
+ const mechanismIdShort = mech.mechanism_id.replace("mc-", "");
174
+ const nameCorresponds = assetBasename.includes(mechanismIdShort) || assetBasename.includes(mech.mechanism_name);
175
+ if (!nameCorresponds && asset.consumption_mode === "supporting") {
176
+ hardFail("TEMPLATE_SEMANTIC_MISALIGN", `机制 ${mech.mechanism_id} 的模板 ${asset.path} 在 consumable_asset_registry 中未声明 owner_mechanism_id 为该机制,且文件名不对应机制名称`, [asset.path, "src/engine/consumable_asset_registry.ts"], mech.mechanism_id, "旧 gate 用 template_assets.length > 0 判断模板层通过,不检查资产是否语义归属该机制", "修复语义归位");
177
+ }
178
+ }
179
+ }
180
+ }
181
+ const firstPrinciples = enforced.find((m) => m.mechanism_id === "mc-first-principles");
182
+ if (firstPrinciples) {
183
+ const assets = firstPrinciples.template_assets || [];
184
+ if (assets.length === 1 && assets[0].path.includes("架构设计工作流") && assets[0].consumption_mode === "supporting") {
185
+ hardFail("FIRST_PRINCIPLES_MISALIGNED", "mc-first-principles 只挂了 架构设计工作流.md(supporting),无自有模板资产。第一性原理检查应有独立的推理框架模板或规则", ["templates/knowledge/procedures/架构设计工作流.md", "src/engine/dual_layer_mechanism_registry.ts"], "mc-first-principles", "旧 gate 用 template_assets.length > 0 判断通过,不检查资产内容是否匹配机制语义", "修复语义归位");
186
+ }
187
+ }
188
+ for (const sm of [{ id: "mc-brainstorm-contract", name: "脑暴与方案探索" }, { id: "mc-detail-discipline", name: "细节纪律" }, { id: "mc-decision-sovereignty", name: "技术决策主权" }]) {
189
+ const mech = enforced.find((m) => m.mechanism_id === sm.id);
190
+ if (!mech)
191
+ continue;
192
+ const assets = mech.template_assets || [];
193
+ if (assets.every((a) => a.path.includes("架构设计工作流") || a.path.includes("测试优先编码工作流")) && assets.every((a) => a.consumption_mode === "supporting")) {
194
+ hardFail("SHARED_SUPPORTING_ONLY", `${sm.id}(${sm.name}) 只挂了共享的 supporting 模板(架构设计工作流/测试优先编码工作流),无自有 required 模板资产`, assets.map((a) => a.path), sm.id, "旧 gate 用 template_assets.length > 0 判断通过,不检查模板是否专属", "修复语义归位");
195
+ }
196
+ }
197
+ // 检查 required template asset 是否在 ASSET_MANIFEST 中注册
198
+ try {
199
+ const manifestPath = path.join(rootDir, "dist/engine/asset_manifest.js");
200
+ const manifestMod = await import(manifestPath);
201
+ const manifestEntries = manifestMod.ASSET_MANIFEST || [];
202
+ for (const mech of enforced) {
203
+ const assets = mech.template_assets || [];
204
+ for (const asset of assets) {
205
+ if (asset.consumption_mode !== "required")
206
+ continue;
207
+ const inManifest = manifestEntries.some((me) => me.path === asset.path && me.owner_mechanism_id === mech.mechanism_id && me.consumption_mode === "required");
208
+ if (!inManifest) {
209
+ hardFail("ASSET_MANIFEST_GAP", `机制 ${mech.mechanism_id} 的 required 模板 ${asset.path} 未在 ASSET_MANIFEST 中注册`, [asset.path, "src/engine/asset_manifest.ts"], mech.mechanism_id, "旧 gate 不检查 required 模板是否同步进入 ASSET_MANIFEST", "修复语义归位");
210
+ }
211
+ }
212
+ }
213
+ }
214
+ catch (e) {
215
+ _info(` [警告] 无法加载 asset_manifest 进行 required 模板检查: ${e.message}`);
216
+ }
217
+ _info(` 共检查 ${enforced.length} 个 dual_layer_enforced 机制`);
218
+ }
219
+ // ── 3. 主链路真实消费 ──
220
+ /** 已知的消费者入口→文件映射 */
221
+ const CONSUMER_ENTRY_FILES = {
222
+ "CLI validate": ["src/bin/soloforge.ts"],
223
+ "CLI sync-templates": ["src/bin/soloforge.ts"],
224
+ "CLI sync-adapters": ["src/bin/soloforge.ts"],
225
+ "CLI migrate": ["src/bin/soloforge.ts"],
226
+ "CLI validate-knowledge": ["src/engine/knowledge_scenario_registry.ts"],
227
+ "sf_verify": ["src/engine/verifier.ts"],
228
+ "sf_deliver": ["src/adapters/claude_code/tools.ts", "src/engine/delivery_readiness.ts"],
229
+ "sf_expand": ["src/adapters/claude_code/tools.ts", "src/engine/intent_expander.ts"],
230
+ "问题管理流程": [],
231
+ };
232
+ /** 模块名→文件路径映射 (用于模块间调用链如 "knowledge_evolution.validateCandidateTrust") */
233
+ const MODULE_FILE_MAP = {
234
+ "knowledge_lifecycle": "src/engine/knowledge_lifecycle.ts",
235
+ "knowledge_evolution": "src/engine/knowledge_evolution.ts",
236
+ "chinese_semantic_priority": "src/engine/chinese_semantic_priority.ts",
237
+ "language_policy": "src/engine/language_policy.ts",
238
+ "documentation_governance": "src/engine/documentation_governance.ts",
239
+ "template_sync": "src/engine/template_sync.ts",
240
+ "user_promise": "src/engine/user_promise.ts",
241
+ "adapter_prompt_contract": "src/engine/adapter_prompt_contract.ts",
242
+ "release_compatibility": "src/engine/release_compatibility.ts",
243
+ "extension_contract": "src/engine/extension_contract.ts",
244
+ "platform_context": "src/engine/platform_context.ts",
245
+ "metric_governance": "src/engine/metric_governance.ts",
246
+ "technology_decision": "src/engine/technology_decision.ts",
247
+ "brainstorm_contract": "src/engine/brainstorm_contract.ts",
248
+ "detail_discipline": "src/engine/detail_discipline.ts",
249
+ "first_principles": "src/engine/first_principles.ts",
250
+ "architecture_design_contract": "src/engine/architecture_design_contract.ts",
251
+ "existing_system_analysis": "src/engine/existing_system_analysis.ts",
252
+ "coding_readiness_gate": "src/engine/coding_readiness_gate.ts",
253
+ "local_docker_acceptance": "src/engine/local_docker_acceptance.ts",
254
+ "workflow_template_pack": "src/engine/workflow_template_pack.ts",
255
+ "evolution_regression_gate": "src/engine/evolution_regression_gate.ts",
256
+ "delivery_readiness": "src/engine/delivery_readiness.ts",
257
+ "knowledge_scenario_registry": "src/engine/knowledge_scenario_registry.ts",
258
+ "intent_expander": "src/engine/intent_expander.ts",
259
+ };
260
+ /** 从调用链文本中解析出所有消费者文件 */
261
+ function resolveConsumerFiles(chainText) {
262
+ const files = new Set();
263
+ const segments = chainText.split("→").map(s => s.trim()).filter(Boolean);
264
+ for (const seg of segments) {
265
+ // 检查是否匹配已知入口 (如 "CLI validate →" 或 "sf_verify →")
266
+ for (const [entry, paths] of Object.entries(CONSUMER_ENTRY_FILES)) {
267
+ if (seg.includes(entry) || seg.startsWith(entry)) {
268
+ for (const p of paths)
269
+ files.add(p);
270
+ }
271
+ }
272
+ // 检查是否匹配 cmdXxx 命令 (如 "cmdValidate")
273
+ const cmdMatch = seg.match(/cmd([A-Z]\w+)/);
274
+ if (cmdMatch) {
275
+ // cmd* 函数通常在 src/bin/soloforge.ts
276
+ files.add("src/bin/soloforge.ts");
277
+ }
278
+ // 检查是否匹配 generateVerifyCommands
279
+ if (seg.includes("generateVerifyCommands")) {
280
+ files.add("src/engine/verifier.ts");
281
+ }
282
+ // 检查是否匹配 evaluateDeliveryReadiness
283
+ if (seg.includes("evaluateDeliveryReadiness")) {
284
+ files.add("src/engine/delivery_readiness.ts");
285
+ files.add("src/adapters/claude_code/tools.ts");
286
+ }
287
+ // 检查是否匹配 cmdSyncTemplates/cmdSyncAdapters/cmdMigrate
288
+ if (seg.includes("cmdSyncTemplates") || seg.includes("cmdSyncAdapters") || seg.includes("cmdMigrate") || seg.includes("cmdValidate")) {
289
+ files.add("src/bin/soloforge.ts");
290
+ }
291
+ // 检查模块.function 模式 (如 "knowledge_evolution.validateCandidateTrust")
292
+ for (const [modName, modPath] of Object.entries(MODULE_FILE_MAP)) {
293
+ if (seg.includes(`${modName}.`) || seg.includes(modName)) {
294
+ files.add(modPath);
295
+ }
296
+ }
297
+ // 检查 buildTemplateManifestFromSource
298
+ if (seg.includes("buildTemplateManifestFromSource")) {
299
+ files.add("src/bin/soloforge.ts");
300
+ }
301
+ }
302
+ return [...files];
303
+ }
304
+ /** 从字符串数组格式的字段中提取文件路径列表 */
305
+ function extractStringArray(rawValue) {
306
+ // 处理 ["a", "b"] 格式
307
+ const items = rawValue.match(/["']([^"']+)["']/g) || [];
308
+ return items.map(s => s.replace(/["']/g, ""));
309
+ }
310
+ /** 从注册表文件内容中提取所有验收条目的结构化数据 */
311
+ function parseAcceptanceEntries(content) {
312
+ const entries = [];
313
+ const lines = content.split("\n");
314
+ let currentEntry = null;
315
+ for (let i = 0; i < lines.length; i++) {
316
+ const line = lines[i];
317
+ // 检测新条目开始 (issue_id 出现)
318
+ const issueMatch = line.match(/issue_id:\s*["']([^"']+)["']/);
319
+ if (issueMatch) {
320
+ if (currentEntry)
321
+ entries.push(currentEntry);
322
+ currentEntry = {
323
+ issue_id: issueMatch[1],
324
+ owner_files: [],
325
+ required_entrypoints: [],
326
+ mainline_consumption_check: "",
327
+ entryStartLine: i,
328
+ };
329
+ continue;
330
+ }
331
+ if (!currentEntry)
332
+ continue;
333
+ // 提取 owner_files
334
+ if (line.includes("owner_files:") && !line.includes("//")) {
335
+ // 可能是单行或多行
336
+ let raw = line;
337
+ if (!raw.includes("]")) {
338
+ let j = i + 1;
339
+ while (j < lines.length && !raw.includes("]")) {
340
+ raw += lines[j];
341
+ j++;
342
+ }
343
+ }
344
+ currentEntry.owner_files = extractStringArray(raw.replace(/^.*owner_files:\s*/, ""));
345
+ }
346
+ // 提取 required_entrypoints
347
+ if (line.includes("required_entrypoints:") && !line.includes("//")) {
348
+ let raw = line;
349
+ if (!raw.includes("]")) {
350
+ let j = i + 1;
351
+ while (j < lines.length && !raw.includes("]")) {
352
+ raw += lines[j];
353
+ j++;
354
+ }
355
+ }
356
+ currentEntry.required_entrypoints = extractStringArray(raw.replace(/^.*required_entrypoints:\s*/, ""));
357
+ }
358
+ // 提取 mainline_consumption_check
359
+ if (line.includes("mainline_consumption_check:") && !line.includes("//")) {
360
+ let raw = line;
361
+ if (!raw.includes("]")) {
362
+ let j = i + 1;
363
+ while (j < lines.length && !raw.includes("]")) {
364
+ raw += lines[j];
365
+ j++;
366
+ }
367
+ }
368
+ currentEntry.mainline_consumption_check = raw.replace(/^.*mainline_consumption_check:\s*/, "");
369
+ }
370
+ }
371
+ if (currentEntry)
372
+ entries.push(currentEntry);
373
+ return entries;
374
+ }
375
+ function checkMainlineConsumption(rootDir, hardFail, _info) {
376
+ const registryFiles = [
377
+ { filePath: "tests/engine/extension_acceptance_registry.ts", label: "Extension 验收" },
378
+ { filePath: "src/engine/knowledge_acceptance_registry.ts", label: "知识验收" },
379
+ ];
380
+ for (const reg of registryFiles) {
381
+ const content = safeRead(path.join(rootDir, reg.filePath));
382
+ if (!content) {
383
+ _info(` [跳过] ${reg.filePath} 不存在`);
384
+ continue;
385
+ }
386
+ const entries = parseAcceptanceEntries(content);
387
+ for (const entry of entries) {
388
+ // ── 检查 1: owner_files 必须在磁盘上存在 ──
389
+ for (const ownerFile of entry.owner_files) {
390
+ const fullPath = path.join(rootDir, ownerFile);
391
+ if (!fs.existsSync(fullPath)) {
392
+ hardFail("MAINLINE_OWNER_FILE_MISSING", `${reg.label}: ${entry.issue_id} 的 owner_file "${ownerFile}" 不存在`, [reg.filePath, ownerFile], entry.issue_id, "旧 gate 不校验 owner_files 是否真实存在", "创建缺失文件或修正 owner_files");
393
+ }
394
+ }
395
+ // ── 检查 2: required_entrypoints 必须在 owner_files 中真实 export ──
396
+ for (const ep of entry.required_entrypoints) {
397
+ let found = false;
398
+ for (const ownerFile of entry.owner_files) {
399
+ const srcContent = safeRead(path.join(rootDir, ownerFile));
400
+ if (!srcContent)
401
+ continue;
402
+ // 检查 export function 或 export const 或 export async function
403
+ const exportPattern = new RegExp(`export\\s+(async\\s+)?function\\s+${ep}\\b|export\\s+const\\s+${ep}\\b`);
404
+ if (exportPattern.test(srcContent)) {
405
+ found = true;
406
+ break;
407
+ }
408
+ }
409
+ if (!found) {
410
+ hardFail("MAINLINE_ENTRYPOINT_NOT_EXPORTED", `${reg.label}: ${entry.issue_id} 的 required_entrypoint "${ep}" 未在 owner_files 中找到 export`, [reg.filePath, ...entry.owner_files], entry.issue_id, "旧 gate 不校验 required_entrypoints 是否真实导出", "添加缺失的 export 或修正 required_entrypoints");
411
+ }
412
+ }
413
+ // ── 检查 3: 调用链格式 — pending_integration 或至少 2 级 (→ 分隔) ──
414
+ const chainText = entry.mainline_consumption_check.match(/\[([^\]]+)\]/)?.[1] || "";
415
+ const isPendingIntegration = chainText.includes("pending_integration");
416
+ const chainSegments = chainText.split("→").map(s => s.trim()).filter(Boolean);
417
+ if (isPendingIntegration) {
418
+ // 诚实标记: 入口已 export 但无生产消费者 — hard_fail 提醒集成未完成
419
+ hardFail("MAINLINE_PENDING_INTEGRATION", `${reg.label}: ${entry.issue_id} 标记为 pending_integration: ${chainText.replace("pending_integration: ", "")}`, [reg.filePath], entry.issue_id, "入口函数已实现但无真实生产消费路径", "补充消费者源码调用");
420
+ continue;
421
+ }
422
+ if (chainSegments.length < 2) {
423
+ hardFail("MAINLINE_CHAIN_TOO_SHORT", `${reg.label}: ${entry.issue_id} 的 mainline_consumption_check 调用链不足 2 级: "${chainText}"`, [reg.filePath], entry.issue_id, "调用链必须包含入口→调用→效果至少 2 级", "补充调用链");
424
+ continue;
425
+ }
426
+ // ── 检查 4: 调用链中声称的消费者必须真实 import/call required_entrypoints ──
427
+ const consumerFiles = resolveConsumerFiles(chainText);
428
+ if (consumerFiles.length === 0) {
429
+ // 调用链中的入口无法映射到任何消费者文件
430
+ hardFail("MAINLINE_CONSUMER_NOT_FOUND", `${reg.label}: ${entry.issue_id} 的调用链入口无法映射到已知消费者文件: "${chainSegments[0]}"`, [reg.filePath], entry.issue_id, "调用链声称的入口没有对应的消费者文件", "补充消费源码或修正调用链描述");
431
+ continue;
432
+ }
433
+ // 对每个 required_entrypoint,验证至少有一条真实消费路径
434
+ // 路径 A: 消费者文件直接 import + call 该 entrypoint
435
+ // 路径 B: entrypoint 在 owner_file 内部被同一模块的另一个已消费函数调用 (传递消费)
436
+ // 条件: 消费者 import 了 owner_file 的某个函数 + entrypoint 在 owner_file 内被调用
437
+ for (const ep of entry.required_entrypoints) {
438
+ let consumedByRealCode = false;
439
+ // 路径 A: 直接消费
440
+ for (const consumerFile of consumerFiles) {
441
+ const consumerContent = safeRead(path.join(rootDir, consumerFile));
442
+ if (!consumerContent)
443
+ continue;
444
+ const staticImportPattern = new RegExp(`import\\s+\\{[^}]*\\b${ep}\\b[^}]*\\}\\s+from`);
445
+ const dynamicImportPattern = new RegExp(`\\{[^}]*\\b${ep}\\b[^}]*\\}\\s*=\\s*await\\s+import\\(`);
446
+ const hasLazyModuleImport = entry.owner_files.some((ownerFile) => {
447
+ const moduleName = path.basename(ownerFile, ".ts");
448
+ return consumerContent.includes(`import("../../engine/${moduleName}.js")`)
449
+ || consumerContent.includes(`import("../engine/${moduleName}.js")`)
450
+ || consumerContent.includes(`import("./${moduleName}.js")`);
451
+ });
452
+ const hasImport = staticImportPattern.test(consumerContent)
453
+ || dynamicImportPattern.test(consumerContent)
454
+ || hasLazyModuleImport;
455
+ if (!hasImport)
456
+ continue;
457
+ const importLinePattern = new RegExp(`import\\s+\\{[^}]*\\b${ep}\\b|\\{[^}]*\\b${ep}\\b[^}]*\\}\\s*=\\s*await\\s+import`);
458
+ const callLines = consumerContent.split("\n").filter(l => !importLinePattern.test(l) && l.includes(ep));
459
+ if (callLines.length > 0) {
460
+ consumedByRealCode = true;
461
+ break;
462
+ }
463
+ }
464
+ // 路径 B: 传递消费 — entrypoint 在 owner_file 内部被另一个函数调用
465
+ // 且消费者 import 了 owner_file 中的某个函数
466
+ if (!consumedByRealCode) {
467
+ for (const ownerFile of entry.owner_files) {
468
+ const ownerContent = safeRead(path.join(rootDir, ownerFile));
469
+ if (!ownerContent)
470
+ continue;
471
+ // 检查 entrypoint 在 owner_file 内部被非 export 行调用
472
+ const ownerLines = ownerContent.split("\n");
473
+ const exportLinePattern = new RegExp(`export\\s+(async\\s+)?function\\s+${ep}\\b|export\\s+const\\s+${ep}\\b`);
474
+ const internalCalls = ownerLines.filter(l => !exportLinePattern.test(l) && l.includes(ep));
475
+ if (internalCalls.length === 0)
476
+ continue; // entrypoint 在 owner_file 内部未被调用
477
+ // entrypoint 在 owner_file 内部被调用 — 检查消费者是否 import 了 owner_file 的任何函数
478
+ for (const consumerFile of consumerFiles) {
479
+ const consumerContent = safeRead(path.join(rootDir, consumerFile));
480
+ if (!consumerContent)
481
+ continue;
482
+ // 检查消费者是否从 owner_file import 了任何东西
483
+ const ownerBasename = ownerFile.replace(/^src\/engine\//, "").replace(/\.ts$/, ".js");
484
+ const ownerImportPattern = new RegExp(`from\\s+["']\\./${ownerBasename.replace(".js", "")}\\.js["']|from\\s+["']\\.\\./engine/${ownerBasename.replace(".js", "")}\\.js["']`);
485
+ // 对于 CLI: from "../engine/xxx.js"
486
+ const cliImportPattern = new RegExp(`\\bimport\\s*\\([^)]*${ownerBasename.replace(/\.js$/, "")}`);
487
+ if (ownerImportPattern.test(consumerContent) || cliImportPattern.test(consumerContent)) {
488
+ consumedByRealCode = true;
489
+ break;
490
+ }
491
+ }
492
+ if (consumedByRealCode)
493
+ break;
494
+ }
495
+ }
496
+ if (!consumedByRealCode) {
497
+ hardFail("MAINLINE_ENTRYPOINT_NOT_CONSUMED", `${reg.label}: ${entry.issue_id} 的 required_entrypoint "${ep}" 无真实消费路径 (直接或传递)`, [reg.filePath, ...consumerFiles, ...entry.owner_files], entry.issue_id, "旧 gate 不校验消费者是否真实调用入口函数", "补充消费者源码调用或修正 required_entrypoints");
498
+ }
499
+ }
500
+ // ── 检查 5: owner_files 源码中必须包含调用链提到的函数名 ──
501
+ let funcInSource = false;
502
+ for (const ownerFile of entry.owner_files) {
503
+ const srcContent = safeRead(path.join(rootDir, ownerFile));
504
+ if (!srcContent)
505
+ continue;
506
+ for (const seg of chainSegments) {
507
+ const funcName = seg.match(/([a-z][a-zA-Z_]{4,})/)?.[1];
508
+ if (funcName && srcContent.includes(funcName)) {
509
+ funcInSource = true;
510
+ break;
511
+ }
512
+ }
513
+ if (funcInSource)
514
+ break;
515
+ }
516
+ if (!funcInSource) {
517
+ hardFail("MAINLINE_CHAIN_FUNC_NOT_IN_OWNER", `${reg.label}: ${entry.issue_id} 的调用链函数名未在 owner_files 源码中找到`, [reg.filePath, ...entry.owner_files], entry.issue_id, "旧 gate 对调用链与 owner_files 交叉引用失败时仅发 _info", "修正调用链或 owner_files");
518
+ }
519
+ }
520
+ }
521
+ }
522
+ // ── 4. 模板/adapter 更新空洞 ──
523
+ function checkTemplateAdapterGaps(rootDir, hardFail) {
524
+ const registryFiles = [
525
+ { filePath: "tests/engine/extension_acceptance_registry.ts", label: "Extension 验收" },
526
+ { filePath: "src/engine/knowledge_acceptance_registry.ts", label: "知识验收" },
527
+ ];
528
+ for (const reg of registryFiles) {
529
+ const content = safeRead(path.join(rootDir, reg.filePath));
530
+ if (!content)
531
+ continue;
532
+ const lines = content.split("\n");
533
+ for (let i = 0; i < lines.length; i++) {
534
+ const line = lines[i];
535
+ if (!line.includes("required_template_or_adapter_updates:"))
536
+ continue;
537
+ if (line.includes("[]") || line.includes("[ ]")) {
538
+ const contextBefore = lines.slice(Math.max(0, i - 20), i);
539
+ const issueMatch = contextBefore.find(l => l.includes("issue_id:"));
540
+ const issueId = issueMatch ? (issueMatch.match(/issue_id:\s*["']([^"']+)["']/)?.[1] ?? "未知") : "未知";
541
+ const contextAfter = lines.slice(i, Math.min(lines.length, i + 10));
542
+ const notApplicable = contextAfter.some(l => l.includes("not_applicable") || l.includes("N/A") || l.includes("不适用"));
543
+ if (!notApplicable) {
544
+ hardFail("TEMPLATE_ADAPTER_GAP", `${reg.label}: ${issueId} 的 required_template_or_adapter_updates 为空,无 not_applicable 说明`, [reg.filePath], issueId, "旧 gate 不检查空数组是否有合理说明", "清理");
545
+ }
546
+ }
547
+ }
548
+ }
549
+ }
550
+ // ── 5. 旧 gate 误导 ──
551
+ function checkOldGateMisdirection(rootDir, hardFail, _info) {
552
+ const gateFiles = ["scripts/validate_batch1_gate.mjs", "scripts/validate_batch2_gate.mjs", "scripts/validate_batch3_gate.mjs", "scripts/validate_batch4_gate.mjs", "scripts/validate_batch5_gate.mjs"];
553
+ // 检查 package.json 中对应脚本是否先输出历史警告
554
+ const pkgPath = path.join(rootDir, "package.json");
555
+ const pkgContent = safeRead(pkgPath);
556
+ const noticeModule = "validate_batch_historical_notice.mjs";
557
+ let pkgNoticeOk = true;
558
+ if (pkgContent) {
559
+ for (let i = 1; i <= 5; i++) {
560
+ const scriptKey = `"validate-batch${i}"`;
561
+ const scriptLine = pkgContent.split("\n").find(l => l.includes(scriptKey));
562
+ if (!scriptLine || !scriptLine.includes(noticeModule)) {
563
+ hardFail("HISTORICAL_GATE_NOT_RELEASE_PROOF", `package.json 中 ${scriptKey} 未在测试前输出历史 gate 警告(缺少 ${noticeModule})`, ["package.json"], `validate-batch${i}`, "旧 gate 可能让用户误以为是正式发布门禁", "添加历史声明");
564
+ pkgNoticeOk = false;
565
+ }
566
+ }
567
+ }
568
+ // 检查每个旧 gate 脚本是否已降级为历史施工 gate
569
+ for (const gf of gateFiles) {
570
+ const content = safeRead(path.join(rootDir, gf));
571
+ if (!content)
572
+ continue;
573
+ const batchNum = gf.match(/batch(\d)/)?.[1] ?? "?";
574
+ const issues = [];
575
+ // 1. 顶部注释不得自称 Release Gate
576
+ if (/Release Gate/.test(content) && !/历史施工 gate/.test(content)) {
577
+ issues.push("仍自称 Release Gate,未改为历史施工 gate");
578
+ }
579
+ // 2. 必须导入 printHistoricalNotice
580
+ if (!content.includes("printHistoricalNotice")) {
581
+ issues.push("缺少 printHistoricalNotice 调用");
582
+ }
583
+ // 3. 必须包含 historical_only: true(JSON 输出场景)
584
+ if (!content.includes("historical_only") && !content.includes("getHistoricalJsonFields")) {
585
+ issues.push("JSON 输出缺少 historical_only: true / getHistoricalJsonFields()");
586
+ }
587
+ // 4. 底部消息不得称 Release Gate(应为历史施工 Gate)
588
+ if (/Release Gate/.test(content)) {
589
+ issues.push("底部消息仍称 Release Gate");
590
+ }
591
+ if (issues.length > 0) {
592
+ hardFail("HISTORICAL_GATE_NOT_RELEASE_PROOF", `旧 gate ${gf} 未完成历史降级: ${issues.join("; ")}`, [gf], `validate-batch${batchNum}`, "旧 gate 误导性的通过结论被标记为不可作为发布依据", "完成历史降级");
593
+ }
594
+ }
595
+ _info(` 已检查 ${gateFiles.length} 个旧 gate 和 package.json 历史声明`);
596
+ }
597
+ // ── 6. 测试污染初筛 ──
598
+ function checkTestPollution(rootDir, hardFail, _info) {
599
+ const categories = { product_test: [], useful_contract_test: [], batch_construction_test: [], suspicious_test_pollution: [] };
600
+ const usefulContractExemptions = new Set([
601
+ "tests/engine/implementation_roadmap_registry.test.ts",
602
+ ]);
603
+ const testDir = path.join(rootDir, "tests");
604
+ function scanTestDir(dir) {
605
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
606
+ for (const entry of entries) {
607
+ const full = path.join(dir, entry.name);
608
+ if (entry.isDirectory()) {
609
+ scanTestDir(full);
610
+ }
611
+ else if (entry.isFile() && (entry.name.endsWith(".test.ts") || entry.name.endsWith(".test.js"))) {
612
+ const content = safeRead(full);
613
+ if (!content)
614
+ continue;
615
+ const rel = path.relative(rootDir, full);
616
+ const isScenarioMatrix = rel.includes("scenario_matrix");
617
+ const isBatchGateRelated = /batch\d/.test(content) && !rel.includes("scripts/");
618
+ const checksImplementedVerified = content.includes("implemented_verified");
619
+ const checksFileExists = /existsSync/.test(content) && /required.*file/i.test(content);
620
+ const checksScenarioSelfAttest = /fixture_status.*ready|scenario.*status.*PASS/.test(content);
621
+ if (isScenarioMatrix) {
622
+ categories.batch_construction_test.push(rel);
623
+ }
624
+ else if (usefulContractExemptions.has(rel)) {
625
+ categories.useful_contract_test.push(rel);
626
+ }
627
+ else if (isBatchGateRelated && (checksImplementedVerified || checksFileExists)) {
628
+ categories.suspicious_test_pollution.push(rel);
629
+ }
630
+ else if (checksScenarioSelfAttest && !content.includes("真实") && !content.includes("real")) {
631
+ categories.suspicious_test_pollution.push(rel);
632
+ }
633
+ else if (checksFileExists && !isBatchGateRelated) {
634
+ categories.useful_contract_test.push(rel);
635
+ }
636
+ else {
637
+ categories.product_test.push(rel);
638
+ }
639
+ }
640
+ }
641
+ }
642
+ scanTestDir(testDir);
643
+ _info(` product_test: ${categories.product_test.length} 个`);
644
+ _info(` useful_contract_test: ${categories.useful_contract_test.length} 个`);
645
+ _info(` batch_construction_test: ${categories.batch_construction_test.length} 个`);
646
+ _info(` suspicious_test_pollution: ${categories.suspicious_test_pollution.length} 个`);
647
+ for (const t of categories.suspicious_test_pollution) {
648
+ _info(` [可疑] ${t}`);
649
+ }
650
+ if (categories.suspicious_test_pollution.length > 0) {
651
+ hardFail("SUSPICIOUS_TEST_POLLUTION", `发现 ${categories.suspicious_test_pollution.length} 个可疑测试文件: 可能只为 Batch 状态、implemented_verified、文件存在、scenario 自证而存在`, categories.suspicious_test_pollution, "测试体系", "旧 gate 把这些测试作为通过证据,但它们可能是循环自证", "删除测试污染");
652
+ }
653
+ }
654
+ // ── 8. 关键问题消费验证 (problem-17/38/57) ──
655
+ async function checkCriticalProblemConsumption(rootDir, hardFail, _info) {
656
+ const taskContextPath = path.join(rootDir, "src/engine/task_context.ts");
657
+ const cliPath = path.join(rootDir, "src/bin/soloforge.ts");
658
+ // problem-17: StateFact 分区 — save() 必须调用 validateStateFactPartition,hard_fail 必须 throw
659
+ const stateFactPath = path.join(rootDir, "src/engine/state_fact_classifier.ts");
660
+ if (!fs.existsSync(stateFactPath)) {
661
+ hardFail("CRITICAL_PROBLEM_FILE_MISSING", "problem-17: state_fact_classifier.ts 不存在", ["src/engine/state_fact_classifier.ts"], "problem-17", "发布门禁不检查 problem-17 实现", "创建 state_fact_classifier.ts");
662
+ }
663
+ else {
664
+ const sfContent = safeRead(stateFactPath);
665
+ const tcContent = safeRead(taskContextPath);
666
+ if (!sfContent || !sfContent.includes("validateStateFactPartition")) {
667
+ hardFail("CRITICAL_PROBLEM_EXPORT_MISSING", "problem-17: state_fact_classifier.ts 未导出 validateStateFactPartition", ["src/engine/state_fact_classifier.ts"], "problem-17", "StateFact 分类器缺少核心导出函数", "添加 validateStateFactPartition 导出");
668
+ }
669
+ if (!tcContent || !tcContent.includes("validateStateFactPartition")) {
670
+ hardFail("CRITICAL_PROBLEM_NOT_CONSUMED", "problem-17: task_context.ts save() 未调用 validateStateFactPartition", ["src/engine/task_context.ts", "src/engine/state_fact_classifier.ts"], "problem-17", "StateFact 分区定义存在但未接入 TaskContext 保存路径", "在 task_context.ts save() 中接入 validateStateFactPartition");
671
+ }
672
+ else {
673
+ // 验证 hard_fail 时 throw(不是静默跳过)
674
+ const tcLines = tcContent.split("\n");
675
+ const vspLine = tcLines.findIndex(l => l.includes("validateStateFactPartition"));
676
+ if (vspLine === -1) {
677
+ hardFail("CRITICAL_PROBLEM_NOT_CONSUMED", "problem-17: task_context.ts save() 未调用 validateStateFactPartition", ["src/engine/task_context.ts"], "problem-17", "StateFact 分区定义存在但未接入 TaskContext 保存路径", "接入 validateStateFactPartition");
678
+ }
679
+ else {
680
+ // 检查调用后有 hard_fail throw 路径
681
+ const afterVsp = tcLines.slice(vspLine, vspLine + 15).join("\n");
682
+ if (!afterVsp.includes("throw") || !afterVsp.includes("hardFails") && !afterVsp.includes("hard_fail")) {
683
+ hardFail("CRITICAL_PROBLEM_SOFT_ENFORCEMENT", "problem-17: task_context.ts 中 validateStateFactPartition 调用后缺少 hard_fail throw 路径", ["src/engine/task_context.ts"], "problem-17", "StateFact 校验结果被忽略而非阻断", "校验 hard_fail 时 throw Error");
684
+ }
685
+ }
686
+ }
687
+ }
688
+ // problem-38: Retention Policy — cleanup 必须调用 evaluateCleanup/checkForbiddenContent,存在 referenced evidence 保护
689
+ const retentionPath = path.join(rootDir, "src/engine/retention_policy.ts");
690
+ if (!fs.existsSync(retentionPath)) {
691
+ hardFail("CRITICAL_PROBLEM_FILE_MISSING", "problem-38: retention_policy.ts 不存在", ["src/engine/retention_policy.ts"], "problem-38", "发布门禁不检查 problem-38 实现", "创建 retention_policy.ts");
692
+ }
693
+ else {
694
+ const retContent = safeRead(retentionPath);
695
+ if (!retContent || !retContent.includes("evaluateCleanup") || !retContent.includes("checkForbiddenContent")) {
696
+ hardFail("CRITICAL_PROBLEM_EXPORT_MISSING", "problem-38: retention_policy.ts 未导出 evaluateCleanup 或 checkForbiddenContent", ["src/engine/retention_policy.ts"], "problem-38", "Retention Policy 缺少核心清理函数", "添加 evaluateCleanup 和 checkForbiddenContent 导出");
697
+ }
698
+ const tcContent = safeRead(taskContextPath);
699
+ const cliContent = safeRead(cliPath);
700
+ const tcHasCleanup = tcContent?.includes("evaluateCleanup") ?? false;
701
+ const cliHasCleanup = cliContent?.includes("evaluateCleanup") ?? false;
702
+ const cliHasCheck = cliContent?.includes("checkForbiddenContent") ?? false;
703
+ if (!tcHasCleanup && !cliHasCleanup) {
704
+ hardFail("CRITICAL_PROBLEM_NOT_CONSUMED", "problem-38: evaluateCleanup 未被 task_context.ts 或 soloforge.ts 调用", ["src/engine/task_context.ts", "src/bin/soloforge.ts", "src/engine/retention_policy.ts"], "problem-38", "Retention Policy 定义存在但无清理消费者", "将 evaluateCleanup 接入 TaskContext cleanup 或 CLI cleanup 命令");
705
+ }
706
+ // 验证 CLI cleanup 中有 referenced evidence 保护逻辑
707
+ if (cliContent) {
708
+ const cliLines = cliContent.split("\n");
709
+ const cleanupFn = cliLines.findIndex(l => l.match(/^(async\s+)?function\s+cmdCleanup/));
710
+ if (cleanupFn !== -1) {
711
+ // 搜索到下一个顶层函数或文件末尾
712
+ let cleanupEnd = cliLines.length;
713
+ for (let i = cleanupFn + 3; i < cliLines.length; i++) {
714
+ if (cliLines[i].match(/^async function\s+\w+|^function\s+\w+/)) {
715
+ cleanupEnd = i;
716
+ break;
717
+ }
718
+ }
719
+ const cleanupBody = cliLines.slice(cleanupFn, cleanupEnd).join("\n");
720
+ if (!cleanupBody.includes("referencedEvidenceIds") || !cleanupBody.includes("is_referenced")) {
721
+ hardFail("CRITICAL_PROBLEM_SOFT_ENFORCEMENT", "problem-38: CLI cleanup 缺少真实 evidence 引用扫描(无 referencedEvidenceIds 或 is_referenced 逻辑)", ["src/bin/soloforge.ts"], "problem-38", "cleanup 未扫描 task context / governance report 中的 evidence 引用", "添加真实引用扫描");
722
+ }
723
+ // 验证策略异常导致非零退出
724
+ if (!cleanupBody.includes("process.exit(1)")) {
725
+ hardFail("CRITICAL_PROBLEM_SOFT_ENFORCEMENT", "problem-38: CLI cleanup 策略异常时未非零退出", ["src/bin/soloforge.ts"], "problem-38", "策略异常被吞而非阻断", "添加 process.exit(1) 在 catch 中");
726
+ }
727
+ }
728
+ }
729
+ }
730
+ // problem-57: Knowledge Asset Audit — audit-template-mechanisms 必须调用 auditKnowledgeAssets 且 hard_fail/异常 process.exit(1)
731
+ const kaAuditPath = path.join(rootDir, "src/engine/knowledge_asset_audit.ts");
732
+ if (!fs.existsSync(kaAuditPath)) {
733
+ hardFail("CRITICAL_PROBLEM_FILE_MISSING", "problem-57: knowledge_asset_audit.ts 不存在", ["src/engine/knowledge_asset_audit.ts"], "problem-57", "发布门禁不检查 problem-57 实现", "创建 knowledge_asset_audit.ts");
734
+ }
735
+ else {
736
+ const kaContent = safeRead(kaAuditPath);
737
+ if (!kaContent || !kaContent.includes("auditKnowledgeAssets")) {
738
+ hardFail("CRITICAL_PROBLEM_EXPORT_MISSING", "problem-57: knowledge_asset_audit.ts 未导出 auditKnowledgeAssets", ["src/engine/knowledge_asset_audit.ts"], "problem-57", "Knowledge Asset Audit 缺少核心审计函数", "添加 auditKnowledgeAssets 导出");
739
+ }
740
+ const cliContent = safeRead(cliPath);
741
+ if (!cliContent?.includes("auditKnowledgeAssets")) {
742
+ hardFail("CRITICAL_PROBLEM_NOT_CONSUMED", "problem-57: auditKnowledgeAssets 未被 soloforge.ts CLI 消费", ["src/bin/soloforge.ts", "src/engine/knowledge_asset_audit.ts"], "problem-57", "Knowledge Asset Audit 定义存在但未接入 CLI", "将 auditKnowledgeAssets 接入 audit-template-mechanisms 命令");
743
+ }
744
+ else {
745
+ // 验证 hard_fail 阻断路径
746
+ const cliLines = cliContent.split("\n");
747
+ const kaCallLine = cliLines.findIndex(l => l.includes("auditKnowledgeAssets") && l.includes("await"));
748
+ if (kaCallLine !== -1) {
749
+ // 搜索到函数末尾(下一个 async function 或文件末尾)
750
+ let kaEnd = cliLines.length;
751
+ for (let i = kaCallLine + 1; i < cliLines.length; i++) {
752
+ if (cliLines[i].match(/^async function\s+\w+|^function\s+\w+/)) {
753
+ kaEnd = i;
754
+ break;
755
+ }
756
+ }
757
+ const afterKaCall = cliLines.slice(kaCallLine, kaEnd).join("\n");
758
+ if (!afterKaCall.includes("hard_fail_count") || !afterKaCall.includes("process.exit(1)")) {
759
+ hardFail("CRITICAL_PROBLEM_SOFT_ENFORCEMENT", "problem-57: auditKnowledgeAssets 调用后 hard_fail 未阻断(缺少 process.exit(1))", ["src/bin/soloforge.ts"], "problem-57", "知识资产审计 hard_fail 未阻断命令", "添加 hard_fail_count > 0 时 process.exit(1)");
760
+ }
761
+ // 验证异常也阻断(搜索整个函数体中的 catch 块)
762
+ const catchBlocks = afterKaCall.match(/catch\s*\(e[^)]*\)\s*\{[^}]+\}/g);
763
+ const hasKaAudit = afterKaCall.includes("auditKnowledgeAssets");
764
+ if (catchBlocks && hasKaAudit) {
765
+ for (const cb of catchBlocks) {
766
+ // 只检查紧跟 auditKnowledgeAssets 的 catch
767
+ if (cb.includes("process.exit(1)"))
768
+ continue;
769
+ // 检查是否是 auditKnowledgeAssets 的 catch(通过位置判断)
770
+ }
771
+ }
772
+ // 简化: 检查 auditKnowledgeAssets 后面的 catch 块中是否有 process.exit(1)
773
+ const kaCatchIdx = afterKaCall.lastIndexOf("catch");
774
+ if (kaCatchIdx !== -1) {
775
+ const afterCatch = afterKaCall.slice(kaCatchIdx);
776
+ if (!afterCatch.includes("process.exit(1)")) {
777
+ hardFail("CRITICAL_PROBLEM_SOFT_ENFORCEMENT", "problem-57: auditKnowledgeAssets 异常时未阻断(catch 中缺少 process.exit(1))", ["src/bin/soloforge.ts"], "problem-57", "知识资产审计异常被吞而非阻断", "catch 中添加 process.exit(1)");
778
+ }
779
+ }
780
+ }
781
+ }
782
+ }
783
+ _info(" problem-17/38/57 消费验证完成");
784
+ // 问题六十:证据驱动与反幻觉契约 — 行为级检查
785
+ {
786
+ const evidenceGroundingPath = path.join(rootDir, "src/engine/evidence_grounding_contract.ts");
787
+ if (!fs.existsSync(evidenceGroundingPath)) {
788
+ hardFail("CRITICAL_PROBLEM_FILE_MISSING", "problem-60: evidence_grounding_contract.ts 不存在", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "发布门禁不检查 problem-60 实现", "创建 evidence_grounding_contract.ts");
789
+ }
790
+ else {
791
+ // 行为级检查:动态导入并验证核心门禁行为
792
+ try {
793
+ const eg = await import(path.join(rootDir, "dist/engine/evidence_grounding_contract.js"));
794
+ const sys = eg.createEvidenceGroundingSystem();
795
+ // 检查 1:无证据高风险 claim 必须被 blocked
796
+ {
797
+ const noEvClaims = [{
798
+ id: "gate-test-no-ev", claim_text: "项目使用 React", category: "project_fact",
799
+ evidence_ids: [], is_uncertain: false, risk_level: "high",
800
+ }];
801
+ const noEvResult = sys.verifier.verify(noEvClaims, "high");
802
+ if (noEvResult.unsupported.length === 0) {
803
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: 无证据高风险 claim 未被 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 未阻断无证据声明", "验证 classify 逻辑");
804
+ }
805
+ }
806
+ // 检查 2:generated_inference 单独支撑 project_fact 必须被 blocked
807
+ {
808
+ const infEv = sys.registry.register({
809
+ source_type: "generated_inference", authority: "weak", freshness: "unknown",
810
+ permission: "allowed", scope: "test", description: "推理",
811
+ });
812
+ const infClaims = [{
813
+ id: "gate-test-inference", claim_text: "项目使用 Vue", category: "tech_stack",
814
+ evidence_ids: [infEv.id], is_uncertain: false, risk_level: "high",
815
+ }];
816
+ const infResult = sys.verifier.verify(infClaims, "high");
817
+ if (infResult.unsupported.length === 0) {
818
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: generated_inference 单独支撑 project_fact 未被 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 未阻断推理自证", "验证 isSelfAttestation 逻辑");
819
+ }
820
+ }
821
+ // 检查 3:validation_plan 冒充 validation_result 必须被 blocked
822
+ {
823
+ const planEv = sys.registry.register({
824
+ source_type: "generated_inference", authority: "weak", freshness: "unknown",
825
+ permission: "allowed", scope: "test", description: "验证计划",
826
+ });
827
+ const planClaims = [{
828
+ id: "gate-test-plan-as-result", claim_text: "验证已通过",
829
+ category: "validation_result",
830
+ evidence_ids: [planEv.id], is_uncertain: false, risk_level: "high",
831
+ }];
832
+ const planResult = sys.verifier.verify(planClaims, "high");
833
+ if (planResult.unsupported.length === 0) {
834
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: validation_plan 冒充 validation_result 未被 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 未阻断验证计划冒充", "验证 validation_result 检查逻辑");
835
+ }
836
+ }
837
+ // 检查 4:forbidden source 必须被 blocked
838
+ {
839
+ const matrix = sys.builder.buildContext([], {
840
+ target_claims: [], source_types: [], keywords: [], max_results: 10,
841
+ });
842
+ matrix.evidence.push({
843
+ id: "ev-forbidden-test", source_type: "project_file",
844
+ authority: "authoritative", freshness: "current",
845
+ permission: "forbidden", scope: "sensitive",
846
+ description: "敏感数据", timestamp: new Date().toISOString(),
847
+ });
848
+ matrix.risk_summary = { low: 0, medium: 0, high: 0, critical: 1 };
849
+ const forbiddenResult = sys.gate.evaluate(matrix, "high");
850
+ if (forbiddenResult.allowed) {
851
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: forbidden source 未被 UnsupportedClaimGate 阻断", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "UnsupportedClaimGate 允许 forbidden 证据通过", "验证 forbidden 检查逻辑");
852
+ }
853
+ }
854
+ // 检查 5:conflict unresolved 必须被 blocked(高风险)
855
+ {
856
+ const confMatrix = sys.builder.buildContext([], {
857
+ target_claims: [], source_types: [], keywords: [], max_results: 10,
858
+ });
859
+ confMatrix.conflicts.push({
860
+ claim_id: "claim-conflict-test",
861
+ conflicting_evidence_ids: ["ev-a", "ev-b"],
862
+ description: "矛盾",
863
+ resolution_status: "unresolved",
864
+ });
865
+ confMatrix.risk_summary = { low: 0, medium: 0, high: 1, critical: 0 };
866
+ const confResult = sys.gate.evaluate(confMatrix, "high");
867
+ if (confResult.allowed) {
868
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: unresolved conflict 未被 UnsupportedClaimGate 阻断", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "UnsupportedClaimGate 允许未裁决冲突通过", "验证 conflict 检查逻辑");
869
+ }
870
+ }
871
+ // 检查 6:classification-only 证据不得支撑 architecture 声明
872
+ {
873
+ sys.registry.clear();
874
+ const clsOnlyEv = sys.registry.register({
875
+ source_type: "task_context", authority: "authoritative", freshness: "current",
876
+ permission: "allowed", scope: "classification", description: "任务分类结果",
877
+ });
878
+ const clsOnlyClaims = [{
879
+ id: "gate-test-cls-only", claim_text: "技术方案基于现有系统分析",
880
+ category: "architecture",
881
+ evidence_ids: [clsOnlyEv.id], is_uncertain: false, risk_level: "high",
882
+ }];
883
+ const clsOnlyResult = sys.verifier.verify(clsOnlyClaims, "high");
884
+ if (clsOnlyResult.unsupported.length === 0) {
885
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: classification-only 证据支撑 architecture 声明未被 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 允许 task_context:classification 支撑项目事实声明", "验证 CATEGORY_REQUIRED_SOURCES 逻辑");
886
+ }
887
+ }
888
+ // 检查 7:project_file + project_source_file 证据可以支撑 architecture 声明
889
+ {
890
+ sys.registry.clear();
891
+ const pfEv = sys.registry.register({
892
+ source_type: "project_file", evidence_role: "project_source_file",
893
+ authority: "authoritative", freshness: "current",
894
+ permission: "allowed", scope: "src/", description: "项目源码文件",
895
+ });
896
+ const pfClaims = [{
897
+ id: "gate-test-pf-ok", claim_text: "技术方案基于现有系统分析",
898
+ category: "architecture",
899
+ evidence_ids: [pfEv.id], is_uncertain: false, risk_level: "high",
900
+ }];
901
+ const pfResult = sys.verifier.verify(pfClaims, "high");
902
+ if (pfResult.unsupported.length > 0) {
903
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: project_source_file 证据支撑 architecture 声明被错误 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 误阻断了有效证据", "验证 CATEGORY_REQUIRED_ROLES 逻辑");
904
+ }
905
+ }
906
+ // 检查 8:template_guidance 证据不得支撑 architecture 声明
907
+ {
908
+ sys.registry.clear();
909
+ const tgEv = sys.registry.register({
910
+ source_type: "knowledge_asset", evidence_role: "template_guidance",
911
+ authority: "trusted", freshness: "current",
912
+ permission: "allowed", scope: "knowledge", description: "默认模板",
913
+ });
914
+ const tgClaims = [{
915
+ id: "gate-test-tg-block", claim_text: "技术方案基于现有系统分析",
916
+ category: "architecture",
917
+ evidence_ids: [tgEv.id], is_uncertain: false, risk_level: "high",
918
+ }];
919
+ const tgResult = sys.verifier.verify(tgClaims, "high");
920
+ if (tgResult.unsupported.length === 0) {
921
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: template_guidance 证据支撑 architecture 声明未被 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 允许 template_guidance 支撑项目事实声明", "验证 CATEGORY_REQUIRED_ROLES 逻辑");
922
+ }
923
+ }
924
+ // 检查 9:project_source_file 证据角色可以支撑 architecture 声明
925
+ {
926
+ sys.registry.clear();
927
+ const psfEv = sys.registry.register({
928
+ source_type: "project_file", evidence_role: "project_source_file",
929
+ authority: "authoritative", freshness: "current",
930
+ permission: "allowed", scope: "src/", description: "项目源码文件",
931
+ });
932
+ const psfClaims = [{
933
+ id: "gate-test-psf-ok", claim_text: "技术方案基于现有系统分析",
934
+ category: "architecture",
935
+ evidence_ids: [psfEv.id], is_uncertain: false, risk_level: "high",
936
+ }];
937
+ const psfResult = sys.verifier.verify(psfClaims, "high");
938
+ if (psfResult.unsupported.length > 0) {
939
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: project_source_file 角色支撑 architecture 声明被错误 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 误阻断了有效 project_source_file 证据", "验证 CATEGORY_REQUIRED_ROLES 逻辑");
940
+ }
941
+ }
942
+ // 检查 10:普通 code_change 不应因无 project_source_file 被 blocked(无 architecture claim 时)
943
+ {
944
+ sys.registry.clear();
945
+ const clsEv = sys.registry.register({
946
+ source_type: "task_context", evidence_role: "classification",
947
+ authority: "authoritative", freshness: "current",
948
+ permission: "allowed", scope: "classification", description: "任务分类结果",
949
+ });
950
+ // 普通 code_change 只有 user_confirmation claim(无 architecture claim)
951
+ const ccClaims = [{
952
+ id: "gate-test-cc-ok", claim_text: "任务路由和执行范围已确认",
953
+ category: "user_confirmation",
954
+ evidence_ids: [clsEv.id], is_uncertain: false, risk_level: "high",
955
+ }];
956
+ const ccResult = sys.verifier.verify(ccClaims, "high");
957
+ if (ccResult.unsupported.length > 0) {
958
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: 普通 code_change 的 user_confirmation claim 被 classification 证据错误 blocked", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 误阻断了不需要项目事实的普通任务", "验证 claim 语义逻辑");
959
+ }
960
+ }
961
+ // 检查 11:architecture_design 无真实项目证据必须 blocked
962
+ {
963
+ sys.registry.clear();
964
+ const clsOnlyEv = sys.registry.register({
965
+ source_type: "task_context", evidence_role: "classification",
966
+ authority: "authoritative", freshness: "current",
967
+ permission: "allowed", scope: "classification", description: "任务分类结果",
968
+ });
969
+ const tgOnlyEv = sys.registry.register({
970
+ source_type: "knowledge_asset", evidence_role: "template_guidance",
971
+ authority: "trusted", freshness: "current",
972
+ permission: "allowed", scope: "knowledge", description: "默认模板",
973
+ });
974
+ const archClaims = [{
975
+ id: "gate-test-arch-block", claim_text: "技术方案基于现有系统分析",
976
+ category: "architecture",
977
+ evidence_ids: [clsOnlyEv.id, tgOnlyEv.id], is_uncertain: false, risk_level: "high",
978
+ }];
979
+ const archResult = sys.verifier.verify(archClaims, "high");
980
+ if (archResult.unsupported.length === 0) {
981
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", "problem-60: architecture_design 无真实项目证据未被 blocked(classification + template_guidance 不够)", ["src/engine/evidence_grounding_contract.ts"], "problem-60", "FactClaimVerifier 允许非项目证据支撑架构声明", "验证 CATEGORY_REQUIRED_ROLES + claim 语义逻辑");
982
+ }
983
+ }
984
+ }
985
+ catch (behaviorErr) {
986
+ hardFail("CRITICAL_PROBLEM_BEHAVIOR", `problem-60: 行为级检查执行失败: ${behaviorErr?.message ?? behaviorErr}`, ["src/engine/evidence_grounding_contract.ts"], "problem-60", "证据驱动机制行为检查不可执行", "修复 import 或机制代码");
987
+ }
988
+ }
989
+ // 静态检查:导出完整性
990
+ const egContent = safeRead(evidenceGroundingPath);
991
+ if (egContent) {
992
+ const requiredExports = ["createEvidenceGroundingSystem", "assessTaskRisk", "EvidenceSourceRegistry", "FactClaimVerifier", "UnsupportedClaimGate"];
993
+ for (const exp of requiredExports) {
994
+ if (!egContent.includes(exp)) {
995
+ hardFail("CRITICAL_PROBLEM_EXPORT_MISSING", `problem-60: evidence_grounding_contract.ts 缺少导出: ${exp}`, ["src/engine/evidence_grounding_contract.ts"], "problem-60", "证据驱动机制缺少核心导出", `添加 ${exp} 导出`);
996
+ }
997
+ }
998
+ }
999
+ // 静态检查:InstructionContract schema 必须包含 evidence 字段
1000
+ const instrContractPath = path.join(rootDir, "src/engine/instruction_contract.ts");
1001
+ const instrContent = safeRead(instrContractPath);
1002
+ if (instrContent) {
1003
+ const evidenceFields = ["evidence_matrix", "unsupported_claim_policy", "uncertainty_policy", "conflict_resolution_policy"];
1004
+ for (const field of evidenceFields) {
1005
+ if (!instrContent.includes(field)) {
1006
+ hardFail("CRITICAL_PROBLEM_SCHEMA_INCOMPLETE", `problem-60: instruction_contract.ts schema 缺少证据字段: ${field}`, ["src/engine/instruction_contract.ts"], "problem-60", "施工指令契约缺少证据驱动字段", `添加 ${field} 字段`);
1007
+ }
1008
+ }
1009
+ }
1010
+ // 静态检查:主链路必须有 runtime 阻断(不能只是 advisory)
1011
+ const toolsPath = path.join(rootDir, "src/adapters/claude_code/tools.ts");
1012
+ const toolsContent = safeRead(toolsPath);
1013
+ if (!toolsContent?.includes("evidence_grounding_contract")) {
1014
+ hardFail("CRITICAL_PROBLEM_NOT_CONSUMED", "problem-60: tools.ts 未消费 evidence_grounding_contract", ["src/adapters/claude_code/tools.ts"], "problem-60", "证据驱动机制未接入主链路", "在 sf_expand/sf_verify/sf_deliver 中接入");
1015
+ }
1016
+ // sf_expand 必须有 blocked/manual_required 分支
1017
+ if (toolsContent && !toolsContent.includes("_evGate.allowed") && !toolsContent.includes("evidence_blocked")) {
1018
+ hardFail("CRITICAL_PROBLEM_ADVISORY_ONLY", "problem-60: sf_expand 证据检查只有 advisory,缺少 blocked 分支", ["src/adapters/claude_code/tools.ts"], "problem-60", "sf_expand 证据门禁不阻断", "添加 evidence gate blocked 分支");
1019
+ }
1020
+ // sf_verify: 验证计划描述行中不得包含 source_type: "validation_result"
1021
+ if (toolsContent) {
1022
+ // 找到 sf_verify handler 中问题六十部分
1023
+ const verifyStart = toolsContent.indexOf("问题六十:验证结论必须经过 FactClaimVerifier");
1024
+ const verifyEnd = toolsContent.indexOf("// 验证后核心体验评估", verifyStart);
1025
+ if (verifyStart >= 0 && verifyEnd >= 0) {
1026
+ const verifySection = toolsContent.substring(verifyStart, verifyEnd);
1027
+ // 检查验证计划注册调用中是否使用了 validation_result
1028
+ const planRegMatch = verifySection.match(/register\(\{[^}]*验证计划:[^}]*\}\)/s);
1029
+ if (planRegMatch && planRegMatch[0].includes("source_type: \"validation_result\"")) {
1030
+ hardFail("CRITICAL_PROBLEM_PLAN_AS_RESULT", "problem-60: sf_verify 把验证计划注册为 validation_result", ["src/adapters/claude_code/tools.ts"], "problem-60", "验证计划冒充验证结果", "验证计划应注册为 task_context 类型");
1031
+ }
1032
+ }
1033
+ }
1034
+ // 静态检查:负向测试
1035
+ const testPath = path.join(rootDir, "tests/engine/evidence_grounding_contract.test.ts");
1036
+ if (!fs.existsSync(testPath)) {
1037
+ hardFail("CRITICAL_PROBLEM_TEST_MISSING", "problem-60: 缺少负向测试文件", ["tests/engine/evidence_grounding_contract.test.ts"], "problem-60", "证据驱动机制缺少测试覆盖", "创建 evidence_grounding_contract.test.ts");
1038
+ }
1039
+ // 静态检查:知识规则
1040
+ const kaRulePath = path.join(rootDir, "templates/knowledge/rules/证据驱动与反幻觉规则.md");
1041
+ if (!fs.existsSync(kaRulePath)) {
1042
+ hardFail("CRITICAL_PROBLEM_ASSET_MISSING", "problem-60: 缺少知识规则文件 证据驱动与反幻觉规则.md", ["templates/knowledge/rules/证据驱动与反幻觉规则.md"], "problem-60", "证据驱动知识规则缺失", "创建知识规则文件");
1043
+ }
1044
+ // 静态检查:workflow_template
1045
+ const wfPath = path.join(rootDir, "src/adapters/shared/workflow_template.ts");
1046
+ const wfContent = safeRead(wfPath);
1047
+ if (!wfContent?.includes("wf-evidence-grounding")) {
1048
+ hardFail("CRITICAL_PROBLEM_TEMPLATE_MISSING", "problem-60: workflow_template.ts 缺少 wf-evidence-grounding 硬规则", ["src/adapters/shared/workflow_template.ts"], "problem-60", "工作流模板未包含证据驱动规则", "添加 wf-evidence-grounding 硬规则");
1049
+ }
1050
+ // 静态检查:TaskContext 类型必须有证据字段
1051
+ const typesPath = path.join(rootDir, "src/types.ts");
1052
+ const typesContent = safeRead(typesPath);
1053
+ if (typesContent && !typesContent.includes("evidence_matrix?:") && !typesContent.includes("evidence_gate_result?:")) {
1054
+ hardFail("CRITICAL_PROBLEM_TASKCTX_MISSING", "problem-60: TaskContext 缺少 evidence_matrix/evidence_gate_result 字段", ["src/types.ts"], "problem-60", "TaskContext 未保存证据结果", "添加 evidence_matrix 和 evidence_gate_result 字段");
1055
+ }
1056
+ // 静态检查:task_context.ts 必须有 setEvidenceGroundingResult 写入方法
1057
+ const tcPath = path.join(rootDir, "src/engine/task_context.ts");
1058
+ const tcContent = safeRead(tcPath);
1059
+ if (tcContent && !tcContent.includes("setEvidenceGroundingResult")) {
1060
+ hardFail("CRITICAL_PROBLEM_NO_WRITEBACK", "problem-60: task_context.ts 缺少 setEvidenceGroundingResult 写入方法", ["src/engine/task_context.ts"], "problem-60", "TaskContext 只有类型字段没有写入方法", "添加 setEvidenceGroundingResult 方法");
1061
+ }
1062
+ // 静态检查:tools.ts 主链路必须调用 setEvidenceGroundingResult
1063
+ if (toolsContent && !toolsContent.includes("setEvidenceGroundingResult")) {
1064
+ hardFail("CRITICAL_PROBLEM_NO_RUNTIME_WRITEBACK", "problem-60: tools.ts 未调用 setEvidenceGroundingResult 写回 TaskContext", ["src/adapters/claude_code/tools.ts"], "problem-60", "主链路不写回证据结果到 TaskContext", "在 sf_expand/sf_verify/sf_deliver 中调用 setEvidenceGroundingResult");
1065
+ }
1066
+ // 静态检查:tools.ts 不得出现 registry.query({}).map() 无差别证据绑定
1067
+ if (toolsContent) {
1068
+ const toolsLines = toolsContent.split("\n");
1069
+ for (let i = 0; i < toolsLines.length; i++) {
1070
+ if (/registry\.query\(\{\}\)\.map/.test(toolsLines[i])) {
1071
+ hardFail("CRITICAL_PROBLEM_INDISCRIMINATE_BINDING", `problem-60: tools.ts:${i + 1} 使用 registry.query({}).map() 无差别绑定证据到所有 claim`, ["src/adapters/claude_code/tools.ts"], "problem-60", "所有 registry 证据被无差别绑定到所有 claim,不区分语义", "按 claim 语义筛选 evidence_ids");
1072
+ }
1073
+ }
1074
+ }
1075
+ // 行为检查:setEvidenceGroundingResult 写入后 load 能读回
1076
+ try {
1077
+ const tcModule = await import(path.join(rootDir, "dist/engine/task_context.js"));
1078
+ const tmpStateDir = path.join(rootDir, ".soloforge", "state");
1079
+ const fsModule = await import("node:fs");
1080
+ if (!fsModule.existsSync(tmpStateDir)) {
1081
+ fsModule.mkdirSync(tmpStateDir, { recursive: true });
1082
+ }
1083
+ const tmpMgr = new tcModule.TaskContextManager(tmpStateDir);
1084
+ const tmpCtx = await tmpMgr.create("gate-evidence-writeback-test", "test");
1085
+ const testMatrix = {
1086
+ task_id: tmpCtx.task_id, claims: [], evidence: [],
1087
+ conflicts: [], unsupported_claims: ["test-claim"],
1088
+ risk_summary: { low: 0, medium: 0, high: 1, critical: 0 },
1089
+ created_at: new Date().toISOString(),
1090
+ };
1091
+ const testGate = {
1092
+ allowed: false, reason_zh: "测试", diagnostic_code: "SF-EVIDENCE-TEST",
1093
+ unsupported_claims: ["test-claim"], unresolved_conflicts: [],
1094
+ missing_evidence: [], risk_level: "high",
1095
+ requires_user_confirmation: [],
1096
+ };
1097
+ await tmpMgr.setEvidenceGroundingResult(tmpCtx.task_id, {
1098
+ evidence_matrix: testMatrix,
1099
+ evidence_gate_result: testGate,
1100
+ unsupported_claims: ["test-claim"],
1101
+ });
1102
+ const loaded = await tmpMgr.load(tmpCtx.task_id);
1103
+ if (!loaded?.evidence_matrix || !loaded?.evidence_gate_result) {
1104
+ hardFail("CRITICAL_PROBLEM_WRITEBACK_FAILED", "problem-60: setEvidenceGroundingResult 写入后 load 无法读回", ["src/engine/task_context.ts"], "problem-60", "TaskContext 写入方法不工作", "修复 setEvidenceGroundingResult 或 save/load");
1105
+ }
1106
+ if (loaded.evidence_gate_result?.allowed !== false) {
1107
+ hardFail("CRITICAL_PROBLEM_WRITEBACK_CORRUPT", "problem-60: setEvidenceGroundingResult 写入的 gate result 数据损坏", ["src/engine/task_context.ts"], "problem-60", "写入的 allowed=false 被读回为 true", "检查序列化逻辑");
1108
+ }
1109
+ // 清理测试任务
1110
+ try {
1111
+ fsModule.rmSync(path.join(tmpStateDir, `${tmpCtx.task_id}.json`), { force: true });
1112
+ }
1113
+ catch { }
1114
+ }
1115
+ catch (wbErr) {
1116
+ hardFail("CRITICAL_PROBLEM_WRITEBACK_ERROR", `problem-60: setEvidenceGroundingResult 行为检查失败: ${wbErr?.message ?? wbErr}`, ["src/engine/task_context.ts"], "problem-60", "TaskContext 写入方法不可用", "修复 import 或方法实现");
1117
+ }
1118
+ }
1119
+ _info(" problem-60 证据驱动消费验证完成");
1120
+ }
1121
+ // ── 7. Batch 问题文档格式一致性 ──
1122
+ async function checkBatchIssueFormatConsistency(rootDir, hardFail, _info) {
1123
+ // 复用 scripts/batch_issue_details.mjs 的共享解析逻辑,不维护独立的问题识别规则
1124
+ const scriptPath = path.join(rootDir, "scripts", "batch_issue_details.mjs");
1125
+ let loadBatchIssueDetails;
1126
+ try {
1127
+ const mod = await import(scriptPath);
1128
+ loadBatchIssueDetails = mod.loadBatchIssueDetails;
1129
+ }
1130
+ catch (e) {
1131
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", `无法加载共享解析脚本: ${e.message}`, ["scripts/batch_issue_details.mjs"], "构建系统", "共享解析脚本不可用", "修复脚本");
1132
+ return;
1133
+ }
1134
+ if (!loadBatchIssueDetails) {
1135
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", "loadBatchIssueDetails 导出未找到", ["scripts/batch_issue_details.mjs"], "构建系统", "共享解析脚本导出不正确", "修复脚本");
1136
+ return;
1137
+ }
1138
+ const expectedCounts = { 1: 19, 2: 12, 3: 9, 4: 13, 5: 6, 6: 2 };
1139
+ const requiredPerProblemSections = [
1140
+ "问题背景", "用户反馈 / 触发场景", "根因分析", "解决方案", "方案细节",
1141
+ "硬规则", "非目标", "影响范围", "落地文件", "验收标准", "回归风险",
1142
+ "与其他问题的关联", "发布门禁要求",
1143
+ ];
1144
+ for (let batch = 1; batch <= 6; batch++) {
1145
+ const details = loadBatchIssueDetails(batch, rootDir);
1146
+ if (!details.loaded) {
1147
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", `Batch${batch} 问题集未加载: ${details.error}`, [`docs/SoloForge-Batch${batch}问题集.md`], `Batch${batch}`, "旧 gate 只检查文档存在,不验证是否可解析", "第 3 步统一格式");
1148
+ continue;
1149
+ }
1150
+ // 检查问题数量(问题X 已被 loadBatchIssueDetails 过滤)
1151
+ const expected = expectedCounts[batch];
1152
+ if (details.issue_count !== expected) {
1153
+ hardFail("BATCH_ISSUE_COUNT_MISMATCH", `Batch${batch} 实际问题数=${details.issue_count},期望=${expected}`, [`docs/SoloForge-Batch${batch}问题集.md`], `Batch${batch}`, "旧 gate 不检查问题数量一致性", "第 3 步统一格式");
1154
+ }
1155
+ // 检查方案细节表和落点表
1156
+ const content = details.markdown;
1157
+ if (!/Batch\s+\d+\s+全问题方案细节表/.test(content)) {
1158
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", `Batch${batch} 缺少全问题方案细节表`, [`docs/SoloForge-Batch${batch}问题集.md`], `Batch${batch}`, "旧 gate 不检查文档结构一致性", "第 3 步统一格式");
1159
+ }
1160
+ if (!/Batch\s+\d+\s+全问题(细节)?落点表/.test(content)) {
1161
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", `Batch${batch} 缺少全问题落点表`, [`docs/SoloForge-Batch${batch}问题集.md`], `Batch${batch}`, "旧 gate 不检查文档结构一致性", "第 3 步统一格式");
1162
+ }
1163
+ if (!/Batch\s+\d+\s+全问题真实性落点表/.test(content)) {
1164
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", `Batch${batch} 缺少全问题真实性落点表`, [`docs/SoloForge-Batch${batch}问题集.md`], `Batch${batch}`, "旧 gate 不检查文档结构一致性", "第 3 步统一格式");
1165
+ }
1166
+ // 基于 loadBatchIssueDetails 结果检查必备章节
1167
+ for (const issue of details.issues) {
1168
+ const sectionNames = (issue.sections || []).map((s) => s.heading);
1169
+ const missing = requiredPerProblemSections.filter(s => !sectionNames.some(sn => sn.includes(s)));
1170
+ if (missing.length > 0) {
1171
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", `Batch${batch} ${issue.issue_label} 缺少必备章节: ${missing.join(", ")}(其他 Batch 的问题均有这些章节)`, [`docs/SoloForge-Batch${batch}问题集.md`], `Batch${batch}/${issue.issue_label}`, "旧 gate 只检查文档存在和行数,不检查问题内部结构完整性", "第 3 步统一格式");
1172
+ }
1173
+ // 检查章节顺序
1174
+ const expectedOrder = [
1175
+ "问题背景", "用户反馈 / 触发场景", "根因分析", "解决方案", "方案细节",
1176
+ "硬规则", "非目标", "影响范围", "落地文件", "验收标准", "回归风险",
1177
+ "与其他问题的关联", "发布门禁要求",
1178
+ ];
1179
+ if (sectionNames.length >= expectedOrder.length) {
1180
+ const orderOk = expectedOrder.length === sectionNames.length
1181
+ && expectedOrder.every((v, i) => sectionNames[i] === v);
1182
+ if (!orderOk) {
1183
+ hardFail("BATCH_ISSUE_FORMAT_INCONSISTENT", `Batch${batch} ${issue.issue_label} 章节顺序不符合模板要求: 实际 ${sectionNames.slice(0, 5).join(", ")}...`, [`docs/SoloForge-Batch${batch}问题集.md`], `Batch${batch}/${issue.issue_label}`, "旧 gate 只检查章节存在,不检查章节顺序", "第 3 步统一格式");
1184
+ }
1185
+ }
1186
+ }
1187
+ _info(` Batch${batch}: 已检查 (${details.issue_count} 个问题)`);
1188
+ }
1189
+ _info(" 说明: 本检查不修改文档。格式不一致问题将在第 3 步统一处理。");
1190
+ }
1191
+ // ── 机制身份一致性 ──
1192
+ async function checkMechanismIdentityConsistency(rootDir, hardFail, _info) {
1193
+ // 加载 DL registry
1194
+ const dlPath = path.join(rootDir, "dist/engine/dual_layer_mechanism_registry.js");
1195
+ if (!fs.existsSync(dlPath)) {
1196
+ hardFail("MECHANISM_IDENTITY", "dual_layer_mechanism_registry.js 未编译", ["dist/engine/"], "机制身份一致性", "旧 gate 不检查机制身份一致性", "npm run build");
1197
+ return;
1198
+ }
1199
+ let dlModule;
1200
+ try {
1201
+ dlModule = await import(dlPath);
1202
+ }
1203
+ catch (e) {
1204
+ hardFail("MECHANISM_IDENTITY", `无法加载 dual_layer_mechanism_registry: ${e.message}`, ["dist/engine/"], "机制身份一致性", "旧 gate 不检查机制身份一致性", "修复编译错误");
1205
+ return;
1206
+ }
1207
+ const canonicalIds = dlModule.getAllCanonicalMechanismIds();
1208
+ const resolveId = dlModule.resolveMechanismId;
1209
+ const aliases = dlModule.MECHANISM_ALIASES;
1210
+ // 加载 MC registry
1211
+ const mcPath = path.join(rootDir, "dist/engine/mechanism_contract_registry.js");
1212
+ if (!fs.existsSync(mcPath)) {
1213
+ hardFail("MECHANISM_IDENTITY", "mechanism_contract_registry.js 未编译", ["dist/engine/"], "机制身份一致性", "旧 gate 不检查机制身份一致性", "npm run build");
1214
+ return;
1215
+ }
1216
+ let mcModule;
1217
+ try {
1218
+ mcModule = await import(mcPath);
1219
+ }
1220
+ catch (e) {
1221
+ hardFail("MECHANISM_IDENTITY", `无法加载 mechanism_contract_registry: ${e.message}`, ["dist/engine/"], "机制身份一致性", "旧 gate 不检查机制身份一致性", "修复编译错误");
1222
+ return;
1223
+ }
1224
+ const mcContracts = mcModule.listMechanismContracts();
1225
+ // 检查 MC 中 active/enforced 的机制必须能解析到 DL canonical ID
1226
+ for (const c of mcContracts) {
1227
+ if (c.status === "deprecated")
1228
+ continue;
1229
+ const resolved = resolveId(c.id);
1230
+ if (!canonicalIds.has(resolved)) {
1231
+ hardFail("MECHANISM_IDENTITY", `mechanism_contract_registry 中 ${c.id} (status=${c.status}) 无法解析到 dual_layer_mechanism_registry 的正式机制 ID (resolved=${resolved})`, ["src/engine/mechanism_contract_registry.ts", "src/engine/dual_layer_mechanism_registry.ts"], c.id, "旧 gate 不检查 MC 与 DL 的机制身份一致性", `在 dual_layer_mechanism_registry.ts 中添加 ${resolved} 或建立 alias 映射`);
1232
+ }
1233
+ }
1234
+ // 检查 DL 中的机制必须能解析到 MC 中(canonical 或 deprecated alias)
1235
+ const mcIds = new Set(mcContracts.map((c) => c.id));
1236
+ for (const id of canonicalIds) {
1237
+ if (!mcIds.has(id)) {
1238
+ hardFail("MECHANISM_IDENTITY", `dual_layer_mechanism_registry 中 ${id} 在 mechanism_contract_registry 中不存在`, ["src/engine/dual_layer_mechanism_registry.ts", "src/engine/mechanism_contract_registry.ts"], id, "旧 gate 不检查 DL 与 MC 的双向一致性", `在 mechanism_contract_registry.ts 中添加 ${id}`);
1239
+ }
1240
+ }
1241
+ // 检查 templates/knowledge frontmatter owner_mechanism_id 可解析
1242
+ const knowledgeDir = path.join(rootDir, "templates/knowledge");
1243
+ if (fs.existsSync(knowledgeDir)) {
1244
+ const knowledgeFiles = findFilesRecursive(knowledgeDir, ".md");
1245
+ for (const f of knowledgeFiles) {
1246
+ const content = safeRead(f);
1247
+ if (!content)
1248
+ continue;
1249
+ const match = content.match(/^owner_mechanism_id:\s*(.+)$/m);
1250
+ if (match) {
1251
+ const ownerId = match[1].trim();
1252
+ const resolved = resolveId(ownerId);
1253
+ if (!canonicalIds.has(resolved)) {
1254
+ hardFail("MECHANISM_IDENTITY", `模板 ${path.relative(rootDir, f)} 的 owner_mechanism_id="${ownerId}" 无法解析到正式机制 ID (resolved=${resolved})`, [path.relative(rootDir, f)], ownerId, "旧 gate 不检查知识模板的 owner_mechanism_id 可解析性", `将 owner_mechanism_id 改为正式机制 ID 或建立 alias 映射`);
1255
+ }
1256
+ }
1257
+ }
1258
+ }
1259
+ // 检查 consumable_asset_registry owner_mechanism_id 可解析
1260
+ const carPath = path.join(rootDir, "dist/engine/consumable_asset_registry.js");
1261
+ if (fs.existsSync(carPath)) {
1262
+ try {
1263
+ const carModule = await import(carPath);
1264
+ const assets = carModule.listBuiltinConsumableAssets();
1265
+ for (const a of assets) {
1266
+ if (!a.owner_mechanism_id)
1267
+ continue;
1268
+ const resolved = resolveId(a.owner_mechanism_id);
1269
+ if (!canonicalIds.has(resolved)) {
1270
+ hardFail("MECHANISM_IDENTITY", `consumable_asset_registry 中 ${a.id} 的 owner_mechanism_id="${a.owner_mechanism_id}" 无法解析到正式机制 ID`, ["src/engine/consumable_asset_registry.ts"], a.owner_mechanism_id, "旧 gate 不检查 consumable_asset 的 owner_mechanism_id 可解析性", `将 owner_mechanism_id 改为正式机制 ID 或建立 alias 映射`);
1271
+ }
1272
+ }
1273
+ }
1274
+ catch { /* 模块加载失败,跳过 */ }
1275
+ }
1276
+ // 检查 workflow_contract_registry required_mechanisms/advisory_mechanisms 可解析
1277
+ const wcPath = path.join(rootDir, "dist/engine/workflow_contract_registry.js");
1278
+ if (fs.existsSync(wcPath)) {
1279
+ try {
1280
+ const wcModule = await import(wcPath);
1281
+ const contracts = wcModule.listWorkflowContracts();
1282
+ for (const c of contracts) {
1283
+ for (const mId of [...c.required_mechanisms, ...c.advisory_mechanisms]) {
1284
+ const resolved = resolveId(mId);
1285
+ if (!canonicalIds.has(resolved)) {
1286
+ hardFail("MECHANISM_IDENTITY", `workflow_contract_registry 中 ${c.id} 引用机制 "${mId}" 无法解析到正式机制 ID (resolved=${resolved})`, ["src/engine/workflow_contract_registry.ts"], mId, "旧 gate 不检查 workflow required_mechanisms 的可解析性", `将 ${mId} 改为正式机制 ID 或建立 alias 映射`);
1287
+ }
1288
+ }
1289
+ }
1290
+ }
1291
+ catch { /* 模块加载失败,跳过 */ }
1292
+ }
1293
+ // 检查 asset_manifest owner_mechanism_id 可解析
1294
+ const amSrcPath = path.join(rootDir, "src/engine/asset_manifest.ts");
1295
+ if (fs.existsSync(amSrcPath)) {
1296
+ const amContent = safeRead(amSrcPath);
1297
+ if (amContent) {
1298
+ const ownerMatches = amContent.matchAll(/owner_mechanism_id:\s*"([^"]+)"/g);
1299
+ for (const m of ownerMatches) {
1300
+ const ownerId = m[1];
1301
+ const resolved = resolveId(ownerId);
1302
+ if (!canonicalIds.has(resolved)) {
1303
+ hardFail("MECHANISM_IDENTITY", `asset_manifest.ts 中 owner_mechanism_id="${ownerId}" 无法解析到正式机制 ID`, ["src/engine/asset_manifest.ts"], ownerId, "旧 gate 不检查 asset_manifest 的 owner_mechanism_id 可解析性", `将 owner_mechanism_id 改为正式机制 ID 或建立 alias 映射`);
1304
+ }
1305
+ }
1306
+ }
1307
+ }
1308
+ }
1309
+ function findFilesRecursive(dir, ext) {
1310
+ const results = [];
1311
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
1312
+ const full = path.join(dir, entry.name);
1313
+ if (entry.isDirectory())
1314
+ results.push(...findFilesRecursive(full, ext));
1315
+ else if (entry.name.endsWith(ext))
1316
+ results.push(full);
1317
+ }
1318
+ return results;
1319
+ }
1320
+ // ── Phase 10: P0/P1 知识资产 schema 完整性 ──
1321
+ async function checkKnowledgeAssetSchema(rootDir, hardFail, _info) {
1322
+ const matter = (await import("gray-matter")).default;
1323
+ const { validateKnowledgeAssetFrontmatter } = await import("./knowledge_asset_schema.js");
1324
+ const knowledgeDir = path.join(rootDir, "templates", "knowledge");
1325
+ if (!fs.existsSync(knowledgeDir))
1326
+ return;
1327
+ const mdFiles = findFilesRecursive(knowledgeDir, ".md");
1328
+ for (const filePath of mdFiles) {
1329
+ const raw = fs.readFileSync(filePath, "utf-8");
1330
+ const { data: frontmatter } = matter(raw);
1331
+ if (!frontmatter || Object.keys(frontmatter).length === 0)
1332
+ continue;
1333
+ if (!frontmatter.asset_kind)
1334
+ continue;
1335
+ const findings = validateKnowledgeAssetFrontmatter(frontmatter, filePath);
1336
+ for (const f of findings) {
1337
+ if (f.severity === "hard_fail") {
1338
+ hardFail(`KA_SCHEMA_${f.kind}`, f.message_zh, [filePath], f.asset_id, "旧 validate-release 不独立校验知识资产 schema", "补齐缺失的 frontmatter 字段");
1339
+ }
1340
+ }
1341
+ }
1342
+ }
1343
+ // ── Phase 11: engine console.log 检查 ──
1344
+ function checkEngineConsoleLog(rootDir, hardFail) {
1345
+ const targets = ["src/engine/", "src/index.ts"];
1346
+ for (const target of targets) {
1347
+ const fullTarget = path.join(rootDir, target);
1348
+ if (!fs.existsSync(fullTarget))
1349
+ continue;
1350
+ const isDir = fs.statSync(fullTarget).isDirectory();
1351
+ const files = isDir
1352
+ ? findFilesRecursive(fullTarget, ".ts")
1353
+ : [fullTarget];
1354
+ for (const file of files) {
1355
+ const content = fs.readFileSync(file, "utf-8");
1356
+ const lines = content.split("\n");
1357
+ for (let i = 0; i < lines.length; i++) {
1358
+ const line = lines[i];
1359
+ if (/^\s*\/\//.test(line))
1360
+ continue;
1361
+ if (/^\s*\*|^\s*\/\*/.test(line))
1362
+ continue;
1363
+ if (/"console\.log"|`console\.log`|'console\.log'|console\\.log/.test(line))
1364
+ continue;
1365
+ // 日志模块内部 stdout 封装允许 console.log
1366
+ if (/logger\.ts$/.test(file) && /^\s*console\.log\(/.test(line))
1367
+ continue;
1368
+ if (/console\.log\s*\(/.test(line)) {
1369
+ const rel = path.relative(rootDir, file);
1370
+ hardFail("ENGINE_CONSOLE_LOG", `${rel}:${i + 1} 使用 console.log(应使用 logger 或 console.error 写 stderr)`, [rel], "发布门禁 console 检查", "旧 gate 不检查 engine console.log", "替换为 logger 模块调用");
1371
+ }
1372
+ }
1373
+ }
1374
+ }
1375
+ }
1376
+ // ── Phase 12: 中文注释检查 ──
1377
+ function checkChineseComments(rootDir, hardFail) {
1378
+ const srcDir = path.join(rootDir, "src");
1379
+ if (!fs.existsSync(srcDir))
1380
+ return;
1381
+ const tsFiles = findFilesRecursive(srcDir, ".ts");
1382
+ for (const file of tsFiles) {
1383
+ const content = fs.readFileSync(file, "utf-8");
1384
+ const lines = content.split("\n");
1385
+ for (let i = 0; i < lines.length; i++) {
1386
+ const line = lines[i];
1387
+ if (!/^\s*\/\//.test(line))
1388
+ continue;
1389
+ if (/[一-龥]/.test(line))
1390
+ continue;
1391
+ // 跳过装饰分隔线
1392
+ if (/^\s*\/\/\s*[─═\-~=*#]+\s*$/.test(line))
1393
+ continue;
1394
+ // 跳过工具指令
1395
+ if (/@ts-|eslint|TODO|FIXME|NOTE|prettier|istanbul|c8/.test(line))
1396
+ continue;
1397
+ // 跳过机制 ID 标签
1398
+ if (/\/\/\s*──\s*\d+\./.test(line))
1399
+ continue;
1400
+ if (/\/\/\s*mc-[a-z]/.test(line))
1401
+ continue;
1402
+ // 跳过纯代码标识符
1403
+ if (/^\s*\/\/\s*[a-z][a-z0-9_.\/-]+\s*$/.test(line))
1404
+ continue;
1405
+ // 跳过大小标注
1406
+ if (/^\s*\/\/\s*\d+\s*(MB|KB|GB|ms|min|分钟|秒)/.test(line))
1407
+ continue;
1408
+ // 跳过技术术语注释
1409
+ if (/^\s*\/\/\s*[a-z_]+\.[a-z_]+/.test(line))
1410
+ continue;
1411
+ // 检查连续 4+ 字母
1412
+ if (/[a-zA-Z]{4,}/.test(line)) {
1413
+ const rel = path.relative(rootDir, file);
1414
+ hardFail("ENGLISH_COMMENT", `${rel}:${i + 1}: ${line.trim()}(应使用中文注释)`, [rel], "中文注释检查", "旧 gate 不检查中文注释", "将英文注释改为中文");
1415
+ }
1416
+ }
1417
+ }
1418
+ }
1419
+ // ── 13. 第五批文档↔roadmap↔scenario 一致性 ──
1420
+ async function checkLastBatchConsistency(rootDir, hardFail, _info) {
1421
+ // 动态导入避免循环依赖
1422
+ const roadmapPath = path.join(rootDir, "dist", "engine", "implementation_roadmap_registry.js");
1423
+ const scenarioPath = path.join(rootDir, "dist", "engine", "release_gate_scenario_registry.js");
1424
+ let listAllProblems;
1425
+ let listBatches;
1426
+ let RELEASE_GATE_SCENARIOS;
1427
+ let runAllReleaseGateScenarios;
1428
+ try {
1429
+ const roadmap = await import(roadmapPath);
1430
+ listAllProblems = roadmap.listAllProblems;
1431
+ listBatches = roadmap.listBatches;
1432
+ }
1433
+ catch {
1434
+ hardFail("LAST_BATCH_CONSISTENCY", "无法导入 implementation_roadmap_registry", ["src/engine/implementation_roadmap_registry.ts"], "末批一致性", "旧 gate 不检查 roadmap↔scenario 一致性", "先 build");
1435
+ return;
1436
+ }
1437
+ try {
1438
+ const scenario = await import(scenarioPath);
1439
+ RELEASE_GATE_SCENARIOS = scenario.RELEASE_GATE_SCENARIOS;
1440
+ runAllReleaseGateScenarios = scenario.runAllReleaseGateScenarios;
1441
+ }
1442
+ catch {
1443
+ hardFail("LAST_BATCH_CONSISTENCY", "无法导入 release_gate_scenario_registry", ["src/engine/release_gate_scenario_registry.ts"], "末批一致性", "旧 gate 不检查 roadmap↔scenario 一致性", "先 build");
1444
+ return;
1445
+ }
1446
+ // 1. 末批必须存在且包含 problem-55 到 problem-60
1447
+ const batches = listBatches();
1448
+ const lastBatch = batches.find((b) => b.batch_id === "batch-5");
1449
+ if (!lastBatch) {
1450
+ hardFail("LAST_BATCH_CONSISTENCY", "implementation_roadmap_registry 缺少 batch-5", ["src/engine/implementation_roadmap_registry.ts"], "末批一致性", "旧 gate 不检查末批是否存在于 roadmap", "新增 batch-5 并登记 problem-55 到 problem-60");
1451
+ return;
1452
+ }
1453
+ const expectedLastProblems = ["problem-55", "problem-56", "problem-57", "problem-58", "problem-59", "problem-60"];
1454
+ const missing = expectedLastProblems.filter((pid) => !lastBatch.included_problem_ids.includes(pid));
1455
+ if (missing.length > 0) {
1456
+ hardFail("LAST_BATCH_CONSISTENCY", `batch-5 缺少问题: ${missing.join(", ")}`, ["src/engine/implementation_roadmap_registry.ts"], "末批一致性", "旧 gate 不检查末批问题归属完整性", `将 ${missing.join(", ")} 加入 batch-5`);
1457
+ }
1458
+ // 2. problem-58 和 problem-60 不得在 batch-4
1459
+ const prevBatch = batches.find((b) => b.batch_id === "batch-4");
1460
+ if (prevBatch) {
1461
+ const misattrib = ["problem-58", "problem-60"].filter((pid) => prevBatch.included_problem_ids.includes(pid));
1462
+ if (misattrib.length > 0) {
1463
+ hardFail("LAST_BATCH_CONSISTENCY", `problem-58/60 错误归属到 batch-4: ${misattrib.join(", ")}`, ["src/engine/implementation_roadmap_registry.ts"], "末批一致性", "旧 gate 不检查问题是否被错误归入其他批次", "将 problem-58/60 从 batch-4 迁到 batch-5");
1464
+ }
1465
+ }
1466
+ // 3. 场景矩阵必须覆盖问题五十五到问题六十
1467
+ const scenarios = RELEASE_GATE_SCENARIOS;
1468
+ const allCoveredIssues = scenarios.flatMap((s) => s.covered_issues);
1469
+ const expectedIssueLabels = ["问题五十五", "问题五十六", "问题五十七", "问题五十八", "问题五十九", "问题六十"];
1470
+ const uncovered = expectedIssueLabels.filter((label) => !allCoveredIssues.includes(label));
1471
+ if (uncovered.length > 0) {
1472
+ hardFail("LAST_BATCH_CONSISTENCY", `场景矩阵未覆盖: ${uncovered.join(", ")}`, ["src/engine/release_gate_scenario_registry.ts"], "末批一致性", "旧 gate 不检查场景矩阵是否覆盖所有末批问题", `为 ${uncovered.join(", ")} 新增场景`);
1473
+ }
1474
+ // 4. 场景矩阵必须全部通过
1475
+ const results = runAllReleaseGateScenarios();
1476
+ const failedScenarios = results.filter((r) => !r.passed);
1477
+ if (failedScenarios.length > 0) {
1478
+ hardFail("LAST_BATCH_CONSISTENCY", `场景矩阵未全部通过: ${failedScenarios.map((r) => `${r.scenario_id}: ${r.failures.join("; ")}`).join(", ")}`, ["src/engine/release_gate_scenario_registry.ts"], "末批一致性", "旧 gate 不运行场景矩阵验证", "修复失败场景");
1479
+ }
1480
+ _info(" 第五批一致性校验通过");
1481
+ }
1482
+ // ── 14. 依赖漏洞扫描 ──
1483
+ function checkDependencyAudit(rootDir, hardFail, _info) {
1484
+ const reportPath = path.join(rootDir, ".soloforge", "advisory-report.json");
1485
+ if (!fs.existsSync(reportPath)) {
1486
+ hardFail("DEPENDENCY_AUDIT", "未找到依赖漏洞扫描报告 (.soloforge/advisory-report.json)", ["package.json"], "依赖健康", "旧 gate 不检查依赖漏洞", "运行 npm run audit-deps");
1487
+ return;
1488
+ }
1489
+ try {
1490
+ const report = JSON.parse(fs.readFileSync(reportPath, "utf-8"));
1491
+ if (!report.timestamp) {
1492
+ hardFail("DEPENDENCY_AUDIT", "漏洞扫描报告缺少时间戳", ["package.json"], "依赖健康", "旧 gate 不验证报告完整性", "重新运行 npm run audit-deps");
1493
+ return;
1494
+ }
1495
+ // 报告过期检查: 超过 24 小时视为过期
1496
+ const reportAge = Date.now() - new Date(report.timestamp).getTime();
1497
+ const maxAge = 24 * 60 * 60 * 1000;
1498
+ if (reportAge > maxAge) {
1499
+ hardFail("DEPENDENCY_AUDIT", `漏洞扫描报告已过期 (生成于 ${report.timestamp})`, ["package.json"], "依赖健康", "旧 gate 不检查报告时效", "重新运行 npm run audit-deps");
1500
+ return;
1501
+ }
1502
+ const blocked = report.blocked || [];
1503
+ if (blocked.length > 0) {
1504
+ const details = blocked.map((b) => `[${b.severity}] ${b.package}: ${b.title}`).join("; ");
1505
+ hardFail("DEPENDENCY_AUDIT", `发现 ${blocked.length} 个阻断级漏洞: ${details}`, ["package.json"], "依赖健康", "旧 gate 不扫描依赖漏洞", "npm audit fix 或升级依赖");
1506
+ return;
1507
+ }
1508
+ const total = report.vulnerability_summary?.total || 0;
1509
+ _info(` 依赖漏洞扫描通过: ${total} 个已知漏洞(无阻断级)`);
1510
+ }
1511
+ catch {
1512
+ hardFail("DEPENDENCY_AUDIT", "漏洞扫描报告格式无效", ["package.json"], "依赖健康", "旧 gate 不验证报告格式", "删除 .soloforge/advisory-report.json 并重新运行 npm run audit-deps");
1513
+ }
1514
+ }
1515
+ // ── 15. Batch6 架构决策与设计产物真实消费 ──
1516
+ async function checkBatch6DesignPath(rootDir, hardFail, _info) {
1517
+ const toolsText = safeRead(path.join(rootDir, "src", "adapters", "claude_code", "tools.ts")) ?? "";
1518
+ const cliText = safeRead(path.join(rootDir, "src", "bin", "soloforge.ts")) ?? "";
1519
+ const workflowText = safeRead(path.join(rootDir, "src", "adapters", "shared", "workflow_template.ts")) ?? "";
1520
+ if (!toolsText.includes("checkArchitectureDecisionWorkshopGate({") ||
1521
+ !toolsText.includes("projectContext: detectedArchitectureContext")) {
1522
+ hardFail("BATCH6_MAINLINE_MISSING", "问题六十一未接入 sf_expand 架构研讨阻断路径", ["src/adapters/claude_code/tools.ts"], "problem-61", "仅有合同或模板不能证明主链路消费", "在 sf_expand 真实路由调用架构研讨门");
1523
+ }
1524
+ if (!toolsText.includes("verifyDesignArtifactPack(projectPath, designPack)") ||
1525
+ !toolsText.includes("ctx.design_artifact_pack.status !== \"implementation_ready\"") ||
1526
+ !toolsText.includes("checkDesignArtifactWriteGate({ ctx, toolName: name, sideEffects: effectiveSideEffects })")) {
1527
+ hardFail("BATCH6_MAINLINE_MISSING", "问题六十二未同时接入真实 sf_verify、实现写入与 sf_deliver 就绪阻断", ["src/adapters/claude_code/tools.ts"], "problem-62", "仅有文档校验函数不能阻断用户编码/交付", "在验证、写入与交付路径消费设计产物包状态");
1528
+ }
1529
+ if (!cliText.includes("cmdAuditDesignArtifacts") ||
1530
+ !cliText.includes("cmdUpgradeDesignArtifacts") ||
1531
+ !cliText.includes("currentTask?.design_artifact_pack")) {
1532
+ hardFail("BATCH6_USER_CLI_MISSING", "问题六十二缺少用户 CLI 审计/升级或 Claude Code 写入 hook 阻断路径", ["src/bin/soloforge.ts"], "problem-62", "MCP 内部调用不能覆盖用户现有文档升级与直接 Edit/Write 路径", "接入 audit/upgrade CLI 与 check-write 设计产物门");
1533
+ }
1534
+ if (!workflowText.includes("wf-architecture-workshop-first") || !workflowText.includes("wf-design-artifact-pack")) {
1535
+ hardFail("BATCH6_USER_INJECTION_MISSING", "用户项目工作流模板未注入 Batch6 薄硬协议", ["src/adapters/shared/workflow_template.ts"], "problem-61/problem-62", "运行时有门但用户不可预期会造成体验断裂", "向 workflow template 注入硬规则");
1536
+ }
1537
+ try {
1538
+ const workshop = await import(path.join(rootDir, "dist", "engine", "architecture_decision_workshop.js"));
1539
+ const designPack = await import(path.join(rootDir, "dist", "engine", "design_artifact_pack.js"));
1540
+ const draft = workshop.createArchitectureDecisionWorkshop("release-batch6", "new_system");
1541
+ if (workshop.evaluateArchitectureDecisionWorkshop(draft).allowed) {
1542
+ hardFail("BATCH6_BEHAVIOR_FALSE_PASS", "问题六十一未确认六域的草稿错误放行", ["src/engine/architecture_decision_workshop.ts"], "problem-61", "必须有负向行为证据", "修复研讨生成门");
1543
+ }
1544
+ const missingPackResult = designPack.verifyDesignArtifactPack(rootDir, designPack.createDesignArtifactPack("release-batch6"));
1545
+ if (missingPackResult.passed) {
1546
+ hardFail("BATCH6_BEHAVIOR_FALSE_PASS", "问题六十二缺少用户项目设计产物时错误放行", ["src/engine/design_artifact_pack.ts"], "problem-62", "必须读取真实资产并阻断缺失", "修复设计产物复验门");
1547
+ }
1548
+ }
1549
+ catch (error) {
1550
+ hardFail("BATCH6_MODULE_LOAD_FAILED", `无法执行 Batch6 行为复验: ${error?.message ?? error}`, ["src/engine/architecture_decision_workshop.ts", "src/engine/design_artifact_pack.ts"], "Batch6", "模块不可执行", "修复构建或导出");
1551
+ }
1552
+ _info(" Batch6 架构决策与设计产物真实消费复验完成");
1553
+ }
1554
+ // ── 主入口 ──
1555
+ export async function runReleaseReadinessGate(rootDir) {
1556
+ const hardFails = [];
1557
+ const phases = [];
1558
+ let capturedNoiseCount = 0;
1559
+ // 初始化日志器为静默模式,防止 debug/internalWarn 输出
1560
+ const { initLogger, resetLogger } = await import("./logger.js");
1561
+ initLogger({ silent: true });
1562
+ // 兜底: 仍然拦截 console.error,捕获任何绕过日志器的直接调用
1563
+ const origConsoleError = console.error;
1564
+ const noiseLogs = [];
1565
+ console.error = (...args) => { noiseLogs.push(args.join(" ")); };
1566
+ function hardFail(code, message, files, issueOrMech, oldGateMissed, nextStep) {
1567
+ hardFails.push({ code, message, files, issueOrMech, oldGateMissed, nextStep });
1568
+ }
1569
+ function _info(_msg) { }
1570
+ function beginPhase(name) {
1571
+ phases.push({ name, hard_fail_count: -1 }); // -1 标记进行中
1572
+ }
1573
+ function endPhase(name) {
1574
+ const phase = phases.find(p => p.name === name && p.hard_fail_count === -1);
1575
+ if (phase)
1576
+ phase.hard_fail_count = hardFails.length - (phases.filter(p => p.hard_fail_count >= 0).reduce((s, p) => s + p.hard_fail_count, 0));
1577
+ else
1578
+ phases.push({ name, hard_fail_count: 0 });
1579
+ }
1580
+ // 0
1581
+ beginPhase("dist 旧产物风险");
1582
+ checkDistFreshness(rootDir, hardFail);
1583
+ endPhase("dist 旧产物风险");
1584
+ // 1
1585
+ beginPhase("Batch 施工痕迹泄漏");
1586
+ checkBatchTraceLeakage(rootDir, hardFail, _info);
1587
+ endPhase("Batch 施工痕迹泄漏");
1588
+ // 2
1589
+ beginPhase("双层模型语义归位");
1590
+ await checkDualLayerSemantics(rootDir, hardFail, _info);
1591
+ endPhase("双层模型语义归位");
1592
+ // 3
1593
+ beginPhase("主链路真实消费");
1594
+ checkMainlineConsumption(rootDir, hardFail, _info);
1595
+ endPhase("主链路真实消费");
1596
+ // 4
1597
+ beginPhase("模板/adapter 更新空洞");
1598
+ checkTemplateAdapterGaps(rootDir, hardFail);
1599
+ endPhase("模板/adapter 更新空洞");
1600
+ // 5
1601
+ beginPhase("旧 gate 误导标记");
1602
+ checkOldGateMisdirection(rootDir, hardFail, _info);
1603
+ endPhase("旧 gate 误导标记");
1604
+ // 6
1605
+ beginPhase("测试污染初筛");
1606
+ checkTestPollution(rootDir, hardFail, _info);
1607
+ endPhase("测试污染初筛");
1608
+ // 7
1609
+ beginPhase("Batch 问题文档格式一致性");
1610
+ await checkBatchIssueFormatConsistency(rootDir, hardFail, _info);
1611
+ endPhase("Batch 问题文档格式一致性");
1612
+ // 8
1613
+ beginPhase("关键问题消费验证");
1614
+ await checkCriticalProblemConsumption(rootDir, hardFail, _info);
1615
+ endPhase("关键问题消费验证");
1616
+ // 9
1617
+ beginPhase("机制身份一致性");
1618
+ await checkMechanismIdentityConsistency(rootDir, hardFail, _info);
1619
+ endPhase("机制身份一致性");
1620
+ // 10: P0/P1 知识资产 schema 完整性
1621
+ beginPhase("P0/P1 知识资产 schema");
1622
+ await checkKnowledgeAssetSchema(rootDir, hardFail, _info);
1623
+ endPhase("P0/P1 知识资产 schema");
1624
+ // 11: console.log 检查
1625
+ beginPhase("engine console.log 检查");
1626
+ checkEngineConsoleLog(rootDir, hardFail);
1627
+ endPhase("engine console.log 检查");
1628
+ // 12: 中文注释检查
1629
+ beginPhase("中文注释检查");
1630
+ checkChineseComments(rootDir, hardFail);
1631
+ endPhase("中文注释检查");
1632
+ // 13: 第五批文档↔roadmap↔scenario 一致性
1633
+ beginPhase("第五批一致性校验");
1634
+ await checkLastBatchConsistency(rootDir, hardFail, _info);
1635
+ endPhase("第五批一致性校验");
1636
+ // 14: 依赖漏洞扫描(在 console.error 恢复前执行以避免干扰)
1637
+ beginPhase("依赖漏洞扫描");
1638
+ checkDependencyAudit(rootDir, hardFail, _info);
1639
+ endPhase("依赖漏洞扫描");
1640
+ // 15: Batch6 新增真实用户路径
1641
+ beginPhase("Batch6 架构决策与设计产物真实消费");
1642
+ await checkBatch6DesignPath(rootDir, hardFail, _info);
1643
+ endPhase("Batch6 架构决策与设计产物真实消费");
1644
+ // 恢复 console.error 和日志器
1645
+ console.error = origConsoleError;
1646
+ resetLogger();
1647
+ // 噪音检测: 捕获任何绕过日志器的直接 console.error("[soloForge]...") 调用
1648
+ capturedNoiseCount = noiseLogs.filter(l => l.includes("[soloForge]")).length;
1649
+ if (capturedNoiseCount > 0) {
1650
+ hardFail("OUTPUT_NOISE", `发布门禁运行时产生 ${capturedNoiseCount} 条模块噪音日志`, ["src/engine/logger.ts"], "发布门禁输出质量", "旧 gate 不检查自身输出噪音", "日志治理");
1651
+ }
1652
+ return {
1653
+ passed: hardFails.length === 0,
1654
+ hard_fail_count: hardFails.length,
1655
+ hard_fails: hardFails,
1656
+ phases: phases.map(p => ({ name: p.name, hard_fail_count: p.hard_fail_count >= 0 ? p.hard_fail_count : 0 })),
1657
+ noise_log_count: capturedNoiseCount,
1658
+ };
1659
+ }
1660
+ //# sourceMappingURL=release_readiness_gate.js.map