@xulthekl/team-flow 0.22.4

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 (405) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.agents/skills +1 -0
  3. package/.claude/always/phase-guard.md +3 -0
  4. package/.claude-plugin/marketplace.json +20 -0
  5. package/.claude-plugin/plugin.json +31 -0
  6. package/.codex-plugin/plugin.json +45 -0
  7. package/.codexignore +6 -0
  8. package/.cursor-plugin/marketplace.json +17 -0
  9. package/.cursor-plugin/plugin.json +31 -0
  10. package/.github/copilot-instructions.md +15 -0
  11. package/.github/dependabot.yml +10 -0
  12. package/.github/plugin/marketplace.json +42 -0
  13. package/.github/workflows/ci.yml +98 -0
  14. package/.github/workflows/hol-plugin-scanner.yml +17 -0
  15. package/.opencode/INSTALL.md +61 -0
  16. package/.opencode/plugins/team-flow.js +70 -0
  17. package/AGENTS.md +280 -0
  18. package/CHANGELOG.md +635 -0
  19. package/CONTRIBUTING.md +115 -0
  20. package/GEMINI.md +14 -0
  21. package/HANDOFF.md +219 -0
  22. package/INSTALL.md +810 -0
  23. package/LICENSE +21 -0
  24. package/README.md +185 -0
  25. package/SECURITY.md +37 -0
  26. package/agents/bug-investigator.md +180 -0
  27. package/agents/change-split-auditor.md +257 -0
  28. package/agents/code-reviewer.md +171 -0
  29. package/agents/cross-change-consistency-checker.md +215 -0
  30. package/agents/prd-completeness-reviewer.md +197 -0
  31. package/agents/prototype-builder.md +230 -0
  32. package/agents/prototype-env-scout.md +156 -0
  33. package/agents/prototype-reviewer.md +226 -0
  34. package/assets/icon.svg +6 -0
  35. package/dist/index.d.ts +13 -0
  36. package/dist/index.js +5 -0
  37. package/dist/parsing/change-parser.d.ts +12 -0
  38. package/dist/parsing/change-parser.js +54 -0
  39. package/dist/parsing/requirement-blocks.d.ts +31 -0
  40. package/dist/parsing/requirement-blocks.js +192 -0
  41. package/dist/schema/base.d.ts +7 -0
  42. package/dist/schema/base.js +1 -0
  43. package/dist/schema/change.d.ts +25 -0
  44. package/dist/schema/change.js +1 -0
  45. package/dist/schema/index.d.ts +3 -0
  46. package/dist/schema/index.js +1 -0
  47. package/dist/schema/spec.d.ts +11 -0
  48. package/dist/schema/spec.js +1 -0
  49. package/dist/validation/constants.d.ts +42 -0
  50. package/dist/validation/constants.js +42 -0
  51. package/dist/validation/tokenizer.d.ts +17 -0
  52. package/dist/validation/tokenizer.js +173 -0
  53. package/dist/validation/types.d.ts +40 -0
  54. package/dist/validation/types.js +1 -0
  55. package/dist/validation/validator.d.ts +21 -0
  56. package/dist/validation/validator.js +489 -0
  57. package/docs/README_en.md +358 -0
  58. package/docs/artifact-contract.md +96 -0
  59. package/docs/decision-points.md +88 -0
  60. package/docs/e2e-integration-design.md +207 -0
  61. package/docs/examples/README.md +25 -0
  62. package/docs/examples/add-dark-mode/README.md +13 -0
  63. package/docs/examples/add-dark-mode/design.md +49 -0
  64. package/docs/examples/add-dark-mode/execution-contract.md +56 -0
  65. package/docs/examples/add-dark-mode/proposal.md +46 -0
  66. package/docs/examples/add-dark-mode/specs/ui-theme/spec.md +35 -0
  67. package/docs/examples/add-dark-mode/tasks.md +26 -0
  68. package/docs/examples/refactor-auth-boundary/README.md +15 -0
  69. package/docs/examples/refactor-auth-boundary/design.md +41 -0
  70. package/docs/examples/refactor-auth-boundary/execution-contract.md +61 -0
  71. package/docs/examples/refactor-auth-boundary/proposal.md +47 -0
  72. package/docs/examples/refactor-auth-boundary/specs/auth-boundary/spec.md +45 -0
  73. package/docs/examples/refactor-auth-boundary/tasks.md +25 -0
  74. package/docs/plans/2026-07-07-fix-batch-design.md +68 -0
  75. package/docs/plans/2026-07-20-001-refactor-skill-collaboration-protocol-plan.md +128 -0
  76. package/docs/platform-matrix.md +45 -0
  77. package/docs/prototype-design-research.md +206 -0
  78. package/docs/release-checklist.md +96 -0
  79. package/docs/showcase.html +699 -0
  80. package/docs/skill-rename-v0.8.0.md +49 -0
  81. package/docs/state-machine.md +162 -0
  82. package/gemini-extension.json +6 -0
  83. package/hooks/hooks-cursor.json +8 -0
  84. package/hooks/hooks.json +26 -0
  85. package/hooks/pre-tool-use-guard +116 -0
  86. package/hooks/session-start +14 -0
  87. package/llms.txt +51 -0
  88. package/package.json +48 -0
  89. package/plugin.json +27 -0
  90. package/prd/v1/plan.md +443 -0
  91. package/prd/v1/prd.md +580 -0
  92. package/scripts/check-update.mjs +91 -0
  93. package/scripts/check-version-consistency.mjs +345 -0
  94. package/scripts/ensure-branch.mjs +71 -0
  95. package/scripts/get-config +31 -0
  96. package/scripts/guard/checks/artifacts-exist.mjs +36 -0
  97. package/scripts/guard/checks/contract-current.mjs +33 -0
  98. package/scripts/guard/checks/contract-fresh.mjs +17 -0
  99. package/scripts/guard/checks/dp-gate-passed.mjs +35 -0
  100. package/scripts/guard/checks/dp3-approved.mjs +22 -0
  101. package/scripts/guard/checks/execution-plan-ready.mjs +40 -0
  102. package/scripts/guard/checks/execution-reviews-passed.mjs +36 -0
  103. package/scripts/guard/checks/schema-valid.mjs +63 -0
  104. package/scripts/guard/checks/specs-merged.mjs +51 -0
  105. package/scripts/guard/checks/tasks-complete.mjs +31 -0
  106. package/scripts/guard/checks/tests-passing.mjs +31 -0
  107. package/scripts/guard/design-token-guard.mjs +237 -0
  108. package/scripts/guard/guard.mjs +205 -0
  109. package/scripts/infer-workflow.mjs +136 -0
  110. package/scripts/install-amazon-q.mjs +9 -0
  111. package/scripts/install-cline.mjs +9 -0
  112. package/scripts/install-continue.mjs +9 -0
  113. package/scripts/install-cursor.mjs +265 -0
  114. package/scripts/install-git-hooks.mjs +82 -0
  115. package/scripts/install-kiro.mjs +9 -0
  116. package/scripts/install-pi.mjs +9 -0
  117. package/scripts/install-qoder.mjs +9 -0
  118. package/scripts/install-qwen.mjs +9 -0
  119. package/scripts/install-roocode.mjs +9 -0
  120. package/scripts/install-windsurf.mjs +9 -0
  121. package/scripts/install-zcode.mjs +265 -0
  122. package/scripts/lib/cmd-audit.mjs +127 -0
  123. package/scripts/lib/cmd-checkpoint.mjs +118 -0
  124. package/scripts/lib/cmd-config.mjs +88 -0
  125. package/scripts/lib/cmd-doctor.mjs +267 -0
  126. package/scripts/lib/cmd-execution.mjs +206 -0
  127. package/scripts/lib/cmd-handoff.mjs +94 -0
  128. package/scripts/lib/cmd-inject.mjs +310 -0
  129. package/scripts/lib/cmd-install-amazon-q.mjs +11 -0
  130. package/scripts/lib/cmd-install-cline.mjs +11 -0
  131. package/scripts/lib/cmd-install-continue.mjs +11 -0
  132. package/scripts/lib/cmd-install-cursor.mjs +14 -0
  133. package/scripts/lib/cmd-install-kiro.mjs +11 -0
  134. package/scripts/lib/cmd-install-pi.mjs +11 -0
  135. package/scripts/lib/cmd-install-qoder.mjs +11 -0
  136. package/scripts/lib/cmd-install-qwen.mjs +11 -0
  137. package/scripts/lib/cmd-install-roocode.mjs +11 -0
  138. package/scripts/lib/cmd-install-windsurf.mjs +11 -0
  139. package/scripts/lib/cmd-install-workbuddy.mjs +359 -0
  140. package/scripts/lib/cmd-install-zcode.mjs +14 -0
  141. package/scripts/lib/cmd-isolate.mjs +37 -0
  142. package/scripts/lib/cmd-list.mjs +71 -0
  143. package/scripts/lib/cmd-runtime.mjs +85 -0
  144. package/scripts/lib/cmd-solutions.mjs +71 -0
  145. package/scripts/lib/cmd-state.mjs +231 -0
  146. package/scripts/lib/cmd-sync.mjs +102 -0
  147. package/scripts/lib/cmd-validate.mjs +105 -0
  148. package/scripts/lib/cmd-version.mjs +148 -0
  149. package/scripts/lib/config-loader.mjs +107 -0
  150. package/scripts/lib/execution-plan.mjs +492 -0
  151. package/scripts/lib/execution-recommendation.mjs +221 -0
  152. package/scripts/lib/hash.mjs +74 -0
  153. package/scripts/lib/install.mjs +267 -0
  154. package/scripts/lib/platform-runtime-inventory.mjs +27 -0
  155. package/scripts/lib/platforms.mjs +165 -0
  156. package/scripts/lib/prototype-sync.mjs +192 -0
  157. package/scripts/lib/sdd-overlay.mjs +262 -0
  158. package/scripts/lib/shell-quote.mjs +4 -0
  159. package/scripts/lib/solutions-capture.mjs +102 -0
  160. package/scripts/lib/solutions-index-gen.mjs +112 -0
  161. package/scripts/lib/solutions-inject.mjs +77 -0
  162. package/scripts/lib/solutions-promote.mjs +145 -0
  163. package/scripts/lib/spec-paths.mjs +85 -0
  164. package/scripts/lib/state-loader.mjs +154 -0
  165. package/scripts/lint/lint-skills.mjs +149 -0
  166. package/scripts/lint/rules/behavior-consistency.mjs +56 -0
  167. package/scripts/lint/rules/dp-trigger-points.mjs +60 -0
  168. package/scripts/lint/rules/exception-handling.mjs +59 -0
  169. package/scripts/lint/rules/no-contradictory-instructions.mjs +67 -0
  170. package/scripts/lint/rules/no-redundant-checks.mjs +50 -0
  171. package/scripts/lint/rules/token-rules.mjs +122 -0
  172. package/scripts/review-package +44 -0
  173. package/scripts/task-brief +40 -0
  174. package/scripts/team-flow.mjs +164 -0
  175. package/scripts/token-baseline.mjs +158 -0
  176. package/scripts/validate-artifacts +96 -0
  177. package/scripts/verify-marketplace-release.mjs +59 -0
  178. package/skills/architecture-design/SKILL.md +140 -0
  179. package/skills/architecture-design/chapters/ch01-4a-domains.md +27 -0
  180. package/skills/architecture-design/chapters/ch02-change-cascade.md +27 -0
  181. package/skills/architecture-design/chapters/ch03-architecture-outputs.md +25 -0
  182. package/skills/architecture-design/chapters/ch04-entity-to-aggregate.md +27 -0
  183. package/skills/architecture-design/chapters/ch05-cqrs.md +32 -0
  184. package/skills/architecture-design/chapters/ch06-integration.md +54 -0
  185. package/skills/architecture-design/cheatsheet.md +51 -0
  186. package/skills/architecture-design/glossary.md +23 -0
  187. package/skills/architecture-design/patterns.md +32 -0
  188. package/skills/bug-investigator/SKILL.md +77 -0
  189. package/skills/build-executor/SKILL.md +163 -0
  190. package/skills/build-executor/implementer-prompt.md +162 -0
  191. package/skills/build-executor/references/execution-modes.md +86 -0
  192. package/skills/build-executor/task-reviewer-prompt.md +195 -0
  193. package/skills/ce-brainstorm/SKILL.md +415 -0
  194. package/skills/ce-brainstorm/references/agents/slack-researcher.md +127 -0
  195. package/skills/ce-brainstorm/references/blindspot-pass.md +70 -0
  196. package/skills/ce-brainstorm/references/brainstorm-sections.md +285 -0
  197. package/skills/ce-brainstorm/references/handoff.md +168 -0
  198. package/skills/ce-brainstorm/references/html-rendering.md +634 -0
  199. package/skills/ce-brainstorm/references/markdown-rendering.md +241 -0
  200. package/skills/ce-brainstorm/references/model-tiers.md +9 -0
  201. package/skills/ce-brainstorm/references/prd-mapping.md +71 -0
  202. package/skills/ce-brainstorm/references/product-pressure-test.md +42 -0
  203. package/skills/ce-brainstorm/references/reasoning-elevation.md +63 -0
  204. package/skills/ce-brainstorm/references/settled-decisions.md +45 -0
  205. package/skills/ce-brainstorm/references/synthesis-summary.md +282 -0
  206. package/skills/ce-brainstorm/references/universal-brainstorming.md +73 -0
  207. package/skills/ce-brainstorm/references/verdict-routing.md +26 -0
  208. package/skills/ce-brainstorm/references/visual-probes.md +158 -0
  209. package/skills/ce-brainstorm/scripts/visual-probe-server.js +418 -0
  210. package/skills/ce-compound/SKILL.md +114 -0
  211. package/skills/ce-compound/assets/resolution-template.md +94 -0
  212. package/skills/ce-compound/references/agents/best-practices-researcher.md +115 -0
  213. package/skills/ce-compound/references/agents/data-integrity-guardian.md +68 -0
  214. package/skills/ce-compound/references/agents/framework-docs-researcher.md +93 -0
  215. package/skills/ce-compound/references/agents/pattern-recognition-specialist.md +55 -0
  216. package/skills/ce-compound/references/agents/performance-oracle.md +108 -0
  217. package/skills/ce-compound/references/agents/security-sentinel.md +91 -0
  218. package/skills/ce-compound/references/agents/session-historian.md +83 -0
  219. package/skills/ce-compound/references/concepts-vocabulary.md +78 -0
  220. package/skills/ce-compound/references/full-mode-workflow.md +413 -0
  221. package/skills/ce-compound/references/grounding-validation.md +84 -0
  222. package/skills/ce-compound/references/lightweight-mode.md +53 -0
  223. package/skills/ce-compound/references/output-standards.md +182 -0
  224. package/skills/ce-compound/references/promotion-rules.md +38 -0
  225. package/skills/ce-compound/references/schema.yaml +231 -0
  226. package/skills/ce-compound/references/three-tier-index.md +55 -0
  227. package/skills/ce-compound/references/v0.5-upgrade.md +32 -0
  228. package/skills/ce-compound/references/write-flow.md +36 -0
  229. package/skills/ce-compound/references/yaml-schema.md +118 -0
  230. package/skills/ce-compound/scripts/session-history/discover-sessions.sh +130 -0
  231. package/skills/ce-compound/scripts/session-history/extract-errors.py +254 -0
  232. package/skills/ce-compound/scripts/session-history/extract-metadata.py +456 -0
  233. package/skills/ce-compound/scripts/session-history/extract-skeleton.py +575 -0
  234. package/skills/ce-compound/scripts/validate-doc-claims.py +346 -0
  235. package/skills/ce-compound/scripts/validate-frontmatter.py +137 -0
  236. package/skills/ce-ideate/SKILL.md +402 -0
  237. package/skills/ce-ideate/references/agents/issue-intelligence-analyst.md +200 -0
  238. package/skills/ce-ideate/references/agents/learnings-researcher.md +247 -0
  239. package/skills/ce-ideate/references/agents/slack-researcher.md +127 -0
  240. package/skills/ce-ideate/references/agents/web-researcher.md +121 -0
  241. package/skills/ce-ideate/references/divergent-ideation.md +89 -0
  242. package/skills/ce-ideate/references/html-rendering.md +634 -0
  243. package/skills/ce-ideate/references/ideation-sections.md +191 -0
  244. package/skills/ce-ideate/references/markdown-rendering.md +238 -0
  245. package/skills/ce-ideate/references/post-ideation-workflow.md +167 -0
  246. package/skills/ce-ideate/references/universal-ideation.md +107 -0
  247. package/skills/ce-ideate/references/web-research-cache.md +56 -0
  248. package/skills/ce-plan/SKILL.md +137 -0
  249. package/skills/ce-plan/references/agents/agent-native-planning-strategist.md +62 -0
  250. package/skills/ce-plan/references/agents/architecture-strategist.md +46 -0
  251. package/skills/ce-plan/references/agents/best-practices-researcher.md +114 -0
  252. package/skills/ce-plan/references/agents/data-integrity-guardian.md +68 -0
  253. package/skills/ce-plan/references/agents/data-migration-reviewer.md +103 -0
  254. package/skills/ce-plan/references/agents/deployment-verification-agent.md +157 -0
  255. package/skills/ce-plan/references/agents/framework-docs-researcher.md +93 -0
  256. package/skills/ce-plan/references/agents/git-history-analyzer.md +40 -0
  257. package/skills/ce-plan/references/agents/learnings-researcher.md +247 -0
  258. package/skills/ce-plan/references/agents/pattern-recognition-specialist.md +55 -0
  259. package/skills/ce-plan/references/agents/performance-oracle.md +108 -0
  260. package/skills/ce-plan/references/agents/repo-research-analyst.md +258 -0
  261. package/skills/ce-plan/references/agents/security-sentinel.md +91 -0
  262. package/skills/ce-plan/references/agents/slack-researcher.md +127 -0
  263. package/skills/ce-plan/references/agents/spec-flow-analyzer.md +80 -0
  264. package/skills/ce-plan/references/agents/web-researcher.md +121 -0
  265. package/skills/ce-plan/references/approach-altitude.md +55 -0
  266. package/skills/ce-plan/references/change-splitting.md +65 -0
  267. package/skills/ce-plan/references/completion-contract.md +33 -0
  268. package/skills/ce-plan/references/core-principles.md +40 -0
  269. package/skills/ce-plan/references/deepening-workflow.md +263 -0
  270. package/skills/ce-plan/references/dependency-graph.md +36 -0
  271. package/skills/ce-plan/references/html-rendering.md +634 -0
  272. package/skills/ce-plan/references/intake-routing.md +189 -0
  273. package/skills/ce-plan/references/markdown-rendering.md +238 -0
  274. package/skills/ce-plan/references/plan-handoff.md +150 -0
  275. package/skills/ce-plan/references/plan-sections.md +427 -0
  276. package/skills/ce-plan/references/plan-structure.md +120 -0
  277. package/skills/ce-plan/references/planning-modes.md +69 -0
  278. package/skills/ce-plan/references/reasoning-elevation.md +63 -0
  279. package/skills/ce-plan/references/research-workflow.md +165 -0
  280. package/skills/ce-plan/references/review-and-write.md +127 -0
  281. package/skills/ce-plan/references/settled-decisions.md +45 -0
  282. package/skills/ce-plan/references/synthesis-summary.md +418 -0
  283. package/skills/ce-plan/references/universal-planning.md +168 -0
  284. package/skills/ce-proof/SKILL.md +346 -0
  285. package/skills/ce-strategy/SKILL.md +97 -0
  286. package/skills/ce-strategy/references/interview.md +143 -0
  287. package/skills/ce-strategy/references/strategy-template.md +89 -0
  288. package/skills/code-reviewer/SKILL.md +84 -0
  289. package/skills/code-reviewer/code-reviewer-prompt.md +195 -0
  290. package/skills/contract-builder/SKILL.md +72 -0
  291. package/skills/design-system/SKILL.md +75 -0
  292. package/skills/design-system/references/agents/design-system-architect.md +138 -0
  293. package/skills/design-system/references/creation-flow.md +170 -0
  294. package/skills/design-system/references/preview-template.html +319 -0
  295. package/skills/design-system/references/token-derivation.md +115 -0
  296. package/skills/design-system/references/variant-schema.md +60 -0
  297. package/skills/e2e/SKILL.md +56 -0
  298. package/skills/e2e/references/test-verifier.md +40 -0
  299. package/skills/need-explorer/SKILL.md +79 -0
  300. package/skills/prototype/SKILL.md +98 -0
  301. package/skills/prototype/references/agents/design-system-architect.md +122 -0
  302. package/skills/prototype/references/checklist.md +82 -0
  303. package/skills/prototype/references/craft/accessibility-baseline.md +71 -0
  304. package/skills/prototype/references/craft/anti-ai-slop.md +87 -0
  305. package/skills/prototype/references/craft/laws-of-ux.md +60 -0
  306. package/skills/prototype/references/craft/state-coverage.md +81 -0
  307. package/skills/prototype/references/craft/typography-hierarchy.md +50 -0
  308. package/skills/prototype/references/layouts.md +223 -0
  309. package/skills/prototype/references/orchestration-flow.md +101 -0
  310. package/skills/prototype/references/prototype-scaffold/assets/design-tokens.css +19 -0
  311. package/skills/prototype/references/prototype-scaffold/components/button.html +3 -0
  312. package/skills/prototype/references/prototype-scaffold/design-system.md +7 -0
  313. package/skills/prototype/references/prototype-scaffold/flow.md +11 -0
  314. package/skills/prototype/references/prototype-scaffold/index.html +20 -0
  315. package/skills/prototype/references/prototype-scaffold/pages/index.html +11 -0
  316. package/skills/prototype/references/template.html +396 -0
  317. package/skills/release-archivist/SKILL.md +166 -0
  318. package/skills/release-archivist/references/closing-procedures.md +81 -0
  319. package/skills/session-handoff/SKILL.md +110 -0
  320. package/skills/session-handoff/references/context-extraction.md +70 -0
  321. package/skills/session-handoff/references/handoff-template.md +90 -0
  322. package/skills/session-handoff/references/skill-recommendation.md +43 -0
  323. package/skills/spec-merger/SKILL.md +66 -0
  324. package/skills/spec-writer/SKILL.md +149 -0
  325. package/skills/workflow-bootstrap/SKILL.md +148 -0
  326. package/skills/workflow-bootstrap/references/agents/codebase-recon-analyst.md +121 -0
  327. package/skills/workflow-bootstrap/references/b1-reconnaissance.md +80 -0
  328. package/skills/workflow-bootstrap/scripts/recon-probe.sh +328 -0
  329. package/skills/workflow-feedback/SKILL.md +120 -0
  330. package/skills/workflow-feedback/references/category-guide.md +121 -0
  331. package/skills/workflow-feedback/references/feedback-template.md +73 -0
  332. package/skills/workflow-feedback/references/review-mode.md +92 -0
  333. package/skills/workflow-orchestrator/SKILL.md +94 -0
  334. package/skills/workflow-orchestrator/references/feedback-loops.md +56 -0
  335. package/skills/workflow-orchestrator/references/s1-path-router.md +81 -0
  336. package/skills/workflow-orchestrator/references/s2-prd-prototype-loop.md +96 -0
  337. package/skills/workflow-orchestrator/references/s3-plan-pipeline.md +50 -0
  338. package/skills/workflow-orchestrator/references/s4-split-validate.md +108 -0
  339. package/skills/workflow-orchestrator/references/s5-monitoring.md +61 -0
  340. package/skills/workflow-orchestrator/references/state-model.md +185 -0
  341. package/skills/workflow-start/SKILL.md +147 -0
  342. package/skills/workflow-start/references/routing-rules.md +155 -0
  343. package/src/index.ts +16 -0
  344. package/src/parsing/change-parser.ts +79 -0
  345. package/src/parsing/requirement-blocks.ts +244 -0
  346. package/src/schema/base.ts +8 -0
  347. package/src/schema/change.ts +29 -0
  348. package/src/schema/index.ts +3 -0
  349. package/src/schema/spec.ts +12 -0
  350. package/src/validation/constants.ts +53 -0
  351. package/src/validation/tokenizer.ts +180 -0
  352. package/src/validation/types.ts +47 -0
  353. package/src/validation/validator.ts +552 -0
  354. package/templates/abandonment-summary.md +29 -0
  355. package/templates/design.md +37 -0
  356. package/templates/execution-contract.md +99 -0
  357. package/templates/plan.md +86 -0
  358. package/templates/prd.md +468 -0
  359. package/templates/proposal.md +37 -0
  360. package/templates/spec.md +31 -0
  361. package/templates/tasks.md +47 -0
  362. package/tests/e2e.test.mjs +266 -0
  363. package/tests/lib/cmd-audit.test.mjs +202 -0
  364. package/tests/lib/cmd-checkpoint.test.mjs +98 -0
  365. package/tests/lib/cmd-config.test.mjs +101 -0
  366. package/tests/lib/cmd-doctor.test.mjs +450 -0
  367. package/tests/lib/cmd-execution.test.mjs +647 -0
  368. package/tests/lib/cmd-handoff.test.mjs +137 -0
  369. package/tests/lib/cmd-inject.test.mjs +218 -0
  370. package/tests/lib/cmd-install-workbuddy.test.mjs +113 -0
  371. package/tests/lib/cmd-install-zcode.test.mjs +42 -0
  372. package/tests/lib/cmd-isolate.test.mjs +68 -0
  373. package/tests/lib/cmd-list.test.mjs +127 -0
  374. package/tests/lib/cmd-runtime.test.mjs +83 -0
  375. package/tests/lib/cmd-state-missing.test.mjs +65 -0
  376. package/tests/lib/cmd-state.test.mjs +365 -0
  377. package/tests/lib/cmd-sync-paths.test.mjs +84 -0
  378. package/tests/lib/cmd-validate-paths.test.mjs +90 -0
  379. package/tests/lib/config-loader.test.mjs +175 -0
  380. package/tests/lib/ensure-branch.test.mjs +59 -0
  381. package/tests/lib/execution-control-plane.test.mjs +168 -0
  382. package/tests/lib/execution-plan.test.mjs +474 -0
  383. package/tests/lib/guard-specs-merged.test.mjs +108 -0
  384. package/tests/lib/guard-tests-passing.test.mjs +112 -0
  385. package/tests/lib/guard-transitions.test.mjs +262 -0
  386. package/tests/lib/guard.test.mjs +611 -0
  387. package/tests/lib/hash.test.mjs +138 -0
  388. package/tests/lib/infer-workflow.test.mjs +161 -0
  389. package/tests/lib/install-git-hooks.test.mjs +20 -0
  390. package/tests/lib/marketplace-release-docs.test.mjs +31 -0
  391. package/tests/lib/minimality-discipline.test.mjs +37 -0
  392. package/tests/lib/model-profiles-docs.test.mjs +33 -0
  393. package/tests/lib/node20-compatibility.test.mjs +73 -0
  394. package/tests/lib/node20-test-entry.test.mjs +17 -0
  395. package/tests/lib/platform-runtime-distribution.test.mjs +150 -0
  396. package/tests/lib/raw-mode-smoke.test.mjs +42 -0
  397. package/tests/lib/sdd-overlay.test.mjs +118 -0
  398. package/tests/lib/spec-paths.test.mjs +80 -0
  399. package/tests/lib/state-loader.test.mjs +251 -0
  400. package/tests/lib/token-baseline.test.mjs +72 -0
  401. package/tests/lib/token-rules.test.mjs +94 -0
  402. package/tests/lib/verify-marketplace-release.test.mjs +128 -0
  403. package/tests/tsconfig.json +12 -0
  404. package/token-baseline.json +95 -0
  405. package/tsconfig.json +14 -0
@@ -0,0 +1,552 @@
1
+ import { ValidationReport, ValidationIssue, ValidationLevel } from './types.js';
2
+ import type { VerificationReport, VerificationFinding, ConflictReport, SyncConflict } from './types.js';
3
+ import {
4
+ MIN_PURPOSE_LENGTH,
5
+ MIN_WHY_SECTION_LENGTH,
6
+ MAX_WHY_SECTION_LENGTH,
7
+ MAX_REQUIREMENT_TEXT_LENGTH,
8
+ MAX_DELTAS_PER_CHANGE,
9
+ VALIDATION_MESSAGES,
10
+ VERIFICATION_MESSAGES,
11
+ } from './constants.js';
12
+ import { tokenize } from './tokenizer.js';
13
+ import {
14
+ parseDeltaSpec,
15
+ normalizeRequirementName,
16
+ extractRequirementsSection,
17
+ } from '../parsing/requirement-blocks.js';
18
+
19
+ const REQUIREMENT_HEADER_REGEX = /^###\s*Requirement:\s*(.+)\s*$/i;
20
+ const SCENARIO_HEADER_REGEX = /^####\s+Scenario:/i;
21
+
22
+ function normalizeLineEndings(content: string): string {
23
+ return content.replace(/\r\n?/g, '\n');
24
+ }
25
+
26
+ function extractSection(content: string, heading: string): string | undefined {
27
+ const normalized = normalizeLineEndings(content);
28
+ const lines = normalized.split('\n');
29
+ // Match headings that contain the English keyword — supports both
30
+ // "## Why" and "## 背景(Why)" style bilingual headings.
31
+ const headingRegex = new RegExp(`^##\\s+.*\\b${heading.replace(/\s+/g, '\\s+')}\\b.*$`, 'i');
32
+ const idx = lines.findIndex((l) => headingRegex.test(l));
33
+ if (idx === -1) return undefined;
34
+
35
+ let endIdx = lines.length;
36
+ for (let i = idx + 1; i < lines.length; i++) {
37
+ if (/^##\s+/.test(lines[i])) {
38
+ endIdx = i;
39
+ break;
40
+ }
41
+ }
42
+
43
+ return lines.slice(idx + 1, endIdx).join('\n').trim();
44
+ }
45
+
46
+ function containsShallOrMust(text: string): boolean {
47
+ return /\b(SHALL|MUST)\b/.test(text);
48
+ }
49
+
50
+ function countScenarios(blockRaw: string): number {
51
+ const matches = blockRaw.match(/^####\s+/gm);
52
+ return matches ? matches.length : 0;
53
+ }
54
+
55
+ function extractRequirementText(blockRaw: string): string | undefined {
56
+ const lines = blockRaw.split('\n');
57
+ for (let i = 1; i < lines.length; i++) {
58
+ const line = lines[i];
59
+ if (/^####\s+/.test(line)) break;
60
+ const trimmed = line.trim();
61
+ if (trimmed.length === 0) continue;
62
+ if (/^\*\*[^*]+\*\*:/.test(trimmed)) continue;
63
+ return trimmed;
64
+ }
65
+ return undefined;
66
+ }
67
+
68
+ function buildMissingShallOrMustMessage(
69
+ action: 'ADDED' | 'MODIFIED',
70
+ blockName: string
71
+ ): string {
72
+ const base = `${action} "${blockName}" must contain SHALL or MUST`;
73
+ if (containsShallOrMust(blockName)) {
74
+ return `${base} in the requirement body, not only in the header. Move the SHALL/MUST statement to the line immediately after the "### Requirement: ..." header.`;
75
+ }
76
+ return base;
77
+ }
78
+
79
+ function formatSectionList(sections: string[]): string {
80
+ if (sections.length === 0) return '';
81
+ if (sections.length === 1) return sections[0];
82
+ const head = sections.slice(0, -1);
83
+ const last = sections[sections.length - 1];
84
+ return `${head.join(', ')} and ${last}`;
85
+ }
86
+
87
+ function enrichTopLevelError(itemId: string, baseMessage: string): string {
88
+ const msg = baseMessage.trim();
89
+ if (msg === VALIDATION_MESSAGES.CHANGE_NO_DELTAS) {
90
+ return `${msg}. ${VALIDATION_MESSAGES.GUIDE_NO_DELTAS}`;
91
+ }
92
+ if (
93
+ msg.includes('Spec must have a Purpose section') ||
94
+ msg.includes('Spec must have a Requirements section')
95
+ ) {
96
+ return `${msg}. ${VALIDATION_MESSAGES.GUIDE_MISSING_SPEC_SECTIONS}`;
97
+ }
98
+ if (
99
+ msg.includes('Change must have a Why section') ||
100
+ msg.includes('Change must have a What Changes section')
101
+ ) {
102
+ return `${msg}. ${VALIDATION_MESSAGES.GUIDE_MISSING_CHANGE_SECTIONS}`;
103
+ }
104
+ return msg;
105
+ }
106
+
107
+ function createReport(issues: ValidationIssue[], strictMode: boolean = false): ValidationReport {
108
+ const errors = issues.filter((i) => i.level === 'ERROR').length;
109
+ const warnings = issues.filter((i) => i.level === 'WARNING').length;
110
+ const info = issues.filter((i) => i.level === 'INFO').length;
111
+
112
+ const valid = strictMode ? errors === 0 && warnings === 0 : errors === 0;
113
+
114
+ return {
115
+ valid,
116
+ issues,
117
+ summary: { errors, warnings, info },
118
+ };
119
+ }
120
+
121
+ export class Validator {
122
+ private strictMode: boolean;
123
+
124
+ constructor(strictMode: boolean = false) {
125
+ this.strictMode = strictMode;
126
+ }
127
+
128
+ validateSpecContent(specName: string, content: string): ValidationReport {
129
+ const issues: ValidationIssue[] = [];
130
+
131
+ if (!specName || specName.trim().length === 0) {
132
+ issues.push({ level: 'ERROR', path: 'name', message: VALIDATION_MESSAGES.SPEC_NAME_EMPTY });
133
+ }
134
+
135
+ const purposeSection = extractSection(content, 'Purpose');
136
+ if (!purposeSection || purposeSection.trim().length === 0) {
137
+ issues.push({
138
+ level: 'ERROR',
139
+ path: 'overview',
140
+ message: VALIDATION_MESSAGES.SPEC_PURPOSE_EMPTY,
141
+ });
142
+ } else if (purposeSection.length < MIN_PURPOSE_LENGTH) {
143
+ issues.push({
144
+ level: 'WARNING',
145
+ path: 'overview',
146
+ message: VALIDATION_MESSAGES.PURPOSE_TOO_BRIEF,
147
+ });
148
+ }
149
+
150
+ const reqSectionParts = extractRequirementsSection(content);
151
+ if (reqSectionParts.bodyBlocks.length === 0) {
152
+ issues.push({
153
+ level: 'ERROR',
154
+ path: 'requirements',
155
+ message: VALIDATION_MESSAGES.SPEC_NO_REQUIREMENTS,
156
+ });
157
+ }
158
+
159
+ for (const block of reqSectionParts.bodyBlocks) {
160
+ const reqText = extractRequirementText(block.raw);
161
+ if (!reqText || reqText.trim().length === 0) {
162
+ issues.push({
163
+ level: 'ERROR',
164
+ path: `requirements.${block.name}`,
165
+ message: VALIDATION_MESSAGES.REQUIREMENT_EMPTY,
166
+ });
167
+ } else {
168
+ if (!containsShallOrMust(reqText)) {
169
+ issues.push({
170
+ level: 'ERROR',
171
+ path: `requirements.${block.name}`,
172
+ message: buildMissingShallOrMustMessage('ADDED', block.name),
173
+ });
174
+ }
175
+ if (reqText.length > MAX_REQUIREMENT_TEXT_LENGTH) {
176
+ issues.push({
177
+ level: 'INFO',
178
+ path: `requirements.${block.name}`,
179
+ message: VALIDATION_MESSAGES.REQUIREMENT_TOO_LONG,
180
+ });
181
+ }
182
+ }
183
+
184
+ const scenarioCount = countScenarios(block.raw);
185
+ if (scenarioCount < 1) {
186
+ issues.push({
187
+ level: 'WARNING',
188
+ path: `requirements.${block.name}.scenarios`,
189
+ message: `${VALIDATION_MESSAGES.REQUIREMENT_NO_SCENARIOS}. ${VALIDATION_MESSAGES.GUIDE_SCENARIO_FORMAT}`,
190
+ });
191
+ }
192
+ }
193
+
194
+ return createReport(issues, this.strictMode);
195
+ }
196
+
197
+ validateChangeContent(changeName: string, content: string): ValidationReport {
198
+ const issues: ValidationIssue[] = [];
199
+
200
+ if (!changeName || changeName.trim().length === 0) {
201
+ issues.push({ level: 'ERROR', path: 'name', message: VALIDATION_MESSAGES.CHANGE_NAME_EMPTY });
202
+ }
203
+
204
+ const whySection = extractSection(content, 'Why');
205
+ if (!whySection || whySection.trim().length === 0) {
206
+ issues.push({
207
+ level: 'ERROR',
208
+ path: 'why',
209
+ message: VALIDATION_MESSAGES.CHANGE_WHY_TOO_SHORT,
210
+ });
211
+ } else {
212
+ if (whySection.length < MIN_WHY_SECTION_LENGTH) {
213
+ issues.push({
214
+ level: 'ERROR',
215
+ path: 'why',
216
+ message: VALIDATION_MESSAGES.CHANGE_WHY_TOO_SHORT,
217
+ });
218
+ }
219
+ if (whySection.length > MAX_WHY_SECTION_LENGTH) {
220
+ issues.push({
221
+ level: 'WARNING',
222
+ path: 'why',
223
+ message: VALIDATION_MESSAGES.CHANGE_WHY_TOO_LONG,
224
+ });
225
+ }
226
+ }
227
+
228
+ const whatChanges = extractSection(content, 'What Changes');
229
+ if (!whatChanges || whatChanges.trim().length === 0) {
230
+ issues.push({
231
+ level: 'ERROR',
232
+ path: 'whatChanges',
233
+ message: VALIDATION_MESSAGES.CHANGE_WHAT_EMPTY,
234
+ });
235
+ }
236
+
237
+ return createReport(issues, this.strictMode);
238
+ }
239
+
240
+ validateDeltaSpec(content: string): ValidationReport {
241
+ const issues: ValidationIssue[] = [];
242
+
243
+ const plan = parseDeltaSpec(content);
244
+ const totalDeltas =
245
+ plan.added.length + plan.modified.length + plan.removed.length + plan.renamed.length;
246
+
247
+ if (totalDeltas === 0) {
248
+ issues.push({
249
+ level: 'ERROR',
250
+ path: 'file',
251
+ message: enrichTopLevelError('change', VALIDATION_MESSAGES.CHANGE_NO_DELTAS),
252
+ });
253
+ return createReport(issues, this.strictMode);
254
+ }
255
+
256
+ if (totalDeltas > MAX_DELTAS_PER_CHANGE) {
257
+ issues.push({
258
+ level: 'WARNING',
259
+ path: 'file',
260
+ message: VALIDATION_MESSAGES.CHANGE_TOO_MANY_DELTAS,
261
+ });
262
+ }
263
+
264
+ const addedNames = new Set<string>();
265
+ const modifiedNames = new Set<string>();
266
+ const removedNames = new Set<string>();
267
+ const renamedFrom = new Set<string>();
268
+ const renamedTo = new Set<string>();
269
+
270
+ for (const block of plan.added) {
271
+ const key = normalizeRequirementName(block.name);
272
+ if (addedNames.has(key)) {
273
+ issues.push({
274
+ level: 'ERROR',
275
+ path: 'added',
276
+ message: `Duplicate requirement in ADDED: "${block.name}"`,
277
+ });
278
+ } else {
279
+ addedNames.add(key);
280
+ }
281
+ const reqText = extractRequirementText(block.raw);
282
+ if (!reqText) {
283
+ issues.push({
284
+ level: 'ERROR',
285
+ path: `added.${block.name}`,
286
+ message: `ADDED "${block.name}" is missing requirement text`,
287
+ });
288
+ } else if (!containsShallOrMust(reqText)) {
289
+ issues.push({
290
+ level: 'ERROR',
291
+ path: `added.${block.name}`,
292
+ message: buildMissingShallOrMustMessage('ADDED', block.name),
293
+ });
294
+ }
295
+ if (countScenarios(block.raw) < 1) {
296
+ issues.push({
297
+ level: 'ERROR',
298
+ path: `added.${block.name}`,
299
+ message: `ADDED "${block.name}" must include at least one scenario`,
300
+ });
301
+ }
302
+ }
303
+
304
+ for (const block of plan.modified) {
305
+ const key = normalizeRequirementName(block.name);
306
+ if (modifiedNames.has(key)) {
307
+ issues.push({
308
+ level: 'ERROR',
309
+ path: 'modified',
310
+ message: `Duplicate requirement in MODIFIED: "${block.name}"`,
311
+ });
312
+ } else {
313
+ modifiedNames.add(key);
314
+ }
315
+ const reqText = extractRequirementText(block.raw);
316
+ if (!reqText) {
317
+ issues.push({
318
+ level: 'ERROR',
319
+ path: `modified.${block.name}`,
320
+ message: `MODIFIED "${block.name}" is missing requirement text`,
321
+ });
322
+ } else if (!containsShallOrMust(reqText)) {
323
+ issues.push({
324
+ level: 'ERROR',
325
+ path: `modified.${block.name}`,
326
+ message: buildMissingShallOrMustMessage('MODIFIED', block.name),
327
+ });
328
+ }
329
+ if (countScenarios(block.raw) < 1) {
330
+ issues.push({
331
+ level: 'ERROR',
332
+ path: `modified.${block.name}`,
333
+ message: `MODIFIED "${block.name}" must include at least one scenario`,
334
+ });
335
+ }
336
+ }
337
+
338
+ for (const name of plan.removed) {
339
+ const key = normalizeRequirementName(name);
340
+ if (removedNames.has(key)) {
341
+ issues.push({
342
+ level: 'ERROR',
343
+ path: 'removed',
344
+ message: `Duplicate requirement in REMOVED: "${name}"`,
345
+ });
346
+ } else {
347
+ removedNames.add(key);
348
+ }
349
+ }
350
+
351
+ for (const { from, to } of plan.renamed) {
352
+ const fromKey = normalizeRequirementName(from);
353
+ const toKey = normalizeRequirementName(to);
354
+ if (renamedFrom.has(fromKey)) {
355
+ issues.push({
356
+ level: 'ERROR',
357
+ path: 'renamed',
358
+ message: `Duplicate FROM in RENAMED: "${from}"`,
359
+ });
360
+ } else {
361
+ renamedFrom.add(fromKey);
362
+ }
363
+ if (renamedTo.has(toKey)) {
364
+ issues.push({
365
+ level: 'ERROR',
366
+ path: 'renamed',
367
+ message: `Duplicate TO in RENAMED: "${to}"`,
368
+ });
369
+ } else {
370
+ renamedTo.add(toKey);
371
+ }
372
+ }
373
+
374
+ for (const n of modifiedNames) {
375
+ if (removedNames.has(n)) {
376
+ issues.push({
377
+ level: 'ERROR',
378
+ path: 'cross-section',
379
+ message: `Requirement present in both MODIFIED and REMOVED: "${n}"`,
380
+ });
381
+ }
382
+ if (addedNames.has(n)) {
383
+ issues.push({
384
+ level: 'ERROR',
385
+ path: 'cross-section',
386
+ message: `Requirement present in both MODIFIED and ADDED: "${n}"`,
387
+ });
388
+ }
389
+ }
390
+ for (const n of addedNames) {
391
+ if (removedNames.has(n)) {
392
+ issues.push({
393
+ level: 'ERROR',
394
+ path: 'cross-section',
395
+ message: `Requirement present in both ADDED and REMOVED: "${n}"`,
396
+ });
397
+ }
398
+ }
399
+ for (const { from, to } of plan.renamed) {
400
+ const fromKey = normalizeRequirementName(from);
401
+ const toKey = normalizeRequirementName(to);
402
+ if (modifiedNames.has(fromKey)) {
403
+ issues.push({
404
+ level: 'ERROR',
405
+ path: 'cross-section',
406
+ message: `MODIFIED references old name from RENAMED. Use new header for "${to}"`,
407
+ });
408
+ }
409
+ if (addedNames.has(toKey)) {
410
+ issues.push({
411
+ level: 'ERROR',
412
+ path: 'cross-section',
413
+ message: `RENAMED TO collides with ADDED for "${to}"`,
414
+ });
415
+ }
416
+ }
417
+
418
+ return createReport(issues, this.strictMode);
419
+ }
420
+
421
+ validateImplementation(
422
+ diffSummary: string,
423
+ specContent: string,
424
+ designContent: string,
425
+ config?: { verification?: { language?: string } }
426
+ ): VerificationReport {
427
+ const dimensions: VerificationReport['dimensions'] = [];
428
+ const language = (config?.verification?.language as 'auto' | 'en' | 'zh') ?? 'auto';
429
+
430
+ // --- Completeness ---
431
+ const completenessFindings: VerificationFinding[] = [];
432
+ const requirements = this.extractRequirementNames(specContent);
433
+ const diffTokens = tokenize(diffSummary, language);
434
+ for (const req of requirements) {
435
+ // A requirement is considered covered when every significant token appears
436
+ // somewhere in the diff tokens. Uses language-aware tokenization so that
437
+ // both English (stemming) and Chinese (CJK sliding window) are handled.
438
+ const reqTokens = tokenize(req, language);
439
+ const allPresent = reqTokens.size === 0 || [...reqTokens].every(t => diffTokens.has(t));
440
+ if (!allPresent) {
441
+ completenessFindings.push({
442
+ level: 'CRITICAL',
443
+ dimension: 'Completeness',
444
+ message: VERIFICATION_MESSAGES.COMPLETENESS_MISSING_REQUIREMENT.replace('{requirement}', req),
445
+ });
446
+ }
447
+ }
448
+ dimensions.push({
449
+ name: 'Completeness',
450
+ status: completenessFindings.some(f => f.level === 'CRITICAL') ? 'FAIL' : completenessFindings.length > 0 ? 'WARN' : 'PASS',
451
+ findings: completenessFindings,
452
+ });
453
+
454
+ // --- Correctness ---
455
+ const correctnessFindings: VerificationFinding[] = [];
456
+ const placeholderPatterns = ['TODO', 'FIXME', 'HACK', 'XXX', 'PLACEHOLDER'];
457
+ for (const pattern of placeholderPatterns) {
458
+ if (diffSummary.includes(pattern)) {
459
+ correctnessFindings.push({
460
+ level: 'CRITICAL',
461
+ dimension: 'Correctness',
462
+ message: VERIFICATION_MESSAGES.VERIFICATION_PLACEHOLDER_DETECTED,
463
+ });
464
+ break;
465
+ }
466
+ }
467
+ dimensions.push({
468
+ name: 'Correctness',
469
+ status: correctnessFindings.some(f => f.level === 'CRITICAL') ? 'FAIL' : correctnessFindings.length > 0 ? 'WARN' : 'PASS',
470
+ findings: correctnessFindings,
471
+ });
472
+
473
+ // --- Coherence ---
474
+ const coherenceFindings: VerificationFinding[] = [];
475
+ const decisionNames = this.extractDecisionNames(designContent);
476
+ for (const name of decisionNames) {
477
+ // Tokenize both the decision name and the diff summary using language-aware
478
+ // tokenization, then check that all decision tokens appear in diff tokens.
479
+ const decisionTokens = tokenize(name, language);
480
+ const allPresent = decisionTokens.size === 0 || [...decisionTokens].every(t => diffTokens.has(t));
481
+ if (!allPresent) {
482
+ coherenceFindings.push({
483
+ level: 'IMPORTANT',
484
+ dimension: 'Coherence',
485
+ message: VERIFICATION_MESSAGES.COHERENCE_PATTERN_MISSING.replace('{pattern}', name),
486
+ });
487
+ }
488
+ }
489
+ dimensions.push({
490
+ name: 'Coherence',
491
+ status: coherenceFindings.some(f => f.level === 'CRITICAL') ? 'FAIL' : coherenceFindings.length > 0 ? 'WARN' : 'PASS',
492
+ findings: coherenceFindings,
493
+ });
494
+
495
+ // --- Verdict ---
496
+ const hasCritical = dimensions.some(d => d.status === 'FAIL');
497
+ const hasWarning = dimensions.some(d => d.status === 'WARN');
498
+ const verdict: VerificationReport['verdict'] = hasCritical ? 'FAIL' : hasWarning ? 'CONDITIONAL' : 'PASS';
499
+
500
+ return { dimensions, verdict };
501
+ }
502
+
503
+ private extractRequirementNames(specContent: string): string[] {
504
+ const regex = /### Requirement:\s*(.+)/g;
505
+ const names: string[] = [];
506
+ let match;
507
+ while ((match = regex.exec(specContent)) !== null) {
508
+ names.push(match[1].trim());
509
+ }
510
+ return names;
511
+ }
512
+
513
+ private extractDecisionNames(designContent: string): string[] {
514
+ const regex = /- Choice:\s*(.+)/g;
515
+ const names: string[] = [];
516
+ let match;
517
+ while ((match = regex.exec(designContent)) !== null) {
518
+ names.push(match[1].trim());
519
+ }
520
+ return names;
521
+ }
522
+
523
+ detectSyncConflicts(deltaSpecs: Array<{ changeName: string; content: string }>): ConflictReport {
524
+ const reqToChanges = new Map<string, string[]>();
525
+
526
+ for (const { changeName, content } of deltaSpecs) {
527
+ const plan = parseDeltaSpec(content);
528
+ const names: string[] = [
529
+ ...plan.modified.map(b => normalizeRequirementName(b.name)),
530
+ ...plan.renamed.map(r => normalizeRequirementName(r.to)),
531
+ ];
532
+ for (const name of names) {
533
+ const existing = reqToChanges.get(name) || [];
534
+ existing.push(changeName);
535
+ reqToChanges.set(name, existing);
536
+ }
537
+ }
538
+
539
+ const conflicts: SyncConflict[] = [];
540
+ for (const [requirement, changes] of reqToChanges) {
541
+ if (changes.length >= 2) {
542
+ conflicts.push({ requirement, spec: requirement, changes });
543
+ }
544
+ }
545
+
546
+ return { hasConflicts: conflicts.length > 0, conflicts };
547
+ }
548
+
549
+ isValid(report: ValidationReport): boolean {
550
+ return report.valid;
551
+ }
552
+ }
@@ -0,0 +1,29 @@
1
+ # Abandonment Summary
2
+
3
+ ## Change
4
+
5
+ - **Name**: [change name]
6
+ - **Original goal**: [one sentence]
7
+
8
+ ## Reason
9
+
10
+ [At least 50 characters explaining why this change was abandoned]
11
+
12
+ ## What Was Tried
13
+
14
+ - [Action 1 and its outcome]
15
+ - [Action 2 and its outcome]
16
+
17
+ ## Lessons Learned
18
+
19
+ - [Concrete insight 1 that may help future attempts]
20
+
21
+ ## Recommendations
22
+
23
+ - [Suggested next step or alternative approach]
24
+
25
+ ## Preserved Work
26
+
27
+ - [ ] No work preserved (all changes discarded)
28
+ - [ ] Partial work preserved:
29
+ - Commit `[hash]`: [description]
@@ -0,0 +1,37 @@
1
+ # 技术设计
2
+
3
+ ## 上下文
4
+
5
+ - 当前状态:
6
+ - 约束条件:
7
+ - 利益相关者:
8
+
9
+ ## 目标
10
+
11
+ - 本设计必须达成什么
12
+
13
+ ## 非目标
14
+
15
+ - 本设计刻意不解决什么
16
+
17
+ ## 决策
18
+
19
+ ### 决策 1
20
+
21
+ - **选择**:
22
+ - **理由**:
23
+ - **考虑的替代方案**:
24
+
25
+ ## 风险与权衡
26
+
27
+ - 风险 → 缓解措施
28
+
29
+ ## 迁移计划
30
+
31
+ - 上线步骤:
32
+ - 回滚步骤:
33
+
34
+ ## 待明确问题
35
+
36
+ - 问题:
37
+ - 决策负责人: