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