@dommaker/harness 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +9 -12
  3. package/dist/cli/commands/check.d.ts +3 -3
  4. package/dist/cli/commands/check.d.ts.map +1 -1
  5. package/dist/cli/commands/check.js +41 -78
  6. package/dist/cli/commands/check.js.map +1 -1
  7. package/dist/cli/commands/constraints-report.d.ts +2 -10
  8. package/dist/cli/commands/constraints-report.d.ts.map +1 -1
  9. package/dist/cli/commands/constraints-report.js +4 -57
  10. package/dist/cli/commands/constraints-report.js.map +1 -1
  11. package/dist/cli/commands/constraints-retire.d.ts +9 -23
  12. package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
  13. package/dist/cli/commands/constraints-retire.js +39 -121
  14. package/dist/cli/commands/constraints-retire.js.map +1 -1
  15. package/dist/cli/commands/constraints.d.ts +3 -8
  16. package/dist/cli/commands/constraints.d.ts.map +1 -1
  17. package/dist/cli/commands/constraints.js +8 -23
  18. package/dist/cli/commands/constraints.js.map +1 -1
  19. package/dist/cli/commands/definitions.js +2 -2
  20. package/dist/cli/commands/init.d.ts +0 -32
  21. package/dist/cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/commands/init.js +7 -149
  23. package/dist/cli/commands/init.js.map +1 -1
  24. package/dist/cli/commands/report.d.ts.map +1 -1
  25. package/dist/cli/commands/report.js +14 -17
  26. package/dist/cli/commands/report.js.map +1 -1
  27. package/dist/cli/commands/scaffold-templates.d.ts +0 -2
  28. package/dist/cli/commands/scaffold-templates.d.ts.map +1 -1
  29. package/dist/cli/commands/scaffold-templates.js +2 -37
  30. package/dist/cli/commands/scaffold-templates.js.map +1 -1
  31. package/dist/cli/commands/scaffold.d.ts +0 -2
  32. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  33. package/dist/cli/commands/scaffold.js +0 -10
  34. package/dist/cli/commands/scaffold.js.map +1 -1
  35. package/dist/cli/commands/status.js +10 -10
  36. package/dist/cli/commands/status.js.map +1 -1
  37. package/dist/cli/commands/sync-docs/agents-syncer.d.ts +0 -2
  38. package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
  39. package/dist/cli/commands/sync-docs/agents-syncer.js +4 -23
  40. package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
  41. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  42. package/dist/core/constraints/capabilities-parser.js +16 -4
  43. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  44. package/dist/core/constraints/checker.d.ts +15 -24
  45. package/dist/core/constraints/checker.d.ts.map +1 -1
  46. package/dist/core/constraints/checker.js +33 -72
  47. package/dist/core/constraints/checker.js.map +1 -1
  48. package/dist/core/constraints/checkers/docs-freshness.js +1 -1
  49. package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
  50. package/dist/core/constraints/checkers/governance-presence.d.ts +2 -1
  51. package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
  52. package/dist/core/constraints/checkers/governance-presence.js +4 -3
  53. package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
  54. package/dist/core/constraints/checkers/index.d.ts +1 -1
  55. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  56. package/dist/core/constraints/checkers/index.js +4 -8
  57. package/dist/core/constraints/checkers/index.js.map +1 -1
  58. package/dist/core/constraints/checkers/iron-flags.d.ts +3 -4
  59. package/dist/core/constraints/checkers/iron-flags.d.ts.map +1 -1
  60. package/dist/core/constraints/checkers/iron-flags.js +4 -5
  61. package/dist/core/constraints/checkers/iron-flags.js.map +1 -1
  62. package/dist/core/constraints/checkers/no-test-simplification.js +1 -1
  63. package/dist/core/constraints/checkers/no-test-simplification.js.map +1 -1
  64. package/dist/core/constraints/checkers/types.d.ts +1 -1
  65. package/dist/core/constraints/checkers/types.js +1 -1
  66. package/dist/core/constraints/definitions/guidelines.d.ts +4 -4
  67. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  68. package/dist/core/constraints/definitions/guidelines.js +9 -25
  69. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  70. package/dist/core/constraints/definitions/iron-laws.d.ts +4 -4
  71. package/dist/core/constraints/definitions/iron-laws.d.ts.map +1 -1
  72. package/dist/core/constraints/definitions/iron-laws.js +10 -81
  73. package/dist/core/constraints/definitions/iron-laws.js.map +1 -1
  74. package/dist/core/constraints/definitions.d.ts +7 -9
  75. package/dist/core/constraints/definitions.d.ts.map +1 -1
  76. package/dist/core/constraints/definitions.js +13 -16
  77. package/dist/core/constraints/definitions.js.map +1 -1
  78. package/dist/core/constraints/index.d.ts +2 -5
  79. package/dist/core/constraints/index.d.ts.map +1 -1
  80. package/dist/core/constraints/index.js +3 -13
  81. package/dist/core/constraints/index.js.map +1 -1
  82. package/dist/core/constraints/injection-writer.d.ts +10 -38
  83. package/dist/core/constraints/injection-writer.d.ts.map +1 -1
  84. package/dist/core/constraints/injection-writer.js +17 -54
  85. package/dist/core/constraints/injection-writer.js.map +1 -1
  86. package/dist/core/constraints/run-env.d.ts +1 -10
  87. package/dist/core/constraints/run-env.d.ts.map +1 -1
  88. package/dist/core/constraints/run-env.js +1 -22
  89. package/dist/core/constraints/run-env.js.map +1 -1
  90. package/dist/core/constraints/usage-report.d.ts +5 -7
  91. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  92. package/dist/core/constraints/usage-report.js +5 -10
  93. package/dist/core/constraints/usage-report.js.map +1 -1
  94. package/dist/core/effective-constraints.d.ts +12 -22
  95. package/dist/core/effective-constraints.d.ts.map +1 -1
  96. package/dist/core/effective-constraints.js +13 -30
  97. package/dist/core/effective-constraints.js.map +1 -1
  98. package/dist/core/index.d.ts +2 -2
  99. package/dist/core/index.d.ts.map +1 -1
  100. package/dist/core/index.js +3 -9
  101. package/dist/core/index.js.map +1 -1
  102. package/dist/core/project-config-loader.d.ts +4 -42
  103. package/dist/core/project-config-loader.d.ts.map +1 -1
  104. package/dist/core/project-config-loader.js +16 -125
  105. package/dist/core/project-config-loader.js.map +1 -1
  106. package/dist/core/validators/passes-gate.d.ts +2 -2
  107. package/dist/core/validators/passes-gate.js +6 -6
  108. package/dist/core/validators/passes-gate.js.map +1 -1
  109. package/dist/index.d.ts +7 -10
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +9 -18
  112. package/dist/index.js.map +1 -1
  113. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  114. package/dist/monitoring/trace-analyzer.js +11 -12
  115. package/dist/monitoring/trace-analyzer.js.map +1 -1
  116. package/dist/monitoring/traces.d.ts +4 -4
  117. package/dist/monitoring/traces.d.ts.map +1 -1
  118. package/dist/monitoring/traces.js +8 -8
  119. package/dist/monitoring/traces.js.map +1 -1
  120. package/dist/presets/standard.d.ts +8 -10
  121. package/dist/presets/standard.d.ts.map +1 -1
  122. package/dist/presets/standard.js +10 -16
  123. package/dist/presets/standard.js.map +1 -1
  124. package/dist/types/constraint.d.ts +24 -35
  125. package/dist/types/constraint.d.ts.map +1 -1
  126. package/dist/types/constraint.js +8 -7
  127. package/dist/types/constraint.js.map +1 -1
  128. package/dist/types/passes-gate.d.ts +5 -5
  129. package/dist/types/passes-gate.d.ts.map +1 -1
  130. package/dist/types/project-config.d.ts +8 -66
  131. package/dist/types/project-config.d.ts.map +1 -1
  132. package/dist/types/project-config.js +3 -2
  133. package/dist/types/project-config.js.map +1 -1
  134. package/dist/types/trace.d.ts +8 -10
  135. package/dist/types/trace.d.ts.map +1 -1
  136. package/package.json +2 -2
  137. package/src/CONTEXT.md +2 -2
  138. package/src/__tests__/checker-extra.test.ts +37 -61
  139. package/src/__tests__/checker.test.ts +10 -115
  140. package/src/__tests__/effective-constraints.test.ts +18 -83
  141. package/src/__tests__/iron-laws.test.ts +71 -90
  142. package/src/__tests__/passes-gate-check.test.ts +2 -2
  143. package/src/__tests__/project-config-loader-extra.test.ts +22 -123
  144. package/src/__tests__/project-config-loader.test.ts +5 -33
  145. package/src/__tests__/public-exports.test.ts +1 -7
  146. package/src/__tests__/public-type-surface.test.ts +2 -5
  147. package/src/__tests__/public-value-surface.test.ts +1 -7
  148. package/src/__tests__/skip-semantics.test.ts +21 -37
  149. package/src/__tests__/trace-analyzer-extra.test.ts +14 -14
  150. package/src/__tests__/trace-analyzer.test.ts +21 -21
  151. package/src/__tests__/trace-collector.test.ts +22 -22
  152. package/src/__tests__/traces.test.ts +27 -28
  153. package/src/cli/commands/CONTEXT.md +9 -9
  154. package/src/cli/commands/__tests__/check-read-count.test.ts +4 -15
  155. package/src/cli/commands/__tests__/check-skip-output.test.ts +14 -14
  156. package/src/cli/commands/__tests__/check.test.ts +14 -31
  157. package/src/cli/commands/__tests__/constraints-report.test.ts +12 -80
  158. package/src/cli/commands/__tests__/constraints-retire.test.ts +42 -231
  159. package/src/cli/commands/__tests__/init-governance-io.test.ts +12 -58
  160. package/src/cli/commands/__tests__/init-ondisk.test.ts +12 -20
  161. package/src/cli/commands/__tests__/init.test.ts +0 -11
  162. package/src/cli/commands/__tests__/project-path-anchoring.test.ts +2 -2
  163. package/src/cli/commands/__tests__/report-extra.test.ts +4 -4
  164. package/src/cli/commands/__tests__/report.test.ts +1 -1
  165. package/src/cli/commands/__tests__/scaffold.test.ts +4 -14
  166. package/src/cli/commands/__tests__/status-analysis-wiring.test.ts +3 -3
  167. package/src/cli/commands/__tests__/status-extra.test.ts +14 -14
  168. package/src/cli/commands/__tests__/status.test.ts +12 -12
  169. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +1 -1
  170. package/src/cli/commands/check.ts +43 -82
  171. package/src/cli/commands/constraints-report.ts +4 -59
  172. package/src/cli/commands/constraints-retire.ts +49 -154
  173. package/src/cli/commands/constraints.ts +11 -26
  174. package/src/cli/commands/definitions.ts +2 -2
  175. package/src/cli/commands/init.ts +8 -179
  176. package/src/cli/commands/report.ts +19 -23
  177. package/src/cli/commands/scaffold-templates.ts +1 -37
  178. package/src/cli/commands/scaffold.ts +0 -11
  179. package/src/cli/commands/status.ts +10 -10
  180. package/src/cli/commands/sync-docs/agents-syncer.ts +4 -25
  181. package/src/core/CONTEXT.md +9 -9
  182. package/src/core/constraints/__tests__/capability-counts.test.ts +5 -5
  183. package/src/core/constraints/__tests__/collect-constraints.test.ts +13 -8
  184. package/src/core/constraints/__tests__/git-evidence.test.ts +4 -7
  185. package/src/core/constraints/__tests__/injection-writer.test.ts +8 -61
  186. package/src/core/constraints/__tests__/run-env.test.ts +5 -34
  187. package/src/core/constraints/__tests__/trace-injection.test.ts +1 -1
  188. package/src/core/constraints/capabilities-parser.ts +17 -5
  189. package/src/core/constraints/checker.ts +39 -88
  190. package/src/core/constraints/checkers/__tests__/check-outcome.test.ts +5 -8
  191. package/src/core/constraints/checkers/__tests__/governance-presence.test.ts +1 -53
  192. package/src/core/constraints/checkers/__tests__/iron-flags.test.ts +5 -25
  193. package/src/core/constraints/checkers/docs-freshness.ts +1 -1
  194. package/src/core/constraints/checkers/governance-presence.ts +4 -3
  195. package/src/core/constraints/checkers/index.ts +4 -10
  196. package/src/core/constraints/checkers/iron-flags.ts +3 -12
  197. package/src/core/constraints/checkers/no-test-simplification.ts +1 -1
  198. package/src/core/constraints/checkers/types.ts +1 -1
  199. package/src/core/constraints/definitions/guidelines.ts +8 -25
  200. package/src/core/constraints/definitions/iron-laws.ts +9 -82
  201. package/src/core/constraints/definitions.ts +14 -15
  202. package/src/core/constraints/index.ts +4 -19
  203. package/src/core/constraints/injection-writer.ts +16 -61
  204. package/src/core/constraints/run-env.ts +1 -33
  205. package/src/core/constraints/usage-report.ts +8 -15
  206. package/src/core/effective-constraints.ts +14 -45
  207. package/src/core/index.ts +3 -10
  208. package/src/core/project-config-loader.ts +20 -145
  209. package/src/core/validators/passes-gate.ts +6 -6
  210. package/src/failure/CONTEXT.md +1 -1
  211. package/src/hooks/__tests__/bootstrap.test.ts +3 -5
  212. package/src/index.ts +8 -18
  213. package/src/monitoring/__tests__/trace-file-anchoring.test.ts +1 -1
  214. package/src/monitoring/__tests__/traces.test.ts +22 -22
  215. package/src/monitoring/trace-analyzer.ts +12 -13
  216. package/src/monitoring/traces.ts +8 -8
  217. package/src/presets/__tests__/standard.test.ts +12 -16
  218. package/src/presets/standard.ts +14 -23
  219. package/src/types/__tests__/types.test.ts +3 -3
  220. package/src/types/constraint.ts +26 -40
  221. package/src/types/passes-gate.ts +5 -5
  222. package/src/types/project-config.ts +8 -77
  223. package/src/types/trace.ts +8 -11
  224. package/dist/core/constraints/agent-prompt-renderer.d.ts +0 -32
  225. package/dist/core/constraints/agent-prompt-renderer.d.ts.map +0 -1
  226. package/dist/core/constraints/agent-prompt-renderer.js +0 -55
  227. package/dist/core/constraints/agent-prompt-renderer.js.map +0 -1
  228. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts +0 -6
  229. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts.map +0 -1
  230. package/dist/core/constraints/checkers/no-bypass-checkpoint.js +0 -40
  231. package/dist/core/constraints/checkers/no-bypass-checkpoint.js.map +0 -1
  232. package/dist/core/constraints/definitions/prompts.d.ts +0 -12
  233. package/dist/core/constraints/definitions/prompts.d.ts.map +0 -1
  234. package/dist/core/constraints/definitions/prompts.js +0 -400
  235. package/dist/core/constraints/definitions/prompts.js.map +0 -1
  236. package/dist/core/constraints/injection-drift.d.ts +0 -61
  237. package/dist/core/constraints/injection-drift.d.ts.map +0 -1
  238. package/dist/core/constraints/injection-drift.js +0 -131
  239. package/dist/core/constraints/injection-drift.js.map +0 -1
  240. package/dist/core/constraints/injection-renderer.d.ts +0 -23
  241. package/dist/core/constraints/injection-renderer.d.ts.map +0 -1
  242. package/dist/core/constraints/injection-renderer.js +0 -44
  243. package/dist/core/constraints/injection-renderer.js.map +0 -1
  244. package/src/cli/commands/__tests__/check-drift.test.ts +0 -158
  245. package/src/cli/commands/__tests__/init-injection.test.ts +0 -466
  246. package/src/core/constraints/__tests__/agent-prompt-renderer.test.ts +0 -129
  247. package/src/core/constraints/__tests__/injection-drift.test.ts +0 -247
  248. package/src/core/constraints/agent-prompt-renderer.ts +0 -67
  249. package/src/core/constraints/checkers/__tests__/no-bypass-checkpoint.test.ts +0 -76
  250. package/src/core/constraints/checkers/no-bypass-checkpoint.ts +0 -40
  251. package/src/core/constraints/definitions/prompts.ts +0 -414
  252. package/src/core/constraints/injection-drift.ts +0 -142
  253. package/src/core/constraints/injection-renderer.ts +0 -44
@@ -1,414 +0,0 @@
1
- /**
2
- * prompt 类约束定义(ADR-0001:kind 二元模型)
3
- *
4
- * 纯文本提示层:
5
- * - kind: 'prompt',level 统一为 'prompt'
6
- * - 不带 checker,不参与运行时检查与 trace 统计
7
- * - promptInjection 参与 init 注入;trigger 供消费端(studio)做角色路由
8
- * - appliesTo 标注适用场景(如 'agent-skill'、'llm-app'),缺省为通用
9
- */
10
-
11
- import type { Constraint } from '../../../types/constraint';
12
-
13
- export const PROMPTS: Record<string, Constraint> = {
14
- /**
15
- * 禁止模糊完成声明(合并枢纽)
16
- * 吸收:no_self_approval、no_claim_without_evidence、no_excuse_patterns
17
- */
18
- no_fuzzy_completion_claim: {
19
- id: 'no_fuzzy_completion_claim',
20
- kind: 'prompt',
21
- rule: 'NO FUZZY COMPLETION CLAIMS WITHOUT QUANTIFIABLE EVIDENCE',
22
- message: '禁止模糊完成声明,必须提供可量化证据',
23
- level: 'prompt',
24
- trigger: ['code_implementation', 'design_request', 'task_completion_claim', 'file_deletion', 'module_modification'],
25
- enforcement: 'fuzzy-check',
26
- description: `声明任务完成时,禁止使用模糊词语,必须提供具体、可量化、可复现的验证结果;不得仅凭自己的判断声称完成(吸收 no_self_approval / no_claim_without_evidence)。
27
-
28
- 【禁止的模糊词】
29
- - "应该没问题"、"大概完成了"、"可能可以了"
30
- - "好像通过了"、"似乎工作正常"、"应该能跑"
31
- - "基本完成"、"差不多"、"大部分功能可用"
32
- - "我记得删过了"、"之前说删了"、"已删除"(未经 ls/grep 验证)
33
- - "大部分实现"(未经逐 AC 对照 spec)
34
- - "已修复"(未经 test 验证)
35
-
36
- 【必须提供】
37
- - 测试通过的精确数量(如 "142 tests passed")
38
- - 验证命令输出(如 "npm test 全部通过")
39
- - 删除操作后 ls 确认(如 "ls packages/dead-pkg → No such file")
40
- - Spec AC 对照表(逐项标注 pass/fail)
41
-
42
- 【禁止借口】(吸收 no_excuse_patterns)
43
- - "稍后修复"、"小问题"、"不影响功能"、"以后再说"、"先这样"、"临时方案"
44
- - 必须说明问题的具体影响、修复的时间点或版本;临时方案须给出正式方案计划`,
45
- promptInjection: '声明任务完成时,必须附可复现的验证证据,不得仅凭自己的判断声称完成:测试给出精确通过数量与验证命令输出(如 "142 passed, 0 failed"),声明"已删除"前用 ls 确认文件不存在,文档结论用 grep 确认,Spec 完成前逐条 AC 对照标注 pass/fail。禁用模糊词:"应该没问题""大概完成了""基本完成""差不多""我记得""之前说""已修复"(未经 test 验证)。遇困难禁止借口搪塞("稍后修复""小问题""不影响功能""以后再说""先这样""临时方案")——必须说明问题的具体影响、修复的时间点或版本;是临时方案的,给出正式方案的计划。',
46
- },
47
-
48
- /**
49
- * 禁止无根因修复(合并枢纽)
50
- * 吸收:no_fallback_without_root_cause、analysis_verification_gate、diagnosis_to_fix_gate
51
- */
52
- no_fix_without_root_cause: {
53
- id: 'no_fix_without_root_cause',
54
- kind: 'prompt',
55
- rule: 'NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST',
56
- message: '复杂 bug 必须先调查根本原因',
57
- level: 'prompt',
58
- trigger: ['code_implementation', 'module_modification', 'file_modification', 'design_request', 'diagnosis'],
59
- enforcement: 'debug-systematic',
60
- description: `在尝试修复 bug 之前,必须先诊断根因(吸收 no_fallback_without_root_cause / analysis_verification_gate / diagnosis_to_fix_gate)。
61
-
62
- [复杂 bug - 必须系统性调查]
63
- - 业务逻辑错误(需追踪数据流)
64
- - 状态不一致(需分析状态变化链)
65
- - 性能问题(需定位瓶颈)
66
- - 多模块联动问题(需分析调用链)
67
-
68
- [简单 bug - 快速确认即可]
69
- - typo/拼写错误
70
- - 配置值错误
71
- - 缺少必要配置
72
-
73
- [禁止]
74
- - 没有任何调查就直接猜测修复
75
- - 看到 error 就直接 try-catch 掩盖
76
- - 用 fallback/兜底值掩盖上游数据异常而不追根因
77
- - Read 定位后直接 Edit,不对照设计原型确认意图
78
- - 从"数字异常"直接跳到根因结论,不验证假设的含义与量纲`,
79
- promptInjection: '修复问题前必须先诊断根因——不止"哪里出错",而是"为什么设计成这样":用 Read/Grep 定位后禁止直接 Edit,先对照设计原型(CLAUDE.md、类型定义、commit message)确认原设计意图,呈现确认的根因+方案草案后才能动手。遇到空值/异常/不完整数据,禁止用 fallback/兜底/try-catch 掩盖——先追上游:数据谁产生的?为什么是空的?选择防御性兜底时必须在注释中说明根因;同一位置连续兜底 2+ 次是上游 bug 信号,停止修下游、追踪源头。从数据到结论必须先验证关键假设:数字的含义(累积/单次?量纲?)、正常范围、同类场景对比与反例,禁止"数字异常→直接定根因→直接改"的跳级推理。不绕过问题、不遮掩症状、不用临时方案代替根本修复。',
80
- },
81
-
82
- /**
83
- * 简单方案优先(合并枢纽)
84
- * 吸收:no_creation_without_reuse_check、yagni_check
85
- */
86
- simplest_solution_first: {
87
- id: 'simplest_solution_first',
88
- kind: 'prompt',
89
- rule: 'CHECK LOCAL/SIMPLE OPTIONS BEFORE REMOTE/COMPLEX',
90
- message: '先检查本地/简单方案',
91
- level: 'prompt',
92
- trigger: ['code_implementation', 'module_extension', 'module_creation', 'design_request'],
93
- enforcement: 'check-local-first',
94
- description: `在实现功能时,必须按顺序检查(吸收 no_creation_without_reuse_check / yagni_check):
95
- 1) 是否有本地数据源(内存/文件)?
96
- 2) 是否有更简单的方案(更少依赖/更少代码)?
97
- 3) 创建新能力前是否查过现有能力索引,确认无可复用?
98
- 4) 如需远程查询/复杂架构,必须说明理由。
99
-
100
- 复用优先级:直接复用 > 扩展现有 > 组合现有 > 创建新能力。
101
-
102
- 例外情况(可跳过简单方案):
103
- - scalability_required: 需要多实例/分布式部署
104
- - security_required: 需要加密/鉴权等安全措施
105
- - performance_required: 本地方案性能不足
106
- - reliability_required: 需要持久化/高可用
107
-
108
- YAGNI:不为"未来可能需要"添加抽象层、接口、配置项或插件系统;一个抽象只有一个实现者时删除该抽象。`,
109
- promptInjection: '最简方案优先:用最少代码解决当前问题,不添加"以防万一"的冗余功能,不为仅用一次的代码强行设计抽象。创建新模块/文件/能力前,先查现有能力索引确认无可复用——优先级:直接复用 > 扩展现有 > 组合现有 > 新建。遵循 YAGNI:不为"未来可能需要"添加抽象层、接口、配置项或插件系统;一个 interface/abstract class 只有一个实现者时,删除这个抽象。自检:资深工程师是否会认为此实现过度复杂?若是,立即简化。',
110
- injectPrompt: true,
111
- },
112
-
113
- /**
114
- * 业务逻辑代码必须先写测试
115
- * 例外:配置文件、类型定义
116
- */
117
- no_code_without_test: {
118
- id: 'no_code_without_test',
119
- kind: 'prompt',
120
- rule: 'PRODUCTION LOGIC CODE MUST HAVE TESTS FIRST',
121
- message: '业务逻辑代码必须先写测试',
122
- level: 'prompt',
123
- trigger: 'code_implementation',
124
- enforcement: 'tdd-cycle',
125
- description: `在编写代码时,按类型区分测试要求:
126
-
127
- [必须先写测试]
128
- - 业务逻辑代码(算法、计算、数据处理)
129
- - 工具函数(可复用的独立函数)
130
- - API 接口(输入输出验证)
131
- - 核心组件(影响系统行为的组件)
132
-
133
- [不强制测试]
134
- - 配置文件(config、env)
135
- - 类型定义文件(.d.ts、interface)
136
- - 简单 getter/setter
137
- - 纯展示 UI 组件(无交互逻辑)`,
138
- promptInjection: '新代码必须同时编写测试。实现功能前先写测试用例(RED),然后实现让测试通过(GREEN)。不得提交无测试覆盖的实现代码。',
139
- },
140
-
141
- /**
142
- * 禁止砍功能
143
- * 例外:冗余代码清理
144
- */
145
- no_simplification_without_approval: {
146
- id: 'no_simplification_without_approval',
147
- kind: 'prompt',
148
- rule: 'NO SIMPLIFYING LOGIC WITHOUT USER APPROVAL',
149
- message: '禁止砍功能,合理重构除外',
150
- level: 'prompt',
151
- trigger: 'code_implementation',
152
- enforcement: 'preserve-complexity',
153
- description: `在实现或修改代码时,区分简化类型:
154
-
155
- [禁止] 必须向用户说明并获取批准
156
- - 为了赶进度砍掉必要功能
157
- - 为了省事跳过边界条件处理
158
- - 为了简化逻辑牺牲用户体验
159
-
160
- [允许] 合理优化,不需要批准
161
- - 发现冗余代码后的重构优化
162
- - 用更简洁的实现达到相同效果
163
- - 删除不再使用的遗留代码`,
164
- promptInjection: '不得擅自简化或删除测试、lint 规则、类型检查或约束。如需降低检查标准,必须先提案并获明确批准。',
165
- },
166
-
167
- /**
168
- * 修复触发门禁的问题,而非门禁本身
169
- * 原因:质量门阻断是信号,不是障碍。调整门禁而非修复违规是自我欺骗。
170
- */
171
- fix_the_problem_not_the_gate: {
172
- id: 'fix_the_problem_not_the_gate',
173
- kind: 'prompt',
174
- rule: 'FIX THE PROBLEM THAT TRIGGERED THE GATE, NOT THE GATE ITSELF',
175
- message: '修复触发门禁的问题,不降低门禁本身',
176
- level: 'prompt',
177
- trigger: ['code_implementation', 'module_modification', 'file_modification'],
178
- enforcement: 'principle-check',
179
- description: `质量门禁(测试失败、lint 报错、覆盖率不足、约束违规)阻断时,修复导致阻断的代码,而非调整门禁门槛。降低阈值、删除测试、关闭 lint 规则是对质量信号的压制,不是质量改进。`,
180
- promptInjection: '质量门禁阻断时修复代码,不修复门禁。不降阈值、不删测试、不关 lint、不改断言让 CI 通过。',
181
- injectPrompt: true,
182
- },
183
-
184
- /**
185
- * 禁止实现未验证的外部依赖能力
186
- * 原因:假设外部系统能力存在,实现后发现不支持,浪费开发时间
187
- */
188
- verify_external_capability: {
189
- id: 'verify_external_capability',
190
- kind: 'prompt',
191
- rule: 'VERIFY EXTERNAL CAPABILITY BEFORE IMPLEMENTATION',
192
- message: '外部依赖能力必须先验证',
193
- level: 'prompt',
194
- trigger: 'api_change',
195
- enforcement: 'capability-verification',
196
- description: `实现方案依赖外部系统的未确认能力时,必须先验证。
197
-
198
- 【触发条件】(满足任一)
199
- - 依赖外部 API/服务的回调/交互机制
200
- - 使用未验证过的外部系统高级功能
201
- - 假设外部系统支持某种能力但未查阅文档
202
-
203
- 【必须执行】
204
- 1. 查阅官方文档 → 确认能力是否存在
205
- 2. 发送最小测试 → 验证可行性
206
- 3. 记录限制 → 作为设计约束
207
-
208
- 【不触发】
209
- - 内部逻辑实现
210
- - 已熟悉的库/框架基本功能
211
- - 标准 CRUD 操作
212
-
213
- 【正确流程】
214
- 设计方案 → 查阅文档限制 → 发送最小测试 → 验证可行 → 开发`,
215
- promptInjection: '实现方案依赖外部 API/服务未确认的能力时,必须先查阅官方文档确认能力存在,再发送最小测试验证可行性,记录限制作为设计约束。不要假设外部系统支持某种能力就直接开发。',
216
- },
217
-
218
- /**
219
- * 禁止无上下文删除
220
- * 原因:删除代码前应评估是否有可吸收的功能,避免丢弃有用设计
221
- */
222
- no_delete_without_context: {
223
- id: 'no_delete_without_context',
224
- kind: 'prompt',
225
- rule: 'NO DELETION WITHOUT DESIGN DOCUMENT REVIEW',
226
- message: '禁止删除代码前未审查设计文档和吸收价值',
227
- level: 'prompt',
228
- trigger: ['file_deletion', 'module_deletion'],
229
- enforcement: 'context-check',
230
- description: `删除任何代码(包/模块/文件)前,必须:
231
- 1. 查设计文档(CLAUDE.md / roadmap / specs)
232
- 2. 分析是否有可吸收的功能
233
- 3. 查替代函数是否丢失了关键设计模式(零引用≠无价值)
234
- 4. 分类:未接线(应接线)/ 被替代但有可吸收设计 / 真正无用
235
- 5. 记录分析结论(有/无吸收价值,原因)`,
236
- promptInjection: '删除任何代码前,先查设计意图(JSDoc/commit/spec),分析被替代的函数是否有丢失的关键模式。零引用≠无价值。分类:未接线→接线,被替代→吸收模式,真正无用→才删。',
237
- },
238
-
239
- /**
240
- * 设计决策需先讨论
241
- * 例外:明确指令、紧急修复、已有设计文档
242
- */
243
- design_decision_requires_discussion: {
244
- id: 'design_decision_requires_discussion',
245
- kind: 'prompt',
246
- rule: 'DESIGN DECISIONS MUST BE DISCUSSED BEFORE IMPLEMENTATION',
247
- message: '设计决策类任务需先讨论方案再实现',
248
- level: 'prompt',
249
- trigger: ['design_request', 'architecture_change', 'code_implementation'],
250
- enforcement: 'require-discussion',
251
- description: `当用户问"怎么实现"、"设计方案"时,应先:
252
-
253
- 1. 提供方案选项(至少 2 个)
254
- - 方案 A: ...(优点/缺点)
255
- - 方案 B: ...(优点/缺点)
256
-
257
- 2. 说明推荐方案和理由
258
-
259
- 3. 让用户选择或确认
260
-
261
- 4. 用户确认后再实现
262
-
263
- [判断标准]
264
- - 用户问"怎么实现"、"如何设计" → 设计决策
265
- - 用户说"帮我做 xxx" → 执行任务
266
-
267
- [例外]
268
- - 用户明确说"直接做"、"不用问"
269
- - 紧急修复
270
- - 已有明确设计文档`,
271
- promptInjection: '涉及架构变更、新增依赖、API 设计等重大决策时,必须先提出讨论获得确认,再开始实现。不要凭单方面判断做架构决策。',
272
- },
273
-
274
- /**
275
- * 外科手术式修改 — Mnilax Rule 3
276
- * 原因:只改必要部分,不顺手改相邻代码
277
- */
278
- surgical_changes_only: {
279
- id: 'surgical_changes_only',
280
- kind: 'prompt',
281
- rule: 'ONLY CHANGE WHAT IS ABSOLUTELY NECESSARY',
282
- message: '只改必要部分,不顺手改相邻代码和格式',
283
- level: 'prompt',
284
- trigger: ['code_implementation', 'file_modification'],
285
- enforcement: 'surgical-check',
286
- description: `仅改动绝对必要的部分。不"顺手优化"相邻代码、注释或排版格式。未出问题的代码不重构。严格贴合项目既有风格。`,
287
- promptInjection: '外科手术式修改:仅改动绝对必要的部分。不顺手"优化"相邻代码、注释或格式。未出问题的代码不重构。',
288
- injectPrompt: true,
289
- },
290
-
291
- /**
292
- * 约定胜于新奇 — Mnilax Rule 11
293
- * 原因:规范一致性 > 技术偏好
294
- */
295
- follow_conventions: {
296
- id: 'follow_conventions',
297
- kind: 'prompt',
298
- rule: 'MATCH CODEBASE CONVENTIONS, EVEN IF YOU DISAGREE',
299
- message: '规范一致性 > 技术偏好,有异议显式提出不暗中背离',
300
- level: 'prompt',
301
- trigger: ['code_implementation', 'module_extension'],
302
- enforcement: 'convention-check',
303
- description: `在代码库内部:规范一致性 > 个人技术偏好。若项目用 snake_case 而你偏好 camelCase:用 snake_case。若项目用 class 组件而你偏好 hooks:用 class。若确信某规范存在实质危害,请显式提出。切勿暗中背离规范另起范式。`,
304
- promptInjection: '约定胜于新奇:规范一致性 > 技术偏好。项目用 snake_case 就用 snake_case。有异议显式提出,不暗中另起范式。',
305
- injectPrompt: true,
306
- },
307
-
308
- /**
309
- * 第一性优先 — Mnilax extension
310
- * 原因:从当前状态推导结论会自我证明。正确顺序:第一性→事实校验→结论。
311
- */
312
- first_principles_first: {
313
- id: 'first_principles_first',
314
- kind: 'prompt',
315
- rule: 'ANALYZE FROM FIRST PRINCIPLES, NOT FROM CURRENT STATE',
316
- message: '分析顺序: 第一性→事实校验→结论。禁止"代码就是这样"作为理由',
317
- level: 'prompt',
318
- trigger: ['code_implementation', 'module_modification', 'file_modification'],
319
- enforcement: 'principle-check',
320
- description: `架构分析与设计决策必须从第一性原理出发,而非从当前实现状态推导。禁止的模式: "当前代码这样写的所以应该保持这样"——这是自我证明的错误逻辑。`,
321
- promptInjection: '第一性优先: 分析设计问题从本质出发,不从当前代码推导。正确设计是什么→当前实现匹配吗→差距决定行动。禁止"代码就是这样"作为理由。',
322
- injectPrompt: true,
323
- },
324
-
325
- /**
326
- * 暴露冲突 — Mnilax Rule 7
327
- * 原因:两种模式冲突时不要折中
328
- */
329
- no_conflict_blending: {
330
- id: 'no_conflict_blending',
331
- kind: 'prompt',
332
- rule: 'SURFACE CONFLICTS, DO NOT BLEND THEM',
333
- message: '两种模式冲突→选其一+说明理由,不折中',
334
- level: 'prompt',
335
- trigger: ['code_implementation', 'module_extension'],
336
- enforcement: 'conflict-check',
337
- description: `若代码库中既有的两种模式相互矛盾,明确选择其一(优先更新或更经测试的版本),阐明选择理由,将另一种标记为待清理项。试图同时迎合两套规则的中庸代码往往是最糟的。`,
338
- promptInjection: '暴露冲突不折中:若两种模式冲突→选其一(优先更经测试的版本)+说明理由+标记另一种为待清理。',
339
- injectPrompt: true,
340
- },
341
-
342
- /**
343
- * 禁止表演性同意
344
- * 原因:同意不等于理解,必须先分析再确认
345
- * 来源:Superpowers no_performative_agreement
346
- */
347
- no_performative_agreement: {
348
- id: 'no_performative_agreement',
349
- kind: 'prompt',
350
- rule: 'NO PERFORMATIVE AGREEMENT WITHOUT ANALYSIS',
351
- message: '禁止表演性同意,必须先分析再确认',
352
- level: 'prompt',
353
- trigger: ['design_request'],
354
- enforcement: 'performative-check',
355
- description: `收到需求或反馈时,不能仅表示"好的"、"明白了"就直接执行。必须先分析、复述理解、确认一致。
356
-
357
- 【禁止模式】
358
- - "好的,我来做" → 无分析直接行动
359
- - "明白了" → 没有复述理解
360
- - "没问题" → 没有提出疑问
361
-
362
- 【必须步骤】
363
- 1. 复述你对需求的理解
364
- 2. 提出潜在的疑问或边界情况
365
- 3. 说明你的实现方案
366
- 4. 确认理解一致后再行动`,
367
- promptInjection: '先思后码。明确声明前提假设。遇不确定先提问而非猜测。存在歧义时列出多种理解路径。若存在更简方案应果断提出异议。收到需求时:①复述理解 ②提出疑问 ③说明方案 ④确认一致。',
368
- },
369
-
370
- /**
371
- * 技能需要测试
372
- * 例外:MVP
373
- */
374
- no_skill_without_test: {
375
- id: 'no_skill_without_test',
376
- kind: 'prompt',
377
- rule: 'NO SKILL WITHOUT A FAILING TEST FIRST',
378
- message: '创建技能前必须先定义测试场景',
379
- level: 'prompt',
380
- trigger: 'module_creation',
381
- enforcement: 'skill-test-scenario',
382
- appliesTo: ['agent-skill'],
383
- description: `在创建新的 agent 技能之前,必须先定义测试场景:
384
-
385
- 1. 定义输入/输出期望
386
- 2. 定义边界条件
387
- 3. 定义失败场景
388
- 4. 编写测试用例
389
-
390
- 测试场景帮助:
391
- - 明确技能的功能边界
392
- - 验证技能的正确性
393
- - 防止回归`,
394
- promptInjection: '新创建的 Skill 模块必须有对应的测试文件。测试应覆盖正常路径、边界情况和错误处理。',
395
- },
396
-
397
- /**
398
- * 模型只做判断 — Mnilax Rule 5
399
- * 原因:路由/重试/状态码用代码比 LLM 可靠
400
- */
401
- no_model_for_deterministic: {
402
- id: 'no_model_for_deterministic',
403
- kind: 'prompt',
404
- rule: 'USE MODEL ONLY FOR JUDGMENT CALLS, NOT DETERMINISTIC LOGIC',
405
- message: '路由/重试/状态码处理→代码,不要调 LLM 决策',
406
- level: 'prompt',
407
- trigger: ['code_implementation'],
408
- enforcement: 'deterministic-check',
409
- appliesTo: ['llm-app'],
410
- description: `仅将模型用于需要判断与裁量的场景:分类、内容起草、摘要、信息提取。切勿将模型用于:路由分发、重试机制、状态码处理、确定性数据转换。若常规代码能给出答案,就由代码处理。`,
411
- promptInjection: '模型只做判断不做决策:路由、重试、状态码处理→用代码,不调 LLM。若常规代码能给出答案,就由代码处理。',
412
- injectPrompt: true,
413
- },
414
- };
@@ -1,142 +0,0 @@
1
- /**
2
- * 治理约束注入段漂移校验(ADR-0001 决策 7)
3
- *
4
- * 检测三类漂移:
5
- * 1. 版本漂移:标记段内 `<!-- version: x -->` ≠ 当前 harness 包版本
6
- * 2. 内容漂移:标记段实际条目 ≠ renderConstraintsSection(当前生效集, 当前版本)
7
- * (手改裁剪 / harness 升级后未重跑 init / config.yml 变更后未同步),
8
- * 产出条目级差异(missing/extra),比逐行 diff 更可读
9
- * 3. 重复章节:标记段之外还存在另一个 `## Governance Rules` 标题
10
- * (init 旧版本在无标记时追加第二个同名章节的历史问题)
11
- *
12
- * 落点路由(studio #307,ADR 2026-08-21 落点模型):注入段可能在
13
- * CLAUDE.md(旧模型仓)或 AGENTS.md `PRESERVE:governance` 段内(新模型仓),
14
- * 与 init 的 setupGovernanceConstraints 路由一致——CLAUDE.md 有标记优先。
15
- *
16
- * 纯检测、只读:不改任何文件。check 仅警告不阻断,详细差异进 report。
17
- * 两处均无标记段 = 未注入,不算漂移(report 一句话提示,check 不警告)。
18
- */
19
-
20
- import * as path from 'path';
21
- import type { Constraint } from '../../types/constraint';
22
- import { getEffectiveConstraints } from '../effective-constraints';
23
- import { resolveRunEnv, type RunTarget } from './run-env';
24
- import { getHarnessPackageVersion } from '../../utils/package-version';
25
- import { CONSTRAINTS_END_MARKER, renderConstraintsSection } from './injection-renderer';
26
- import {
27
- resolveInjectionTarget,
28
- readIfExists,
29
- countGovernanceHeadings,
30
- type InjectionFile,
31
- } from './injection-writer';
32
-
33
- export type { InjectionFile };
34
-
35
- /** 注入漂移检测结果 */
36
- export interface InjectionDrift {
37
- /** 是否存在任一漂移(版本/内容/重复章节) */
38
- hasDrift: boolean;
39
- /** CLAUDE.md / AGENTS.md 均无约束标记段(未注入,不算漂移) */
40
- notInjected: boolean;
41
- /** 注入段落点文件(未注入时 undefined) */
42
- injectionFile?: InjectionFile;
43
- /** 版本漂移:注入段版本 ≠ 当前 harness 版本 */
44
- versionDrift?: { expected: string; actual: string };
45
- /**
46
- * 内容漂移(条目级):
47
- * missing = 期望渲染中有、实际段中缺失的条目;extra = 实际段中多出的条目
48
- */
49
- contentDrift?: { missing: string[]; extra: string[] };
50
- /** 标记段之外还存在另一个 `## Governance Rules` 标题 */
51
- duplicateHeading: boolean;
52
- /** 修复指引 */
53
- fixHint: string;
54
- }
55
-
56
- /** 修复指引(重跑 init 幂等同步注入段) */
57
- export const INJECTION_DRIFT_FIX_HINT = '重跑 `npx @dommaker/harness init` 同步注入段(漂移仅警告,不阻断)';
58
-
59
- const VERSION_LINE_RE = /<!-- version: ([^ ]+) -->/;
60
- const ENTRY_LINE_RE = /^- \*\*.+?\*\*: .+$/;
61
- const GROUP_HEADING_RE = /^### .+$/;
62
-
63
- /**
64
- * 提取参与条目级比对的"有效行":注入条目(- **id**: text)与分组标题(### ...)。
65
- * 标记行、版本行、空行不参与——版本单独比对,空行/标记属排版噪音。
66
- */
67
- function significantLines(section: string): string[] {
68
- return section
69
- .split('\n')
70
- .map(l => l.trim())
71
- .filter(l => ENTRY_LINE_RE.test(l) || GROUP_HEADING_RE.test(l));
72
- }
73
-
74
- /**
75
- * 检测约束注入段漂移
76
- *
77
- * @param target 项目根路径,或本 run 的运行级观察面(CLI check 传入即与本 run 共用
78
- * 同一份 config.yml 读取,漂移侧的生效集计算不再重读文件——ADR-0023 决策 2)
79
- * @param currentVersion 当前 harness 版本(缺省经 getHarnessPackageVersion 正本读取;测试可显式传入)
80
- * @param expectedConstraints 本 run 已算好的生效集(CLI check 传入 → 生效集链路一次运行只算
81
- * 一遍,且比对用的就是本 run 实际执法的那份)。不传则按 target 自取,行为与改前逐字一致
82
- */
83
- export function detectInjectionDrift(
84
- target: RunTarget,
85
- currentVersion: string = getHarnessPackageVersion(),
86
- expectedConstraints?: Constraint[]
87
- ): InjectionDrift {
88
- const env = resolveRunEnv(target);
89
- const projectRoot = env.projectPath;
90
- const result: InjectionDrift = {
91
- hasDrift: false,
92
- notInjected: false,
93
- duplicateHeading: false,
94
- fixHint: INJECTION_DRIFT_FIX_HINT,
95
- };
96
-
97
- const injected = resolveInjectionTarget(projectRoot);
98
- if (!injected) {
99
- // 两处均无标记段 = 未注入,不算漂移(check 不警告)。
100
- // 重复章节仍如实记录供 report 提示:旧落点 CLAUDE.md 优先,其次 AGENTS.md。
101
- const legacy =
102
- readIfExists(path.join(projectRoot, 'CLAUDE.md')) ??
103
- readIfExists(path.join(projectRoot, 'AGENTS.md'));
104
- if (legacy !== null) {
105
- result.duplicateHeading = countGovernanceHeadings(legacy) > 1;
106
- }
107
- result.notInjected = true;
108
- return result;
109
- }
110
-
111
- result.injectionFile = injected.file;
112
- const { content, startIdx, endIdx } = injected;
113
-
114
- // 重复章节:全文统计治理标题数(严格计数 injection-writer.countGovernanceHeadings,#83)
115
- const headingCount = countGovernanceHeadings(content);
116
- result.duplicateHeading = headingCount > 1;
117
-
118
- const actualSection = content.slice(startIdx, endIdx + CONSTRAINTS_END_MARKER.length);
119
-
120
- // 1. 版本漂移
121
- const versionMatch = VERSION_LINE_RE.exec(actualSection);
122
- const actualVersion = versionMatch ? versionMatch[1] : '(缺失)';
123
- if (actualVersion !== currentVersion) {
124
- result.versionDrift = { expected: currentVersion, actual: actualVersion };
125
- }
126
-
127
- // 2. 内容漂移(条目级:期望渲染 vs 实际段)
128
- const expectedSection = renderConstraintsSection(
129
- expectedConstraints ?? getEffectiveConstraints(env),
130
- currentVersion
131
- );
132
- const expectedLines = new Set(significantLines(expectedSection));
133
- const actualLines = new Set(significantLines(actualSection));
134
- const missing = [...expectedLines].filter(l => !actualLines.has(l));
135
- const extra = [...actualLines].filter(l => !expectedLines.has(l));
136
- if (missing.length > 0 || extra.length > 0) {
137
- result.contentDrift = { missing, extra };
138
- }
139
-
140
- result.hasDrift = Boolean(result.versionDrift) || Boolean(result.contentDrift) || result.duplicateHeading;
141
- return result;
142
- }
@@ -1,44 +0,0 @@
1
- /**
2
- * CLAUDE.md 约束注入段渲染(ADR-0001)
3
- *
4
- * 纯函数:输入生效约束集 + harness 版本,输出标记区间的期望文本。
5
- * 与写文件分离——init 注入与 P6 注入漂移校验(期望 vs 实际)共用此渲染。
6
- */
7
-
8
- import type { Constraint } from '../../types/constraint';
9
-
10
- /** 约束注入段开始标记 */
11
- export const CONSTRAINTS_START_MARKER = '<!-- HARNESS_CONSTRAINTS_START -->';
12
- /** 约束注入段结束标记 */
13
- export const CONSTRAINTS_END_MARKER = '<!-- HARNESS_CONSTRAINTS_END -->';
14
-
15
- /**
16
- * 渲染 CLAUDE.md 约束注入段(含 START/END 标记,不含 `## Governance Rules` 标题)
17
- *
18
- * 结构:### Iron Laws / ### Guidelines / ### Prompts(行为约束),
19
- * 条目为 `- **id**: promptInjection`;无 promptInjection 的 check 条目
20
- * (如 docs_freshness)不出现在注入段。返回文本以换行结尾。
21
- *
22
- * @param constraints 生效约束集(getEffectiveConstraints 的输出)
23
- * @param version harness 版本号(写入 `<!-- version: x -->` 供漂移校验)
24
- */
25
- export function renderConstraintsSection(constraints: Constraint[], version: string): string {
26
- const lines: string[] = [CONSTRAINTS_START_MARKER, `<!-- version: ${version} -->`];
27
-
28
- const renderGroup = (level: 'iron_law' | 'guideline' | 'prompt', heading: string, first: boolean) => {
29
- const items = constraints.filter(c => c.level === level && c.promptInjection);
30
- if (items.length === 0) return;
31
- if (!first) lines.push('');
32
- lines.push(heading);
33
- for (const c of items) {
34
- lines.push(`- **${c.id}**: ${c.promptInjection}`);
35
- }
36
- };
37
-
38
- renderGroup('iron_law', '### Iron Laws (违反将阻断)', true);
39
- renderGroup('guideline', '### Guidelines (应遵循)', lines.length === 2);
40
- renderGroup('prompt', '### Prompts (行为约束)', lines.length === 2);
41
-
42
- lines.push(CONSTRAINTS_END_MARKER);
43
- return lines.join('\n') + '\n';
44
- }