@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
@@ -52,6 +52,8 @@ if (!slug) {
52
52
  const taskDir = path.join(TEAM_ROOT, 'tasks', slug);
53
53
  const statusPath = path.join(taskDir, 'status.json');
54
54
  const pipelinePath = path.join(taskDir, 'pipeline.json');
55
+ const METRICS_PATH = path.join(taskDir, 'metrics.json');
56
+ const METRICS_LOCK = `${METRICS_PATH}.lock`;
55
57
 
56
58
  if (!fs.existsSync(statusPath)) {
57
59
  process.stdout.write('{}');
@@ -59,18 +61,119 @@ if (!fs.existsSync(statusPath)) {
59
61
  }
60
62
 
61
63
  let status;
64
+ const now = new Date().toISOString();
65
+ const STACK = 'mcp-ts';
66
+ const PLATFORM = 'claude';
67
+
68
+ function waitForMetricsLock() {
69
+ for (let attempt = 0; attempt < 200; attempt += 1) {
70
+ try { fs.mkdirSync(METRICS_LOCK); return; } catch (error) {
71
+ if (error && error.code !== 'EEXIST') throw error;
72
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);
73
+ }
74
+ }
75
+ throw new Error('metrics lock timeout');
76
+ }
77
+ let taskLockHeld = false;
78
+ function releaseTaskLock() {
79
+ if (!taskLockHeld) return;
80
+ taskLockHeld = false;
81
+ try { fs.rmdirSync(METRICS_LOCK); } catch {}
82
+ }
83
+ waitForMetricsLock();
84
+ taskLockHeld = true;
85
+ process.on('exit', releaseTaskLock);
62
86
  try {
63
87
  status = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
64
88
  } catch {
89
+ releaseTaskLock();
65
90
  process.stdout.write('{}');
66
91
  process.exit(0);
67
92
  }
93
+ function mutateMetrics(mutator) {
94
+ const acquiredHere = !taskLockHeld;
95
+ if (acquiredHere) waitForMetricsLock();
96
+ try {
97
+ let metrics;
98
+ try { metrics = JSON.parse(fs.readFileSync(METRICS_PATH, 'utf8')); } catch {
99
+ const runId = status.metricsRunId || `${slug}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
100
+ status.metricsRunId = runId;
101
+ metrics = { schemaVersion: 1, task: { runId, slug, preset: 'ai-rules', stack: STACK, platform: PLATFORM, intent: status.intent || 'unknown', profile: 'unknown' }, events: [] };
102
+ metrics.events.push({ eventId: `${runId}:task_started`, type: 'task_started', at: now, source: 'hook', attributionConfidence: 'high' });
103
+ }
104
+ mutator(metrics);
105
+ const temporary = `${METRICS_PATH}.${process.pid}.${Date.now()}.tmp`;
106
+ fs.writeFileSync(temporary, JSON.stringify(metrics, null, 2) + '\n');
107
+ fs.renameSync(temporary, METRICS_PATH);
108
+ } finally {
109
+ if (acquiredHere) { try { fs.rmdirSync(METRICS_LOCK); } catch {} }
110
+ }
111
+ }
112
+ function appendMetric(event) { mutateMetrics((metrics) => metrics.events.push({ eventId: `${metrics.task.runId}:${Date.now()}:${Math.random().toString(16).slice(2)}`, ...event })); }
113
+ function nextAttemptOrdinal(stepIndex, agent) {
114
+ try {
115
+ const metrics = JSON.parse(fs.readFileSync(METRICS_PATH, 'utf8'));
116
+ 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;
117
+ } catch { return 1; }
118
+ }
119
+ function roleFor(agent) {
120
+ if (/analyst|architect|router|migration/.test(agent || '')) return 'planning';
121
+ if (/verifier/.test(agent || '')) return 'validation';
122
+ if (/reviewer|auditor/.test(agent || '')) return 'review';
123
+ if (/test|qa/.test(agent || '')) return 'testing';
124
+ if (/writer/.test(agent || '')) return 'docs';
125
+ return 'implementation';
126
+ }
127
+ function activateAttempts(step, stepIndex) {
128
+ const active = { ...(status.activeAttempts || {}) }; const agents = getStepAgents(step);
129
+ const parallelGroupId = step.parallel && agents.length > 1 ? `${status.metricsRunId || slug}:step-${stepIndex}` : null;
130
+ for (const agent of agents) {
131
+ const attempt = nextAttemptOrdinal(stepIndex, agent); const runId = status.metricsRunId || `${slug}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
132
+ status.metricsRunId = runId; const attemptId = `${runId}:step-${stepIndex}:${agent}:attempt-${attempt}`;
133
+ if (active[attemptId]) continue;
134
+ active[attemptId] = { agent, stepIndex, attempt, startedAt: now, parallelGroupId };
135
+ appendMetric({ type: 'attempt_started', at: now, attemptId, stepIndex, stepLabel: step.label || null, agent, role: roleFor(agent), attempt, parallelGroupId, source: 'hook', attributionConfidence: 'high' });
136
+ }
137
+ status.activeAttempts = active;
138
+ }
139
+ function resolvedAttempt() {
140
+ const active = status.activeAttempts || {}; const entries = Object.entries(active);
141
+ const stableAttemptId = hookInput.attemptId;
142
+ if (stableAttemptId) {
143
+ return active[stableAttemptId] ? { attemptId: stableAttemptId, entry: active[stableAttemptId], confidence: 'high' } : null;
144
+ }
145
+ if (entries.length === 1) return { attemptId: entries[0][0], entry: entries[0][1], confidence: 'high' };
146
+ 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 {}
147
+ return null;
148
+ }
149
+ function finishActiveAttempt() {
150
+ const resolved = resolvedAttempt(); if (!resolved) return null;
151
+ const durationMs = Date.parse(now) - Date.parse(resolved.entry.startedAt);
152
+ 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 });
153
+ const active = { ...(status.activeAttempts || {}) }; delete active[resolved.attemptId]; status.activeAttempts = active; status.lastCompletedAttempt = { attemptId: resolved.attemptId, completedAt: now }; return resolved;
154
+ }
155
+ 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; }
156
+ function endHumanGateIfResumed() {
157
+ if (!status.activeHumanGateEventId || status.awaitingHumanGate || status.state === 'awaiting_approval') return;
158
+ appendMetric({ type: 'human_gate_ended', at: now, gateStartedEventId: status.activeHumanGateEventId, source: 'hook', attributionConfidence: 'high' });
159
+ delete status.activeHumanGateEventId;
160
+ }
161
+ function completeTaskMetrics() { appendMetric({ type: 'task_completed', at: now, outcome: status.state === 'completed' ? 'completed' : 'unknown', source: 'hook', attributionConfidence: 'high' }); }
162
+ function recordSkippedStep(step, stepIndex) {
163
+ for (const agent of getStepAgents(step)) {
164
+ const runId = status.metricsRunId || `${slug}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
165
+ status.metricsRunId = runId;
166
+ const attempt = nextAttemptOrdinal(stepIndex, agent);
167
+ 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' });
168
+ }
169
+ }
68
170
 
69
- const now = new Date().toISOString();
70
171
 
71
172
  function writeStatus(next) {
72
173
  status = { ...status, ...next, slug, updatedAt: now };
73
- fs.writeFileSync(statusPath, JSON.stringify(status, null, 2) + '\n');
174
+ const temporary = `${statusPath}.${process.pid}.${Date.now()}.tmp`;
175
+ fs.writeFileSync(temporary, JSON.stringify(status, null, 2) + '\n');
176
+ fs.renameSync(temporary, statusPath);
74
177
  }
75
178
 
76
179
  function out(message) {
@@ -108,9 +211,8 @@ function skipIfMatches(skipIf, dir) {
108
211
 
109
212
  function findNextExecutableStep(steps, startIdx, dir) {
110
213
  for (let i = startIdx; i < steps.length; i++) {
111
- if (!skipIfMatches(steps[i].skipIf, dir)) {
112
- return { step: steps[i], index: i };
113
- }
214
+ if (!skipIfMatches(steps[i].skipIf, dir)) return { step: steps[i], index: i };
215
+ recordSkippedStep(steps[i], i);
114
216
  }
115
217
  return null;
116
218
  }
@@ -138,16 +240,29 @@ const REVIEW_AGENTS = new Set([
138
240
  ]);
139
241
 
140
242
 
243
+ function metricsHandoff(agent) {
244
+ const matches = Object.entries(status.activeAttempts || {}).filter(([, entry]) => entry.agent === agent);
245
+ if (matches.length === 1) {
246
+ 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.`;
247
+ }
248
+ 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.';
249
+ }
250
+
141
251
  function handoffForAgent(agent, scope) {
142
252
  const fn = AGENT_HANDOFF[agent];
143
- return fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
253
+ const handoff = fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
254
+ return handoff + metricsHandoff(agent);
144
255
  }
145
256
 
146
257
  function handoffForParallelStep(step) {
147
258
  const agents = getStepAgents(step);
259
+ const attemptIds = Object.entries(status.activeAttempts || {})
260
+ .filter(([, entry]) => agents.includes(entry.agent))
261
+ .map(([attemptId, entry]) => `${entry.agent}=${attemptId}`);
148
262
  return (
149
263
  `Invoke IN PARALLEL (one message, multiple Task calls): ${agents.join(' AND ')} for slug "${slug}". ` +
150
- `Each agent writes its artifact and appends itself to status.json parallelCompleted when done.`
264
+ `Each agent writes its artifact and appends itself to status.json parallelCompleted when done. ` +
265
+ `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.`
151
266
  );
152
267
  }
153
268
 
@@ -179,34 +294,38 @@ function legacyFlow() {
179
294
  out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
180
295
  process.exit(0);
181
296
  }
297
+ function scheduleLegacyRetry(agent, retryAfterFix) {
298
+ const stepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
299
+ const predecessorAttemptId = status.lastCompletedAttempt?.attemptId || null;
300
+ appendMetric({ type: 'retry_scheduled', at: now, attemptId: predecessorAttemptId, nextAgent: agent, retryAfterFix: retryAfterFix || null, source: 'hook', attributionConfidence: 'unknown' });
301
+ activateAttempts({ agent }, stepIndex);
302
+ }
182
303
  if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
304
+ const reviewer = status.currentAgent;
305
+ scheduleLegacyRetry('feature-developer', reviewer);
183
306
  writeStatus({
184
307
  currentAgent: 'feature-developer',
185
308
  state: 'in_progress',
186
309
  phase: 'executing',
187
- retryAfterFix: status.currentAgent,
310
+ retryAfterFix: reviewer,
188
311
  });
189
- out(
190
- handoffForAgent('feature-developer') +
191
- ` After fixes, re-run ${status.currentAgent}.`,
192
- );
312
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${reviewer}.`);
193
313
  process.exit(0);
194
314
  }
195
315
  if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
316
+ scheduleLegacyRetry('feature-developer', 'build-verifier');
196
317
  writeStatus({
197
318
  currentAgent: 'feature-developer',
198
319
  state: 'in_progress',
199
320
  phase: 'executing',
200
321
  retryAfterFix: 'build-verifier',
201
322
  });
202
- out(
203
- handoffForAgent('feature-developer') +
204
- ` Read validation-report.md. After fixes, re-run build-verifier.`,
205
- );
323
+ out(handoffForAgent('feature-developer') + ' Read validation-report.md. After fixes, re-run build-verifier.');
206
324
  process.exit(0);
207
325
  }
208
326
  if (status.state === 'completed' && status.retryAfterFix) {
209
327
  const retry = status.retryAfterFix;
328
+ scheduleLegacyRetry(retry, null);
210
329
  writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
211
330
  out(handoffForAgent(retry));
212
331
  process.exit(0);
@@ -220,6 +339,56 @@ function legacyFlow() {
220
339
  process.exit(0);
221
340
  }
222
341
 
342
+
343
+ if (hookInput.action === 'end_human_gate') {
344
+ status.awaitingHumanGate = false;
345
+ if (status.state === 'awaiting_approval') {
346
+ status.state = 'in_progress';
347
+ status.phase = status.phase === 'human_gate' ? 'executing' : status.phase;
348
+ }
349
+ if (status.activeHumanGateEventId) {
350
+ appendMetric({
351
+ type: 'human_gate_ended',
352
+ at: now,
353
+ gateStartedEventId: status.activeHumanGateEventId,
354
+ source: 'orchestrator',
355
+ attributionConfidence: 'high',
356
+ });
357
+ delete status.activeHumanGateEventId;
358
+ }
359
+ if (hookInput.activateNext && fs.existsSync(pipelinePath)) {
360
+ let resumePipeline = null;
361
+ try { resumePipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8')); } catch {}
362
+ if (resumePipeline) {
363
+ const resumeSteps = resumePipeline.steps || [];
364
+ const resumeStart = (typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0) + 1;
365
+ const resumeNext = findNextExecutableStep(resumeSteps, resumeStart, taskDir);
366
+ if (resumeNext) {
367
+ const resumeAgents = getStepAgents(resumeNext.step);
368
+ activateAttempts(resumeNext.step, resumeNext.index);
369
+ writeStatus({
370
+ pipelineIndex: resumeNext.index,
371
+ currentAgent: resumeAgents[0],
372
+ phase: 'executing',
373
+ state: 'in_progress',
374
+ awaitingHumanGate: false,
375
+ parallelCompleted: [],
376
+ });
377
+ if (resumeNext.step.parallel && resumeAgents.length > 1) out(handoffForParallelStep(resumeNext.step));
378
+ else out(handoffForAgent(resumeAgents[0], resumeNext.step.scope));
379
+ process.exit(0);
380
+ }
381
+ }
382
+ }
383
+ writeStatus({
384
+ awaitingHumanGate: false,
385
+ state: status.state,
386
+ phase: status.phase,
387
+ });
388
+ process.stdout.write(JSON.stringify({ ok: true, action: 'end_human_gate', activeHumanGateEventId: status.activeHumanGateEventId || null }));
389
+ process.exit(0);
390
+ }
391
+
223
392
  if (!fs.existsSync(pipelinePath)) {
224
393
  legacyFlow();
225
394
  }
@@ -232,6 +401,15 @@ try {
232
401
  }
233
402
 
234
403
  const steps = pipeline.steps || [];
404
+ const initialIdx = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
405
+ const initialStep = steps[initialIdx];
406
+ const activeAttemptCountBeforeFinish = Object.keys(status.activeAttempts || {}).length;
407
+ const finishedAttempt = finishActiveAttempt();
408
+ if (!finishedAttempt && (hookInput.attemptId || activeAttemptCountBeforeFinish > 0)) {
409
+ process.stdout.write('{}');
410
+ process.exit(0);
411
+ }
412
+ endHumanGateIfResumed();
235
413
  if (steps.length === 0 || pipeline.autoChain === false) {
236
414
  process.stdout.write('{}');
237
415
  process.exit(0);
@@ -242,38 +420,57 @@ if (status.awaitingHumanGate || status.state === 'awaiting_approval') {
242
420
  process.exit(0);
243
421
  }
244
422
 
423
+ function nearestPrecedingStepIndex(agent, fromIndex, fallback) {
424
+ for (let index = fromIndex - 1; index >= 0; index -= 1) {
425
+ if (getStepAgents(steps[index]).includes(agent)) return index;
426
+ }
427
+ const match = steps.findIndex((step) => getStepAgents(step).includes(agent));
428
+ return match >= 0 ? match : fallback;
429
+ }
430
+ function scheduleRetry(agent, retryAfterFix, predecessor, explicitStepIndex = null) {
431
+ const currentIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
432
+ const stepIndex = Number.isInteger(explicitStepIndex) ? explicitStepIndex : nearestPrecedingStepIndex(agent, currentIndex, currentIndex);
433
+ const predecessorAttemptId = predecessor?.attemptId || status.lastCompletedAttempt?.attemptId || null;
434
+ appendMetric({ type: 'retry_scheduled', at: now, attemptId: predecessorAttemptId, nextAgent: agent, retryAfterFix: retryAfterFix || null, source: 'hook', attributionConfidence: predecessor ? predecessor.confidence : 'unknown' });
435
+ activateAttempts(steps[stepIndex] || { agent }, stepIndex);
436
+ return stepIndex;
437
+ }
438
+
245
439
  if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
246
440
  const reviewer = status.currentAgent;
441
+ const retryAfterFixStepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
442
+ const developerIndex = scheduleRetry('feature-developer', reviewer, finishedAttempt);
247
443
  writeStatus({
444
+ pipelineIndex: developerIndex,
248
445
  currentAgent: 'feature-developer',
249
446
  state: 'in_progress',
250
447
  phase: 'executing',
251
448
  retryAfterFix: reviewer,
449
+ retryAfterFixStepIndex,
252
450
  });
253
- out(
254
- handoffForAgent('feature-developer') +
255
- ` After fixes, re-run ${reviewer}.`,
256
- );
451
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${reviewer}.`);
257
452
  process.exit(0);
258
453
  }
259
454
 
260
455
  if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
456
+ const retryAfterFixStepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
457
+ const developerIndex = scheduleRetry('feature-developer', 'build-verifier', finishedAttempt);
261
458
  writeStatus({
459
+ pipelineIndex: developerIndex,
262
460
  currentAgent: 'feature-developer',
263
461
  state: 'in_progress',
264
462
  phase: 'executing',
265
463
  retryAfterFix: 'build-verifier',
464
+ retryAfterFixStepIndex,
266
465
  });
267
- out(
268
- handoffForAgent('feature-developer') +
269
- ` Read validation-report.md. After fixes, re-run build-verifier.`,
270
- );
466
+ out(handoffForAgent('feature-developer') + ' Read validation-report.md. After fixes, re-run build-verifier.');
271
467
  process.exit(0);
272
468
  }
273
469
 
274
470
  if (status.state === 'completed' && status.retryAfterFix) {
275
471
  const retry = status.retryAfterFix;
276
- writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
472
+ const retryIndex = scheduleRetry(retry, null, finishedAttempt, status.retryAfterFixStepIndex);
473
+ writeStatus({ pipelineIndex: retryIndex, currentAgent: retry, state: 'in_progress', retryAfterFix: null, retryAfterFixStepIndex: null });
277
474
  out(handoffForAgent(retry));
278
475
  process.exit(0);
279
476
  }
@@ -286,7 +483,7 @@ if (!currentStep) {
286
483
  process.exit(0);
287
484
  }
288
485
 
289
- const completedAgent = status.currentAgent || getStepAgents(currentStep)[0];
486
+ const completedAgent = finishedAttempt?.entry?.agent || status.currentAgent || getStepAgents(currentStep)[0];
290
487
  const stepAgents = getStepAgents(currentStep);
291
488
 
292
489
  if (currentStep.parallel && stepAgents.length > 1) {
@@ -304,6 +501,7 @@ if (currentStep.parallel && stepAgents.length > 1) {
304
501
  }
305
502
 
306
503
  if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
504
+ beginHumanGate();
307
505
  writeStatus({
308
506
  awaitingHumanGate: true,
309
507
  state: 'awaiting_approval',
@@ -315,6 +513,7 @@ if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
315
513
 
316
514
  const next = findNextExecutableStep(steps, idx + 1, taskDir);
317
515
  if (!next) {
516
+ completeTaskMetrics();
318
517
  writeStatus({
319
518
  pipelineIndex: steps.length,
320
519
  phase: 'done',
@@ -329,6 +528,7 @@ if (!next) {
329
528
  const { step: nextStep, index: nextIdx } = next;
330
529
  const nextAgents = getStepAgents(nextStep);
331
530
 
531
+ activateAttempts(nextStep, nextIdx);
332
532
  writeStatus({
333
533
  pipelineIndex: nextIdx,
334
534
  currentAgent: nextAgents[0],
@@ -50,3 +50,9 @@ Claude topic `.md` files are **derived** from Cursor SoT `presets/cursor/mcp-ts/
50
50
 
51
51
  `architecture/`, `stack/`, `api-and-data/`, `testing/`, `tooling-and-review/`.
52
52
  `ui-and-accessibility/` — README stub only (N/A for MCP server authoring).
53
+
54
+ ## Metrics policy mapping
55
+
56
+ | Shared core | Runtime integration | Loading |
57
+ |-------------|---------------------|---------|
58
+ | `agent-team/agent-task-metrics.md` | `agent-team-orchestrator` + `hooks/chain-team-phases.sh` | requestable/on-demand; never session-start |
@@ -63,6 +63,10 @@ flowchart TD
63
63
 
64
64
  **Source of truth for order:** `pipeline.json` → `steps[]`. Never hardcode analyst → dev → review → QA when `pipeline.json` exists.
65
65
 
66
+ ## Metrics lifecycle
67
+
68
+ 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`.
69
+
66
70
  ## status.json (pipeline mode)
67
71
 
68
72
  ```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,8 +13,6 @@ paths:
13
13
 
14
14
  **`commands/technical-retro.md`** → `/technical-retro`
15
15
 
16
- Используй rule только если command недоступен. Не дублируй содержимое command в ответе следуй command-файлу и skill `technical-retro`.
17
-
18
- ## Stack notes
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.
19
17
 
20
- - **Phase 1:** skill `technical-retro` is not shipped follow `commands/technical-retro.md` only; do not fail if the skill is absent (Phase 2 may add the skill).
18
+ Используй rule только если command недоступен. Не дублируй содержимое command в ответе следуй command-файлу и skill `technical-retro`.
@@ -15,3 +15,11 @@ Phase 1 agents: see `agents/README.md`.
15
15
  `task-router`, `task-analyst`, `solution-architect`, `feature-developer`, `build-verifier`, `security-reviewer`.
16
16
 
17
17
  Do **not** name Phase 2 agents (`contract-test-*`, `debugger`, Playwright stems, etc.) in fixture JSON — even as skips. Defer those until the agents ship.
18
+
19
+ ## Local metrics ledger
20
+
21
+ `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. 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.
22
+
23
+ `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`.
24
+
25
+ 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.
@@ -35,14 +35,14 @@ When validating **preset packaging** changes (paths under `packages/ai-rules/pre
35
35
  2. **Leakage (next):** hooks/agents must not require `xcuitest-test-*` handoffs or `xcodebuild` as the default Next post-change gate. See `tooling-and-review/preset-no-cross-stack-leakage.md`.
36
36
  3. **Mapping / README:** `rules/README.md` must include a Cursor→Claude mapping table; document core→stack mapping when `_shared` consumers exist.
37
37
  4. **shared-core consumers:** if `_shared/core/**` changed, every file with matching `<!-- shared-core: … -->` in this PR must be updated (or intentional fork documented).
38
- 5. **Twin presence:** Cursor rule change without Claude twin same PR → **FAIL** (next, ios-swift, go, and java). Domain twin body ≥15 lines; thin aliases may be shorter.
38
+ 5. **Twin presence:** Cursor rule change without Claude twin same PR → **FAIL** (next, ios-swift, go, java, mcp-ts, php-hexagonal, and php-laravel). Domain twin body ≥15 lines; thin aliases may be shorter.
39
39
  6. **Session-start body budget:** sum body lines of the **3** intended session-start rules ≤ **140** (stretch ≤120); do **not** include `**/README.md` — record in validation-report; FAIL if grossly over.
40
40
  7. **Embed drift (hard in `check:preset-structure`):** run `packages/ai-rules/scripts/check-shared-core-drift.sh` with `AI_RULES_DRIFT_FAIL=1` (bundled by the structure orchestrator). Lineage stems excluded from body equality.
41
41
  8. **Dogfood (monorepo soft):** prefer `packages/ai-rules/scripts/sync-dogfood-cursor.sh`; mass dogfood deletion without migration doc → risk / FAIL for maintainers.
42
42
 
43
- 9. **Root AGENTS template:** each installable preset (`cursor|claude` × `next|ios-swift|go|java`) must ship `REPO_AGENTS.md` when validating preset packaging → **FAIL** if missing.
43
+ 9. **Root AGENTS template:** each installable preset (`cursor|claude` × `next|ios-swift|go|java|mcp-ts|php-hexagonal`) must ship `REPO_AGENTS.md` when validating preset packaging → **FAIL** if missing.
44
44
  10. **Hooks cookbook:** default `hooks.json` must **not** reference `hooks/examples/` → **FAIL** if it does.
45
- 11. **No react-performance on ios/go/java:** skill directory / required handoff must be absent under ios-swift, go, and java → **FAIL** (leakage). Prefer `check:preset-leakage`.
45
+ 11. **No react-performance on ios/go/java:** skill directory / required handoff must be absent under ios-swift, go, java, mcp-ts, php-hexagonal, and php-laravel → **FAIL** (leakage). Prefer `check:preset-leakage`.
46
46
  12. **Rule eval (WARN):** `scripts/check-rule-eval.mjs` / `yarn check:rule-eval` should exist for maintainers; smoke optional. Hard fail only when the opt-in eval job runs — not part of default `check:preset-structure`.
47
47
 
48
48
  ### Soft notes
@@ -106,3 +106,7 @@ Write `.claude/team/tasks/<slug>/pipeline.json` and initial `status.json` (write
106
106
  5. Invoke `steps[0].agent` now (unless `retro` → `/technical-retro`).
107
107
 
108
108
  Do not invoke implementation agents yourself.
109
+
110
+ ## Metrics initialization
111
+
112
+ Alongside `pipeline.json` and `status.json`, create `metrics.json` with `schemaVersion: 1`, immutable task dimensions, `task_started`, and a generated `runId`. Before the parent invokes each agent, append `attempt_started` and set `status.activeAttempts[attemptId]` with agent, step index, attempt number, and host-clock `startedAt`. For parallel work create one entry per agent; do not use `currentAgent` to identify their completion.
@@ -22,22 +22,19 @@ description: Continue an agent-team task after a human gate, pause, or review ch
22
22
  ## Алгоритм
23
23
 
24
24
  1. Запиши `.claude/team/active-task.json` → `{ "slug": "<slug>" }`.
25
- 2. Сбрось gate: `awaitingHumanGate: false`.
26
- 3. Определи **следующий шаг**:
27
- - После approval analyst/architect: `pipelineIndex + 1` следующий agent в `steps`.
28
- - После `changes_requested`: снова **feature-developer** (тот же index или найди developer в steps).
29
- 4. Обнови `status.json`:
30
- ```json
31
- {
32
- "pipelineIndex": <n>,
33
- "currentAgent": "<steps[n].agent>",
34
- "phase": "executing",
35
- "state": "in_progress",
36
- "awaitingHumanGate": false
37
- }
38
- ```
39
- 5. Вызови subagent для `currentAgent` с контекстом slug и артефактов.
40
- 6. Если hook `chain-team-phases.sh` включён в проекте и `autoChain: true`, он продолжит цепочку по `pipeline.json`; иначе продолжай следующий шаг вручную.
25
+ 2. **Human gate resume** (`awaitingHumanGate` / `awaiting_approval`):
26
+ 1. **Do not** manually increment `pipelineIndex` or invent `currentAgent` first.
27
+ 2. Close the gate + activate the next attempt via the **installed** hook (single authority for ledger + status):
28
+
29
+ ```bash
30
+ printf '%s\n' '{"status":"completed","action":"end_human_gate","activateNext":true}' | bash .claude/hooks/chain-team-phases.sh
31
+ ```
32
+
33
+ 3. Re-read `status.json` (and the hook `followup_message`).
34
+ 4. Invoke the subagent named in `status.currentAgent` / followup — do **not** advance the pipeline a second time.
35
+ 3. **Review `changes_requested`** (not a human gate): set `currentAgent` to `feature-developer` (same index / find developer in steps), `state: in_progress`, then invoke developer. Do **not** call `end_human_gate` unless `activeHumanGateEventId` is set.
36
+ 4. **Other resume**: restore `pipelineIndex` / `currentAgent` from status and invoke that agent.
37
+ 5. After the invoked agent completes, `chain-team-phases.sh` on `subagentStop` continues the chain when `autoChain: true`.
41
38
 
42
39
  ## Артефакты для handoff
43
40
 
@@ -47,3 +44,7 @@ description: Continue an agent-team task after a human gate, pause, or review ch
47
44
  | build-verifier | git diff, decomposition.md |
48
45
  | code-reviewer | brief.md, validation-report.md, git diff |
49
46
  | qa-tester | brief.md, decomposition.md, scope from pipeline step |
47
+
48
+ ## Metrics
49
+
50
+ On human-gate resume, the hook action above appends `human_gate_ended` under the per-task lock **before** any new `attempt_started`. Agents must not calculate durations.
@@ -48,3 +48,7 @@ description: Route a natural-language task through the agent-team pipeline: task
48
48
  ## Legacy
49
49
 
50
50
  `/feature-start` и `/feature-continue` остаются совместимыми; для новых задач предпочитай `/task`.
51
+
52
+ ## Metrics
53
+
54
+ Initialize `metrics.json` before the first invocation with frozen task dimensions and `task_started`; add one `activeAttempts[attemptId]` entry plus `attempt_started` per scheduled agent. On `/task-continue`, append `human_gate_ended` (referencing the stored gate event) before activating the next attempt. Do not calculate durations in agents.
@@ -56,3 +56,7 @@ description: Facilitate a technical retrospective for a period, incident, releas
56
56
  - Не приписывать команде цитаты или факты, которых не было во входе.
57
57
  - Не выдавать юридические/HR‑рекомендации; при явных конфликтах или токсичности — мягко предложить эскалацию человеку, ответственному за команду, без детализации «наказаний».
58
58
  - Если пользователь просит только шаблон — выдать **шаблон повестки и доски** (колонки, таймбоксы) без выдуманного контента.
59
+
60
+ ### Metrics evidence
61
+
62
+ When `metrics.json` exists, run the local aggregation script and report the cohort, sample size, incomplete artifacts, attribution confidence, active attempt duration, and human-gate wait separately. Do not treat gate wait or malformed ledgers as agent duration.