@bonesofspring/ai-rules 0.2.11 → 0.2.12

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 (530) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +5 -1
  3. package/bin/cli.js +4 -0
  4. package/package.json +1 -1
  5. package/presets/_shared/README.md +1 -1
  6. package/presets/_shared/core/agent-team/agent-task-metrics.md +30 -0
  7. package/presets/_shared/core/agent-team/agent-team-orchestrator.md +9 -1
  8. package/presets/_shared/core/meta/preset-layering.md +1 -1
  9. package/presets/_shared/core/meta/preset-no-cross-stack-leakage.md +5 -5
  10. package/presets/_shared/core/meta/preset-pr-checklist.md +1 -1
  11. package/presets/_shared/core/meta/preset-twin-sync.md +4 -0
  12. package/presets/_shared/core/review/technical-retro.md +2 -0
  13. package/presets/claude/go/agents/build-verifier.md +2 -2
  14. package/presets/claude/go/agents/task-router.md +4 -0
  15. package/presets/claude/go/commands/task-continue.md +17 -16
  16. package/presets/claude/go/commands/task.md +4 -0
  17. package/presets/claude/go/commands/technical-retro.md +4 -0
  18. package/presets/claude/go/hooks/chain-team-phases.sh +226 -26
  19. package/presets/claude/go/rules/README.md +6 -0
  20. package/presets/claude/go/rules/tooling-and-review/agent-team-orchestrator.md +4 -0
  21. package/presets/claude/go/rules/tooling-and-review/preset-layering.md +1 -1
  22. package/presets/claude/go/rules/tooling-and-review/preset-no-cross-stack-leakage.md +5 -5
  23. package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +1 -1
  24. package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +4 -0
  25. package/presets/claude/go/rules/tooling-and-review/technical-retro.md +2 -0
  26. package/presets/claude/go/team/README.md +8 -0
  27. package/presets/claude/ios-swift/agents/build-verifier.md +3 -3
  28. package/presets/claude/ios-swift/agents/task-router.md +4 -0
  29. package/presets/claude/ios-swift/commands/task-continue.md +17 -16
  30. package/presets/claude/ios-swift/commands/task.md +4 -0
  31. package/presets/claude/ios-swift/commands/technical-retro.md +4 -0
  32. package/presets/claude/ios-swift/hooks/chain-team-phases.sh +226 -26
  33. package/presets/claude/ios-swift/rules/README.md +6 -0
  34. package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-orchestrator.md +4 -0
  35. package/presets/claude/ios-swift/rules/tooling-and-review/preset-layering.md +1 -1
  36. package/presets/claude/ios-swift/rules/tooling-and-review/preset-no-cross-stack-leakage.md +5 -5
  37. package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +1 -1
  38. package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +4 -0
  39. package/presets/claude/ios-swift/rules/tooling-and-review/technical-retro.md +2 -0
  40. package/presets/claude/ios-swift/team/README.md +8 -0
  41. package/presets/claude/java/agents/build-verifier.md +3 -3
  42. package/presets/claude/java/agents/task-router.md +4 -0
  43. package/presets/claude/java/commands/task-continue.md +17 -16
  44. package/presets/claude/java/commands/task.md +4 -0
  45. package/presets/claude/java/commands/technical-retro.md +4 -0
  46. package/presets/claude/java/hooks/chain-team-phases.sh +226 -26
  47. package/presets/claude/java/rules/README.md +6 -0
  48. package/presets/claude/java/rules/tooling-and-review/agent-team-orchestrator.md +4 -0
  49. package/presets/claude/java/rules/tooling-and-review/preset-layering.md +1 -1
  50. package/presets/claude/java/rules/tooling-and-review/preset-no-cross-stack-leakage.md +5 -5
  51. package/presets/claude/java/rules/tooling-and-review/preset-pr-checklist.md +1 -1
  52. package/presets/claude/java/rules/tooling-and-review/preset-twin-sync.md +4 -0
  53. package/presets/claude/java/rules/tooling-and-review/technical-retro.md +2 -0
  54. package/presets/claude/java/team/README.md +8 -0
  55. package/presets/claude/mcp-ts/agents/build-verifier.md +2 -2
  56. package/presets/claude/mcp-ts/agents/task-router.md +4 -0
  57. package/presets/claude/mcp-ts/commands/task-continue.md +21 -20
  58. package/presets/claude/mcp-ts/commands/task.md +4 -0
  59. package/presets/claude/mcp-ts/commands/technical-retro.md +4 -0
  60. package/presets/claude/mcp-ts/hooks/chain-team-phases.sh +226 -26
  61. package/presets/claude/mcp-ts/rules/README.md +6 -0
  62. package/presets/claude/mcp-ts/rules/tooling-and-review/agent-team-orchestrator.md +4 -0
  63. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-layering.md +1 -1
  64. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-no-cross-stack-leakage.md +5 -5
  65. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +1 -1
  66. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-twin-sync.md +4 -0
  67. package/presets/claude/mcp-ts/rules/tooling-and-review/technical-retro.md +2 -4
  68. package/presets/claude/mcp-ts/team/README.md +8 -0
  69. package/presets/claude/next/agents/build-verifier.md +3 -3
  70. package/presets/claude/next/agents/task-router.md +4 -0
  71. package/presets/claude/next/commands/task-continue.md +17 -16
  72. package/presets/claude/next/commands/task.md +4 -0
  73. package/presets/claude/next/commands/technical-retro.md +4 -0
  74. package/presets/claude/next/hooks/chain-team-phases.sh +226 -26
  75. package/presets/claude/next/rules/README.md +6 -0
  76. package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +4 -0
  77. package/presets/claude/next/rules/tooling-and-review/preset-layering.md +1 -1
  78. package/presets/claude/next/rules/tooling-and-review/preset-no-cross-stack-leakage.md +5 -5
  79. package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +1 -1
  80. package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +4 -0
  81. package/presets/claude/next/rules/tooling-and-review/technical-retro.md +2 -0
  82. package/presets/claude/next/team/README.md +19 -0
  83. package/presets/claude/php-hexagonal/CLAUDE.md +31 -0
  84. package/presets/claude/php-hexagonal/MCP.md +15 -0
  85. package/presets/claude/php-hexagonal/README.md +26 -0
  86. package/presets/claude/php-hexagonal/REPO_AGENTS.md +46 -0
  87. package/presets/claude/php-hexagonal/agents/README.md +32 -0
  88. package/presets/claude/php-hexagonal/agents/api-contract-reviewer.md +23 -0
  89. package/presets/claude/php-hexagonal/agents/build-verifier.md +45 -0
  90. package/presets/claude/php-hexagonal/agents/ci-investigator.md +21 -0
  91. package/presets/claude/php-hexagonal/agents/code-reviewer.md +40 -0
  92. package/presets/claude/php-hexagonal/agents/codebase-analyzer.md +28 -0
  93. package/presets/claude/php-hexagonal/agents/debugger.md +29 -0
  94. package/presets/claude/php-hexagonal/agents/feature-developer.md +47 -0
  95. package/presets/claude/php-hexagonal/agents/integration-test-generator.md +22 -0
  96. package/presets/claude/php-hexagonal/agents/integration-test-healer.md +22 -0
  97. package/presets/claude/php-hexagonal/agents/integration-test-planner.md +22 -0
  98. package/presets/claude/php-hexagonal/agents/migration-specialist.md +31 -0
  99. package/presets/claude/php-hexagonal/agents/performance-auditor.md +22 -0
  100. package/presets/claude/php-hexagonal/agents/qa-tester.md +24 -0
  101. package/presets/claude/php-hexagonal/agents/security-reviewer.md +20 -0
  102. package/presets/claude/php-hexagonal/agents/solution-architect.md +28 -0
  103. package/presets/claude/php-hexagonal/agents/task-analyst.md +25 -0
  104. package/presets/claude/php-hexagonal/agents/task-router.md +73 -0
  105. package/presets/claude/php-hexagonal/agents/tech-writer.md +15 -0
  106. package/presets/claude/php-hexagonal/agents/unit-test-generator.md +21 -0
  107. package/presets/claude/php-hexagonal/agents/unit-test-healer.md +13 -0
  108. package/presets/claude/php-hexagonal/agents/unit-test-planner.md +26 -0
  109. package/presets/claude/php-hexagonal/commands/README.md +13 -0
  110. package/presets/claude/php-hexagonal/commands/feature-continue.md +51 -0
  111. package/presets/claude/php-hexagonal/commands/feature-start.md +30 -0
  112. package/presets/claude/php-hexagonal/commands/task-continue.md +50 -0
  113. package/presets/claude/php-hexagonal/commands/task.md +53 -0
  114. package/presets/claude/php-hexagonal/commands/technical-retro.md +62 -0
  115. package/presets/claude/php-hexagonal/hooks/README.md +16 -0
  116. package/presets/claude/php-hexagonal/hooks/chain-team-phases.sh +582 -0
  117. package/presets/claude/php-hexagonal/hooks/examples/README.md +18 -0
  118. package/presets/claude/php-hexagonal/hooks/examples/format-edited.example.sh +11 -0
  119. package/presets/claude/php-hexagonal/hooks/examples/secret-guard.example.sh +10 -0
  120. package/presets/claude/php-hexagonal/hooks/examples/test-on-save.example.sh +19 -0
  121. package/presets/claude/php-hexagonal/hooks/guard-shell-command.sh +80 -0
  122. package/presets/claude/php-hexagonal/mcp.json +11 -0
  123. package/presets/claude/php-hexagonal/rules/README.md +67 -0
  124. package/presets/claude/php-hexagonal/rules/api-and-data/README.md +14 -0
  125. package/presets/claude/php-hexagonal/rules/api-and-data/adapters-driven.md +38 -0
  126. package/presets/claude/php-hexagonal/rules/api-and-data/adapters-driving.md +38 -0
  127. package/presets/claude/php-hexagonal/rules/api-and-data/api-grpc.md +29 -0
  128. package/presets/claude/php-hexagonal/rules/api-and-data/api-http.md +36 -0
  129. package/presets/claude/php-hexagonal/rules/api-and-data/messaging-adapters.md +37 -0
  130. package/presets/claude/php-hexagonal/rules/api-and-data/persistence-adapters.md +33 -0
  131. package/presets/claude/php-hexagonal/rules/architecture/README.md +16 -0
  132. package/presets/claude/php-hexagonal/rules/architecture/application-usecases.md +31 -0
  133. package/presets/claude/php-hexagonal/rules/architecture/boundaries.md +34 -0
  134. package/presets/claude/php-hexagonal/rules/architecture/composition-root.md +33 -0
  135. package/presets/claude/php-hexagonal/rules/architecture/domain-layer.md +37 -0
  136. package/presets/claude/php-hexagonal/rules/architecture/feature-delivery.md +53 -0
  137. package/presets/claude/php-hexagonal/rules/architecture/module-public-api.md +31 -0
  138. package/presets/claude/php-hexagonal/rules/architecture/ports-interfaces.md +34 -0
  139. package/presets/claude/php-hexagonal/rules/architecture/reference-features.md +39 -0
  140. package/presets/claude/php-hexagonal/rules/stack/README.md +10 -0
  141. package/presets/claude/php-hexagonal/rules/stack/php-app-core.md +35 -0
  142. package/presets/claude/php-hexagonal/rules/stack/php-conventions.md +51 -0
  143. package/presets/claude/php-hexagonal/rules/testing/README.md +11 -0
  144. package/presets/claude/php-hexagonal/rules/testing/e2e.md +35 -0
  145. package/presets/claude/php-hexagonal/rules/testing/integration.md +31 -0
  146. package/presets/claude/php-hexagonal/rules/testing/unit.md +32 -0
  147. package/presets/claude/php-hexagonal/rules/tooling-and-review/README.md +21 -0
  148. package/presets/claude/php-hexagonal/rules/tooling-and-review/agent-team-intake.md +26 -0
  149. package/presets/claude/php-hexagonal/rules/tooling-and-review/agent-team-orchestrator.md +183 -0
  150. package/presets/claude/php-hexagonal/rules/tooling-and-review/anti-sycophancy-discipline.md +29 -0
  151. package/presets/claude/php-hexagonal/rules/tooling-and-review/code-quality.md +53 -0
  152. package/presets/claude/php-hexagonal/rules/tooling-and-review/code-review.md +60 -0
  153. package/presets/claude/php-hexagonal/rules/tooling-and-review/design-guidance.md +111 -0
  154. package/presets/claude/php-hexagonal/rules/tooling-and-review/php-tooling.md +39 -0
  155. package/presets/claude/php-hexagonal/rules/tooling-and-review/post-change-test.md +31 -0
  156. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-layering.md +36 -0
  157. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-no-cross-stack-leakage.md +69 -0
  158. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-pr-checklist.md +39 -0
  159. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-token-budget.md +41 -0
  160. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-twin-sync.md +50 -0
  161. package/presets/claude/php-hexagonal/rules/tooling-and-review/security-php.md +29 -0
  162. package/presets/claude/php-hexagonal/rules/tooling-and-review/technical-retro.md +22 -0
  163. package/presets/claude/php-hexagonal/rules/ui-and-accessibility/README.md +5 -0
  164. package/presets/claude/php-hexagonal/skills/README.md +5 -0
  165. package/presets/claude/php-hexagonal/skills/ci-investigation/SKILL.md +11 -0
  166. package/presets/claude/php-hexagonal/skills/code-review/SKILL.md +25 -0
  167. package/presets/claude/php-hexagonal/skills/debug-investigation/SKILL.md +15 -0
  168. package/presets/claude/php-hexagonal/skills/feature-delivery/SKILL.md +30 -0
  169. package/presets/claude/php-hexagonal/skills/integration-testing/SKILL.md +15 -0
  170. package/presets/claude/php-hexagonal/skills/technical-retro/SKILL.md +54 -0
  171. package/presets/claude/php-hexagonal/skills/unit-testing/SKILL.md +14 -0
  172. package/presets/claude/php-hexagonal/skills/write-adr/SKILL.md +41 -0
  173. package/presets/claude/php-hexagonal/team/README.md +37 -0
  174. package/presets/claude/php-hexagonal/team/conventions.md +21 -0
  175. package/presets/claude/php-hexagonal/team/fixtures/bugfix-standard.json +37 -0
  176. package/presets/claude/php-hexagonal/team/fixtures/feature-full.json +25 -0
  177. package/presets/claude/php-hexagonal/team/fixtures/feature-light.json +17 -0
  178. package/presets/claude/php-laravel/CLAUDE.md +20 -0
  179. package/presets/claude/php-laravel/MCP.md +5 -0
  180. package/presets/claude/php-laravel/README.md +30 -0
  181. package/presets/claude/php-laravel/REPO_AGENTS.md +47 -0
  182. package/presets/claude/php-laravel/agents/README.md +32 -0
  183. package/presets/claude/php-laravel/agents/api-contract-reviewer.md +23 -0
  184. package/presets/claude/php-laravel/agents/build-verifier.md +45 -0
  185. package/presets/claude/php-laravel/agents/ci-investigator.md +21 -0
  186. package/presets/claude/php-laravel/agents/code-reviewer.md +40 -0
  187. package/presets/claude/php-laravel/agents/codebase-analyzer.md +28 -0
  188. package/presets/claude/php-laravel/agents/debugger.md +29 -0
  189. package/presets/claude/php-laravel/agents/feature-developer.md +47 -0
  190. package/presets/claude/php-laravel/agents/integration-test-generator.md +22 -0
  191. package/presets/claude/php-laravel/agents/integration-test-healer.md +22 -0
  192. package/presets/claude/php-laravel/agents/integration-test-planner.md +22 -0
  193. package/presets/claude/php-laravel/agents/migration-specialist.md +31 -0
  194. package/presets/claude/php-laravel/agents/performance-auditor.md +22 -0
  195. package/presets/claude/php-laravel/agents/qa-tester.md +30 -0
  196. package/presets/claude/php-laravel/agents/security-reviewer.md +32 -0
  197. package/presets/claude/php-laravel/agents/solution-architect.md +29 -0
  198. package/presets/claude/php-laravel/agents/task-analyst.md +25 -0
  199. package/presets/claude/php-laravel/agents/task-router.md +92 -0
  200. package/presets/claude/php-laravel/agents/tech-writer.md +15 -0
  201. package/presets/claude/php-laravel/agents/unit-test-generator.md +21 -0
  202. package/presets/claude/php-laravel/agents/unit-test-healer.md +13 -0
  203. package/presets/claude/php-laravel/agents/unit-test-planner.md +26 -0
  204. package/presets/claude/php-laravel/commands/README.md +13 -0
  205. package/presets/claude/php-laravel/commands/feature-continue.md +51 -0
  206. package/presets/claude/php-laravel/commands/feature-start.md +30 -0
  207. package/presets/claude/php-laravel/commands/task-continue.md +50 -0
  208. package/presets/claude/php-laravel/commands/task.md +53 -0
  209. package/presets/claude/php-laravel/commands/technical-retro.md +62 -0
  210. package/presets/claude/php-laravel/hooks/README.md +16 -0
  211. package/presets/claude/php-laravel/hooks/chain-team-phases.sh +582 -0
  212. package/presets/claude/php-laravel/hooks/examples/README.md +18 -0
  213. package/presets/claude/php-laravel/hooks/examples/format-edited.example.sh +11 -0
  214. package/presets/claude/php-laravel/hooks/examples/secret-guard.example.sh +10 -0
  215. package/presets/claude/php-laravel/hooks/examples/test-on-save.example.sh +19 -0
  216. package/presets/claude/php-laravel/hooks/guard-shell-command.sh +80 -0
  217. package/presets/claude/php-laravel/mcp.json +11 -0
  218. package/presets/claude/php-laravel/rules/README.md +67 -0
  219. package/presets/claude/php-laravel/rules/api-and-data/README.md +3 -0
  220. package/presets/claude/php-laravel/rules/api-and-data/eloquent-persistence.md +31 -0
  221. package/presets/claude/php-laravel/rules/api-and-data/events-listeners.md +31 -0
  222. package/presets/claude/php-laravel/rules/api-and-data/form-requests.md +29 -0
  223. package/presets/claude/php-laravel/rules/api-and-data/http-layer.md +32 -0
  224. package/presets/claude/php-laravel/rules/api-and-data/jobs-queues.md +41 -0
  225. package/presets/claude/php-laravel/rules/api-and-data/policies-authorization.md +29 -0
  226. package/presets/claude/php-laravel/rules/api-and-data/routes-api.md +29 -0
  227. package/presets/claude/php-laravel/rules/architecture/README.md +3 -0
  228. package/presets/claude/php-laravel/rules/architecture/actions-services.md +30 -0
  229. package/presets/claude/php-laravel/rules/architecture/boundaries.md +34 -0
  230. package/presets/claude/php-laravel/rules/architecture/domain-layer.md +24 -0
  231. package/presets/claude/php-laravel/rules/architecture/feature-delivery.md +51 -0
  232. package/presets/claude/php-laravel/rules/architecture/module-public-api.md +29 -0
  233. package/presets/claude/php-laravel/rules/architecture/reference-features.md +40 -0
  234. package/presets/claude/php-laravel/rules/architecture/service-providers.md +28 -0
  235. package/presets/claude/php-laravel/rules/stack/README.md +3 -0
  236. package/presets/claude/php-laravel/rules/stack/laravel-app-core.md +32 -0
  237. package/presets/claude/php-laravel/rules/stack/laravel-conventions.md +38 -0
  238. package/presets/claude/php-laravel/rules/testing/README.md +3 -0
  239. package/presets/claude/php-laravel/rules/testing/e2e.md +34 -0
  240. package/presets/claude/php-laravel/rules/testing/integration.md +30 -0
  241. package/presets/claude/php-laravel/rules/testing/unit.md +30 -0
  242. package/presets/claude/php-laravel/rules/tooling-and-review/README.md +3 -0
  243. package/presets/claude/php-laravel/rules/tooling-and-review/agent-team-intake.md +21 -0
  244. package/presets/claude/php-laravel/rules/tooling-and-review/agent-team-orchestrator.md +180 -0
  245. package/presets/claude/php-laravel/rules/tooling-and-review/anti-sycophancy-discipline.md +29 -0
  246. package/presets/claude/php-laravel/rules/tooling-and-review/code-quality.md +52 -0
  247. package/presets/claude/php-laravel/rules/tooling-and-review/code-review.md +58 -0
  248. package/presets/claude/php-laravel/rules/tooling-and-review/design-guidance.md +111 -0
  249. package/presets/claude/php-laravel/rules/tooling-and-review/php-tooling.md +37 -0
  250. package/presets/claude/php-laravel/rules/tooling-and-review/post-change-test.md +29 -0
  251. package/presets/claude/php-laravel/rules/tooling-and-review/preset-layering.md +33 -0
  252. package/presets/claude/php-laravel/rules/tooling-and-review/preset-no-cross-stack-leakage.md +66 -0
  253. package/presets/claude/php-laravel/rules/tooling-and-review/preset-pr-checklist.md +36 -0
  254. package/presets/claude/php-laravel/rules/tooling-and-review/preset-token-budget.md +38 -0
  255. package/presets/claude/php-laravel/rules/tooling-and-review/preset-twin-sync.md +47 -0
  256. package/presets/claude/php-laravel/rules/tooling-and-review/security-php.md +58 -0
  257. package/presets/claude/php-laravel/rules/tooling-and-review/technical-retro.md +17 -0
  258. package/presets/claude/php-laravel/rules/ui-and-accessibility/README.md +3 -0
  259. package/presets/claude/php-laravel/skills/README.md +5 -0
  260. package/presets/claude/php-laravel/skills/ci-investigation/SKILL.md +11 -0
  261. package/presets/claude/php-laravel/skills/code-review/SKILL.md +25 -0
  262. package/presets/claude/php-laravel/skills/debug-investigation/SKILL.md +15 -0
  263. package/presets/claude/php-laravel/skills/feature-delivery/SKILL.md +30 -0
  264. package/presets/claude/php-laravel/skills/integration-testing/SKILL.md +15 -0
  265. package/presets/claude/php-laravel/skills/technical-retro/SKILL.md +54 -0
  266. package/presets/claude/php-laravel/skills/unit-testing/SKILL.md +14 -0
  267. package/presets/claude/php-laravel/skills/write-adr/SKILL.md +41 -0
  268. package/presets/claude/php-laravel/team/README.md +17 -0
  269. package/presets/claude/php-laravel/team/conventions.md +21 -0
  270. package/presets/claude/php-laravel/team/fixtures/bugfix-standard.json +12 -0
  271. package/presets/claude/php-laravel/team/fixtures/feature-full.json +15 -0
  272. package/presets/claude/php-laravel/team/fixtures/feature-light.json +8 -0
  273. package/presets/cursor/go/agents/build-verifier.md +2 -2
  274. package/presets/cursor/go/agents/task-router.md +4 -0
  275. package/presets/cursor/go/commands/task-continue.md +17 -16
  276. package/presets/cursor/go/commands/task.md +4 -0
  277. package/presets/cursor/go/commands/technical-retro.md +4 -0
  278. package/presets/cursor/go/hooks/chain-team-phases.sh +226 -26
  279. package/presets/cursor/go/rules/README.md +6 -0
  280. package/presets/cursor/go/rules/agent-team-orchestrator.mdc +4 -0
  281. package/presets/cursor/go/rules/preset-layering.mdc +1 -1
  282. package/presets/cursor/go/rules/preset-no-cross-stack-leakage.mdc +5 -5
  283. package/presets/cursor/go/rules/preset-pr-checklist.mdc +1 -1
  284. package/presets/cursor/go/rules/preset-twin-sync.mdc +4 -0
  285. package/presets/cursor/go/rules/technical-retro.mdc +2 -0
  286. package/presets/cursor/go/team/README.md +8 -0
  287. package/presets/cursor/ios-swift/agents/build-verifier.md +3 -3
  288. package/presets/cursor/ios-swift/agents/task-router.md +4 -0
  289. package/presets/cursor/ios-swift/commands/task-continue.md +17 -16
  290. package/presets/cursor/ios-swift/commands/task.md +4 -0
  291. package/presets/cursor/ios-swift/commands/technical-retro.md +4 -0
  292. package/presets/cursor/ios-swift/hooks/chain-team-phases.sh +226 -26
  293. package/presets/cursor/ios-swift/rules/README.md +6 -0
  294. package/presets/cursor/ios-swift/rules/agent-team-orchestrator.mdc +4 -0
  295. package/presets/cursor/ios-swift/rules/preset-layering.mdc +1 -1
  296. package/presets/cursor/ios-swift/rules/preset-no-cross-stack-leakage.mdc +5 -5
  297. package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +1 -1
  298. package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +4 -0
  299. package/presets/cursor/ios-swift/rules/technical-retro.mdc +2 -0
  300. package/presets/cursor/ios-swift/team/README.md +8 -0
  301. package/presets/cursor/java/agents/build-verifier.md +3 -3
  302. package/presets/cursor/java/agents/task-router.md +4 -0
  303. package/presets/cursor/java/commands/task-continue.md +17 -16
  304. package/presets/cursor/java/commands/task.md +4 -0
  305. package/presets/cursor/java/commands/technical-retro.md +4 -0
  306. package/presets/cursor/java/hooks/chain-team-phases.sh +226 -26
  307. package/presets/cursor/java/rules/README.md +6 -0
  308. package/presets/cursor/java/rules/agent-team-orchestrator.mdc +4 -0
  309. package/presets/cursor/java/rules/preset-layering.mdc +1 -1
  310. package/presets/cursor/java/rules/preset-no-cross-stack-leakage.mdc +5 -5
  311. package/presets/cursor/java/rules/preset-pr-checklist.mdc +1 -1
  312. package/presets/cursor/java/rules/preset-twin-sync.mdc +4 -0
  313. package/presets/cursor/java/rules/technical-retro.mdc +2 -0
  314. package/presets/cursor/java/team/README.md +8 -0
  315. package/presets/cursor/mcp-ts/agents/build-verifier.md +2 -2
  316. package/presets/cursor/mcp-ts/agents/task-router.md +4 -0
  317. package/presets/cursor/mcp-ts/commands/task-continue.md +19 -18
  318. package/presets/cursor/mcp-ts/commands/task.md +4 -0
  319. package/presets/cursor/mcp-ts/commands/technical-retro.md +4 -0
  320. package/presets/cursor/mcp-ts/hooks/chain-team-phases.sh +226 -26
  321. package/presets/cursor/mcp-ts/rules/README.md +6 -0
  322. package/presets/cursor/mcp-ts/rules/agent-team-orchestrator.mdc +4 -0
  323. package/presets/cursor/mcp-ts/rules/preset-layering.mdc +1 -1
  324. package/presets/cursor/mcp-ts/rules/preset-no-cross-stack-leakage.mdc +5 -5
  325. package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +1 -1
  326. package/presets/cursor/mcp-ts/rules/preset-twin-sync.mdc +4 -0
  327. package/presets/cursor/mcp-ts/rules/technical-retro.mdc +2 -4
  328. package/presets/cursor/mcp-ts/team/README.md +8 -0
  329. package/presets/cursor/next/agents/build-verifier.md +3 -3
  330. package/presets/cursor/next/agents/task-router.md +4 -0
  331. package/presets/cursor/next/commands/task-continue.md +17 -16
  332. package/presets/cursor/next/commands/task.md +4 -0
  333. package/presets/cursor/next/commands/technical-retro.md +4 -0
  334. package/presets/cursor/next/hooks/chain-team-phases.sh +230 -26
  335. package/presets/cursor/next/rules/README.md +6 -0
  336. package/presets/cursor/next/rules/agent-team-orchestrator.mdc +4 -0
  337. package/presets/cursor/next/rules/preset-layering.mdc +1 -1
  338. package/presets/cursor/next/rules/preset-no-cross-stack-leakage.mdc +5 -5
  339. package/presets/cursor/next/rules/preset-pr-checklist.mdc +1 -1
  340. package/presets/cursor/next/rules/preset-twin-sync.mdc +4 -0
  341. package/presets/cursor/next/rules/technical-retro.mdc +2 -0
  342. package/presets/cursor/next/team/README.md +19 -0
  343. package/presets/cursor/next/team/fixtures/metrics-scenarios/tasks/human-gate/metrics.json +69 -0
  344. package/presets/cursor/next/team/fixtures/metrics-scenarios/tasks/missing-ledger/status.json +5 -0
  345. package/presets/cursor/next/team/fixtures/metrics-scenarios/tasks/parallel-receipts/metrics.json +79 -0
  346. package/presets/cursor/next/team/fixtures/metrics-scenarios/tasks/serial-retry/metrics.json +124 -0
  347. package/presets/cursor/next/team/fixtures/metrics-scenarios/tasks/validation-failed/metrics.json +124 -0
  348. package/presets/cursor/next/team/fixtures/metrics.example.json +54 -0
  349. package/presets/cursor/php-hexagonal/AGENTS.md +39 -0
  350. package/presets/cursor/php-hexagonal/BUGBOT.md +11 -0
  351. package/presets/cursor/php-hexagonal/MCP.md +15 -0
  352. package/presets/cursor/php-hexagonal/README.md +26 -0
  353. package/presets/cursor/php-hexagonal/REPO_AGENTS.md +46 -0
  354. package/presets/cursor/php-hexagonal/agents/README.md +36 -0
  355. package/presets/cursor/php-hexagonal/agents/api-contract-reviewer.md +23 -0
  356. package/presets/cursor/php-hexagonal/agents/build-verifier.md +45 -0
  357. package/presets/cursor/php-hexagonal/agents/ci-investigator.md +21 -0
  358. package/presets/cursor/php-hexagonal/agents/code-reviewer.md +40 -0
  359. package/presets/cursor/php-hexagonal/agents/codebase-analyzer.md +28 -0
  360. package/presets/cursor/php-hexagonal/agents/debugger.md +29 -0
  361. package/presets/cursor/php-hexagonal/agents/feature-developer.md +47 -0
  362. package/presets/cursor/php-hexagonal/agents/integration-test-generator.md +22 -0
  363. package/presets/cursor/php-hexagonal/agents/integration-test-healer.md +22 -0
  364. package/presets/cursor/php-hexagonal/agents/integration-test-planner.md +22 -0
  365. package/presets/cursor/php-hexagonal/agents/migration-specialist.md +31 -0
  366. package/presets/cursor/php-hexagonal/agents/performance-auditor.md +22 -0
  367. package/presets/cursor/php-hexagonal/agents/qa-tester.md +24 -0
  368. package/presets/cursor/php-hexagonal/agents/security-reviewer.md +20 -0
  369. package/presets/cursor/php-hexagonal/agents/solution-architect.md +28 -0
  370. package/presets/cursor/php-hexagonal/agents/task-analyst.md +25 -0
  371. package/presets/cursor/php-hexagonal/agents/task-router.md +73 -0
  372. package/presets/cursor/php-hexagonal/agents/tech-writer.md +15 -0
  373. package/presets/cursor/php-hexagonal/agents/unit-test-generator.md +21 -0
  374. package/presets/cursor/php-hexagonal/agents/unit-test-healer.md +13 -0
  375. package/presets/cursor/php-hexagonal/agents/unit-test-planner.md +26 -0
  376. package/presets/cursor/php-hexagonal/commands/README.md +54 -0
  377. package/presets/cursor/php-hexagonal/commands/feature-continue.md +19 -0
  378. package/presets/cursor/php-hexagonal/commands/feature-start.md +33 -0
  379. package/presets/cursor/php-hexagonal/commands/task-continue.md +50 -0
  380. package/presets/cursor/php-hexagonal/commands/task.md +53 -0
  381. package/presets/cursor/php-hexagonal/commands/technical-retro.md +85 -0
  382. package/presets/cursor/php-hexagonal/hooks/README.md +12 -0
  383. package/presets/cursor/php-hexagonal/hooks/chain-team-phases.sh +582 -0
  384. package/presets/cursor/php-hexagonal/hooks/examples/README.md +18 -0
  385. package/presets/cursor/php-hexagonal/hooks/examples/format-edited.example.sh +11 -0
  386. package/presets/cursor/php-hexagonal/hooks/examples/secret-guard.example.sh +10 -0
  387. package/presets/cursor/php-hexagonal/hooks/examples/test-on-save.example.sh +19 -0
  388. package/presets/cursor/php-hexagonal/hooks/guard-shell-command.sh +80 -0
  389. package/presets/cursor/php-hexagonal/hooks.json +17 -0
  390. package/presets/cursor/php-hexagonal/mcp.json +11 -0
  391. package/presets/cursor/php-hexagonal/rules/README.md +106 -0
  392. package/presets/cursor/php-hexagonal/rules/adapters-driven.mdc +41 -0
  393. package/presets/cursor/php-hexagonal/rules/adapters-driving.mdc +42 -0
  394. package/presets/cursor/php-hexagonal/rules/agent-team-intake.mdc +20 -0
  395. package/presets/cursor/php-hexagonal/rules/agent-team-orchestrator.mdc +177 -0
  396. package/presets/cursor/php-hexagonal/rules/anti-sycophancy-discipline.mdc +30 -0
  397. package/presets/cursor/php-hexagonal/rules/api-grpc.mdc +31 -0
  398. package/presets/cursor/php-hexagonal/rules/api-http.mdc +40 -0
  399. package/presets/cursor/php-hexagonal/rules/application-usecases.mdc +33 -0
  400. package/presets/cursor/php-hexagonal/rules/architecture-boundaries.mdc +36 -0
  401. package/presets/cursor/php-hexagonal/rules/code-quality-and-refactoring.mdc +54 -0
  402. package/presets/cursor/php-hexagonal/rules/code-review-mr.mdc +54 -0
  403. package/presets/cursor/php-hexagonal/rules/composition-root.mdc +37 -0
  404. package/presets/cursor/php-hexagonal/rules/design-guidance.mdc +112 -0
  405. package/presets/cursor/php-hexagonal/rules/domain-layer.mdc +39 -0
  406. package/presets/cursor/php-hexagonal/rules/feature-delivery-workflow.mdc +47 -0
  407. package/presets/cursor/php-hexagonal/rules/messaging-adapters.mdc +38 -0
  408. package/presets/cursor/php-hexagonal/rules/module-public-api.mdc +32 -0
  409. package/presets/cursor/php-hexagonal/rules/persistence-adapters.mdc +35 -0
  410. package/presets/cursor/php-hexagonal/rules/php-app-core.mdc +37 -0
  411. package/presets/cursor/php-hexagonal/rules/php-conventions.mdc +53 -0
  412. package/presets/cursor/php-hexagonal/rules/php-tooling.mdc +38 -0
  413. package/presets/cursor/php-hexagonal/rules/ports-interfaces.mdc +37 -0
  414. package/presets/cursor/php-hexagonal/rules/post-change-test.mdc +30 -0
  415. package/presets/cursor/php-hexagonal/rules/preset-layering.mdc +36 -0
  416. package/presets/cursor/php-hexagonal/rules/preset-no-cross-stack-leakage.mdc +69 -0
  417. package/presets/cursor/php-hexagonal/rules/preset-pr-checklist.mdc +39 -0
  418. package/presets/cursor/php-hexagonal/rules/preset-token-budget.mdc +41 -0
  419. package/presets/cursor/php-hexagonal/rules/preset-twin-sync.mdc +50 -0
  420. package/presets/cursor/php-hexagonal/rules/reference-features.mdc +40 -0
  421. package/presets/cursor/php-hexagonal/rules/security-php.mdc +33 -0
  422. package/presets/cursor/php-hexagonal/rules/technical-retro.mdc +16 -0
  423. package/presets/cursor/php-hexagonal/rules/tests-e2e.mdc +36 -0
  424. package/presets/cursor/php-hexagonal/rules/tests-integration.mdc +33 -0
  425. package/presets/cursor/php-hexagonal/rules/tests-unit.mdc +35 -0
  426. package/presets/cursor/php-hexagonal/skills/README.md +5 -0
  427. package/presets/cursor/php-hexagonal/skills/ci-investigation/SKILL.md +11 -0
  428. package/presets/cursor/php-hexagonal/skills/code-review/SKILL.md +25 -0
  429. package/presets/cursor/php-hexagonal/skills/debug-investigation/SKILL.md +15 -0
  430. package/presets/cursor/php-hexagonal/skills/feature-delivery/SKILL.md +30 -0
  431. package/presets/cursor/php-hexagonal/skills/integration-testing/SKILL.md +15 -0
  432. package/presets/cursor/php-hexagonal/skills/technical-retro/SKILL.md +54 -0
  433. package/presets/cursor/php-hexagonal/skills/unit-testing/SKILL.md +14 -0
  434. package/presets/cursor/php-hexagonal/skills/write-adr/SKILL.md +41 -0
  435. package/presets/cursor/php-hexagonal/team/README.md +41 -0
  436. package/presets/cursor/php-hexagonal/team/conventions.md +21 -0
  437. package/presets/cursor/php-hexagonal/team/fixtures/bugfix-standard.json +37 -0
  438. package/presets/cursor/php-hexagonal/team/fixtures/feature-full.json +25 -0
  439. package/presets/cursor/php-hexagonal/team/fixtures/feature-light.json +17 -0
  440. package/presets/cursor/php-laravel/AGENTS.md +39 -0
  441. package/presets/cursor/php-laravel/BUGBOT.md +9 -0
  442. package/presets/cursor/php-laravel/MCP.md +5 -0
  443. package/presets/cursor/php-laravel/README.md +33 -0
  444. package/presets/cursor/php-laravel/REPO_AGENTS.md +47 -0
  445. package/presets/cursor/php-laravel/agents/README.md +36 -0
  446. package/presets/cursor/php-laravel/agents/api-contract-reviewer.md +23 -0
  447. package/presets/cursor/php-laravel/agents/build-verifier.md +45 -0
  448. package/presets/cursor/php-laravel/agents/ci-investigator.md +21 -0
  449. package/presets/cursor/php-laravel/agents/code-reviewer.md +40 -0
  450. package/presets/cursor/php-laravel/agents/codebase-analyzer.md +28 -0
  451. package/presets/cursor/php-laravel/agents/debugger.md +29 -0
  452. package/presets/cursor/php-laravel/agents/feature-developer.md +47 -0
  453. package/presets/cursor/php-laravel/agents/integration-test-generator.md +22 -0
  454. package/presets/cursor/php-laravel/agents/integration-test-healer.md +22 -0
  455. package/presets/cursor/php-laravel/agents/integration-test-planner.md +22 -0
  456. package/presets/cursor/php-laravel/agents/migration-specialist.md +31 -0
  457. package/presets/cursor/php-laravel/agents/performance-auditor.md +22 -0
  458. package/presets/cursor/php-laravel/agents/qa-tester.md +30 -0
  459. package/presets/cursor/php-laravel/agents/security-reviewer.md +32 -0
  460. package/presets/cursor/php-laravel/agents/solution-architect.md +29 -0
  461. package/presets/cursor/php-laravel/agents/task-analyst.md +25 -0
  462. package/presets/cursor/php-laravel/agents/task-router.md +92 -0
  463. package/presets/cursor/php-laravel/agents/tech-writer.md +15 -0
  464. package/presets/cursor/php-laravel/agents/unit-test-generator.md +21 -0
  465. package/presets/cursor/php-laravel/agents/unit-test-healer.md +13 -0
  466. package/presets/cursor/php-laravel/agents/unit-test-planner.md +26 -0
  467. package/presets/cursor/php-laravel/commands/README.md +54 -0
  468. package/presets/cursor/php-laravel/commands/feature-continue.md +19 -0
  469. package/presets/cursor/php-laravel/commands/feature-start.md +33 -0
  470. package/presets/cursor/php-laravel/commands/task-continue.md +50 -0
  471. package/presets/cursor/php-laravel/commands/task.md +53 -0
  472. package/presets/cursor/php-laravel/commands/technical-retro.md +85 -0
  473. package/presets/cursor/php-laravel/hooks/README.md +12 -0
  474. package/presets/cursor/php-laravel/hooks/chain-team-phases.sh +582 -0
  475. package/presets/cursor/php-laravel/hooks/examples/README.md +18 -0
  476. package/presets/cursor/php-laravel/hooks/examples/format-edited.example.sh +11 -0
  477. package/presets/cursor/php-laravel/hooks/examples/secret-guard.example.sh +10 -0
  478. package/presets/cursor/php-laravel/hooks/examples/test-on-save.example.sh +19 -0
  479. package/presets/cursor/php-laravel/hooks/guard-shell-command.sh +80 -0
  480. package/presets/cursor/php-laravel/hooks.json +17 -0
  481. package/presets/cursor/php-laravel/mcp.json +11 -0
  482. package/presets/cursor/php-laravel/rules/README.md +111 -0
  483. package/presets/cursor/php-laravel/rules/actions-services.mdc +33 -0
  484. package/presets/cursor/php-laravel/rules/agent-team-intake.mdc +20 -0
  485. package/presets/cursor/php-laravel/rules/agent-team-orchestrator.mdc +178 -0
  486. package/presets/cursor/php-laravel/rules/anti-sycophancy-discipline.mdc +30 -0
  487. package/presets/cursor/php-laravel/rules/architecture-boundaries.mdc +37 -0
  488. package/presets/cursor/php-laravel/rules/code-quality-and-refactoring.mdc +54 -0
  489. package/presets/cursor/php-laravel/rules/code-review-mr.mdc +56 -0
  490. package/presets/cursor/php-laravel/rules/design-guidance.mdc +112 -0
  491. package/presets/cursor/php-laravel/rules/domain-layer.mdc +27 -0
  492. package/presets/cursor/php-laravel/rules/eloquent-persistence.mdc +34 -0
  493. package/presets/cursor/php-laravel/rules/events-listeners.mdc +34 -0
  494. package/presets/cursor/php-laravel/rules/feature-delivery-workflow.mdc +50 -0
  495. package/presets/cursor/php-laravel/rules/form-requests.mdc +32 -0
  496. package/presets/cursor/php-laravel/rules/http-layer.mdc +35 -0
  497. package/presets/cursor/php-laravel/rules/jobs-queues.mdc +44 -0
  498. package/presets/cursor/php-laravel/rules/laravel-app-core.mdc +35 -0
  499. package/presets/cursor/php-laravel/rules/laravel-conventions.mdc +41 -0
  500. package/presets/cursor/php-laravel/rules/module-public-api.mdc +31 -0
  501. package/presets/cursor/php-laravel/rules/php-tooling.mdc +39 -0
  502. package/presets/cursor/php-laravel/rules/policies-authorization.mdc +32 -0
  503. package/presets/cursor/php-laravel/rules/post-change-test.mdc +31 -0
  504. package/presets/cursor/php-laravel/rules/preset-layering.mdc +36 -0
  505. package/presets/cursor/php-laravel/rules/preset-no-cross-stack-leakage.mdc +69 -0
  506. package/presets/cursor/php-laravel/rules/preset-pr-checklist.mdc +39 -0
  507. package/presets/cursor/php-laravel/rules/preset-token-budget.mdc +41 -0
  508. package/presets/cursor/php-laravel/rules/preset-twin-sync.mdc +50 -0
  509. package/presets/cursor/php-laravel/rules/reference-features.mdc +42 -0
  510. package/presets/cursor/php-laravel/rules/routes-api.mdc +32 -0
  511. package/presets/cursor/php-laravel/rules/security-php.mdc +61 -0
  512. package/presets/cursor/php-laravel/rules/service-providers.mdc +31 -0
  513. package/presets/cursor/php-laravel/rules/technical-retro.mdc +16 -0
  514. package/presets/cursor/php-laravel/rules/tests-e2e.mdc +36 -0
  515. package/presets/cursor/php-laravel/rules/tests-integration.mdc +33 -0
  516. package/presets/cursor/php-laravel/rules/tests-unit.mdc +33 -0
  517. package/presets/cursor/php-laravel/skills/README.md +5 -0
  518. package/presets/cursor/php-laravel/skills/ci-investigation/SKILL.md +11 -0
  519. package/presets/cursor/php-laravel/skills/code-review/SKILL.md +25 -0
  520. package/presets/cursor/php-laravel/skills/debug-investigation/SKILL.md +15 -0
  521. package/presets/cursor/php-laravel/skills/feature-delivery/SKILL.md +30 -0
  522. package/presets/cursor/php-laravel/skills/integration-testing/SKILL.md +15 -0
  523. package/presets/cursor/php-laravel/skills/technical-retro/SKILL.md +54 -0
  524. package/presets/cursor/php-laravel/skills/unit-testing/SKILL.md +14 -0
  525. package/presets/cursor/php-laravel/skills/write-adr/SKILL.md +41 -0
  526. package/presets/cursor/php-laravel/team/README.md +17 -0
  527. package/presets/cursor/php-laravel/team/conventions.md +21 -0
  528. package/presets/cursor/php-laravel/team/fixtures/bugfix-standard.json +12 -0
  529. package/presets/cursor/php-laravel/team/fixtures/feature-full.json +15 -0
  530. package/presets/cursor/php-laravel/team/fixtures/feature-light.json +8 -0
@@ -50,6 +50,8 @@ if (!slug) {
50
50
  const taskDir = path.join(TEAM_ROOT, 'tasks', slug);
51
51
  const statusPath = path.join(taskDir, 'status.json');
52
52
  const pipelinePath = path.join(taskDir, 'pipeline.json');
53
+ const METRICS_PATH = path.join(taskDir, 'metrics.json');
54
+ const METRICS_LOCK = `${METRICS_PATH}.lock`;
53
55
 
54
56
  if (!fs.existsSync(statusPath)) {
55
57
  process.stdout.write('{}');
@@ -57,18 +59,119 @@ if (!fs.existsSync(statusPath)) {
57
59
  }
58
60
 
59
61
  let status;
62
+ const now = new Date().toISOString();
63
+ const STACK = 'next';
64
+ const PLATFORM = 'claude';
65
+
66
+ function waitForMetricsLock() {
67
+ for (let attempt = 0; attempt < 200; attempt += 1) {
68
+ try { fs.mkdirSync(METRICS_LOCK); return; } catch (error) {
69
+ if (error && error.code !== 'EEXIST') throw error;
70
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);
71
+ }
72
+ }
73
+ throw new Error('metrics lock timeout');
74
+ }
75
+ let taskLockHeld = false;
76
+ function releaseTaskLock() {
77
+ if (!taskLockHeld) return;
78
+ taskLockHeld = false;
79
+ try { fs.rmdirSync(METRICS_LOCK); } catch {}
80
+ }
81
+ waitForMetricsLock();
82
+ taskLockHeld = true;
83
+ process.on('exit', releaseTaskLock);
60
84
  try {
61
85
  status = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
62
86
  } catch {
87
+ releaseTaskLock();
63
88
  process.stdout.write('{}');
64
89
  process.exit(0);
65
90
  }
91
+ function mutateMetrics(mutator) {
92
+ const acquiredHere = !taskLockHeld;
93
+ if (acquiredHere) waitForMetricsLock();
94
+ try {
95
+ let metrics;
96
+ try { metrics = JSON.parse(fs.readFileSync(METRICS_PATH, 'utf8')); } catch {
97
+ const runId = status.metricsRunId || `${slug}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
98
+ status.metricsRunId = runId;
99
+ metrics = { schemaVersion: 1, task: { runId, slug, preset: 'ai-rules', stack: STACK, platform: PLATFORM, intent: status.intent || 'unknown', profile: 'unknown' }, events: [] };
100
+ metrics.events.push({ eventId: `${runId}:task_started`, type: 'task_started', at: now, source: 'hook', attributionConfidence: 'high' });
101
+ }
102
+ mutator(metrics);
103
+ const temporary = `${METRICS_PATH}.${process.pid}.${Date.now()}.tmp`;
104
+ fs.writeFileSync(temporary, JSON.stringify(metrics, null, 2) + '\n');
105
+ fs.renameSync(temporary, METRICS_PATH);
106
+ } finally {
107
+ if (acquiredHere) { try { fs.rmdirSync(METRICS_LOCK); } catch {} }
108
+ }
109
+ }
110
+ function appendMetric(event) { mutateMetrics((metrics) => metrics.events.push({ eventId: `${metrics.task.runId}:${Date.now()}:${Math.random().toString(16).slice(2)}`, ...event })); }
111
+ function nextAttemptOrdinal(stepIndex, agent) {
112
+ try {
113
+ const metrics = JSON.parse(fs.readFileSync(METRICS_PATH, 'utf8'));
114
+ return metrics.events.reduce((highest, event) => event.type === 'attempt_started' && event.stepIndex === stepIndex && event.agent === agent ? Math.max(highest, Number(event.attempt) || 0) : highest, 0) + 1;
115
+ } catch { return 1; }
116
+ }
117
+ function roleFor(agent) {
118
+ if (/analyst|architect|router|migration/.test(agent || '')) return 'planning';
119
+ if (/verifier/.test(agent || '')) return 'validation';
120
+ if (/reviewer|auditor/.test(agent || '')) return 'review';
121
+ if (/test|qa/.test(agent || '')) return 'testing';
122
+ if (/writer/.test(agent || '')) return 'docs';
123
+ return 'implementation';
124
+ }
125
+ function activateAttempts(step, stepIndex) {
126
+ const active = { ...(status.activeAttempts || {}) }; const agents = getStepAgents(step);
127
+ const parallelGroupId = step.parallel && agents.length > 1 ? `${status.metricsRunId || slug}:step-${stepIndex}` : null;
128
+ for (const agent of agents) {
129
+ const attempt = nextAttemptOrdinal(stepIndex, agent); const runId = status.metricsRunId || `${slug}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
130
+ status.metricsRunId = runId; const attemptId = `${runId}:step-${stepIndex}:${agent}:attempt-${attempt}`;
131
+ if (active[attemptId]) continue;
132
+ active[attemptId] = { agent, stepIndex, attempt, startedAt: now, parallelGroupId };
133
+ appendMetric({ type: 'attempt_started', at: now, attemptId, stepIndex, stepLabel: step.label || null, agent, role: roleFor(agent), attempt, parallelGroupId, source: 'hook', attributionConfidence: 'high' });
134
+ }
135
+ status.activeAttempts = active;
136
+ }
137
+ function resolvedAttempt() {
138
+ const active = status.activeAttempts || {}; const entries = Object.entries(active);
139
+ const stableAttemptId = hookInput.attemptId;
140
+ if (stableAttemptId) {
141
+ return active[stableAttemptId] ? { attemptId: stableAttemptId, entry: active[stableAttemptId], confidence: 'high' } : null;
142
+ }
143
+ if (entries.length === 1) return { attemptId: entries[0][0], entry: entries[0][1], confidence: 'high' };
144
+ try { const receipts = JSON.parse(fs.readFileSync(path.join(taskDir, '.metrics-receipts.json'), 'utf8')); const receipt = Array.isArray(receipts) ? receipts.find((item) => active[item.attemptId]) : null; if (receipt) return { attemptId: receipt.attemptId, entry: active[receipt.attemptId], confidence: 'fallback', source: 'agent' }; } catch {}
145
+ return null;
146
+ }
147
+ function finishActiveAttempt() {
148
+ const resolved = resolvedAttempt(); if (!resolved) return null;
149
+ const durationMs = Date.parse(now) - Date.parse(resolved.entry.startedAt);
150
+ appendMetric({ type: 'attempt_finished', at: now, attemptId: resolved.attemptId, outcome: ['completed', 'changes_requested', 'validation_failed'].includes(status.state) ? status.state : 'unknown', durationMs: Number.isFinite(durationMs) && durationMs >= 0 ? durationMs : null, retryAfterFix: status.retryAfterFix || null, source: resolved.source || 'hook', attributionConfidence: resolved.confidence });
151
+ const active = { ...(status.activeAttempts || {}) }; delete active[resolved.attemptId]; status.activeAttempts = active; status.lastCompletedAttempt = { attemptId: resolved.attemptId, completedAt: now }; return resolved;
152
+ }
153
+ function beginHumanGate() { const eventId = `${status.metricsRunId || slug}:gate:${Date.now()}`; appendMetric({ eventId, type: 'human_gate_started', at: now, source: 'hook', attributionConfidence: 'high' }); status.activeHumanGateEventId = eventId; }
154
+ function endHumanGateIfResumed() {
155
+ if (!status.activeHumanGateEventId || status.awaitingHumanGate || status.state === 'awaiting_approval') return;
156
+ appendMetric({ type: 'human_gate_ended', at: now, gateStartedEventId: status.activeHumanGateEventId, source: 'hook', attributionConfidence: 'high' });
157
+ delete status.activeHumanGateEventId;
158
+ }
159
+ function completeTaskMetrics() { appendMetric({ type: 'task_completed', at: now, outcome: status.state === 'completed' ? 'completed' : 'unknown', source: 'hook', attributionConfidence: 'high' }); }
160
+ function recordSkippedStep(step, stepIndex) {
161
+ for (const agent of getStepAgents(step)) {
162
+ const runId = status.metricsRunId || `${slug}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
163
+ status.metricsRunId = runId;
164
+ const attempt = nextAttemptOrdinal(stepIndex, agent);
165
+ appendMetric({ type: 'attempt_skipped', at: now, attemptId: `${runId}:step-${stepIndex}:${agent}:attempt-${attempt}`, stepIndex, stepLabel: step.label || null, agent, role: roleFor(agent), attempt, outcome: 'skipped', source: 'hook', attributionConfidence: 'high' });
166
+ }
167
+ }
66
168
 
67
- const now = new Date().toISOString();
68
169
 
69
170
  function writeStatus(next) {
70
171
  status = { ...status, ...next, slug, updatedAt: now };
71
- fs.writeFileSync(statusPath, JSON.stringify(status, null, 2) + '\n');
172
+ const temporary = `${statusPath}.${process.pid}.${Date.now()}.tmp`;
173
+ fs.writeFileSync(temporary, JSON.stringify(status, null, 2) + '\n');
174
+ fs.renameSync(temporary, statusPath);
72
175
  }
73
176
 
74
177
  function out(message) {
@@ -105,9 +208,8 @@ function skipIfMatches(skipIf, dir) {
105
208
 
106
209
  function findNextExecutableStep(steps, startIdx, dir) {
107
210
  for (let i = startIdx; i < steps.length; i++) {
108
- if (!skipIfMatches(steps[i].skipIf, dir)) {
109
- return { step: steps[i], index: i };
110
- }
211
+ if (!skipIfMatches(steps[i].skipIf, dir)) return { step: steps[i], index: i };
212
+ recordSkippedStep(steps[i], i);
111
213
  }
112
214
  return null;
113
215
  }
@@ -172,16 +274,29 @@ const REVIEW_AGENTS = new Set([
172
274
  'api-contract-reviewer',
173
275
  ]);
174
276
 
277
+ function metricsHandoff(agent) {
278
+ const matches = Object.entries(status.activeAttempts || {}).filter(([, entry]) => entry.agent === agent);
279
+ if (matches.length === 1) {
280
+ return ` Metrics attemptId: ${matches[0][0]}; update normal status only. If the hook cannot identify a parallel stop, append a minimal { attemptId, outcome } receipt to .metrics-receipts.json; do not calculate duration.`;
281
+ }
282
+ return ' Metrics: use the supplied attemptId when available; for a parallel completion, write a minimal { attemptId, outcome } receipt to .metrics-receipts.json rather than relying on currentAgent. Do not calculate duration.';
283
+ }
284
+
175
285
  function handoffForAgent(agent, scope) {
176
286
  const fn = AGENT_HANDOFF[agent];
177
- return fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
287
+ const handoff = fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
288
+ return handoff + metricsHandoff(agent);
178
289
  }
179
290
 
180
291
  function handoffForParallelStep(step) {
181
292
  const agents = getStepAgents(step);
293
+ const attemptIds = Object.entries(status.activeAttempts || {})
294
+ .filter(([, entry]) => agents.includes(entry.agent))
295
+ .map(([attemptId, entry]) => `${entry.agent}=${attemptId}`);
182
296
  return (
183
297
  `Invoke IN PARALLEL (one message, multiple Task calls): ${agents.join(' AND ')} for slug "${slug}". ` +
184
- `Each agent writes its artifact and appends itself to status.json parallelCompleted when done.`
298
+ `Each agent writes its artifact and appends itself to status.json parallelCompleted when done. ` +
299
+ `Metrics attemptIds: ${attemptIds.join('; ')}. If the hook cannot identify a parallel stop, append a minimal { attemptId, outcome } receipt to .metrics-receipts.json; do not calculate duration.`
185
300
  );
186
301
  }
187
302
 
@@ -213,34 +328,38 @@ function legacyFlow() {
213
328
  out(handoffForAgent('qa-tester'));
214
329
  process.exit(0);
215
330
  }
331
+ function scheduleLegacyRetry(agent, retryAfterFix) {
332
+ const stepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
333
+ const predecessorAttemptId = status.lastCompletedAttempt?.attemptId || null;
334
+ appendMetric({ type: 'retry_scheduled', at: now, attemptId: predecessorAttemptId, nextAgent: agent, retryAfterFix: retryAfterFix || null, source: 'hook', attributionConfidence: 'unknown' });
335
+ activateAttempts({ agent }, stepIndex);
336
+ }
216
337
  if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
338
+ const reviewer = status.currentAgent;
339
+ scheduleLegacyRetry('feature-developer', reviewer);
217
340
  writeStatus({
218
341
  currentAgent: 'feature-developer',
219
342
  state: 'in_progress',
220
343
  phase: 'executing',
221
- retryAfterFix: status.currentAgent,
344
+ retryAfterFix: reviewer,
222
345
  });
223
- out(
224
- handoffForAgent('feature-developer') +
225
- ` After fixes, re-run ${status.currentAgent}.`,
226
- );
346
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${reviewer}.`);
227
347
  process.exit(0);
228
348
  }
229
349
  if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
350
+ scheduleLegacyRetry('feature-developer', 'build-verifier');
230
351
  writeStatus({
231
352
  currentAgent: 'feature-developer',
232
353
  state: 'in_progress',
233
354
  phase: 'executing',
234
355
  retryAfterFix: 'build-verifier',
235
356
  });
236
- out(
237
- handoffForAgent('feature-developer') +
238
- ` Read validation-report.md. After fixes, re-run build-verifier.`,
239
- );
357
+ out(handoffForAgent('feature-developer') + ' Read validation-report.md. After fixes, re-run build-verifier.');
240
358
  process.exit(0);
241
359
  }
242
360
  if (status.state === 'completed' && status.retryAfterFix) {
243
361
  const retry = status.retryAfterFix;
362
+ scheduleLegacyRetry(retry, null);
244
363
  writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
245
364
  out(handoffForAgent(retry));
246
365
  process.exit(0);
@@ -254,6 +373,56 @@ function legacyFlow() {
254
373
  process.exit(0);
255
374
  }
256
375
 
376
+
377
+ if (hookInput.action === 'end_human_gate') {
378
+ status.awaitingHumanGate = false;
379
+ if (status.state === 'awaiting_approval') {
380
+ status.state = 'in_progress';
381
+ status.phase = status.phase === 'human_gate' ? 'executing' : status.phase;
382
+ }
383
+ if (status.activeHumanGateEventId) {
384
+ appendMetric({
385
+ type: 'human_gate_ended',
386
+ at: now,
387
+ gateStartedEventId: status.activeHumanGateEventId,
388
+ source: 'orchestrator',
389
+ attributionConfidence: 'high',
390
+ });
391
+ delete status.activeHumanGateEventId;
392
+ }
393
+ if (hookInput.activateNext && fs.existsSync(pipelinePath)) {
394
+ let resumePipeline = null;
395
+ try { resumePipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8')); } catch {}
396
+ if (resumePipeline) {
397
+ const resumeSteps = resumePipeline.steps || [];
398
+ const resumeStart = (typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0) + 1;
399
+ const resumeNext = findNextExecutableStep(resumeSteps, resumeStart, taskDir);
400
+ if (resumeNext) {
401
+ const resumeAgents = getStepAgents(resumeNext.step);
402
+ activateAttempts(resumeNext.step, resumeNext.index);
403
+ writeStatus({
404
+ pipelineIndex: resumeNext.index,
405
+ currentAgent: resumeAgents[0],
406
+ phase: 'executing',
407
+ state: 'in_progress',
408
+ awaitingHumanGate: false,
409
+ parallelCompleted: [],
410
+ });
411
+ if (resumeNext.step.parallel && resumeAgents.length > 1) out(handoffForParallelStep(resumeNext.step));
412
+ else out(handoffForAgent(resumeAgents[0], resumeNext.step.scope));
413
+ process.exit(0);
414
+ }
415
+ }
416
+ }
417
+ writeStatus({
418
+ awaitingHumanGate: false,
419
+ state: status.state,
420
+ phase: status.phase,
421
+ });
422
+ process.stdout.write(JSON.stringify({ ok: true, action: 'end_human_gate', activeHumanGateEventId: status.activeHumanGateEventId || null }));
423
+ process.exit(0);
424
+ }
425
+
257
426
  if (!fs.existsSync(pipelinePath)) {
258
427
  legacyFlow();
259
428
  }
@@ -266,6 +435,15 @@ try {
266
435
  }
267
436
 
268
437
  const steps = pipeline.steps || [];
438
+ const initialIdx = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
439
+ const initialStep = steps[initialIdx];
440
+ const activeAttemptCountBeforeFinish = Object.keys(status.activeAttempts || {}).length;
441
+ const finishedAttempt = finishActiveAttempt();
442
+ if (!finishedAttempt && (hookInput.attemptId || activeAttemptCountBeforeFinish > 0)) {
443
+ process.stdout.write('{}');
444
+ process.exit(0);
445
+ }
446
+ endHumanGateIfResumed();
269
447
  if (steps.length === 0 || pipeline.autoChain === false) {
270
448
  process.stdout.write('{}');
271
449
  process.exit(0);
@@ -276,38 +454,57 @@ if (status.awaitingHumanGate || status.state === 'awaiting_approval') {
276
454
  process.exit(0);
277
455
  }
278
456
 
457
+ function nearestPrecedingStepIndex(agent, fromIndex, fallback) {
458
+ for (let index = fromIndex - 1; index >= 0; index -= 1) {
459
+ if (getStepAgents(steps[index]).includes(agent)) return index;
460
+ }
461
+ const match = steps.findIndex((step) => getStepAgents(step).includes(agent));
462
+ return match >= 0 ? match : fallback;
463
+ }
464
+ function scheduleRetry(agent, retryAfterFix, predecessor, explicitStepIndex = null) {
465
+ const currentIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
466
+ const stepIndex = Number.isInteger(explicitStepIndex) ? explicitStepIndex : nearestPrecedingStepIndex(agent, currentIndex, currentIndex);
467
+ const predecessorAttemptId = predecessor?.attemptId || status.lastCompletedAttempt?.attemptId || null;
468
+ appendMetric({ type: 'retry_scheduled', at: now, attemptId: predecessorAttemptId, nextAgent: agent, retryAfterFix: retryAfterFix || null, source: 'hook', attributionConfidence: predecessor ? predecessor.confidence : 'unknown' });
469
+ activateAttempts(steps[stepIndex] || { agent }, stepIndex);
470
+ return stepIndex;
471
+ }
472
+
279
473
  if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
280
474
  const reviewer = status.currentAgent;
475
+ const retryAfterFixStepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
476
+ const developerIndex = scheduleRetry('feature-developer', reviewer, finishedAttempt);
281
477
  writeStatus({
478
+ pipelineIndex: developerIndex,
282
479
  currentAgent: 'feature-developer',
283
480
  state: 'in_progress',
284
481
  phase: 'executing',
285
482
  retryAfterFix: reviewer,
483
+ retryAfterFixStepIndex,
286
484
  });
287
- out(
288
- handoffForAgent('feature-developer') +
289
- ` After fixes, re-run ${reviewer}.`,
290
- );
485
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${reviewer}.`);
291
486
  process.exit(0);
292
487
  }
293
488
 
294
489
  if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
490
+ const retryAfterFixStepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
491
+ const developerIndex = scheduleRetry('feature-developer', 'build-verifier', finishedAttempt);
295
492
  writeStatus({
493
+ pipelineIndex: developerIndex,
296
494
  currentAgent: 'feature-developer',
297
495
  state: 'in_progress',
298
496
  phase: 'executing',
299
497
  retryAfterFix: 'build-verifier',
498
+ retryAfterFixStepIndex,
300
499
  });
301
- out(
302
- handoffForAgent('feature-developer') +
303
- ` Read validation-report.md. After fixes, re-run build-verifier.`,
304
- );
500
+ out(handoffForAgent('feature-developer') + ' Read validation-report.md. After fixes, re-run build-verifier.');
305
501
  process.exit(0);
306
502
  }
307
503
 
308
504
  if (status.state === 'completed' && status.retryAfterFix) {
309
505
  const retry = status.retryAfterFix;
310
- writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
506
+ const retryIndex = scheduleRetry(retry, null, finishedAttempt, status.retryAfterFixStepIndex);
507
+ writeStatus({ pipelineIndex: retryIndex, currentAgent: retry, state: 'in_progress', retryAfterFix: null, retryAfterFixStepIndex: null });
311
508
  out(handoffForAgent(retry));
312
509
  process.exit(0);
313
510
  }
@@ -320,7 +517,7 @@ if (!currentStep) {
320
517
  process.exit(0);
321
518
  }
322
519
 
323
- const completedAgent = status.currentAgent || getStepAgents(currentStep)[0];
520
+ const completedAgent = finishedAttempt?.entry?.agent || status.currentAgent || getStepAgents(currentStep)[0];
324
521
  const stepAgents = getStepAgents(currentStep);
325
522
 
326
523
  if (currentStep.parallel && stepAgents.length > 1) {
@@ -338,6 +535,7 @@ if (currentStep.parallel && stepAgents.length > 1) {
338
535
  }
339
536
 
340
537
  if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
538
+ beginHumanGate();
341
539
  writeStatus({
342
540
  awaitingHumanGate: true,
343
541
  state: 'awaiting_approval',
@@ -349,6 +547,7 @@ if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
349
547
 
350
548
  const next = findNextExecutableStep(steps, idx + 1, taskDir);
351
549
  if (!next) {
550
+ completeTaskMetrics();
352
551
  writeStatus({
353
552
  pipelineIndex: steps.length,
354
553
  phase: 'done',
@@ -363,6 +562,7 @@ if (!next) {
363
562
  const { step: nextStep, index: nextIdx } = next;
364
563
  const nextAgents = getStepAgents(nextStep);
365
564
 
565
+ activateAttempts(nextStep, nextIdx);
366
566
  writeStatus({
367
567
  pipelineIndex: nextIdx,
368
568
  currentAgent: nextAgents[0],
@@ -103,3 +103,9 @@
103
103
  | `tooling-and-review/` | Quality, review, lint, agent-team, retro, **preset meta** |
104
104
 
105
105
  **Коллизии:** импорт типов и API — **`architecture/public-imports.md`**.
106
+
107
+ ## Metrics policy mapping
108
+
109
+ | Shared core | Runtime integration | Loading |
110
+ |-------------|---------------------|---------|
111
+ | `agent-team/agent-task-metrics.md` | `agent-team-orchestrator` + `hooks/chain-team-phases.sh` | requestable/on-demand; never session-start |
@@ -76,6 +76,10 @@ flowchart TD
76
76
 
77
77
  **Source of truth for order:** `pipeline.json` → `steps[]`. Never hardcode analyst → dev → review → QA when `pipeline.json` exists.
78
78
 
79
+ ## Metrics lifecycle
80
+
81
+ Use the local `metrics.json` ledger described by **agent-task-metrics**: initialize attempts before invocation, let hooks record host-clock ends, and never guess a parallel completion from `currentAgent`.
82
+
79
83
  ## status.json (pipeline mode)
80
84
 
81
85
  ```json
@@ -24,7 +24,7 @@ paths:
24
24
  ## Куда класть новое правило
25
25
 
26
26
  1. Общие принципы для всех стеков → **core** + адаптеры с `<!-- shared-core: … -->`.
27
- 2. Только один из installable стеков (`next` / `ios-swift` / `go` / `java`) → **stack-specific** (не в `_shared`).
27
+ 2. Только один из installable стеков (`next` / `ios-swift` / `go` / `java` / `mcp-ts` / `php-hexagonal` / `php-laravel`) → **stack-specific** (не в `_shared`).
28
28
  3. Только Cursor или только Claude packaging → platform artifact / frontmatter, не дублировать семантику.
29
29
 
30
30
  ## SoT
@@ -17,7 +17,7 @@ paths:
17
17
 
18
18
  - `next` must not require iOS-only agents/tooling (`xcuitest-*`, `xcodebuild` as required handoff, Keychain-only rules).
19
19
  - `ios-swift` must not ship Playwright handoffs or Next lint recipes as required commands.
20
- - `go` / `java` / `mcp-ts` must not ship Playwright, XCUITest, Next lint recipes, or `xcodebuild`/`SwiftLint` as required handoffs.
20
+ - `go` / `java` / `php-hexagonal` / `php-laravel` / `mcp-ts` must not ship Playwright, XCUITest, Next lint recipes, or `xcodebuild`/`SwiftLint` as required handoffs.
21
21
  - `mcp-ts` must not ship Go tool commands (`go test`, `go vet`, `golangci-lint`) or `integration-test-*` agents as required delivery gates.
22
22
  - Shared core must not embed stack paths (`app/src/**`, `Features/**`, `playwright`, `xcodebuild`).
23
23
 
@@ -36,16 +36,16 @@ Required instead: `xcuitest-test-*` stems; build-verifier mentions `xcodebuild`
36
36
  - `xcuitest-test-` as handoff stems
37
37
  - Requiring `xcodebuild` / SwiftLint as the default post-change gate for Next app work
38
38
 
39
- ## Forbidden in go / java hooks/agents (FAIL)
39
+ ## Forbidden in go / java / php-hexagonal / php-laravel hooks/agents (FAIL)
40
40
 
41
- Shared backend-stack bans (both `go` and `java`):
41
+ Shared backend-stack bans (`go`, `java`, `php-hexagonal`, and `php-laravel`):
42
42
 
43
43
  - `playwright-test-`, `playwright-e2e`, `user-playwright`, `app/__tests__/e2e`
44
44
  - Positive yarn recipes `lint:js` / `lint:css`
45
45
  - `xcuitest-test-`, `xcodebuild`, `SwiftLint` as required handoffs
46
46
  - Agent file `accessibility-reviewer` (no UI surface)
47
47
 
48
- Required instead: `integration-test-*`; build-verifier / `post-change-test` plus stack tooling — `go-tooling` (`go test`, `go vet`) or `java-tooling` (`mvn test` / `./gradlew test`).
48
+ Required instead: `integration-test-*`; build-verifier / `post-change-test` plus stack tooling — `go-tooling` (`go test`, `go vet`), `java-tooling` (`mvn test` / `./gradlew test`), or `php-tooling` (`php artisan test` / `composer test` / `vendor/bin/phpunit`).
49
49
 
50
50
  ## Forbidden in mcp-ts hooks/agents (FAIL)
51
51
 
@@ -66,4 +66,4 @@ Required instead: package-manager–discovered typecheck/test (`mcp-ts-tooling`,
66
66
 
67
67
  ## Chain fork
68
68
 
69
- `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `ios-swift`, `go`, `java`, and `mcp-ts` (per platform).
69
+ `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `ios-swift`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform).
@@ -17,7 +17,7 @@ paths:
17
17
 
18
18
  - [ ] **SoT:** правки в `packages/…` (не только root `.cursor/`)
19
19
  - [ ] **Core:** если менялся `_shared/core/**` — обновлены все `<!-- shared-core: … -->` consumers (или documented intentional fork)
20
- - [ ] **Twin:** Cursor change → Claude twin **same PR** (**FAIL** if missing on next, ios-swift, go, and java — см. `preset-twin-sync`)
20
+ - [ ] **Twin:** Cursor change → Claude twin **same PR** (**FAIL** if missing on next, ios-swift, go, java, mcp-ts, php-hexagonal, and php-laravel — см. `preset-twin-sync`)
21
21
  - [ ] **Mapping:** `claude/<stack>/rules/README.md` mapping table актуален
22
22
  - [ ] **Token budget:** alwaysApply / session-start ≤ 3; meta rules not always-on
23
23
  - [ ] **Leakage:** нет чужих stack agent stems / handoff strings (`preset-no-cross-stack-leakage`)
@@ -22,6 +22,8 @@ Cursor `.mdc` — **SoT per stack**. Claude topic `.md` — derived twin.
22
22
  | `go` | `presets/cursor/go/rules/*.mdc` | `presets/claude/go/rules/<topic>/` | Keep in `claude/go/rules/README.md` |
23
23
  | `java` | `presets/cursor/java/rules/*.mdc` | `presets/claude/java/rules/<topic>/` | Keep in `claude/java/rules/README.md` |
24
24
  | `mcp-ts` | `presets/cursor/mcp-ts/rules/*.mdc` | `presets/claude/mcp-ts/rules/<topic>/` | Keep in `claude/mcp-ts/rules/README.md` |
25
+ | `php-hexagonal` | `presets/cursor/php-hexagonal/rules/*.mdc` | `presets/claude/php-hexagonal/rules/<topic>/` | Keep in `claude/php-hexagonal/rules/README.md` |
26
+ | `php-laravel` | `presets/cursor/php-laravel/rules/*.mdc` | `presets/claude/php-laravel/rules/<topic>/` | Keep in `claude/php-laravel/rules/README.md` |
25
27
 
26
28
  ## Same-PR checklist
27
29
 
@@ -42,5 +44,7 @@ Cursor `.mdc` — **SoT per stack**. Claude topic `.md` — derived twin.
42
44
  - **go:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift; mapping table required).
43
45
  - **java:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go; mapping table required).
44
46
  - **mcp-ts:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java; mapping table required).
47
+ - **php-hexagonal:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts; mapping table required).
48
+ - **php-laravel:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-hexagonal; mapping table required).
45
49
 
46
50
  Dogfood: sync packages → root `.cursor/` after Cursor SoT changes (not the reverse). Use `packages/ai-rules/scripts/sync-dogfood-cursor.sh`.
@@ -13,4 +13,6 @@ paths:
13
13
 
14
14
  **`commands/technical-retro.md`** → `/technical-retro`
15
15
 
16
+ When a task has `metrics.json`, use the local aggregation script and state the cohort, sample size, incomplete artifacts, attribution confidence, active attempt duration, and human-gate wait separately. Do not score malformed artifacts or gate wait as agent work.
17
+
16
18
  Используй rule только если command недоступен. Не дублируй содержимое command в ответе — следуй command-файлу и skill `technical-retro`.
@@ -12,6 +12,7 @@
12
12
  <slug>/
13
13
  pipeline.json
14
14
  status.json
15
+ metrics.json # schema-v1 append-only event ledger (see Local metrics ledger)
15
16
  brief.md
16
17
  decomposition.md
17
18
  debug-report.md # fixApplied: true/false
@@ -71,6 +72,8 @@
71
72
  "awaitingHumanGate": false,
72
73
  "parallelCompleted": [],
73
74
  "retryAfterFix": null,
75
+ "activeAttempts": {},
76
+ "lastCompletedAttempt": null,
74
77
  "updatedAt": "2026-05-29T12:00:00.000Z"
75
78
  }
76
79
  ```
@@ -103,3 +106,19 @@ Legacy: `/feature-start`, `/feature-continue`.
103
106
  ## Git
104
107
 
105
108
  Commit task artifacts if you want them to survive `ai-rules clean claude`. Or copy finished tasks to `docs/agent-workflow/tasks/<slug>/`.
109
+
110
+ ## Local metrics ledger
111
+
112
+ `metrics.json` is an append-only schema-v1 event ledger for one task run. It contains only allowlisted IDs, task dimensions, timestamps, outcomes, and attribution confidence—never prompts, secrets, file paths, or contents. Policy SoT: `presets/_shared/core/agent-team/agent-task-metrics.md`. The router writes `task_started` / `attempt_started`; the hook records host-clock completion and human-gate edges under a per-task lock with temp-and-rename.
113
+
114
+ `status.json.activeAttempts` is a transient timing bridge keyed by `attemptId`; `lastCompletedAttempt` is diagnostic. For parallel stops, the hook must use a stable payload identity or the sole active attempt. Otherwise an explicit `.metrics-receipts.json` receipt is fallback data marked `source: agent`, `attributionConfidence: fallback`; it must never guess from `currentAgent`.
115
+
116
+ After a human gate, `/task-continue` closes wait via the installed hook (do not hand-edit `pipelineIndex` first):
117
+
118
+ ```bash
119
+ printf '%s\n' '{"status":"completed","action":"end_human_gate","activateNext":true}' | bash .claude/hooks/chain-team-phases.sh
120
+ ```
121
+
122
+ That appends `human_gate_ended` before the next `attempt_started`. Cursor twin uses the same payload against `.cursor/hooks/chain-team-phases.sh`. Other installable stacks ship the same ledger contract in their `team/README.md`.
123
+
124
+ Aggregate with `node packages/ai-rules/scripts/aggregate-agent-task-metrics.mjs --team-root .claude/team`. It reports role/agent count, completed count, total/average duration, distinct completed run IDs, separate human-gate wait, and incomplete artifacts. For retros, see `/technical-retro` → **Metrics evidence**.
@@ -0,0 +1,31 @@
1
+ # PHP hexagonal (Claude)
2
+
3
+ Preset for PHP backends using ports & adapters (PSR / Composer-first).
4
+
5
+ **Repo-root agents:** see [`AGENTS.md`](../../AGENTS.md) at the project root.
6
+
7
+ - Session-start: `php-app-core`, `architecture/boundaries`, `code-quality` (exactly 3).
8
+ - Delivery: `architecture/feature-delivery.md` + skill `feature-delivery`.
9
+ - After PHP edits: `tooling-and-review/post-change-test.md` (+ `php-tooling`).
10
+ - Integration tests: agents `integration-test-*` + skill `integration-testing` (never Playwright/XCUITest).
11
+ - Unit tests: agents `unit-test-*` + skill `unit-testing` (PHPUnit).
12
+ - ADR: skill `write-adr` (on-demand).
13
+ - How does X work: agent `codebase-analyzer` (explain-as-is; no `/task`).
14
+
15
+ ## Inventory
16
+
17
+ - **21 agents** — `agents/README.md` (no a11y / Playwright / XCUITest)
18
+ - **8 skills** — feature-delivery, unit-testing, integration-testing, ci-investigation, debug-investigation, code-review, technical-retro, write-adr
19
+ - **5 commands** — `/task`, `/task-continue`, `/feature-start`, `/feature-continue`, `/technical-retro`
20
+
21
+ ## Dogfood (5 scenarios)
22
+
23
+ Host: `dogfood/php-hexagonal`.
24
+
25
+ 1. `/task` — domain use case through ports, adapters, Composition on the sample.
26
+ 2. HTTP DTO mapping bug — debugger + `TodoController` unit.
27
+ 3. Repository contract — integration-test trio (sample: in-memory persistence).
28
+ 4. PHPUnit unit test for use case with port fake/mock.
29
+ 5. Secrets/authz logging — `security-reviewer` + `security-php`.
30
+
31
+ Init: `npx @bonesofspring/ai-rules init claude --preset php-hexagonal` (also copies `REPO_AGENTS.md` → root `AGENTS.md`).
@@ -0,0 +1,15 @@
1
+ # MCP (preset `php-hexagonal`, Claude)
2
+
3
+ Копируется в project `.mcp.json` при `ai-rules init claude --preset php-hexagonal`.
4
+
5
+ ## Servers
6
+
7
+ | Name | Package | Зачем |
8
+ |------|---------|--------|
9
+ | `context7` | `@upstash/context7-mcp` | Актуальная документация PHP / Composer / популярных библиотек |
10
+
11
+ Figma и browser e2e MCP (Playwright / Chrome DevTools) **не** входят в php-hexagonal-пресет (backend-only).
12
+
13
+ Секреты в файл не кладём. Опционально: `CONTEXT7_API_KEY` в окружении.
14
+
15
+ После init: включить MCP серверы в Claude Code. `init` перезаписывает одноимённый `mcp.json`.
@@ -0,0 +1,26 @@
1
+ # Preset `php-hexagonal` (Claude)
2
+
3
+ Installable Claude Code preset for **PHP hexagonal** services (PSR / Composer-first).
4
+
5
+ ```bash
6
+ npx @bonesofspring/ai-rules init claude --preset php-hexagonal
7
+ ```
8
+
9
+ ## Layout
10
+
11
+ | Path | Role |
12
+ |------|------|
13
+ | `rules/<topic>/` | Derived twins + mapping table in `rules/README.md` |
14
+ | `rules/ui-and-accessibility/` | N/A stub (backend) |
15
+ | `agents/` | 21 agents + README (no a11y / Playwright / XCUITest) |
16
+ | `skills/` | 8 skills + README |
17
+ | `commands/` | 5 slash commands |
18
+ | `team/` | conventions + fixtures |
19
+ | `hooks/` | Shell guard + team chain (byte-forked); **no `hooks.json`** (Claude platform limit) |
20
+ | `REPO_AGENTS.md` | → consumer root `AGENTS.md` |
21
+ | `CLAUDE.md` | Thin Claude entry + inventory / dogfood — **Claude-only** |
22
+ | `MCP.md` / `mcp.json` | Context7 only |
23
+
24
+ **Platform asymmetry:** `CLAUDE.md` is Claude-only. Cursor SoT has `BUGBOT.md` + `hooks.json` (not shipped here).
25
+
26
+ Cursor SoT: `presets/cursor/php-hexagonal/`. Contribution: `docs/PRESET-CONTRIBUTION.md`.
@@ -0,0 +1,46 @@
1
+ # PHP — agent instructions
2
+
3
+ Cross-tool repo-root guide for the **php-hexagonal** preset (PSR / Composer-first). Tool-specific maps stay under `.cursor/AGENTS.md` and `.claude/CLAUDE.md`.
4
+
5
+ ## Cross-tool setup
6
+
7
+ - Treat this file as the **shared** entry for any agent (Cursor, Claude Code, or other).
8
+ - Install:
9
+
10
+ ```bash
11
+ npx @bonesofspring/ai-rules init cursor --preset php-hexagonal
12
+ npx @bonesofspring/ai-rules init claude --preset php-hexagonal
13
+ ```
14
+
15
+ `init` overwrites this file from the preset (`REPO_AGENTS.md` → `AGENTS.md`).
16
+
17
+ ## Commands (test / verify)
18
+
19
+ Detect Composer from the repo (`composer.json` / `composer.lock`). Prefer Composer scripts when present.
20
+
21
+ | Gate | Typical command |
22
+ |------|-----------------|
23
+ | Tests | `composer test` or `vendor/bin/phpunit` (Pest if that is the repo default) |
24
+ | Static analysis (if configured) | `vendor/bin/phpstan` / `vendor/bin/psalm` |
25
+ | Format (if configured) | `vendor/bin/php-cs-fixer` / `vendor/bin/pint` |
26
+ | Post-change | requestable `post-change-test` + `php-tooling` |
27
+
28
+ Static analysis / format — only tools already configured in the repo/CI.
29
+
30
+ ## Security basics
31
+
32
+ - Do not commit secrets (`.env`, tokens, credentials).
33
+ - Review destructive git before running; respect shell hooks.
34
+
35
+ ## Tool entry points
36
+
37
+ | Tool | Map |
38
+ |------|-----|
39
+ | Cursor | `.cursor/AGENTS.md` |
40
+ | Claude Code | `.claude/CLAUDE.md` |
41
+
42
+ Rules: `.cursor/rules/` or `.claude/rules/`. Integration tests: `integration-test-*` (never Playwright/XCUITest).
43
+
44
+ ## Living conventions
45
+
46
+ Gotchas and team decisions: `.cursor/team/conventions.md` and/or `.claude/team/conventions.md` (fill after init; fixtures ship with the preset).