@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,84 @@
1
+ import { describe, it, before, after } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { tmpdir } from 'node:os';
7
+ import { deriveCapabilityDir } from '../../scripts/lib/cmd-sync.mjs';
8
+
9
+ const CLI = join(process.cwd(), 'scripts/team-flow.mjs');
10
+ let tempRoot;
11
+
12
+ function runSync(cwd, changeDir) {
13
+ try {
14
+ const stdout = execFileSync(process.execPath, [CLI, 'sync', changeDir], {
15
+ cwd,
16
+ encoding: 'utf-8',
17
+ stdio: ['pipe', 'pipe', 'pipe'],
18
+ });
19
+ return { exitCode: 0, stdout, stderr: '' };
20
+ } catch (err) {
21
+ return {
22
+ exitCode: err.status || 1,
23
+ stdout: err.stdout?.toString() || '',
24
+ stderr: err.stderr?.toString() || err.message,
25
+ };
26
+ }
27
+ }
28
+
29
+ function writeSpec(path) {
30
+ writeFileSync(path, '## ADDED Requirements\n\n### Requirement: Sync path\n\nThe system SHALL sync canonical paths.\n\n#### Scenario: Sync\n- **WHEN** sync runs\n- **THEN** the main spec is written');
31
+ }
32
+
33
+ describe('cmd-sync: canonical spec paths', () => {
34
+ before(() => {
35
+ tempRoot = mkdtempSync(join(tmpdir(), 'tf-sync-paths-'));
36
+ });
37
+
38
+ after(() => {
39
+ if (tempRoot) rmSync(tempRoot, { recursive: true, force: true });
40
+ });
41
+
42
+ it('syncs canonical specs to main specs/<capability>/spec.md', () => {
43
+ const repo = mkdtempSync(join(tempRoot, 'repo-'));
44
+ const change = join(repo, 'changes', 'canonical');
45
+ mkdirSync(join(change, 'specs', 'ui-theme'), { recursive: true });
46
+ writeSpec(join(change, 'specs', 'ui-theme', 'spec.md'));
47
+
48
+ const result = runSync(repo, change);
49
+ assert.equal(result.exitCode, 0, result.stdout + result.stderr);
50
+ assert.equal(existsSync(join(repo, 'specs', 'ui-theme', 'spec.md')), true);
51
+ assert.match(readFileSync(join(repo, 'specs', 'ui-theme', 'spec.md'), 'utf-8'), /Sync path/);
52
+ });
53
+
54
+ it('derives capability dirs from Windows-style spec paths', () => {
55
+ assert.equal(
56
+ deriveCapabilityDir('C:\\repo\\changes\\feature\\specs', 'C:\\repo\\changes\\feature\\specs\\ui-theme\\spec.md'),
57
+ 'ui-theme',
58
+ );
59
+ });
60
+
61
+ it('rejects flat specs before syncing', () => {
62
+ const repo = mkdtempSync(join(tempRoot, 'repo-flat-'));
63
+ const change = join(repo, 'changes', 'flat');
64
+ mkdirSync(join(change, 'specs'), { recursive: true });
65
+ writeSpec(join(change, 'specs', 'ui-theme.md'));
66
+
67
+ const result = runSync(repo, change);
68
+ assert.equal(result.exitCode, 1);
69
+ assert.match(result.stdout + result.stderr, /Invalid spec path: specs\/ui-theme\.md/);
70
+ assert.equal(existsSync(join(repo, 'specs', 'ui-theme', 'spec.md')), false);
71
+ });
72
+
73
+ it('rejects root specs/spec.md before syncing', () => {
74
+ const repo = mkdtempSync(join(tempRoot, 'repo-root-'));
75
+ const change = join(repo, 'changes', 'root-spec');
76
+ mkdirSync(join(change, 'specs'), { recursive: true });
77
+ writeSpec(join(change, 'specs', 'spec.md'));
78
+
79
+ const result = runSync(repo, change);
80
+ assert.equal(result.exitCode, 1);
81
+ assert.match(result.stdout + result.stderr, /Invalid spec path: specs\/spec\.md/);
82
+ assert.equal(existsSync(join(repo, 'specs', 'spec.md')), false);
83
+ });
84
+ });
@@ -0,0 +1,90 @@
1
+ import { describe, it, before, after } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { tmpdir } from 'node:os';
7
+
8
+ const CLI = join(process.cwd(), 'scripts/team-flow.mjs');
9
+ const LEGACY = join(process.cwd(), 'scripts/validate-artifacts');
10
+ let tempRoot;
11
+
12
+ function runNode(args) {
13
+ try {
14
+ const stdout = execFileSync(process.execPath, args, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
15
+ return { exitCode: 0, stdout, stderr: '' };
16
+ } catch (err) {
17
+ return { exitCode: err.status || 1, stdout: err.stdout?.toString() || '', stderr: err.stderr?.toString() || err.message };
18
+ }
19
+ }
20
+
21
+ function writeBaseChange(dir) {
22
+ writeFileSync(join(dir, 'proposal.md'), '## Why\nThis proposal is long enough to pass validation because it explains the user problem clearly.\n## What Changes\n- Add validated behavior');
23
+ writeFileSync(join(dir, 'design.md'), '## Context\nValidation fixture.\n## Goals\nKeep paths canonical.\n## Decisions\n### D1\n- Choice: canonical specs\n- Rationale: one path');
24
+ writeFileSync(join(dir, 'tasks.md'), '## File Structure\n- Modify: scripts/example.mjs\n## Tasks\n- [x] Validate paths');
25
+ }
26
+
27
+ function writeValidSpec(file) {
28
+ writeFileSync(file, '## ADDED Requirements\n\n### Requirement: Canonical path\n\nThe system SHALL validate canonical specs.\n\n#### Scenario: Valid spec\n- **WHEN** validation runs\n- **THEN** the spec is checked');
29
+ }
30
+
31
+ describe('validate commands: spec paths', () => {
32
+ before(() => {
33
+ tempRoot = mkdtempSync(join(tmpdir(), 'tf-validate-paths-'));
34
+ });
35
+
36
+ after(() => {
37
+ if (tempRoot) rmSync(tempRoot, { recursive: true, force: true });
38
+ });
39
+
40
+ it('tf validate rejects flat specs/<capability>.md', () => {
41
+ const dir = mkdtempSync(join(tempRoot, 'flat-'));
42
+ writeBaseChange(dir);
43
+ mkdirSync(join(dir, 'specs'), { recursive: true });
44
+ writeValidSpec(join(dir, 'specs', 'ui-theme.md'));
45
+
46
+ const result = runNode([CLI, 'validate', dir]);
47
+ assert.equal(result.exitCode, 1);
48
+ assert.match(result.stdout + result.stderr, /Invalid spec path: specs\/ui-theme\.md/);
49
+ assert.match(result.stdout + result.stderr, /specs\/ui-theme\/spec\.md/);
50
+ });
51
+
52
+ it('validate-artifacts rejects specs/ with no canonical spec.md', () => {
53
+ const dir = mkdtempSync(join(tempRoot, 'empty-specs-'));
54
+ writeBaseChange(dir);
55
+ mkdirSync(join(dir, 'specs'), { recursive: true });
56
+
57
+ const result = runNode([LEGACY, dir]);
58
+ assert.equal(result.exitCode, 1);
59
+ assert.match(result.stdout + result.stderr, /No canonical spec files found/);
60
+ });
61
+
62
+ it('tf validate rejects a change with no specs/ directory', () => {
63
+ const dir = mkdtempSync(join(tempRoot, 'missing-specs-cli-'));
64
+ writeBaseChange(dir);
65
+
66
+ const result = runNode([CLI, 'validate', dir]);
67
+ assert.equal(result.exitCode, 1);
68
+ assert.match(result.stdout + result.stderr, /No canonical spec files found/);
69
+ });
70
+
71
+ it('validate-artifacts rejects a change with no specs/ directory', () => {
72
+ const dir = mkdtempSync(join(tempRoot, 'missing-specs-legacy-'));
73
+ writeBaseChange(dir);
74
+
75
+ const result = runNode([LEGACY, dir]);
76
+ assert.equal(result.exitCode, 1);
77
+ assert.match(result.stdout + result.stderr, /No canonical spec files found/);
78
+ });
79
+
80
+ it('tf validate accepts canonical specs/<capability>/spec.md', () => {
81
+ const dir = mkdtempSync(join(tempRoot, 'canonical-'));
82
+ writeBaseChange(dir);
83
+ mkdirSync(join(dir, 'specs', 'ui-theme'), { recursive: true });
84
+ writeValidSpec(join(dir, 'specs', 'ui-theme', 'spec.md'));
85
+
86
+ const result = runNode([CLI, 'validate', dir]);
87
+ assert.equal(result.exitCode, 0, result.stdout + result.stderr);
88
+ assert.match(result.stdout, /specs\/ui-theme\/spec\.md/);
89
+ });
90
+ });
@@ -0,0 +1,175 @@
1
+ // tests/lib/config-loader.test.mjs
2
+ // Tests for scripts/lib/config-loader.mjs
3
+ import { describe, it, before, after } from 'node:test';
4
+ import assert from 'node:assert/strict';
5
+ import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { tmpdir } from 'node:os';
8
+
9
+ // We need to import from the scripts directory. Since config-loader uses
10
+ // relative imports only (no path manipulation), we can test its pure logic
11
+ // by importing and controlling cwd.
12
+
13
+ // Store original cwd
14
+ const originalCwd = process.cwd;
15
+ let tempDir;
16
+
17
+ describe('config-loader: getDefaults()', () => {
18
+ let configLoader;
19
+
20
+ before(async () => {
21
+ // Dynamic import to get fresh module
22
+ const modulePath = join(process.cwd(), 'scripts/lib/config-loader.mjs');
23
+ configLoader = await import(modulePath);
24
+ });
25
+
26
+ it('returns DEFAULTS object with expected shape', () => {
27
+ const defaults = configLoader.getDefaults();
28
+ assert.ok(defaults.artifacts);
29
+ assert.deepStrictEqual(defaults.artifacts.order, ['proposal', 'specs', 'design', 'tasks']);
30
+ assert.deepStrictEqual(defaults.artifacts.skip, []);
31
+ assert.ok(defaults.execution);
32
+ assert.equal(defaults.execution.inlineThreshold, 3);
33
+ assert.equal(defaults.execution.abandonmentReasonMinLength, 50);
34
+ assert.equal(defaults.execution.defaultLanguage, 'auto');
35
+ assert.ok(defaults.verification);
36
+ assert.equal(defaults.verification.language, 'auto');
37
+ });
38
+
39
+ it('returns a deep copy, not a reference', () => {
40
+ const d1 = configLoader.getDefaults();
41
+ const d2 = configLoader.getDefaults();
42
+ d1.artifacts.order.push('execution-contract');
43
+ assert.notDeepStrictEqual(d1.artifacts.order, d2.artifacts.order);
44
+ });
45
+ });
46
+
47
+ describe('config-loader: resolveModelProfile()', () => {
48
+ let configLoader;
49
+
50
+ before(async () => {
51
+ const modulePath = join(process.cwd(), 'scripts/lib/config-loader.mjs');
52
+ configLoader = await import(modulePath);
53
+ });
54
+
55
+ it('exposes the supported model profiles in order', () => {
56
+ assert.deepStrictEqual(configLoader.MODEL_PROFILES, [
57
+ 'mechanical', 'standard', 'strong', 'review',
58
+ ]);
59
+ });
60
+
61
+ it('resolves all four configured profiles without changing their model identifiers', () => {
62
+ const config = {
63
+ models: {
64
+ mechanical: 'vendor-small', standard: 'vendor-standard',
65
+ strong: 'vendor-strong', review: 'vendor-review',
66
+ },
67
+ };
68
+ assert.deepStrictEqual(configLoader.resolveModelProfile(config, 'mechanical'), {
69
+ profile: 'mechanical', model: 'vendor-small', configured: true,
70
+ });
71
+ assert.deepStrictEqual(configLoader.resolveModelProfile(config, 'standard'), {
72
+ profile: 'standard', model: 'vendor-standard', configured: true,
73
+ });
74
+ assert.deepStrictEqual(configLoader.resolveModelProfile(config, 'strong'), {
75
+ profile: 'strong', model: 'vendor-strong', configured: true,
76
+ });
77
+ assert.deepStrictEqual(configLoader.resolveModelProfile(config, 'review'), {
78
+ profile: 'review', model: 'vendor-review', configured: true,
79
+ });
80
+ });
81
+
82
+ it('returns an explicit unmapped result for a known profile', () => {
83
+ assert.deepStrictEqual(configLoader.resolveModelProfile({}, 'strong'), {
84
+ profile: 'strong', model: null, configured: false,
85
+ });
86
+ });
87
+
88
+ it('does not let partial model mappings affect missing known profiles', () => {
89
+ assert.deepStrictEqual(
90
+ configLoader.resolveModelProfile({ models: { review: 'vendor-review' } }, 'standard'),
91
+ { profile: 'standard', model: null, configured: false },
92
+ );
93
+ });
94
+
95
+ it('rejects unknown and malformed mappings deterministically', () => {
96
+ assert.throws(() => configLoader.resolveModelProfile({}, 'fast'),
97
+ /Unknown model profile 'fast'.*mechanical.*standard.*strong.*review/);
98
+ assert.throws(() => configLoader.resolveModelProfile({ models: { review: ' ' } }, 'review'),
99
+ /models\.review must be a non-empty string/);
100
+ assert.throws(() => configLoader.resolveModelProfile({ models: { review: 42 } }, 'review'),
101
+ /models\.review must be a non-empty string/);
102
+ });
103
+ });
104
+
105
+ describe('config-loader: loadConfig()', () => {
106
+ let configLoader;
107
+
108
+ before(async () => {
109
+ tempDir = mkdtempSync(join(tmpdir(), 'tf-config-test-'));
110
+ const modulePath = join(process.cwd(), 'scripts/lib/config-loader.mjs');
111
+ configLoader = await import(modulePath);
112
+ });
113
+
114
+ after(() => {
115
+ if (tempDir) rmSync(tempDir, { recursive: true, force: true });
116
+ });
117
+
118
+ it('returns defaults when no config file exists', () => {
119
+ const config = configLoader.loadConfig(tempDir);
120
+ assert.deepStrictEqual(config.artifacts.order, ['proposal', 'specs', 'design', 'tasks']);
121
+ assert.equal(config.execution.inlineThreshold, 3);
122
+ });
123
+
124
+ it('merges user config with defaults', () => {
125
+ const userConfig = {
126
+ artifacts: {
127
+ order: ['proposal', 'design', 'tasks'],
128
+ skip: ['specs'],
129
+ },
130
+ execution: {
131
+ inlineThreshold: 5,
132
+ },
133
+ };
134
+ writeFileSync(join(tempDir, 'team-flow.config.json'), JSON.stringify(userConfig));
135
+
136
+ const config = configLoader.loadConfig(tempDir);
137
+
138
+ // User values override
139
+ assert.deepStrictEqual(config.artifacts.order, ['proposal', 'design', 'tasks']);
140
+ assert.deepStrictEqual(config.artifacts.skip, ['specs']);
141
+ assert.equal(config.execution.inlineThreshold, 5);
142
+
143
+ // Unspecified defaults preserved
144
+ assert.equal(config.execution.abandonmentReasonMinLength, 50);
145
+ assert.equal(config.verification.language, 'auto');
146
+ });
147
+
148
+ it('handles partial user config without crashing', () => {
149
+ // Clean up previous config
150
+ rmSync(join(tempDir, 'team-flow.config.json'), { force: true });
151
+
152
+ const userConfig = {
153
+ execution: {
154
+ inlineThreshold: 10,
155
+ },
156
+ };
157
+ writeFileSync(join(tempDir, 'team-flow.config.json'), JSON.stringify(userConfig));
158
+
159
+ const config = configLoader.loadConfig(tempDir);
160
+
161
+ assert.equal(config.execution.inlineThreshold, 10);
162
+ // artifacts should still have defaults
163
+ assert.deepStrictEqual(config.artifacts.order, ['proposal', 'specs', 'design', 'tasks']);
164
+ });
165
+
166
+ it('handles invalid JSON gracefully, returning defaults', () => {
167
+ writeFileSync(join(tempDir, 'team-flow.config.json'), 'not valid json {{{');
168
+
169
+ const config = configLoader.loadConfig(tempDir);
170
+
171
+ // Should fall back to defaults on parse error
172
+ assert.deepStrictEqual(config.artifacts.order, ['proposal', 'specs', 'design', 'tasks']);
173
+ assert.equal(config.execution.inlineThreshold, 3);
174
+ });
175
+ });
@@ -0,0 +1,59 @@
1
+ // tests/lib/ensure-branch.test.mjs
2
+ // Regression for #15: git branch isolation must be enforceable, not just advised.
3
+ // `ensure-branch.mjs` must refuse to proceed on a protected branch when it cannot
4
+ // isolate, and must allow work on a non-protected branch.
5
+
6
+ import { describe, it, before, after } from 'node:test';
7
+ import assert from 'node:assert/strict';
8
+ import { execSync } from 'node:child_process';
9
+ import { mkdtempSync, rmSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { tmpdir } from 'node:os';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { dirname } from 'node:path';
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const ROOT = join(__dirname, '..', '..');
17
+ const ENSURE = join(ROOT, 'scripts', 'ensure-branch.mjs');
18
+
19
+ function run(args) {
20
+ try {
21
+ const out = execSync(`node ${ENSURE} ${args}`, { encoding: 'utf-8', stdio: 'pipe', timeout: 10000 });
22
+ return { ok: true, out };
23
+ } catch (e) {
24
+ return { ok: false, out: `${e.stdout || ''}\n${e.stderr || ''}` || e.message };
25
+ }
26
+ }
27
+
28
+ function git(dir, ...args) {
29
+ execSync(`git -c user.email=t@t -c user.name=test ${args.join(' ')}`, { cwd: dir, stdio: 'pipe', timeout: 10000 });
30
+ }
31
+
32
+ describe('BUG/#15: ensure-branch enforces isolation', () => {
33
+ let plainDir, repoDir;
34
+ before(() => {
35
+ plainDir = mkdtempSync(join(tmpdir(), 'tf-ensure-plain-'));
36
+ repoDir = mkdtempSync(join(tmpdir(), 'tf-ensure-repo-'));
37
+ mkdirSync(join(repoDir, 'specs'), { recursive: true });
38
+ writeFileSync(join(repoDir, 'README.md'), 'x');
39
+ git(repoDir, 'init', '-q');
40
+ git(repoDir, 'add', '-A');
41
+ git(repoDir, 'commit', '-q', '-m', 'init');
42
+ git(repoDir, 'checkout', '-q', '-b', 'feature/work');
43
+ });
44
+ after(() => {
45
+ if (existsSync(plainDir)) rmSync(plainDir, { recursive: true, force: true });
46
+ if (existsSync(repoDir)) rmSync(repoDir, { recursive: true, force: true });
47
+ });
48
+
49
+ it('SHALL refuse (non-zero) when not inside a git repository', () => {
50
+ const r = run(`"${plainDir}"`);
51
+ assert.equal(r.ok, false, 'ensure-branch must fail outside a git repo');
52
+ });
53
+
54
+ it('SHALL allow (zero) work on a non-protected branch', () => {
55
+ const r = run(`"${repoDir}"`);
56
+ assert.equal(r.ok, true, `ensure-branch should pass on feature branch, got: ${r.out}`);
57
+ assert.match(r.out, /already isolated/i);
58
+ });
59
+ });
@@ -0,0 +1,168 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+
6
+ const root = process.cwd();
7
+ const read = path => readFileSync(join(root, path), 'utf8');
8
+
9
+ describe('execution control plane instructions', () => {
10
+ it('documents #45 guarded execution without claiming #47 slash commands', () => {
11
+ const documents = [
12
+ 'README.md',
13
+ 'docs/README_en.md',
14
+ 'INSTALL.md',
15
+ 'templates/execution-contract.md',
16
+ 'docs/state-machine.md',
17
+ 'docs/artifact-contract.md',
18
+ ];
19
+
20
+ for (const path of documents) {
21
+ const content = read(path);
22
+ assert.match(content, /execution[ -]plan/i, `${path} documents execution plans`);
23
+ assert.match(content, /execution recommend|execution-recommendation|执行模式推荐/i, `${path} documents execution-mode recommendations`);
24
+ assert.match(content, /execution-recommendation\.json|recommendation receipt|推荐凭据/i, `${path} documents persisted recommendation evidence`);
25
+ assert.match(content, /--confirm|用户.*确认|user.*confirm/is, `${path} documents user confirmation`);
26
+ assert.match(content, /acknowledge-recommendation|确认.*风险|acknowledg/is, `${path} documents acknowledgement for a non-recommended choice`);
27
+ assert.match(content, /review receipt/i, `${path} documents review receipts`);
28
+ }
29
+
30
+ assert.match(read('templates/execution-contract.md'), /Execution Waves/);
31
+ assert.match(read('CHANGELOG.md'), /#45/);
32
+ assert.doesNotMatch(read('README.md'), /\/tf:resume/);
33
+ assert.doesNotMatch(read('docs/README_en.md'), /\/tf:resume/);
34
+ assert.doesNotMatch(read('INSTALL.md'), /\/tf:resume/);
35
+
36
+ for (const path of documents) {
37
+ assert.doesNotMatch(read(path), /automatic(?:ally)?\s+(?:defaults?\s+to\s+)?Batch Inline/i,
38
+ `${path} does not advertise automatic Batch Inline`);
39
+ }
40
+ });
41
+
42
+ it('documents only the persisted execution-plan contract that #45 implements', () => {
43
+ const documents = [
44
+ 'README.md',
45
+ 'docs/README_en.md',
46
+ 'INSTALL.md',
47
+ 'templates/execution-contract.md',
48
+ 'docs/state-machine.md',
49
+ 'docs/artifact-contract.md',
50
+ 'CHANGELOG.md',
51
+ ];
52
+
53
+ for (const path of documents) {
54
+ const content = read(path);
55
+ assert.match(content, /\.superpowers\/sdd\/execution-plan\.json/,
56
+ `${path} identifies the persisted execution-plan path`);
57
+ assert.doesNotMatch(content, /write[- ]?conflict/i,
58
+ `${path} does not claim an unpersisted write-conflict check`);
59
+ }
60
+
61
+ for (const path of ['README.md', 'docs/README_en.md', 'INSTALL.md']) {
62
+ const content = read(path);
63
+ assert.match(content, /execution revise/i, `${path} documents execution revise`);
64
+ assert.match(content,
65
+ /retains?\/upgrades?.*sdd.*replan|inline\/batch-inline.*(?:upgrades?|升级).*sdd.*(?:or|或).*(?:replans?|重规划).*sdd/is,
66
+ `${path} allows SDD replanning while retaining the no-downgrade contract`);
67
+ assert.match(content, /downgrade|降级/i, `${path} keeps SDD downgrade rejection explicit`);
68
+ }
69
+
70
+ assert.match(read('scripts/team-flow.mjs'), /upgrade inline\/batch.*replan existing sdd.*new revision/is,
71
+ 'CLI help describes SDD replanning instead of only inline upgrades');
72
+ });
73
+
74
+ it('documents portable and auditable review receipt evidence', () => {
75
+ const localizedDocuments = ['README.md', 'INSTALL.md'];
76
+
77
+ for (const path of localizedDocuments) {
78
+ const content = read(path);
79
+ assert.match(content,
80
+ /--report.*相对于.*<change>.*解析.*<change>\/.superpowers\/sdd\/reviews/is,
81
+ `${path} resolves review reports from the change directory into its reviews overlay`);
82
+ assert.match(content, /--base.*--head.*真实.*commit/is,
83
+ `${path} requires real commits for review ranges`);
84
+ assert.match(content, /<change>.*Git.*工作树/is,
85
+ `${path} binds review ranges to the change worktree`);
86
+ assert.match(content, /base.*head.*祖先/is,
87
+ `${path} requires base to precede head`);
88
+ assert.match(content,
89
+ /<change>\/.superpowers\/sdd\/reviews\/.*物理.*非符号链接/is,
90
+ `${path} requires physical, non-symlink review overlay directories`);
91
+ assert.match(content,
92
+ /report.*普通.*非空.*非符号链接.*文件/is,
93
+ `${path} requires review reports to be regular, non-empty, non-symlink files`);
94
+ }
95
+
96
+ const english = read('docs/README_en.md');
97
+ assert.match(english,
98
+ /--report.*resolved relative to.*<change>.*must remain under.*<change>\/.superpowers\/sdd\/reviews/is,
99
+ 'English documentation resolves review reports from the change directory into its reviews overlay');
100
+ assert.match(english, /--base.*--head.*real commits/is,
101
+ 'English documentation requires real commits for review ranges');
102
+ assert.match(english, /<change>.*Git worktree/is,
103
+ 'English documentation binds review ranges to the change worktree');
104
+ assert.match(english, /base.*ancestor.*head/is,
105
+ 'English documentation requires base to precede head');
106
+ assert.match(english,
107
+ /<change>\/.superpowers\/sdd\/reviews\/.*physical.*non-symlink/is,
108
+ 'English documentation requires physical, non-symlink review overlay directories');
109
+ assert.match(english,
110
+ /report.*regular.*non-empty.*non-symlink.*file/is,
111
+ 'English documentation requires review reports to be regular, non-empty, non-symlink files');
112
+ });
113
+
114
+ it('keeps execution mode and review gates machine-backed in every entry point', () => {
115
+ const workflowStart = read('skills/workflow-start/SKILL.md');
116
+ const buildExecutor = read('skills/build-executor/SKILL.md');
117
+ const codeReviewer = read('skills/code-reviewer/SKILL.md');
118
+ const inject = read('scripts/lib/cmd-inject.mjs');
119
+
120
+ assert.match(workflowStart, /execution show <change-dir> --json/);
121
+ assert.match(workflowStart, /execution plan <change-dir>/);
122
+ assert.match(buildExecutor, /execution recommend/i);
123
+ assert.match(buildExecutor, /user.*confirm|用户.*确认/is);
124
+ assert.match(buildExecutor, /acknowledge-recommendation/i);
125
+ assert.match(buildExecutor, /parallel.*wave/is);
126
+ assert.match(buildExecutor, /concurren(?:cy|t).*unavailable/i);
127
+ assert.match(buildExecutor, /retryable.*replacement.*pass/is);
128
+ assert.doesNotMatch(buildExecutor, />3 tasks, same module/);
129
+ assert.match(codeReviewer, /execution review <change-dir>.*--verdict <pass\|fail>/s);
130
+ assert.match(codeReviewer, /Critical\/Important.*fail.*receipt/is);
131
+ assert.match(inject, /execution plan/);
132
+ assert.match(inject, /pass.*review receipts.*closing/is);
133
+ assert.match(buildExecutor, /<wave-id>:<parallel\|serial>:<task,.+>\[:<depends-on/i);
134
+ });
135
+
136
+ it('gives every packaged installer the same planned-execution gate', () => {
137
+ for (const path of [
138
+ 'scripts/lib/install.mjs',
139
+ 'scripts/lib/cmd-install-workbuddy.mjs',
140
+ 'scripts/install-cursor.mjs',
141
+ 'scripts/install-zcode.mjs',
142
+ ]) {
143
+ const content = read(path);
144
+ assert.match(content, /execution recommend/);
145
+ assert.match(content, /--confirm/);
146
+ assert.match(content, /acknowledge-recommendation/);
147
+ assert.match(content, /all.*pass.*review receipt.*closing/is);
148
+ assert.match(content, /full\/hotfix.*tweak.*exempt/is);
149
+ }
150
+ });
151
+
152
+ it('keeps task implementer and reviewer prompts aligned with planned waves and receipts', () => {
153
+ const implementer = read('skills/build-executor/implementer-prompt.md');
154
+ const taskReviewer = read('skills/build-executor/task-reviewer-prompt.md');
155
+ const reviewerPrompt = read('skills/code-reviewer/code-reviewer-prompt.md');
156
+
157
+ assert.match(implementer, /planned wave/i);
158
+ assert.match(implementer, /implementer report path/i);
159
+ assert.match(taskReviewer, /execution review <change-dir>/);
160
+ assert.match(taskReviewer, /--verdict <pass\|fail>/);
161
+ assert.match(taskReviewer, /review report\s+path/i);
162
+ assert.match(taskReviewer, /persisted.*review report/i);
163
+ assert.match(reviewerPrompt, /execution review <change-dir>/);
164
+ assert.match(reviewerPrompt, /wave ID/i);
165
+ assert.match(reviewerPrompt, /review report\s+path/i);
166
+ assert.match(reviewerPrompt, /persisted.*review report/i);
167
+ });
168
+ });