@pennyfarthing/core 11.0.0 → 11.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. package/README.md +81 -23
  2. package/package.json +1 -1
  3. package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.d.ts +20 -0
  4. package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.d.ts.map +1 -0
  5. package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.js +278 -0
  6. package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.js.map +1 -0
  7. package/packages/core/dist/cli/utils/constants.d.ts +8 -2
  8. package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
  9. package/packages/core/dist/cli/utils/constants.js +4 -1
  10. package/packages/core/dist/cli/utils/constants.js.map +1 -1
  11. package/packages/core/dist/cli/utils/constants.test.d.ts +10 -0
  12. package/packages/core/dist/cli/utils/constants.test.d.ts.map +1 -0
  13. package/packages/core/dist/cli/utils/constants.test.js +38 -0
  14. package/packages/core/dist/cli/utils/constants.test.js.map +1 -0
  15. package/packages/core/dist/consultation/consultation-protocol.d.ts +139 -0
  16. package/packages/core/dist/consultation/consultation-protocol.d.ts.map +1 -0
  17. package/packages/core/dist/consultation/consultation-protocol.js +178 -0
  18. package/packages/core/dist/consultation/consultation-protocol.js.map +1 -0
  19. package/packages/core/dist/consultation/consultation-protocol.test.d.ts +20 -0
  20. package/packages/core/dist/consultation/consultation-protocol.test.d.ts.map +1 -0
  21. package/packages/core/dist/consultation/consultation-protocol.test.js +474 -0
  22. package/packages/core/dist/consultation/consultation-protocol.test.js.map +1 -0
  23. package/packages/core/dist/consultation/dialogue-manager.d.ts +75 -0
  24. package/packages/core/dist/consultation/dialogue-manager.d.ts.map +1 -0
  25. package/packages/core/dist/consultation/dialogue-manager.js +334 -0
  26. package/packages/core/dist/consultation/dialogue-manager.js.map +1 -0
  27. package/packages/core/dist/consultation/dialogue-manager.test.d.ts +19 -0
  28. package/packages/core/dist/consultation/dialogue-manager.test.d.ts.map +1 -0
  29. package/packages/core/dist/consultation/dialogue-manager.test.js +444 -0
  30. package/packages/core/dist/consultation/dialogue-manager.test.js.map +1 -0
  31. package/packages/core/dist/public/js/react/react.js +3 -3
  32. package/packages/core/dist/scripts/theme-detail.test.d.ts +10 -0
  33. package/packages/core/dist/scripts/theme-detail.test.js +199 -0
  34. package/packages/core/dist/server/api/git.d.ts +13 -1
  35. package/packages/core/dist/server/api/git.d.ts.map +1 -1
  36. package/packages/core/dist/server/api/git.js +53 -34
  37. package/packages/core/dist/server/api/git.js.map +1 -1
  38. package/packages/core/dist/server/api/health-score.d.ts.map +1 -1
  39. package/packages/core/dist/server/api/health-score.js +25 -1
  40. package/packages/core/dist/server/api/health-score.js.map +1 -1
  41. package/packages/core/dist/server/api/settings.d.ts.map +1 -1
  42. package/packages/core/dist/server/api/settings.js +63 -1
  43. package/packages/core/dist/server/api/settings.js.map +1 -1
  44. package/packages/core/dist/server/api/theme-agents.d.ts.map +1 -1
  45. package/packages/core/dist/server/api/theme-agents.js +61 -0
  46. package/packages/core/dist/server/api/theme-agents.js.map +1 -1
  47. package/packages/core/dist/server/server.d.ts.map +1 -1
  48. package/packages/core/dist/server/server.js +17 -12
  49. package/packages/core/dist/server/server.js.map +1 -1
  50. package/packages/core/dist/shared/skill-search.test.js +2 -2
  51. package/packages/core/dist/workflow/gate-file-validation.d.ts +49 -0
  52. package/packages/core/dist/workflow/gate-file-validation.d.ts.map +1 -0
  53. package/packages/core/dist/workflow/gate-file-validation.js +157 -0
  54. package/packages/core/dist/workflow/gate-file-validation.js.map +1 -0
  55. package/packages/core/dist/workflow/gate-file-validation.test.d.ts +19 -0
  56. package/packages/core/dist/workflow/gate-file-validation.test.d.ts.map +1 -0
  57. package/packages/core/dist/workflow/gate-file-validation.test.js +536 -0
  58. package/packages/core/dist/workflow/gate-file-validation.test.js.map +1 -0
  59. package/packages/core/dist/workflow/gate-schema-validation.test.d.ts +14 -0
  60. package/packages/core/dist/workflow/gate-schema-validation.test.d.ts.map +1 -0
  61. package/packages/core/dist/workflow/gate-schema-validation.test.js +339 -0
  62. package/packages/core/dist/workflow/gate-schema-validation.test.js.map +1 -0
  63. package/packages/core/dist/workflow/handoff.js +2 -2
  64. package/packages/core/dist/workflow/handoff.js.map +1 -1
  65. package/packages/core/dist/workflow/handoff.test.js +16 -0
  66. package/packages/core/dist/workflow/handoff.test.js.map +1 -1
  67. package/packages/core/dist/workflow/workflow-schema.d.ts +4 -2
  68. package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -1
  69. package/packages/core/dist/workflow/workflow-schema.js +43 -8
  70. package/packages/core/dist/workflow/workflow-schema.js.map +1 -1
  71. package/pennyfarthing-dist/agents/README.md +6 -14
  72. package/pennyfarthing-dist/agents/architect.md +43 -29
  73. package/pennyfarthing-dist/agents/ba.md +30 -29
  74. package/pennyfarthing-dist/agents/dev.md +32 -43
  75. package/pennyfarthing-dist/agents/devops.md +57 -21
  76. package/pennyfarthing-dist/agents/orchestrator.md +3 -10
  77. package/pennyfarthing-dist/agents/pm.md +45 -31
  78. package/pennyfarthing-dist/agents/reviewer.md +20 -66
  79. package/pennyfarthing-dist/agents/sm-setup.md +2 -2
  80. package/pennyfarthing-dist/agents/sm.md +8 -30
  81. package/pennyfarthing-dist/agents/tea.md +25 -41
  82. package/pennyfarthing-dist/agents/tech-writer.md +33 -90
  83. package/pennyfarthing-dist/agents/ux-designer.md +39 -39
  84. package/pennyfarthing-dist/commands/benchmark-control.md +8 -64
  85. package/pennyfarthing-dist/commands/benchmark.md +8 -480
  86. package/pennyfarthing-dist/commands/job-fair.md +8 -97
  87. package/pennyfarthing-dist/commands/pf-benchmark-control.md +70 -0
  88. package/pennyfarthing-dist/commands/pf-benchmark.md +486 -0
  89. package/pennyfarthing-dist/commands/pf-chore.md +4 -4
  90. package/pennyfarthing-dist/commands/pf-ci.md +40 -0
  91. package/pennyfarthing-dist/commands/pf-close-epic.md +9 -27
  92. package/pennyfarthing-dist/commands/pf-continue-session.md +9 -213
  93. package/pennyfarthing-dist/commands/pf-create-branches-from-story.md +11 -353
  94. package/pennyfarthing-dist/commands/pf-docs.md +28 -0
  95. package/pennyfarthing-dist/commands/pf-epic.md +67 -0
  96. package/pennyfarthing-dist/commands/pf-git-cleanup.md +11 -52
  97. package/pennyfarthing-dist/commands/pf-git.md +75 -0
  98. package/pennyfarthing-dist/commands/pf-help.md +110 -128
  99. package/pennyfarthing-dist/commands/pf-job-fair.md +102 -0
  100. package/pennyfarthing-dist/commands/pf-new-work.md +9 -18
  101. package/pennyfarthing-dist/commands/pf-parallel-work.md +6 -66
  102. package/pennyfarthing-dist/commands/pf-release.md +11 -76
  103. package/pennyfarthing-dist/commands/pf-repo-status.md +11 -44
  104. package/pennyfarthing-dist/commands/pf-run-ci.md +8 -111
  105. package/pennyfarthing-dist/commands/pf-session.md +51 -0
  106. package/pennyfarthing-dist/commands/pf-solo.md +447 -0
  107. package/pennyfarthing-dist/commands/pf-sprint-planning.md +8 -104
  108. package/pennyfarthing-dist/commands/pf-standalone.md +1 -1
  109. package/pennyfarthing-dist/commands/pf-start-epic.md +9 -163
  110. package/pennyfarthing-dist/commands/pf-sync-epic-to-jira.md +8 -179
  111. package/pennyfarthing-dist/commands/pf-sync-work-with-sprint.md +8 -368
  112. package/pennyfarthing-dist/commands/pf-update-domain-docs.md +8 -78
  113. package/pennyfarthing-dist/commands/solo.md +8 -442
  114. package/pennyfarthing-dist/guides/agent-behavior.md +13 -13
  115. package/pennyfarthing-dist/guides/agent-coordination.md +7 -7
  116. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +6 -5
  117. package/pennyfarthing-dist/guides/bikerack.md +128 -0
  118. package/pennyfarthing-dist/guides/brownfield-tools.md +133 -0
  119. package/pennyfarthing-dist/guides/command-tag-taxonomy.md +2 -2
  120. package/pennyfarthing-dist/guides/gate-schema.md +227 -0
  121. package/pennyfarthing-dist/guides/gates.md +120 -0
  122. package/pennyfarthing-dist/guides/handoff-cli.md +116 -0
  123. package/pennyfarthing-dist/guides/hooks.md +86 -4
  124. package/pennyfarthing-dist/guides/output-styles.md +65 -0
  125. package/pennyfarthing-dist/guides/patterns/approval-gates-pattern.md +5 -5
  126. package/pennyfarthing-dist/guides/patterns/tdd-flow-pattern.md +4 -4
  127. package/pennyfarthing-dist/guides/prompt-patterns.md +5 -5
  128. package/pennyfarthing-dist/guides/reflector.md +4 -4
  129. package/pennyfarthing-dist/guides/session-artifacts.md +1 -1
  130. package/pennyfarthing-dist/guides/skill-schema.md +1 -1
  131. package/pennyfarthing-dist/guides/tandem-protocol.md +13 -1
  132. package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
  133. package/pennyfarthing-dist/guides/xml-tags.md +5 -4
  134. package/pennyfarthing-dist/personas/themes/hogans-heroes.yaml +11 -22
  135. package/pennyfarthing-dist/personas/themes/stephen-king.yaml +13 -24
  136. package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +322 -0
  137. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +1 -1
  138. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +19 -14
  139. package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +191 -57
  140. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +26 -10
  141. package/pennyfarthing-dist/skills/pf-changelog/SKILL.md +4 -4
  142. package/pennyfarthing-dist/skills/pf-sprint/skill.md +1 -1
  143. package/pennyfarthing-dist/skills/skill-registry.schema.json +4 -0
  144. package/pennyfarthing-dist/skills/skill-registry.yaml +5 -0
  145. package/pennyfarthing-dist/workflows/2party-tdd.yaml +11 -0
  146. package/pennyfarthing-dist/workflows/agent-docs.yaml +2 -0
  147. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +4 -0
  148. package/pennyfarthing-dist/workflows/bdd.yaml +4 -0
  149. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
  150. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +3 -0
  151. package/pennyfarthing-dist/workflows/tdd.yaml +3 -0
  152. package/pennyfarthing-dist/workflows/trivial.yaml +2 -0
  153. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  154. package/pennyfarthing_scripts/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
  155. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  156. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  157. package/pennyfarthing_scripts/__pycache__/context.cpython-314.pyc +0 -0
  158. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  159. package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  160. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  161. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  162. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  163. package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
  164. package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
  165. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  166. package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  167. package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  169. package/pennyfarthing_scripts/bc/__pycache__/__init__.cpython-314.pyc +0 -0
  170. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  171. package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
  172. package/pennyfarthing_scripts/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
  173. package/pennyfarthing_scripts/bikerack/__pycache__/__main__.cpython-314.pyc +0 -0
  174. package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  175. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  176. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  177. package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  178. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  179. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  180. package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  181. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  182. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  183. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  184. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  185. package/pennyfarthing_scripts/bikerack/cli.py +10 -11
  186. package/pennyfarthing_scripts/bikerack/debug_panel.py +218 -0
  187. package/pennyfarthing_scripts/bikerack/diffs_panel.py +203 -27
  188. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  189. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  190. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  191. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  192. package/pennyfarthing_scripts/cli.py +114 -0
  193. package/pennyfarthing_scripts/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
  194. package/pennyfarthing_scripts/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
  195. package/pennyfarthing_scripts/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
  196. package/pennyfarthing_scripts/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
  197. package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
  198. package/pennyfarthing_scripts/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
  199. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  200. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  201. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  202. package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
  203. package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
  204. package/pennyfarthing_scripts/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
  206. package/pennyfarthing_scripts/complexity/__pycache__/cli.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/complexity/__pycache__/models.cpython-314.pyc +0 -0
  209. package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
  210. package/pennyfarthing_scripts/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
  211. package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
  212. package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
  213. package/pennyfarthing_scripts/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
  214. package/pennyfarthing_scripts/deadcode/__pycache__/models.cpython-314.pyc +0 -0
  215. package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
  216. package/pennyfarthing_scripts/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
  217. package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
  218. package/pennyfarthing_scripts/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
  219. package/pennyfarthing_scripts/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
  220. package/pennyfarthing_scripts/dependencies/__pycache__/models.cpython-314.pyc +0 -0
  221. package/pennyfarthing_scripts/epic/__init__.py +0 -0
  222. package/pennyfarthing_scripts/epic/cli.py +64 -0
  223. package/pennyfarthing_scripts/gate/__init__.py +1 -0
  224. package/pennyfarthing_scripts/gate/__pycache__/__init__.cpython-314.pyc +0 -0
  225. package/pennyfarthing_scripts/gate/__pycache__/cli.cpython-314.pyc +0 -0
  226. package/pennyfarthing_scripts/gate/__pycache__/validate.cpython-314.pyc +0 -0
  227. package/pennyfarthing_scripts/gate/cli.py +56 -0
  228. package/pennyfarthing_scripts/gate/validate.py +266 -0
  229. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  230. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  231. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  232. package/pennyfarthing_scripts/git_group/__init__.py +0 -0
  233. package/pennyfarthing_scripts/git_group/cli.py +100 -0
  234. package/pennyfarthing_scripts/handoff/__init__.py +1 -0
  235. package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  237. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  238. package/pennyfarthing_scripts/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
  239. package/pennyfarthing_scripts/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
  240. package/pennyfarthing_scripts/handoff/__pycache__/marker.cpython-314.pyc +0 -0
  241. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  242. package/pennyfarthing_scripts/handoff/cli.py +120 -0
  243. package/pennyfarthing_scripts/handoff/complete_phase.py +155 -0
  244. package/pennyfarthing_scripts/handoff/gate_file.py +105 -0
  245. package/pennyfarthing_scripts/handoff/gate_runner.py +152 -0
  246. package/pennyfarthing_scripts/handoff/marker.py +109 -0
  247. package/pennyfarthing_scripts/handoff/resolve_gate.py +152 -0
  248. package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
  249. package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
  250. package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
  251. package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
  252. package/pennyfarthing_scripts/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
  253. package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-314.pyc +0 -0
  254. package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  255. package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  256. package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  257. package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  258. package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  259. package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  260. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  261. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  262. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  263. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  264. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  265. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  266. package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
  267. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  268. package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
  269. package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  270. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  271. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  272. package/pennyfarthing_scripts/launch/__pycache__/__init__.cpython-314.pyc +0 -0
  273. package/pennyfarthing_scripts/launch/__pycache__/cli.cpython-314.pyc +0 -0
  274. package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  275. package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
  276. package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
  277. package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
  278. package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
  279. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  280. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  281. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  282. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  283. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  284. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  285. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  286. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  287. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  288. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  289. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  290. package/pennyfarthing_scripts/prime/__pycache__/version_sentinel.cpython-314.pyc +0 -0
  291. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  292. package/pennyfarthing_scripts/prime/workflow.py +39 -0
  293. package/pennyfarthing_scripts/session/__init__.py +0 -0
  294. package/pennyfarthing_scripts/session/cli.py +87 -0
  295. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  296. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  297. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  298. package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  299. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  300. package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
  301. package/pennyfarthing_scripts/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
  302. package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
  303. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  304. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  305. package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  306. package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
  307. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  308. package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  309. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  310. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  311. package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  312. package/pennyfarthing_scripts/sprint/story_finish.py +14 -0
  313. package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
  314. package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
  315. package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
  316. package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
  317. package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
  318. package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
  319. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  320. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  321. package/pennyfarthing_scripts/tests/__pycache__/test_108_2_remove_handoff_fallback.cpython-314-pytest-9.0.2.pyc +0 -0
  322. package/pennyfarthing_scripts/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
  323. package/pennyfarthing_scripts/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
  324. package/pennyfarthing_scripts/tests/__pycache__/test_bikerack.cpython-314-pytest-9.0.2.pyc +0 -0
  325. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  326. package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  327. package/pennyfarthing_scripts/tests/__pycache__/test_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
  328. package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
  329. package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  330. package/pennyfarthing_scripts/tests/__pycache__/test_epic_shard_validation.cpython-314-pytest-9.0.2.pyc +0 -0
  331. package/pennyfarthing_scripts/tests/__pycache__/test_gate_file_resolution.cpython-314-pytest-9.0.2.pyc +0 -0
  332. package/pennyfarthing_scripts/tests/__pycache__/test_gate_runner.cpython-314-pytest-9.0.2.pyc +0 -0
  333. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  334. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  335. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  336. package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
  337. package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  338. package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  339. package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  340. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  341. package/pennyfarthing_scripts/tests/__pycache__/test_resolve_gate_file_field.cpython-314-pytest-9.0.2.pyc +0 -0
  342. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  343. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_panel.cpython-314-pytest-9.0.2.pyc +0 -0
  344. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  345. package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  346. package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  347. package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  348. package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  349. package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  350. package/pennyfarthing_scripts/tests/__pycache__/test_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
  351. package/pennyfarthing_scripts/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
  352. package/pennyfarthing_scripts/tests/__pycache__/test_tui_panel_persistence.cpython-314-pytest-9.0.2.pyc +0 -0
  353. package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  354. package/pennyfarthing_scripts/tests/__pycache__/test_version_sentinel.cpython-314-pytest-9.0.2.pyc +0 -0
  355. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  356. package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  357. package/pennyfarthing_scripts/tests/test_108_1_gate_migration.py +540 -0
  358. package/pennyfarthing_scripts/tests/test_108_2_remove_handoff_fallback.py +339 -0
  359. package/pennyfarthing_scripts/tests/test_confidence_sm_evaluation.py +253 -0
  360. package/pennyfarthing_scripts/tests/test_confidence_sm_gate.py +315 -0
  361. package/pennyfarthing_scripts/tests/test_gate_file_resolution.py +341 -0
  362. package/pennyfarthing_scripts/tests/test_gate_runner.py +620 -0
  363. package/pennyfarthing_scripts/tests/test_handoff_cli.py +929 -0
  364. package/pennyfarthing_scripts/tests/test_handoff_e2e.py +454 -0
  365. package/pennyfarthing_scripts/tests/test_resolve_gate_file_field.py +464 -0
  366. package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
  367. package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
  368. package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.pyc +0 -0
  369. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  370. package/pennyfarthing_scripts/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  371. package/pennyfarthing_scripts/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
  372. package/pennyfarthing_scripts/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
  373. package/pennyfarthing_scripts/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
  374. package/pennyfarthing_scripts/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
  375. package/pennyfarthing_scripts/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
  376. package/pennyfarthing_scripts/validate/adapters/skill_command.py +200 -0
  377. package/pennyfarthing_scripts/validate/adapters/workflow.py +64 -0
  378. package/pennyfarthing_scripts/validate/cli.py +15 -4
  379. package/packages/core/dist/scripts/benchmark-integration.d.ts +0 -182
  380. package/packages/core/dist/scripts/benchmark-integration.d.ts.map +0 -1
  381. package/packages/core/dist/scripts/benchmark-integration.js +0 -691
  382. package/packages/core/dist/scripts/benchmark-integration.js.map +0 -1
  383. package/packages/core/dist/scripts/job-fair-aggregator.d.ts +0 -150
  384. package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +0 -1
  385. package/packages/core/dist/scripts/job-fair-aggregator.js +0 -547
  386. package/packages/core/dist/scripts/job-fair-aggregator.js.map +0 -1
  387. package/pennyfarthing-dist/agents/handoff.md +0 -250
  388. package/pennyfarthing-dist/agents/sm-handoff.md +0 -152
  389. package/pennyfarthing-dist/scripts/core/handoff-marker.sh +0 -112
  390. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  391. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  392. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  393. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  394. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  395. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  396. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  397. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  398. package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  399. package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
  400. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  401. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
@@ -0,0 +1,536 @@
1
+ /**
2
+ * Tests for Story 107-2: Acyclic Validation and Depth Limit Enforcement
3
+ *
4
+ * Validates that gate files (XML-like format with nested <gate> elements)
5
+ * are checked for:
6
+ * 1. Maximum nesting depth (3 levels, where Level 0 = root)
7
+ * 2. Cyclic gate name references (A → B → A)
8
+ *
9
+ * Both checks run at parse time on the gate file content string.
10
+ *
11
+ * ACs:
12
+ * 1. Cycle detection via DFS on directed graph of gate name references
13
+ * 2. Depth validation with max 3, error includes gate name and actual depth
14
+ * 3. Validation runs at parse time (on content string, no file I/O)
15
+ * 4. Specific, actionable error messages for both violation types
16
+ * 5. Valid gate files continue to pass (no regressions)
17
+ */
18
+ import { describe, it } from 'node:test';
19
+ import assert from 'node:assert';
20
+ import { validateGateDepth, detectGateCycles, validateGateFile, } from './gate-file-validation.js';
21
+ // ═══════════════════════════════════════════════════════════════════════════
22
+ // Helper: generate gate file content at various nesting depths
23
+ // ═══════════════════════════════════════════════════════════════════════════
24
+ function makeNestedGates(names, includeBlocks = true) {
25
+ const indent = (level) => ' '.repeat(level);
26
+ let content = '';
27
+ for (let i = 0; i < names.length; i++) {
28
+ content += `${indent(i)}<gate name="${names[i]}" model="haiku">\n`;
29
+ if (includeBlocks) {
30
+ content += `${indent(i + 1)}<purpose>Purpose of ${names[i]}</purpose>\n`;
31
+ content += `${indent(i + 1)}<pass>Pass criteria for ${names[i]}</pass>\n`;
32
+ content += `${indent(i + 1)}<fail>Fail criteria for ${names[i]}</fail>\n`;
33
+ }
34
+ }
35
+ // Close tags in reverse order
36
+ for (let i = names.length - 1; i >= 0; i--) {
37
+ content += `${indent(i)}</gate>\n`;
38
+ }
39
+ return content;
40
+ }
41
+ // ═══════════════════════════════════════════════════════════════════════════
42
+ // AC2: Depth Validation — nesting depth counted and enforced (max 3)
43
+ // ═══════════════════════════════════════════════════════════════════════════
44
+ describe('Gate File Validation (107-2)', () => {
45
+ describe('AC2: Depth limit enforcement', () => {
46
+ it('should accept a single root gate (depth 0)', () => {
47
+ const content = makeNestedGates(['root-gate']);
48
+ const result = validateGateDepth(content);
49
+ assert.strictEqual(result.valid, true, 'Single root gate should be valid');
50
+ assert.strictEqual(result.depth, 0, 'Root gate should be depth 0');
51
+ });
52
+ it('should accept one level of nesting (depth 1)', () => {
53
+ const content = makeNestedGates(['root', 'child-1']);
54
+ const result = validateGateDepth(content);
55
+ assert.strictEqual(result.valid, true, 'Depth 1 nesting should be valid');
56
+ assert.strictEqual(result.depth, 1);
57
+ });
58
+ it('should accept two levels of nesting (depth 2)', () => {
59
+ const content = makeNestedGates(['root', 'child', 'grandchild']);
60
+ const result = validateGateDepth(content);
61
+ assert.strictEqual(result.valid, true, 'Depth 2 nesting should be valid');
62
+ assert.strictEqual(result.depth, 2);
63
+ });
64
+ it('should accept three levels of nesting (depth 3 — maximum allowed)', () => {
65
+ const content = makeNestedGates(['root', 'child', 'grandchild', 'great-grandchild']);
66
+ const result = validateGateDepth(content);
67
+ assert.strictEqual(result.valid, true, 'Depth 3 is the maximum and should be valid');
68
+ assert.strictEqual(result.depth, 3);
69
+ });
70
+ it('should reject four levels of nesting (depth 4 — exceeds limit)', () => {
71
+ const content = makeNestedGates(['root', 'child', 'grandchild', 'great-grandchild', 'too-deep']);
72
+ const result = validateGateDepth(content);
73
+ assert.strictEqual(result.valid, false, 'Depth 4 should be rejected');
74
+ assert.ok(result.errors && result.errors.length > 0, 'Should have errors');
75
+ assert.strictEqual(result.errors[0].type, 'depth', 'Error type should be "depth"');
76
+ });
77
+ it('should reject five levels of nesting (depth 5)', () => {
78
+ const content = makeNestedGates(['a', 'b', 'c', 'd', 'e', 'f']);
79
+ const result = validateGateDepth(content);
80
+ assert.strictEqual(result.valid, false, 'Depth 5 should be rejected');
81
+ });
82
+ it('should include gate name in depth error message', () => {
83
+ const content = makeNestedGates(['root', 'child', 'grandchild', 'great-gc', 'too-deep']);
84
+ const result = validateGateDepth(content);
85
+ assert.strictEqual(result.valid, false);
86
+ const error = result.errors[0];
87
+ assert.ok(error.message.includes('too-deep'), `Error message should include the gate name "too-deep", got: "${error.message}"`);
88
+ });
89
+ it('should include actual depth in depth error message', () => {
90
+ const content = makeNestedGates(['root', 'child', 'grandchild', 'great-gc', 'too-deep']);
91
+ const result = validateGateDepth(content);
92
+ assert.strictEqual(result.valid, false);
93
+ const error = result.errors[0];
94
+ assert.ok(error.message.includes('depth 4'), `Error message should include "depth 4", got: "${error.message}"`);
95
+ });
96
+ it('should include max depth in depth error message', () => {
97
+ const content = makeNestedGates(['root', 'child', 'grandchild', 'great-gc', 'too-deep']);
98
+ const result = validateGateDepth(content);
99
+ assert.strictEqual(result.valid, false);
100
+ const error = result.errors[0];
101
+ assert.ok(error.message.includes('max 3'), `Error message should include "max 3", got: "${error.message}"`);
102
+ });
103
+ it('should match exact error format: "Gate depth limit exceeded: {name} at depth N (max 3)"', () => {
104
+ const content = makeNestedGates(['root', 'child', 'grandchild', 'great-gc', 'overdeep']);
105
+ const result = validateGateDepth(content);
106
+ assert.strictEqual(result.valid, false);
107
+ const error = result.errors[0];
108
+ assert.strictEqual(error.message, 'Gate depth limit exceeded: overdeep at depth 4 (max 3)', 'Error message must match exact format from story spec');
109
+ });
110
+ it('should report max nesting depth found in result', () => {
111
+ const content = makeNestedGates(['root', 'child']);
112
+ const result = validateGateDepth(content);
113
+ assert.strictEqual(result.depth, 1, 'Should report depth 1 for root + one child');
114
+ });
115
+ it('should handle gate with multiple children at same level', () => {
116
+ // root has two children side by side — depth is still 1
117
+ const content = `<gate name="root" model="haiku">
118
+ <purpose>Root purpose</purpose>
119
+ <pass>Pass</pass>
120
+ <fail>Fail</fail>
121
+ <gate name="child-a" model="haiku">
122
+ <purpose>A purpose</purpose>
123
+ <pass>Pass</pass>
124
+ <fail>Fail</fail>
125
+ </gate>
126
+ <gate name="child-b" model="haiku">
127
+ <purpose>B purpose</purpose>
128
+ <pass>Pass</pass>
129
+ <fail>Fail</fail>
130
+ </gate>
131
+ </gate>`;
132
+ const result = validateGateDepth(content);
133
+ assert.strictEqual(result.valid, true, 'Sibling gates should not increase depth');
134
+ assert.strictEqual(result.depth, 1, 'Max depth with siblings at level 1 is 1');
135
+ });
136
+ it('should detect deepest branch when multiple branches exist', () => {
137
+ // root → child-a (depth 1)
138
+ // root → child-b → grandchild (depth 2)
139
+ const content = `<gate name="root" model="haiku">
140
+ <purpose>Root</purpose>
141
+ <pass>Pass</pass>
142
+ <fail>Fail</fail>
143
+ <gate name="child-a" model="haiku">
144
+ <purpose>A</purpose>
145
+ <pass>Pass</pass>
146
+ <fail>Fail</fail>
147
+ </gate>
148
+ <gate name="child-b" model="haiku">
149
+ <purpose>B</purpose>
150
+ <pass>Pass</pass>
151
+ <fail>Fail</fail>
152
+ <gate name="grandchild" model="haiku">
153
+ <purpose>GC</purpose>
154
+ <pass>Pass</pass>
155
+ <fail>Fail</fail>
156
+ </gate>
157
+ </gate>
158
+ </gate>`;
159
+ const result = validateGateDepth(content);
160
+ assert.strictEqual(result.valid, true);
161
+ assert.strictEqual(result.depth, 2, 'Should report max depth across all branches');
162
+ });
163
+ });
164
+ // ═══════════════════════════════════════════════════════════════════════
165
+ // AC1: Cycle Detection — DFS on directed graph of gate name references
166
+ // ═══════════════════════════════════════════════════════════════════════
167
+ describe('AC1: Cycle detection', () => {
168
+ it('should accept acyclic gate hierarchy (no repeated names)', () => {
169
+ const content = makeNestedGates(['root', 'child', 'grandchild']);
170
+ const result = detectGateCycles(content);
171
+ assert.strictEqual(result.valid, true, 'Acyclic gates should be valid');
172
+ });
173
+ it('should accept single root gate (no children, no cycles)', () => {
174
+ const content = makeNestedGates(['root']);
175
+ const result = detectGateCycles(content);
176
+ assert.strictEqual(result.valid, true, 'Single gate cannot have cycles');
177
+ });
178
+ it('should detect direct self-reference cycle (A contains A)', () => {
179
+ // Gate "check-a" nests a child also named "check-a" — cycle: check-a → check-a
180
+ const content = `<gate name="check-a" model="haiku">
181
+ <purpose>Purpose</purpose>
182
+ <pass>Pass</pass>
183
+ <fail>Fail</fail>
184
+ <gate name="check-a" model="haiku">
185
+ <purpose>Purpose</purpose>
186
+ <pass>Pass</pass>
187
+ <fail>Fail</fail>
188
+ </gate>
189
+ </gate>`;
190
+ const result = detectGateCycles(content);
191
+ assert.strictEqual(result.valid, false, 'Self-referencing gate name should be a cycle');
192
+ assert.ok(result.errors && result.errors.length > 0, 'Should have cycle errors');
193
+ assert.strictEqual(result.errors[0].type, 'cycle', 'Error type should be "cycle"');
194
+ });
195
+ it('should detect indirect cycle (A → B → A)', () => {
196
+ // root "gate-a" → child "gate-b" → grandchild "gate-a" — cycle: gate-a → gate-b → gate-a
197
+ const content = `<gate name="gate-a" model="haiku">
198
+ <purpose>Purpose</purpose>
199
+ <pass>Pass</pass>
200
+ <fail>Fail</fail>
201
+ <gate name="gate-b" model="haiku">
202
+ <purpose>Purpose</purpose>
203
+ <pass>Pass</pass>
204
+ <fail>Fail</fail>
205
+ <gate name="gate-a" model="haiku">
206
+ <purpose>Purpose</purpose>
207
+ <pass>Pass</pass>
208
+ <fail>Fail</fail>
209
+ </gate>
210
+ </gate>
211
+ </gate>`;
212
+ const result = detectGateCycles(content);
213
+ assert.strictEqual(result.valid, false, 'Indirect cycle A → B → A should be detected');
214
+ });
215
+ it('should detect longer cycle (A → B → C → A)', () => {
216
+ const content = `<gate name="gate-a" model="haiku">
217
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
218
+ <gate name="gate-b" model="haiku">
219
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
220
+ <gate name="gate-c" model="haiku">
221
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
222
+ <gate name="gate-a" model="haiku">
223
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
224
+ </gate>
225
+ </gate>
226
+ </gate>
227
+ </gate>`;
228
+ const result = detectGateCycles(content);
229
+ assert.strictEqual(result.valid, false, 'Longer cycle A → B → C → A should be detected');
230
+ });
231
+ it('should include cycle path in error message format: "Cycle detected: A → B → A"', () => {
232
+ const content = `<gate name="gate-a" model="haiku">
233
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
234
+ <gate name="gate-b" model="haiku">
235
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
236
+ <gate name="gate-a" model="haiku">
237
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
238
+ </gate>
239
+ </gate>
240
+ </gate>`;
241
+ const result = detectGateCycles(content);
242
+ assert.strictEqual(result.valid, false);
243
+ const error = result.errors[0];
244
+ // Must match: "Cycle detected: gate-a → gate-b → gate-a"
245
+ assert.ok(error.message.startsWith('Cycle detected:'), `Error message should start with "Cycle detected:", got: "${error.message}"`);
246
+ assert.ok(error.message.includes('gate-a') && error.message.includes('gate-b'), `Error should include both gate names, got: "${error.message}"`);
247
+ });
248
+ it('should match exact cycle error format with arrow notation', () => {
249
+ const content = `<gate name="alpha" model="haiku">
250
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
251
+ <gate name="beta" model="haiku">
252
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
253
+ <gate name="alpha" model="haiku">
254
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
255
+ </gate>
256
+ </gate>
257
+ </gate>`;
258
+ const result = detectGateCycles(content);
259
+ assert.strictEqual(result.valid, false);
260
+ const error = result.errors[0];
261
+ assert.strictEqual(error.message, 'Cycle detected: alpha \u2192 beta \u2192 alpha', 'Error message must match exact format from story spec (using → arrow)');
262
+ });
263
+ it('should accept sibling gates with same name (no nesting cycle)', () => {
264
+ // Two siblings named "check" under root — NOT a cycle (they don't nest each other)
265
+ const content = `<gate name="root" model="haiku">
266
+ <purpose>Root</purpose>
267
+ <pass>Pass</pass>
268
+ <fail>Fail</fail>
269
+ <gate name="check" model="haiku">
270
+ <purpose>A</purpose>
271
+ <pass>Pass</pass>
272
+ <fail>Fail</fail>
273
+ </gate>
274
+ <gate name="check" model="haiku">
275
+ <purpose>B</purpose>
276
+ <pass>Pass</pass>
277
+ <fail>Fail</fail>
278
+ </gate>
279
+ </gate>`;
280
+ const result = detectGateCycles(content);
281
+ // Sibling duplicates are NOT cycles — a cycle requires ancestor-descendant name match
282
+ assert.strictEqual(result.valid, true, 'Sibling gates with same name is not a cycle');
283
+ });
284
+ it('should detect cycle only on ancestor-descendant name match', () => {
285
+ // root "shared-name" → child "unique" → grandchild "shared-name"
286
+ // This IS a cycle: shared-name → unique → shared-name
287
+ const content = `<gate name="shared-name" model="haiku">
288
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
289
+ <gate name="unique" model="haiku">
290
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
291
+ <gate name="shared-name" model="haiku">
292
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
293
+ </gate>
294
+ </gate>
295
+ </gate>`;
296
+ const result = detectGateCycles(content);
297
+ assert.strictEqual(result.valid, false, 'Ancestor-descendant name match is a cycle');
298
+ });
299
+ });
300
+ // ═══════════════════════════════════════════════════════════════════════
301
+ // AC3: Parse-time execution — validates content string, no file I/O
302
+ // ═══════════════════════════════════════════════════════════════════════
303
+ describe('AC3: Parse-time validation (content string)', () => {
304
+ it('should validate from string content (no file path needed)', () => {
305
+ const content = makeNestedGates(['test-gate']);
306
+ // The function accepts a string, not a file path
307
+ const result = validateGateFile(content);
308
+ assert.strictEqual(typeof result.valid, 'boolean', 'Should return validation result');
309
+ });
310
+ it('should handle empty content gracefully', () => {
311
+ const result = validateGateFile('');
312
+ // Empty content = no gates = should fail (no root gate found)
313
+ assert.strictEqual(result.valid, false, 'Empty content should fail validation');
314
+ });
315
+ it('should handle content with no gate elements', () => {
316
+ const result = validateGateFile('This is just plain text, no gates here.');
317
+ assert.strictEqual(result.valid, false, 'Content without gates should fail');
318
+ });
319
+ });
320
+ // ═══════════════════════════════════════════════════════════════════════
321
+ // AC4: Error messages — specific and actionable
322
+ // ═══════════════════════════════════════════════════════════════════════
323
+ describe('AC4: Error messages', () => {
324
+ it('depth error should follow format: "Gate depth limit exceeded: {name} at depth {N} (max 3)"', () => {
325
+ const content = makeNestedGates(['root', 'a', 'b', 'c', 'violator']);
326
+ const result = validateGateFile(content);
327
+ assert.strictEqual(result.valid, false);
328
+ const depthError = result.errors?.find(e => e.type === 'depth');
329
+ assert.ok(depthError, 'Should have a depth error');
330
+ assert.strictEqual(depthError.message, 'Gate depth limit exceeded: violator at depth 4 (max 3)');
331
+ });
332
+ it('cycle error should follow format: "Cycle detected: {path}"', () => {
333
+ const content = `<gate name="x" model="haiku">
334
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
335
+ <gate name="y" model="haiku">
336
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
337
+ <gate name="x" model="haiku">
338
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
339
+ </gate>
340
+ </gate>
341
+ </gate>`;
342
+ const result = validateGateFile(content);
343
+ assert.strictEqual(result.valid, false);
344
+ const cycleError = result.errors?.find(e => e.type === 'cycle');
345
+ assert.ok(cycleError, 'Should have a cycle error');
346
+ assert.strictEqual(cycleError.message, 'Cycle detected: x \u2192 y \u2192 x');
347
+ });
348
+ it('should report both depth AND cycle errors when both present', () => {
349
+ // 5 levels deep AND a cycle (name reuse)
350
+ const content = `<gate name="root" model="haiku">
351
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
352
+ <gate name="a" model="haiku">
353
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
354
+ <gate name="b" model="haiku">
355
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
356
+ <gate name="c" model="haiku">
357
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
358
+ <gate name="root" model="haiku">
359
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
360
+ </gate>
361
+ </gate>
362
+ </gate>
363
+ </gate>
364
+ </gate>`;
365
+ const result = validateGateFile(content);
366
+ assert.strictEqual(result.valid, false);
367
+ const depthErrors = result.errors?.filter(e => e.type === 'depth') ?? [];
368
+ const cycleErrors = result.errors?.filter(e => e.type === 'cycle') ?? [];
369
+ assert.ok(depthErrors.length > 0, 'Should have depth errors');
370
+ assert.ok(cycleErrors.length > 0, 'Should have cycle errors');
371
+ });
372
+ });
373
+ // ═══════════════════════════════════════════════════════════════════════
374
+ // AC5: No regressions — valid gate files still pass
375
+ // ═══════════════════════════════════════════════════════════════════════
376
+ describe('AC5: Valid gate files pass (no regressions)', () => {
377
+ it('should accept minimal valid gate file', () => {
378
+ const content = `<gate name="tests-pass" model="haiku">
379
+ <purpose>Verify all tests pass</purpose>
380
+ <pass>All tests green, report summary</pass>
381
+ <fail>Report failing tests with details</fail>
382
+ </gate>`;
383
+ const result = validateGateFile(content);
384
+ assert.strictEqual(result.valid, true, 'Minimal valid gate should pass');
385
+ assert.strictEqual(result.gate, 'tests-pass', 'Should extract root gate name');
386
+ });
387
+ it('should accept gate with one level of nesting', () => {
388
+ const content = `<gate name="full-check" model="haiku">
389
+ <purpose>Run full validation suite</purpose>
390
+ <pass>All checks passed</pass>
391
+ <fail>Report failures</fail>
392
+ <gate name="lint-check" model="haiku">
393
+ <purpose>Check lint rules</purpose>
394
+ <pass>Lint clean</pass>
395
+ <fail>Report lint errors</fail>
396
+ </gate>
397
+ </gate>`;
398
+ const result = validateGateFile(content);
399
+ assert.strictEqual(result.valid, true, 'Valid nested gate should pass');
400
+ assert.strictEqual(result.depth, 1);
401
+ });
402
+ it('should accept gate at max depth (3 levels) with unique names', () => {
403
+ const content = makeNestedGates(['root', 'level-1', 'level-2', 'level-3']);
404
+ const result = validateGateFile(content);
405
+ assert.strictEqual(result.valid, true, 'Max depth with unique names should pass');
406
+ assert.strictEqual(result.depth, 3);
407
+ assert.strictEqual(result.gate, 'root');
408
+ });
409
+ it('should accept gate without model attribute', () => {
410
+ const content = `<gate name="simple">
411
+ <purpose>Simple gate</purpose>
412
+ <pass>Pass</pass>
413
+ <fail>Fail</fail>
414
+ </gate>`;
415
+ const result = validateGateFile(content);
416
+ assert.strictEqual(result.valid, true, 'Gate without model attribute should be valid');
417
+ });
418
+ });
419
+ // ═══════════════════════════════════════════════════════════════════════
420
+ // Combined validateGateFile tests
421
+ // ═══════════════════════════════════════════════════════════════════════
422
+ describe('Combined validation (validateGateFile)', () => {
423
+ it('should run both depth and cycle checks together', () => {
424
+ // Valid file: 2 levels, no cycles
425
+ const content = makeNestedGates(['outer', 'inner']);
426
+ const result = validateGateFile(content);
427
+ assert.strictEqual(result.valid, true);
428
+ assert.strictEqual(result.depth, 1);
429
+ assert.strictEqual(result.gate, 'outer');
430
+ });
431
+ it('should fail on depth violation even when no cycles', () => {
432
+ const content = makeNestedGates(['a', 'b', 'c', 'd', 'e']);
433
+ const result = validateGateFile(content);
434
+ assert.strictEqual(result.valid, false);
435
+ assert.ok(result.errors?.some(e => e.type === 'depth'));
436
+ });
437
+ it('should fail on cycle even when depth is within limits', () => {
438
+ // Depth 2 (within limit) but has cycle: check → sub → check
439
+ const content = `<gate name="check" model="haiku">
440
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
441
+ <gate name="sub" model="haiku">
442
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
443
+ <gate name="check" model="haiku">
444
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
445
+ </gate>
446
+ </gate>
447
+ </gate>`;
448
+ const result = validateGateFile(content);
449
+ assert.strictEqual(result.valid, false, 'Cycle within depth limit should still fail');
450
+ assert.ok(result.errors?.some(e => e.type === 'cycle'));
451
+ });
452
+ it('should report all errors at once (not stop at first)', () => {
453
+ // Both depth violation AND cycle
454
+ const content = `<gate name="root" model="haiku">
455
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
456
+ <gate name="a" model="haiku">
457
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
458
+ <gate name="b" model="haiku">
459
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
460
+ <gate name="c" model="haiku">
461
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
462
+ <gate name="root" model="haiku">
463
+ <purpose>P</purpose><pass>P</pass><fail>F</fail>
464
+ </gate>
465
+ </gate>
466
+ </gate>
467
+ </gate>
468
+ </gate>`;
469
+ const result = validateGateFile(content);
470
+ assert.strictEqual(result.valid, false);
471
+ assert.ok(result.errors && result.errors.length >= 2, `Should report multiple errors, got ${result.errors?.length ?? 0}`);
472
+ });
473
+ });
474
+ // ═══════════════════════════════════════════════════════════════════════
475
+ // Edge Cases
476
+ // ═══════════════════════════════════════════════════════════════════════
477
+ describe('Edge cases', () => {
478
+ it('should handle gate tags with extra whitespace', () => {
479
+ const content = `<gate name="spaced" model="haiku" >
480
+ <purpose>Purpose</purpose>
481
+ <pass>Pass</pass>
482
+ <fail>Fail</fail>
483
+ </gate>`;
484
+ const result = validateGateFile(content);
485
+ assert.strictEqual(result.valid, true, 'Extra whitespace in tag should be handled');
486
+ assert.strictEqual(result.gate, 'spaced');
487
+ });
488
+ it('should handle gate name with hyphens and underscores', () => {
489
+ const content = makeNestedGates(['my-gate_v2']);
490
+ const result = validateGateFile(content);
491
+ assert.strictEqual(result.valid, true);
492
+ assert.strictEqual(result.gate, 'my-gate_v2');
493
+ });
494
+ it('should handle self-closing consideration (gate must have closing tag)', () => {
495
+ // A gate without content between tags
496
+ const content = `<gate name="empty-gate" model="haiku">
497
+ <purpose>P</purpose>
498
+ <pass>P</pass>
499
+ <fail>F</fail>
500
+ </gate>`;
501
+ const result = validateGateFile(content);
502
+ assert.strictEqual(result.valid, true, 'Gate with required blocks but no children is valid');
503
+ });
504
+ it('should extract root gate name in result', () => {
505
+ const content = makeNestedGates(['my-root-gate', 'child']);
506
+ const result = validateGateFile(content);
507
+ assert.strictEqual(result.gate, 'my-root-gate', 'Should extract root gate name');
508
+ });
509
+ it('should handle deeply nested content with mixed indentation', () => {
510
+ const content = `<gate name="root" model="haiku">
511
+ <purpose>P</purpose>
512
+ <pass>P</pass>
513
+ <fail>F</fail>
514
+ <gate name="child" model="haiku">
515
+ <purpose>P</purpose>
516
+ <pass>P</pass>
517
+ <fail>F</fail>
518
+ </gate>
519
+ </gate>`;
520
+ const result = validateGateFile(content);
521
+ assert.strictEqual(result.valid, true, 'Mixed indentation should not affect parsing');
522
+ assert.strictEqual(result.depth, 1);
523
+ });
524
+ it('should handle gate names in single quotes', () => {
525
+ const content = `<gate name='single-quoted' model='haiku'>
526
+ <purpose>P</purpose>
527
+ <pass>P</pass>
528
+ <fail>F</fail>
529
+ </gate>`;
530
+ const result = validateGateFile(content);
531
+ assert.strictEqual(result.valid, true, 'Single-quoted attributes should work');
532
+ assert.strictEqual(result.gate, 'single-quoted');
533
+ });
534
+ });
535
+ });
536
+ //# sourceMappingURL=gate-file-validation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-file-validation.test.js","sourceRoot":"","sources":["../../src/workflow/gate-file-validation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Tests for Story 107-1: Gate Schema Validation at Parse Time
3
+ *
4
+ * Validates that gate definitions in workflow YAML are schema-checked
5
+ * when loaded, catching malformed gates early rather than at runtime.
6
+ *
7
+ * ACs:
8
+ * 1. Schema validates gate structure (type, condition, file if present)
9
+ * 2. Parser validates gates at load time, raises clear errors
10
+ * 3. All existing gate definitions conform to schema (no breaking changes)
11
+ * 4. Error messages guide authors on valid gate syntax
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=gate-schema-validation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-schema-validation.test.d.ts","sourceRoot":"","sources":["../../src/workflow/gate-schema-validation.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}