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