@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,128 @@
1
+ # BikeRack
2
+
3
+ <info>
4
+ Standalone panel viewer for CLI-first developers. BikeRack runs WheelHub (the Express/WebSocket server) without Cyclist's conversation UI, serving dashboard panels in a browser while Claude Code runs in your own terminal.
5
+ </info>
6
+
7
+ ## Overview
8
+
9
+ Cyclist bundles the conversation UI and dashboard panels into one Electron app. BikeRack decouples them: you get the panels (sprint status, git diffs, workflow state, etc.) in a browser, and Claude Code stays in your terminal.
10
+
11
+ ```
12
+ ┌─────────────────┐ ┌──────────────────────┐
13
+ │ Claude CLI │ │ WheelHub (BikeRack) │
14
+ │ (your terminal) │──────▶│ Port 2898 │
15
+ │ │ OTEL │ No ClaudeService │
16
+ │ │ files │ 16 WS channels │
17
+ └─────────────────┘ └──────────┬─────────────┘
18
+ │ HTTP + WS
19
+
20
+ ┌──────────────────────┐
21
+ │ Browser │
22
+ │ Dockview layout │
23
+ │ or ?panel=X routing │
24
+ └──────────────────────┘
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```bash
30
+ # Launch BikeRack + Claude CLI together
31
+ pf bikerack start
32
+
33
+ # Or via just recipe
34
+ just bikerack
35
+
36
+ # With a specific project directory
37
+ just bikerack dir=/path/to/project
38
+
39
+ # Stop a running instance
40
+ pf bikerack stop
41
+
42
+ # Check status
43
+ pf bikerack status
44
+ ```
45
+
46
+ BikeRack opens a browser with the Dockview panel layout. Claude CLI runs in the foreground. When Claude exits, BikeRack shuts down automatically via `trap EXIT`.
47
+
48
+ ## Panel Routing
49
+
50
+ BikeRack supports two modes:
51
+
52
+ **Dockview layout** (default) — full multi-panel workspace at `http://localhost:{port}/bikerack`
53
+
54
+ **Standalone panel** — single panel full-screen via query param:
55
+
56
+ | URL | Panel |
57
+ |-----|-------|
58
+ | `?panel=sprint` | Sprint status |
59
+ | `?panel=git` | Git operations |
60
+ | `?panel=diffs` | Diff viewer |
61
+ | `?panel=workflow` | Workflow state |
62
+ | `?panel=changed` | Changed files |
63
+ | `?panel=ac` | Acceptance criteria |
64
+ | `?panel=todos` | Task list |
65
+ | `?panel=audit` | Audit log |
66
+ | `?panel=background` | Background jobs |
67
+ | `?panel=debug` | Debug/prime context |
68
+ | `?panel=bikelane` | BikeLane workflow |
69
+ | `?panel=settings` | Settings |
70
+ | `?panel=portrait` | Agent portrait |
71
+
72
+ ## How It Works
73
+
74
+ 1. **Launcher** (`pf bikerack start`) starts WheelHub with `IS_BIKERACK=1`
75
+ 2. **WheelHub** listens on port 2898 (separate from Cyclist's 1898)
76
+ 3. **ClaudeService is skipped** — no `/ws/claude` WebSocket channel
77
+ 4. **OTEL telemetry** flows from Claude CLI to WheelHub's OTLP receiver
78
+ 5. **File watchers** detect changes to `.session/`, `sprint/`, and git state
79
+ 6. **Panels** render as React components consuming WebSocket data — identical components to Cyclist
80
+
81
+ ### Mode Detection
82
+
83
+ ```typescript
84
+ // Server-side
85
+ import { isBikeRackMode } from './server.js';
86
+ if (isBikeRackMode()) { /* skip Claude-specific setup */ }
87
+ ```
88
+
89
+ Client-side detection is URL-based: the presence of `?panel=X` triggers standalone rendering.
90
+
91
+ ### Port and PID Files
92
+
93
+ | File | Purpose |
94
+ |------|---------|
95
+ | `.bikerack-port` | Port number, written after `server.listen()` — readiness signal |
96
+ | `.bikerack-pid` | WheelHub PID, written by launcher — enables `pf bikerack stop` |
97
+
98
+ Both are deleted on shutdown. Separate from Cyclist's `.cyclist-port` and `.cyclist-pid` for coexistence.
99
+
100
+ ## Layout Persistence
101
+
102
+ Save and restore BikeRack panel layouts:
103
+
104
+ ```bash
105
+ pf bc save my-layout # Save current layout
106
+ pf bc load my-layout # Restore a saved layout
107
+ pf bc list # List saved layouts
108
+ ```
109
+
110
+ ## Key Files
111
+
112
+ | File | Purpose |
113
+ |------|---------|
114
+ | `packages/cyclist/src/bikerack.ts` | BikeRack WheelHub entry point |
115
+ | `packages/core/src/public/components/BikeRackWorkspace.tsx` | Dockview layout for BikeRack |
116
+ | `packages/core/src/public/components/BikeRackIndex.tsx` | Panel listing index page |
117
+ | `packages/core/src/public/components/StandalonePanel.tsx` | `?panel=X` routing + `PANEL_REGISTRY` |
118
+ | `pennyfarthing_scripts/bikerack/cli.py` | `pf bikerack` launcher CLI |
119
+
120
+ ## Constraints
121
+
122
+ - **No MessagePanel** — Claude conversation stays in your terminal. This is intentional.
123
+ - **Single session** — one Claude CLI per BikeRack instance (multi-session is deferred).
124
+ - **Bell/Relay/Reflector are dormant** — these features require ClaudeService and are skipped in BikeRack mode.
125
+
126
+ <info>
127
+ **ADR:** `docs/adr/0024-bikerack-mode.md`
128
+ </info>
@@ -0,0 +1,133 @@
1
+ # Brownfield & Code Analysis Tools
2
+
3
+ <info>
4
+ CLI tools for analyzing existing codebases. Identify change hotspots, complexity bottlenecks, dead code, stale dependencies, and code markers (TODO/FIXME). Each tool produces table, JSON, or CSV output and has a corresponding WheelHub API route for panel integration.
5
+ </info>
6
+
7
+ ## Overview
8
+
9
+ All tools are available under `pf debug` and share a consistent interface: `--format` (table/json/csv), `--output` (file), `--top` (result count), `--exclude` (patterns), and `--repo` (target).
10
+
11
+ ## Tools
12
+
13
+ ### Hotspots
14
+
15
+ Find files that change most frequently — high churn often correlates with bugs and complexity.
16
+
17
+ ```bash
18
+ # Full analysis (files + directories)
19
+ pf debug hotspots analyze
20
+
21
+ # File-level only
22
+ pf debug hotspots files
23
+
24
+ # Directory-level only
25
+ pf debug hotspots dirs
26
+
27
+ # Options
28
+ pf debug hotspots analyze --days 90 --top 20 --repo pennyfarthing
29
+ pf debug hotspots analyze --format json --output hotspots.json
30
+ pf debug hotspots analyze --exclude "*.test.ts" --branch main
31
+ pf debug hotspots analyze --skip-type orchestrator
32
+ ```
33
+
34
+ ### Complexity
35
+
36
+ Measure code complexity metrics across files.
37
+
38
+ ```bash
39
+ pf debug complexity analyze
40
+ pf debug complexity analyze --path ./packages/core/src
41
+ pf debug complexity analyze --top 30 --format csv
42
+ ```
43
+
44
+ ### Dead Code
45
+
46
+ Find unused code: stale files with no recent commits, and unused TypeScript exports.
47
+
48
+ ```bash
49
+ # Files with no recent commits (default: 180 days)
50
+ pf debug deadcode stale
51
+ pf debug deadcode stale --days 90 --repo pennyfarthing
52
+
53
+ # Unused TypeScript exports (via ts-prune)
54
+ pf debug deadcode exports
55
+ pf debug deadcode exports --repo pennyfarthing --format json
56
+ ```
57
+
58
+ ### Code Markers
59
+
60
+ Detect TODO, FIXME, HACK, and XXX comments with git blame data.
61
+
62
+ ```bash
63
+ # Full analysis with blame data
64
+ pf debug codemarkers analyze
65
+
66
+ # Only stale markers (older than threshold)
67
+ pf debug codemarkers stale --days 90
68
+
69
+ # Summary counts by type
70
+ pf debug codemarkers summary
71
+
72
+ # Deprecated symbol detection
73
+ pf debug codemarkers deprecations
74
+ ```
75
+
76
+ ### Dependencies
77
+
78
+ Analyze dependency staleness and security advisories.
79
+
80
+ ```bash
81
+ pf debug dependencies analyze
82
+ pf debug dependencies analyze --path ./pennyfarthing --format json
83
+ ```
84
+
85
+ ### Health Score
86
+
87
+ Composite health score across all dimensions (hotspots, complexity, dead code, dependencies, markers).
88
+
89
+ ```bash
90
+ pf debug healthscore analyze
91
+ pf debug healthscore analyze --no-cache # Bypass cache
92
+ pf debug healthscore analyze --format json --output health.json
93
+ ```
94
+
95
+ ## Common Options
96
+
97
+ | Option | Description | Default |
98
+ |--------|-------------|---------|
99
+ | `--repo NAME` | Analyze a single named repo from `repos.yaml` | All repos |
100
+ | `--path DIR` | Analyze a standalone directory | Current directory |
101
+ | `--format FMT` | Output format: `table`, `json`, `csv` | `table` |
102
+ | `--output FILE` | Write output to file | stdout |
103
+ | `--top N` | Number of top results | 20 |
104
+ | `--exclude PAT` | Exclude patterns (repeatable) | — |
105
+ | `--days N` | Time window for analysis | Varies by tool |
106
+
107
+ ## WheelHub API Routes
108
+
109
+ Each tool has a corresponding HTTP API in WheelHub for panel integration:
110
+
111
+ | Route | Tool |
112
+ |-------|------|
113
+ | `/api/hotspots` | Hotspot analysis |
114
+ | `/api/complexity` | Complexity metrics |
115
+ | `/api/dead-code` | Dead code detection |
116
+ | `/api/dependencies` | Dependency health |
117
+ | `/api/code-markers` | Code marker scan |
118
+ | `/api/health-score` | Composite health score |
119
+
120
+ These power the **HotspotsPanel** in Cyclist and BikeRack.
121
+
122
+ ## Key Files
123
+
124
+ | Directory | Purpose |
125
+ |-----------|---------|
126
+ | `pennyfarthing_scripts/hotspots/` | Hotspot analysis (analyze, formatters, models) |
127
+ | `pennyfarthing_scripts/complexity/` | Complexity analysis |
128
+ | `pennyfarthing_scripts/deadcode/` | Dead code detection |
129
+ | `pennyfarthing_scripts/dependencies/` | Dependency analysis |
130
+ | `pennyfarthing_scripts/codemarkers/` | Code marker detection |
131
+ | `pennyfarthing_scripts/healthscore/` | Composite health score |
132
+ | `pennyfarthing_scripts/brownfield/` | Brownfield codebase discovery |
133
+ | `packages/core/src/server/api/` | WheelHub API routes |
@@ -65,7 +65,7 @@
65
65
  - `<agent-activation>` — Required to show activation
66
66
  - `<instructions>` — Required for agent behavior
67
67
 
68
- **Script-Based Commands (e.g., /check, /run-ci)**
68
+ **Script-Based Commands (e.g., /check, /pf-ci run)**
69
69
  - `<execution>` — Required with options
70
70
  - `<reference>` — Links to scripts
71
71
 
@@ -78,7 +78,7 @@
78
78
  - `<when-not-to-use>` — When NOT to pick this
79
79
  - `<related>` — Alternatives to consider
80
80
 
81
- **Workflow/Phase Commands (e.g., /sprint, /release)**
81
+ **Workflow/Phase Commands (e.g., /sprint, /pf-git release)**
82
82
  - `<workflow>` — Phase breakdown
83
83
  - `<commands>` or subcommand table — Available subcommands
84
84
 
@@ -0,0 +1,227 @@
1
+ # Gate File Schema
2
+
3
+ <info>
4
+ Gate files define quality checks that run at workflow phase boundaries. A gate file is a markdown document containing XML tags that instruct a subagent to evaluate pass/fail criteria before allowing a workflow to proceed.
5
+ </info>
6
+
7
+ ## File Location
8
+
9
+ Gate files are discovered in this order (first match wins):
10
+
11
+ 1. `.pennyfarthing/gates/{name}.md` — project-local override
12
+ 2. `pennyfarthing-dist/gates/{name}.md` — built-in gates
13
+
14
+ ## Schema
15
+
16
+ ```xml
17
+ <gate name="gate-name" model="haiku">
18
+
19
+ <purpose>
20
+ What this gate checks and why it matters.
21
+ </purpose>
22
+
23
+ <pass>
24
+ Instructions for the subagent when all checks succeed.
25
+ Must include a GATE_RESULT YAML block with status: pass.
26
+ </pass>
27
+
28
+ <fail>
29
+ Instructions for the subagent when any check fails.
30
+ Must include a GATE_RESULT YAML block with status: fail.
31
+ Include recovery guidance so the agent knows how to fix the issue.
32
+ </fail>
33
+
34
+ </gate>
35
+ ```
36
+
37
+ ### Required Elements
38
+
39
+ | Element | Description |
40
+ |---------|-------------|
41
+ | `<gate name="...">` | Root element. `name` attribute is required, must be unique. |
42
+ | `<purpose>` | Describes what the gate checks. Helps agents understand context. |
43
+ | `<pass>` | Instructions when checks succeed. Must template a `GATE_RESULT` with `status: pass`. |
44
+ | `<fail>` | Instructions when checks fail. Must template a `GATE_RESULT` with `status: fail`. |
45
+
46
+ ### Optional Attributes
47
+
48
+ | Attribute | Default | Description |
49
+ |-----------|---------|-------------|
50
+ | `model` | `haiku` | LLM model for the gate subagent. Use `haiku` for fast, cheap checks. |
51
+
52
+ ### Nested Gates
53
+
54
+ Gates can contain nested `<gate>` elements for compound checks. Maximum nesting depth is **3 levels** (root = level 0).
55
+
56
+ ```xml
57
+ <gate name="release-ready" model="haiku">
58
+ <purpose>Verify release readiness</purpose>
59
+ <pass>All release checks pass</pass>
60
+ <fail>Release blocked</fail>
61
+
62
+ <gate name="tests-pass" model="haiku">
63
+ <purpose>All tests green</purpose>
64
+ <pass>Tests passing</pass>
65
+ <fail>Tests failing</fail>
66
+ </gate>
67
+
68
+ <gate name="lint-clean" model="haiku">
69
+ <purpose>No lint errors</purpose>
70
+ <pass>Lint clean</pass>
71
+ <fail>Lint errors found</fail>
72
+ </gate>
73
+ </gate>
74
+ ```
75
+
76
+ **Rules for nesting:**
77
+ - Maximum depth: 3 (root at depth 0, deepest child at depth 3)
78
+ - Gate names must be unique within the file — no duplicates, no cycles
79
+ - Sibling gates at the same depth may share a parent but not a name
80
+
81
+ ## GATE_RESULT Contract
82
+
83
+ Gate subagents must return a `GATE_RESULT` YAML block. The runtime uses default-deny: if no parseable result is found, the gate fails.
84
+
85
+ ```yaml
86
+ GATE_RESULT:
87
+ status: pass | fail
88
+ gate: "gate-name"
89
+ message: "Human-readable summary"
90
+ checks:
91
+ - name: check-name
92
+ status: pass | fail
93
+ detail: "What was checked and the outcome"
94
+ recovery: # Only on fail
95
+ - "Step to fix issue 1"
96
+ - "Step to fix issue 2"
97
+ ```
98
+
99
+ | Field | Required | Description |
100
+ |-------|----------|-------------|
101
+ | `status` | Yes | `pass` or `fail` — strict enum, no other values |
102
+ | `gate` | No | Gate name (for traceability) |
103
+ | `message` | Yes | One-line summary of the result |
104
+ | `checks` | No | Array of individual check results |
105
+ | `recovery` | No | Array of fix instructions (fail only) |
106
+
107
+ ## Working Example
108
+
109
+ Here is a complete gate file that checks whether documentation exists for new exports:
110
+
111
+ ```xml
112
+ <gate name="docs-check" model="haiku">
113
+
114
+ <purpose>
115
+ Verify that all new public exports have corresponding documentation.
116
+ Runs after the Dev phase to catch undocumented APIs before review.
117
+ </purpose>
118
+
119
+ <pass>
120
+ Check the git diff for new export statements. For each new export,
121
+ verify a matching entry exists in the relevant guide or README.
122
+
123
+ If all exports are documented, return:
124
+
125
+ GATE_RESULT:
126
+ status: pass
127
+ gate: docs-check
128
+ message: "All new exports documented"
129
+ checks:
130
+ - name: export-coverage
131
+ status: pass
132
+ detail: "{N} new exports, all documented"
133
+ </pass>
134
+
135
+ <fail>
136
+ If any new export lacks documentation, list the gaps:
137
+
138
+ GATE_RESULT:
139
+ status: fail
140
+ gate: docs-check
141
+ message: "Undocumented exports found"
142
+ checks:
143
+ - name: export-coverage
144
+ status: fail
145
+ detail: "{N} exports missing documentation"
146
+ recovery:
147
+ - "Add documentation for: {list of undocumented exports}"
148
+ - "Update the relevant guide in pennyfarthing-dist/guides/"
149
+ </fail>
150
+
151
+ </gate>
152
+ ```
153
+
154
+ ## Workflow Integration
155
+
156
+ Gates are referenced in workflow YAML files via the `gate.file` field:
157
+
158
+ ```yaml
159
+ workflow:
160
+ name: my-workflow
161
+ phases:
162
+ - name: implement
163
+ agent: dev
164
+ gate:
165
+ file: gates/tests-pass # References pennyfarthing-dist/gates/tests-pass.md
166
+ condition: All tests passing
167
+ ```
168
+
169
+ The `gate.file` value is resolved by the gate file discovery algorithm (project-local first, built-in fallback).
170
+
171
+ ### Built-in Gate Types vs File Gates
172
+
173
+ | Approach | When to Use |
174
+ |----------|-------------|
175
+ | `gate.type` (built-in) | Standard checks: `tests_pass`, `tests_fail`, `approval`, `manual` |
176
+ | `gate.file` (file-based) | Custom checks with specific pass/fail logic |
177
+ | Both | File-based gate with type for fallback categorization |
178
+
179
+ ## Validation
180
+
181
+ Validate gate files before use:
182
+
183
+ ```bash
184
+ pf gate validate path/to/gate-file.md
185
+ ```
186
+
187
+ The validator checks:
188
+ - **Schema:** `<gate>` tag with `name` attribute, `<purpose>`, `<pass>`, `<fail>` present and non-empty
189
+ - **Depth:** Nesting does not exceed 3 levels
190
+ - **Cycles:** No duplicate gate names (which would indicate cycles in nested structures)
191
+ - **Completeness:** Every gate (including nested) has all required elements
192
+
193
+ All errors are reported at once — fix everything in a single pass.
194
+
195
+ On success, the validator prints a structure summary:
196
+
197
+ ```
198
+ Gate 'tests-pass' is valid
199
+ Model: haiku
200
+ Depth: 0 (no nesting)
201
+ Children: 0
202
+ ```
203
+
204
+ ## Best Practices
205
+
206
+ 1. **Keep gates focused.** One gate = one quality dimension. Use nesting for compound checks, not unrelated concerns.
207
+
208
+ 2. **Write actionable fail instructions.** The `<fail>` block should tell the agent exactly how to diagnose and fix the issue. Include specific commands to run and files to check.
209
+
210
+ 3. **Template the GATE_RESULT.** Include the exact YAML structure in both `<pass>` and `<fail>` blocks so the subagent knows the expected output format.
211
+
212
+ 4. **Use `haiku` for speed.** Gate checks should be fast and cheap. Only use a larger model if the gate requires deep reasoning.
213
+
214
+ 5. **Include checks for traceability.** The `checks` array in GATE_RESULT lets the calling agent see exactly what passed or failed without re-running the gate.
215
+
216
+ 6. **Add recovery steps.** The `recovery` array in failed results gives the agent a clear path to fix issues and retry.
217
+
218
+ 7. **Test with the validator.** Run `pf gate validate` on your gate file before referencing it in a workflow.
219
+
220
+ ## Related
221
+
222
+ - [Workflow Schema](workflow-schema.md) — How gates are referenced in workflow definitions
223
+ - [Approval Gates Pattern](patterns/approval-gates-pattern.md) — Pattern for approval-style gates
224
+ - Story 106-2: Gate subagent runner with GATE_RESULT contract
225
+ - Story 106-4: Gate file discovery and resolution
226
+ - Story 107-1: Gate schema validation at parse time
227
+ - Story 107-2: Acyclic validation and depth limit enforcement
@@ -0,0 +1,120 @@
1
+ # Workflow Gates
2
+
3
+ <info>
4
+ Conditional checks that block or allow workflow phase transitions. Gates enforce quality thresholds — tests must pass, reviews must be approved, instructions must be unambiguous — before an agent can hand off to the next phase.
5
+ </info>
6
+
7
+ ## Overview
8
+
9
+ Gates live in `pennyfarthing-dist/gates/` and are referenced by workflow YAML files via the `gate.file` field on phase definitions. When an agent finishes a phase, the handoff CLI resolves the gate, spawns a Haiku subagent to evaluate it, and blocks the transition if the gate fails.
10
+
11
+ ## Built-in Gates
12
+
13
+ | Gate | File | Purpose | Used By |
14
+ |------|------|---------|---------|
15
+ | **tests-pass** | `gates/tests-pass.md` | Verify all tests pass, working tree clean, correct branch | Dev → Reviewer transitions |
16
+ | **tests-fail** | `gates/tests-fail.md` | Verify tests are RED (failing) with AC coverage | TEA → Dev transitions |
17
+ | **approval** | `gates/approval.md` | Verify reviewer has issued explicit APPROVED verdict | Reviewer → SM transitions |
18
+ | **confidence-sm** | `gates/confidence-sm.md` | Check if user instruction to SM is ambiguous | SM entry gate |
19
+
20
+ ## Gate File Format
21
+
22
+ Gates use XML-style tags with `<pass>` and `<fail>` sections:
23
+
24
+ ```xml
25
+ <gate name="tests-pass" model="haiku">
26
+
27
+ <purpose>
28
+ What this gate checks and why.
29
+ </purpose>
30
+
31
+ <pass>
32
+ Instructions for the gate subagent when checks succeed.
33
+ Must return a GATE_RESULT YAML block with status: pass.
34
+ </pass>
35
+
36
+ <fail>
37
+ Instructions for diagnosing failures.
38
+ Must return a GATE_RESULT YAML block with status: fail
39
+ and actionable recovery guidance.
40
+ </fail>
41
+
42
+ </gate>
43
+ ```
44
+
45
+ ## GATE_RESULT Contract
46
+
47
+ Gate subagents must return a structured YAML result:
48
+
49
+ ```yaml
50
+ GATE_RESULT:
51
+ status: pass | fail
52
+ gate: gate-name
53
+ message: "Human-readable summary"
54
+ checks:
55
+ - name: check-name
56
+ status: pass | fail
57
+ detail: "What was checked and the result"
58
+ recovery: # Only on fail
59
+ - "Actionable step to fix the issue"
60
+ ```
61
+
62
+ ## Workflow Integration
63
+
64
+ Gates are declared in workflow YAML on phase transitions:
65
+
66
+ ```yaml
67
+ phases:
68
+ green:
69
+ agent: dev
70
+ gate:
71
+ file: tests-pass # References gates/tests-pass.md
72
+ next: review
73
+ ```
74
+
75
+ ## Agent Exit Protocol
76
+
77
+ Agents interact with gates through the handoff CLI during their exit sequence:
78
+
79
+ ```
80
+ 1. Agent writes assessment to session file
81
+ 2. pf handoff resolve-gate {story-id} {workflow} {phase}
82
+ → Reads workflow YAML, finds gate for current phase
83
+ → Returns RESOLVE_RESULT: {status: ready|skip|blocked, gate_file: ...}
84
+ 3. If ready → spawn Haiku subagent with gate file → GATE_RESULT
85
+ 4. If GATE_RESULT.status == fail → fix issues, retry (max 3)
86
+ 5. If GATE_RESULT.status == pass → continue to complete-phase
87
+ 6. pf handoff complete-phase {story-id} {workflow} {from} {to} {gate-type}
88
+ 7. pf handoff marker {next-agent}
89
+ ```
90
+
91
+ If a phase has no `gate:` block, `resolve-gate` returns `status: skip` and the agent proceeds directly to `complete-phase`.
92
+
93
+ ## Gate Evaluations
94
+
95
+ Extended evaluation criteria can live in `gates/evaluations/`:
96
+
97
+ | File | Purpose |
98
+ |------|---------|
99
+ | `evaluations/confidence-sm.md` | Detailed rubric for SM confidence scoring |
100
+
101
+ ## Creating Custom Gates
102
+
103
+ 1. Create `pennyfarthing-dist/gates/my-gate.md` following the XML format above
104
+ 2. Reference it in a workflow phase: `gate: { file: my-gate }`
105
+ 3. The gate runner discovers files in the `gates/` directory by name
106
+
107
+ Gates run as Haiku subagents — keep instructions focused and evaluation criteria concrete.
108
+
109
+ ## Key Files
110
+
111
+ | File | Purpose |
112
+ |------|---------|
113
+ | `pennyfarthing-dist/gates/*.md` | Gate definitions |
114
+ | `pennyfarthing_scripts/handoff/gate_runner.py` | Spawns gate subagents |
115
+ | `pennyfarthing_scripts/handoff/gate_file.py` | Gate file discovery and resolution |
116
+ | `pennyfarthing_scripts/handoff/resolve_gate.py` | Resolves gate for a workflow phase |
117
+
118
+ <info>
119
+ **ADR:** `docs/adr/0025-script-first-gate-extraction.md`
120
+ </info>