@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 = 'ios-swift';
64
+ const PLATFORM = 'cursor';
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
  }
@@ -174,16 +276,29 @@ const REVIEW_AGENTS = new Set([
174
276
  'api-contract-reviewer',
175
277
  ]);
176
278
 
279
+ function metricsHandoff(agent) {
280
+ const matches = Object.entries(status.activeAttempts || {}).filter(([, entry]) => entry.agent === agent);
281
+ if (matches.length === 1) {
282
+ 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.`;
283
+ }
284
+ 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.';
285
+ }
286
+
177
287
  function handoffForAgent(agent, scope) {
178
288
  const fn = AGENT_HANDOFF[agent];
179
- return fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
289
+ const handoff = fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
290
+ return handoff + metricsHandoff(agent);
180
291
  }
181
292
 
182
293
  function handoffForParallelStep(step) {
183
294
  const agents = getStepAgents(step);
295
+ const attemptIds = Object.entries(status.activeAttempts || {})
296
+ .filter(([, entry]) => agents.includes(entry.agent))
297
+ .map(([attemptId, entry]) => `${entry.agent}=${attemptId}`);
184
298
  return (
185
299
  `Invoke IN PARALLEL (one message, multiple Task calls): ${agents.join(' AND ')} for slug "${slug}". ` +
186
- `Each agent writes its artifact and appends itself to status.json parallelCompleted when done.`
300
+ `Each agent writes its artifact and appends itself to status.json parallelCompleted when done. ` +
301
+ `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.`
187
302
  );
188
303
  }
189
304
 
@@ -215,34 +330,38 @@ function legacyFlow() {
215
330
  out(handoffForAgent('qa-tester'));
216
331
  process.exit(0);
217
332
  }
333
+ function scheduleLegacyRetry(agent, retryAfterFix) {
334
+ const stepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
335
+ const predecessorAttemptId = status.lastCompletedAttempt?.attemptId || null;
336
+ appendMetric({ type: 'retry_scheduled', at: now, attemptId: predecessorAttemptId, nextAgent: agent, retryAfterFix: retryAfterFix || null, source: 'hook', attributionConfidence: 'unknown' });
337
+ activateAttempts({ agent }, stepIndex);
338
+ }
218
339
  if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
340
+ const reviewer = status.currentAgent;
341
+ scheduleLegacyRetry('feature-developer', reviewer);
219
342
  writeStatus({
220
343
  currentAgent: 'feature-developer',
221
344
  state: 'in_progress',
222
345
  phase: 'executing',
223
- retryAfterFix: status.currentAgent,
346
+ retryAfterFix: reviewer,
224
347
  });
225
- out(
226
- handoffForAgent('feature-developer') +
227
- ` After fixes, re-run ${status.currentAgent}.`,
228
- );
348
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${reviewer}.`);
229
349
  process.exit(0);
230
350
  }
231
351
  if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
352
+ scheduleLegacyRetry('feature-developer', 'build-verifier');
232
353
  writeStatus({
233
354
  currentAgent: 'feature-developer',
234
355
  state: 'in_progress',
235
356
  phase: 'executing',
236
357
  retryAfterFix: 'build-verifier',
237
358
  });
238
- out(
239
- handoffForAgent('feature-developer') +
240
- ` Read validation-report.md. After fixes, re-run build-verifier.`,
241
- );
359
+ out(handoffForAgent('feature-developer') + ' Read validation-report.md. After fixes, re-run build-verifier.');
242
360
  process.exit(0);
243
361
  }
244
362
  if (status.state === 'completed' && status.retryAfterFix) {
245
363
  const retry = status.retryAfterFix;
364
+ scheduleLegacyRetry(retry, null);
246
365
  writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
247
366
  out(handoffForAgent(retry));
248
367
  process.exit(0);
@@ -256,6 +375,56 @@ function legacyFlow() {
256
375
  process.exit(0);
257
376
  }
258
377
 
378
+
379
+ if (hookInput.action === 'end_human_gate') {
380
+ status.awaitingHumanGate = false;
381
+ if (status.state === 'awaiting_approval') {
382
+ status.state = 'in_progress';
383
+ status.phase = status.phase === 'human_gate' ? 'executing' : status.phase;
384
+ }
385
+ if (status.activeHumanGateEventId) {
386
+ appendMetric({
387
+ type: 'human_gate_ended',
388
+ at: now,
389
+ gateStartedEventId: status.activeHumanGateEventId,
390
+ source: 'orchestrator',
391
+ attributionConfidence: 'high',
392
+ });
393
+ delete status.activeHumanGateEventId;
394
+ }
395
+ if (hookInput.activateNext && fs.existsSync(pipelinePath)) {
396
+ let resumePipeline = null;
397
+ try { resumePipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8')); } catch {}
398
+ if (resumePipeline) {
399
+ const resumeSteps = resumePipeline.steps || [];
400
+ const resumeStart = (typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0) + 1;
401
+ const resumeNext = findNextExecutableStep(resumeSteps, resumeStart, taskDir);
402
+ if (resumeNext) {
403
+ const resumeAgents = getStepAgents(resumeNext.step);
404
+ activateAttempts(resumeNext.step, resumeNext.index);
405
+ writeStatus({
406
+ pipelineIndex: resumeNext.index,
407
+ currentAgent: resumeAgents[0],
408
+ phase: 'executing',
409
+ state: 'in_progress',
410
+ awaitingHumanGate: false,
411
+ parallelCompleted: [],
412
+ });
413
+ if (resumeNext.step.parallel && resumeAgents.length > 1) out(handoffForParallelStep(resumeNext.step));
414
+ else out(handoffForAgent(resumeAgents[0], resumeNext.step.scope));
415
+ process.exit(0);
416
+ }
417
+ }
418
+ }
419
+ writeStatus({
420
+ awaitingHumanGate: false,
421
+ state: status.state,
422
+ phase: status.phase,
423
+ });
424
+ process.stdout.write(JSON.stringify({ ok: true, action: 'end_human_gate', activeHumanGateEventId: status.activeHumanGateEventId || null }));
425
+ process.exit(0);
426
+ }
427
+
259
428
  if (!fs.existsSync(pipelinePath)) {
260
429
  legacyFlow();
261
430
  }
@@ -268,6 +437,15 @@ try {
268
437
  }
269
438
 
270
439
  const steps = pipeline.steps || [];
440
+ const initialIdx = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
441
+ const initialStep = steps[initialIdx];
442
+ const activeAttemptCountBeforeFinish = Object.keys(status.activeAttempts || {}).length;
443
+ const finishedAttempt = finishActiveAttempt();
444
+ if (!finishedAttempt && (hookInput.attemptId || activeAttemptCountBeforeFinish > 0)) {
445
+ process.stdout.write('{}');
446
+ process.exit(0);
447
+ }
448
+ endHumanGateIfResumed();
271
449
  if (steps.length === 0 || pipeline.autoChain === false) {
272
450
  process.stdout.write('{}');
273
451
  process.exit(0);
@@ -278,38 +456,57 @@ if (status.awaitingHumanGate || status.state === 'awaiting_approval') {
278
456
  process.exit(0);
279
457
  }
280
458
 
459
+ function nearestPrecedingStepIndex(agent, fromIndex, fallback) {
460
+ for (let index = fromIndex - 1; index >= 0; index -= 1) {
461
+ if (getStepAgents(steps[index]).includes(agent)) return index;
462
+ }
463
+ const match = steps.findIndex((step) => getStepAgents(step).includes(agent));
464
+ return match >= 0 ? match : fallback;
465
+ }
466
+ function scheduleRetry(agent, retryAfterFix, predecessor, explicitStepIndex = null) {
467
+ const currentIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
468
+ const stepIndex = Number.isInteger(explicitStepIndex) ? explicitStepIndex : nearestPrecedingStepIndex(agent, currentIndex, currentIndex);
469
+ const predecessorAttemptId = predecessor?.attemptId || status.lastCompletedAttempt?.attemptId || null;
470
+ appendMetric({ type: 'retry_scheduled', at: now, attemptId: predecessorAttemptId, nextAgent: agent, retryAfterFix: retryAfterFix || null, source: 'hook', attributionConfidence: predecessor ? predecessor.confidence : 'unknown' });
471
+ activateAttempts(steps[stepIndex] || { agent }, stepIndex);
472
+ return stepIndex;
473
+ }
474
+
281
475
  if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
282
476
  const reviewer = status.currentAgent;
477
+ const retryAfterFixStepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
478
+ const developerIndex = scheduleRetry('feature-developer', reviewer, finishedAttempt);
283
479
  writeStatus({
480
+ pipelineIndex: developerIndex,
284
481
  currentAgent: 'feature-developer',
285
482
  state: 'in_progress',
286
483
  phase: 'executing',
287
484
  retryAfterFix: reviewer,
485
+ retryAfterFixStepIndex,
288
486
  });
289
- out(
290
- handoffForAgent('feature-developer') +
291
- ` After fixes, re-run ${reviewer}.`,
292
- );
487
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${reviewer}.`);
293
488
  process.exit(0);
294
489
  }
295
490
 
296
491
  if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
492
+ const retryAfterFixStepIndex = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
493
+ const developerIndex = scheduleRetry('feature-developer', 'build-verifier', finishedAttempt);
297
494
  writeStatus({
495
+ pipelineIndex: developerIndex,
298
496
  currentAgent: 'feature-developer',
299
497
  state: 'in_progress',
300
498
  phase: 'executing',
301
499
  retryAfterFix: 'build-verifier',
500
+ retryAfterFixStepIndex,
302
501
  });
303
- out(
304
- handoffForAgent('feature-developer') +
305
- ` Read validation-report.md. After fixes, re-run build-verifier.`,
306
- );
502
+ out(handoffForAgent('feature-developer') + ' Read validation-report.md. After fixes, re-run build-verifier.');
307
503
  process.exit(0);
308
504
  }
309
505
 
310
506
  if (status.state === 'completed' && status.retryAfterFix) {
311
507
  const retry = status.retryAfterFix;
312
- writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
508
+ const retryIndex = scheduleRetry(retry, null, finishedAttempt, status.retryAfterFixStepIndex);
509
+ writeStatus({ pipelineIndex: retryIndex, currentAgent: retry, state: 'in_progress', retryAfterFix: null, retryAfterFixStepIndex: null });
313
510
  out(handoffForAgent(retry));
314
511
  process.exit(0);
315
512
  }
@@ -322,7 +519,7 @@ if (!currentStep) {
322
519
  process.exit(0);
323
520
  }
324
521
 
325
- const completedAgent = status.currentAgent || getStepAgents(currentStep)[0];
522
+ const completedAgent = finishedAttempt?.entry?.agent || status.currentAgent || getStepAgents(currentStep)[0];
326
523
  const stepAgents = getStepAgents(currentStep);
327
524
 
328
525
  if (currentStep.parallel && stepAgents.length > 1) {
@@ -340,6 +537,7 @@ if (currentStep.parallel && stepAgents.length > 1) {
340
537
  }
341
538
 
342
539
  if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
540
+ beginHumanGate();
343
541
  writeStatus({
344
542
  awaitingHumanGate: true,
345
543
  state: 'awaiting_approval',
@@ -351,6 +549,7 @@ if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
351
549
 
352
550
  const next = findNextExecutableStep(steps, idx + 1, taskDir);
353
551
  if (!next) {
552
+ completeTaskMetrics();
354
553
  writeStatus({
355
554
  pipelineIndex: steps.length,
356
555
  phase: 'done',
@@ -365,6 +564,7 @@ if (!next) {
365
564
  const { step: nextStep, index: nextIdx } = next;
366
565
  const nextAgents = getStepAgents(nextStep);
367
566
 
567
+ activateAttempts(nextStep, nextIdx);
368
568
  writeStatus({
369
569
  pipelineIndex: nextIdx,
370
570
  currentAgent: nextAgents[0],
@@ -86,3 +86,9 @@ globs
86
86
  ```
87
87
 
88
88
  Установка: `npx @bonesofspring/ai-rules init cursor --preset ios-swift`
89
+
90
+ ## Metrics policy mapping
91
+
92
+ | Shared core | Runtime integration | Loading |
93
+ |-------------|---------------------|---------|
94
+ | `agent-team/agent-task-metrics.md` | `agent-team-orchestrator` + `hooks/chain-team-phases.sh` | requestable/on-demand; never session-start |
@@ -57,6 +57,10 @@ When editing `packages/ai-rules/presets/**`, follow **`preset-pr-checklist.mdc`*
57
57
 
58
58
  **Source of truth for order:** `pipeline.json` → `steps[]`. Never hardcode analyst → dev → review → QA when `pipeline.json` exists.
59
59
 
60
+ ## Metrics lifecycle
61
+
62
+ 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`.
63
+
60
64
  ## status.json (pipeline mode)
61
65
 
62
66
  | state | Meaning |
@@ -24,7 +24,7 @@ alwaysApply: false
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 @@ alwaysApply: false
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 @@ alwaysApply: false
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`.
@@ -11,4 +11,6 @@ alwaysApply: false
11
11
 
12
12
  **`commands/technical-retro.md`** → `/technical-retro`
13
13
 
14
+ 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.
15
+
14
16
  Используй rule только если command недоступен. Не дублируй содержимое command в ответе — следуй command-файлу и skill `technical-retro`.
@@ -29,3 +29,11 @@
29
29
  ## Creating task dirs
30
30
 
31
31
  Bootstrap `tasks/<slug>/` by **writing** artifacts (Write tool), not Shell `mkdir`. Cursor sandbox → `Operation not permitted` otherwise (worse on Desktop/Documents).
32
+
33
+ ## Local metrics ledger
34
+
35
+ `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.
36
+
37
+ `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`.
38
+
39
+ Aggregate with `node packages/ai-rules/scripts/aggregate-agent-task-metrics.mjs --team-root .cursor/team`. It reports role/agent count, completed count, total/average duration, distinct completed run IDs, separate human-gate wait, and incomplete artifacts.
@@ -32,13 +32,13 @@ Hard gates for the **java** stack:
32
32
  | **twin-map** | `java` missing from `STACKS`, or Cursor↔Claude orphan/missing twins |
33
33
  | **token-budget** | Cursor `alwaysApply` ≠ 3 or Claude session-start (excl. README) ≠ 3, or trio body sum > 140 |
34
34
  | **leakage** | `JAVA_FORBIDDEN_*` hits (Playwright/XCUITest/`lint:js`/`accessibility-reviewer` as required handoffs) |
35
- | **chain fork** | `hooks/chain-team-phases.sh` byte-identical to **next**, **ios-swift**, or **go** (same platform) |
35
+ | **chain fork** | `hooks/chain-team-phases.sh` byte-identical to **next**, **ios-swift**, **go**, **mcp-ts**, **php-hexagonal**, or **php-laravel** (same platform) |
36
36
 
37
37
  Also document:
38
38
 
39
- 1. **Root AGENTS template:** each installable preset (`cursor|claude` × `next|ios-swift|go|java`) must ship `REPO_AGENTS.md` → **FAIL** if missing.
39
+ 1. **Root AGENTS template:** each installable preset (`cursor|claude` × `next|ios-swift|go|java|mcp-ts|php-hexagonal`) must ship `REPO_AGENTS.md` → **FAIL** if missing.
40
40
  2. **Hooks cookbook:** default `hooks.json` must **not** reference `hooks/examples/` → **FAIL** if it does.
41
- 3. **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`.
41
+ 3. **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`.
42
42
  4. **Shared-core drift (hard in `check:preset-structure`):** `check-shared-core-drift` with `AI_RULES_DRIFT_FAIL=1`.
43
43
  5. **Rule eval (WARN):** `yarn check:rule-eval` optional for maintainers; not part of default `check:preset-structure`.
44
44
 
@@ -67,3 +67,7 @@ Write `.cursor/team/tasks/<slug>/pipeline.json` and initial `status.json` via th
67
67
  ## Handoff
68
68
 
69
69
  Intent + steps table + skipped + gates → invoke `steps[0].agent` (unless retro).
70
+
71
+ ## Metrics initialization
72
+
73
+ 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. Запиши `.cursor/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` продолжит цепочку по `pipeline.json`, если `autoChain: true`.
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 .cursor/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.
@@ -47,3 +47,7 @@ description: Route a natural-language task through the agent-team pipeline: task
47
47
  ## Legacy
48
48
 
49
49
  `/feature-start` и `/feature-continue` остаются совместимыми; для новых задач предпочитай `/task`.
50
+
51
+ ## Metrics
52
+
53
+ 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.
@@ -79,3 +79,7 @@ description: Facilitate a technical retrospective for a period, incident, releas
79
79
  - Не приписывать цитаты и факты без входа.
80
80
  - Не выдавать HR‑рекомендации.
81
81
  - Если просят только шаблон — **шаблон повестки** без выдуманного контента.
82
+
83
+ ### Metrics evidence
84
+
85
+ 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.