@bonesofspring/ai-rules 0.2.20 → 0.2.21
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 +28 -0
- package/README.md +17 -2
- package/bin/cli.js +83 -6
- package/package.json +5 -2
- package/presets/_shared/README.md +2 -1
- package/presets/_shared/assets/docs-specs/INDEX.md +4 -1
- package/presets/_shared/core/agent-team/agent-artifact-contracts.md +13 -0
- package/presets/_shared/core/agent-team/agent-task-metrics.md +1 -1
- package/presets/_shared/core/agent-team/agent-team-orchestrator.md +1 -3
- package/presets/_shared/core/meta/preset-pr-checklist.md +5 -1
- package/presets/_shared/core/meta/preset-token-budget.md +7 -3
- package/presets/_shared/core/meta/preset-twin-sync.md +2 -0
- package/presets/_shared/core/testing/testing-principles.md +70 -0
- package/presets/claude/android-kotlin/agents/README.md +2 -1
- package/presets/claude/android-kotlin/agents/feature-developer.md +1 -1
- package/presets/claude/android-kotlin/agents/openspec-author.md +163 -0
- package/presets/claude/android-kotlin/agents/task-analyst.md +1 -1
- package/presets/claude/android-kotlin/agents/task-router.md +5 -1
- package/presets/claude/android-kotlin/agents/tech-writer.md +4 -0
- package/presets/claude/android-kotlin/commands/README.md +0 -2
- package/presets/claude/android-kotlin/commands/task-continue.md +1 -1
- package/presets/claude/android-kotlin/commands/task.md +1 -5
- package/presets/claude/android-kotlin/commands/technical-retro.md +2 -2
- package/presets/claude/android-kotlin/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/android-kotlin/rules/README.md +1 -0
- package/presets/claude/android-kotlin/rules/tooling-and-review/agent-team-orchestrator.md +7 -4
- package/presets/claude/android-kotlin/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/android-kotlin/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/android-kotlin/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/android-kotlin/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/go/README.md +1 -1
- package/presets/claude/go/agents/README.md +3 -2
- package/presets/claude/go/agents/openspec-author.md +163 -0
- package/presets/claude/go/agents/task-router.md +5 -1
- package/presets/claude/go/agents/tech-writer.md +4 -0
- package/presets/claude/go/commands/README.md +0 -2
- package/presets/claude/go/commands/task-continue.md +1 -1
- package/presets/claude/go/commands/task.md +1 -4
- package/presets/claude/go/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/go/rules/README.md +1 -0
- package/presets/claude/go/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/go/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/go/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/ios-swift/agents/README.md +3 -2
- package/presets/claude/ios-swift/agents/feature-developer.md +1 -1
- package/presets/claude/ios-swift/agents/openspec-author.md +163 -0
- package/presets/claude/ios-swift/agents/task-analyst.md +1 -1
- package/presets/claude/ios-swift/agents/task-router.md +5 -1
- package/presets/claude/ios-swift/agents/tech-writer.md +4 -0
- package/presets/claude/ios-swift/commands/README.md +0 -2
- package/presets/claude/ios-swift/commands/task-continue.md +1 -1
- package/presets/claude/ios-swift/commands/task.md +1 -5
- package/presets/claude/ios-swift/commands/technical-retro.md +2 -2
- package/presets/claude/ios-swift/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/ios-swift/rules/README.md +1 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-orchestrator.md +7 -4
- package/presets/claude/ios-swift/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/java/CLAUDE.md +1 -1
- package/presets/claude/java/agents/README.md +3 -2
- package/presets/claude/java/agents/openspec-author.md +163 -0
- package/presets/claude/java/agents/task-router.md +5 -1
- package/presets/claude/java/agents/tech-writer.md +4 -0
- package/presets/claude/java/commands/README.md +0 -2
- package/presets/claude/java/commands/task-continue.md +1 -1
- package/presets/claude/java/commands/task.md +1 -4
- package/presets/claude/java/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/java/rules/README.md +1 -0
- package/presets/claude/java/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/java/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/java/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/java/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/java/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/mcp-ts/agents/task-analyst.md +1 -1
- package/presets/claude/mcp-ts/commands/README.md +0 -2
- package/presets/claude/mcp-ts/commands/task-continue.md +1 -1
- package/presets/claude/mcp-ts/commands/task.md +1 -4
- package/presets/claude/mcp-ts/commands/technical-retro.md +2 -2
- package/presets/claude/mcp-ts/hooks/chain-team-phases.sh +40 -9
- package/presets/claude/mcp-ts/rules/README.md +1 -0
- package/presets/claude/mcp-ts/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/mcp-ts/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/mcp-ts/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/mcp-ts/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/next/README.md +1 -0
- package/presets/claude/next/agents/README.md +2 -2
- package/presets/claude/next/agents/build-verifier.md +11 -1
- package/presets/claude/next/agents/feature-developer.md +1 -1
- package/presets/claude/next/agents/openspec-author.md +163 -0
- package/presets/claude/next/agents/task-analyst.md +1 -1
- package/presets/claude/next/agents/task-router.md +5 -1
- package/presets/claude/next/agents/tech-writer.md +4 -0
- package/presets/claude/next/commands/README.md +0 -2
- package/presets/claude/next/commands/task-continue.md +1 -1
- package/presets/claude/next/commands/task.md +1 -4
- package/presets/claude/next/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/next/rules/README.md +1 -0
- package/presets/claude/next/rules/testing/README.md +6 -0
- package/presets/claude/next/rules/testing/tests-e2e-structure.md +84 -48
- package/presets/claude/next/rules/testing/tests-unit.md +79 -50
- package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +3 -4
- package/presets/claude/next/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/next/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/next/team/README.md +0 -3
- package/presets/claude/nuxt/agents/README.md +1 -1
- package/presets/claude/nuxt/agents/feature-developer.md +1 -1
- package/presets/claude/nuxt/agents/openspec-author.md +163 -0
- package/presets/claude/nuxt/agents/task-analyst.md +1 -1
- package/presets/claude/nuxt/agents/task-router.md +5 -1
- package/presets/claude/nuxt/agents/tech-writer.md +4 -0
- package/presets/claude/nuxt/commands/README.md +0 -2
- package/presets/claude/nuxt/commands/task-continue.md +1 -1
- package/presets/claude/nuxt/commands/task.md +1 -5
- package/presets/claude/nuxt/commands/technical-retro.md +2 -2
- package/presets/claude/nuxt/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/nuxt/rules/README.md +1 -0
- package/presets/claude/nuxt/rules/testing/README.md +6 -0
- package/presets/claude/nuxt/rules/testing/tests-e2e-structure.md +86 -43
- package/presets/claude/nuxt/rules/testing/tests-unit.md +58 -45
- package/presets/claude/nuxt/rules/tooling-and-review/agent-team-orchestrator.md +8 -5
- package/presets/claude/nuxt/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/nuxt/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/nuxt/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/nuxt/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/nuxt/team/README.md +0 -3
- package/presets/claude/php-hexagonal/CLAUDE.md +1 -1
- package/presets/claude/php-hexagonal/agents/README.md +3 -2
- package/presets/claude/php-hexagonal/agents/openspec-author.md +163 -0
- package/presets/claude/php-hexagonal/agents/task-router.md +5 -1
- package/presets/claude/php-hexagonal/agents/tech-writer.md +4 -0
- package/presets/claude/php-hexagonal/commands/README.md +0 -2
- package/presets/claude/php-hexagonal/commands/task-continue.md +1 -1
- package/presets/claude/php-hexagonal/commands/task.md +1 -4
- package/presets/claude/php-hexagonal/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/php-hexagonal/rules/README.md +1 -0
- package/presets/claude/php-hexagonal/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/php-hexagonal/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/php-laravel/agents/README.md +3 -2
- package/presets/claude/php-laravel/agents/openspec-author.md +163 -0
- package/presets/claude/php-laravel/agents/task-router.md +5 -1
- package/presets/claude/php-laravel/agents/tech-writer.md +4 -0
- package/presets/claude/php-laravel/commands/README.md +0 -2
- package/presets/claude/php-laravel/commands/task-continue.md +1 -1
- package/presets/claude/php-laravel/commands/task.md +1 -4
- package/presets/claude/php-laravel/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/php-laravel/rules/README.md +1 -0
- package/presets/claude/php-laravel/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/php-laravel/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/php-laravel/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/php-laravel/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/php-laravel/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/svelte/agents/README.md +1 -1
- package/presets/claude/svelte/agents/feature-developer.md +1 -1
- package/presets/claude/svelte/agents/openspec-author.md +163 -0
- package/presets/claude/svelte/agents/task-analyst.md +1 -1
- package/presets/claude/svelte/agents/task-router.md +5 -1
- package/presets/claude/svelte/agents/tech-writer.md +4 -0
- package/presets/claude/svelte/commands/README.md +0 -2
- package/presets/claude/svelte/commands/task-continue.md +1 -1
- package/presets/claude/svelte/commands/task.md +1 -5
- package/presets/claude/svelte/commands/technical-retro.md +2 -2
- package/presets/claude/svelte/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/svelte/rules/README.md +1 -0
- package/presets/claude/svelte/rules/testing/README.md +6 -0
- package/presets/claude/svelte/rules/testing/tests-e2e-structure.md +87 -45
- package/presets/claude/svelte/rules/testing/tests-unit.md +70 -23
- package/presets/claude/svelte/rules/tooling-and-review/agent-team-orchestrator.md +8 -5
- package/presets/claude/svelte/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/svelte/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/svelte/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/svelte/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/svelte/team/README.md +0 -3
- package/presets/cursor/android-kotlin/agents/README.md +2 -1
- package/presets/cursor/android-kotlin/agents/feature-developer.md +1 -1
- package/presets/cursor/android-kotlin/agents/openspec-author.md +164 -0
- package/presets/cursor/android-kotlin/agents/task-analyst.md +1 -1
- package/presets/cursor/android-kotlin/agents/task-router.md +5 -1
- package/presets/cursor/android-kotlin/agents/tech-writer.md +4 -0
- package/presets/cursor/android-kotlin/commands/README.md +0 -2
- package/presets/cursor/android-kotlin/commands/task-continue.md +1 -1
- package/presets/cursor/android-kotlin/commands/task.md +1 -5
- package/presets/cursor/android-kotlin/commands/technical-retro.md +2 -2
- package/presets/cursor/android-kotlin/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/android-kotlin/rules/agent-team-orchestrator.mdc +7 -4
- package/presets/cursor/android-kotlin/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/android-kotlin/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/android-kotlin/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/android-kotlin/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/go/README.md +6 -6
- package/presets/cursor/go/agents/README.md +3 -2
- package/presets/cursor/go/agents/openspec-author.md +164 -0
- package/presets/cursor/go/agents/task-router.md +5 -1
- package/presets/cursor/go/agents/tech-writer.md +4 -0
- package/presets/cursor/go/commands/README.md +0 -2
- package/presets/cursor/go/commands/task-continue.md +1 -1
- package/presets/cursor/go/commands/task.md +1 -4
- package/presets/cursor/go/commands/technical-retro.md +2 -2
- package/presets/cursor/go/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/go/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/go/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/go/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/go/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/go/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/ios-swift/README.md +6 -6
- package/presets/cursor/ios-swift/agents/README.md +3 -2
- package/presets/cursor/ios-swift/agents/feature-developer.md +1 -1
- package/presets/cursor/ios-swift/agents/openspec-author.md +164 -0
- package/presets/cursor/ios-swift/agents/task-analyst.md +1 -1
- package/presets/cursor/ios-swift/agents/task-router.md +5 -1
- package/presets/cursor/ios-swift/agents/tech-writer.md +4 -0
- package/presets/cursor/ios-swift/commands/README.md +1 -3
- package/presets/cursor/ios-swift/commands/task-continue.md +1 -1
- package/presets/cursor/ios-swift/commands/task.md +1 -5
- package/presets/cursor/ios-swift/commands/technical-retro.md +2 -2
- package/presets/cursor/ios-swift/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/ios-swift/rules/agent-team-orchestrator.mdc +7 -4
- package/presets/cursor/ios-swift/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/ios-swift/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/java/AGENTS.md +1 -1
- package/presets/cursor/java/agents/README.md +3 -2
- package/presets/cursor/java/agents/openspec-author.md +164 -0
- package/presets/cursor/java/agents/task-router.md +5 -1
- package/presets/cursor/java/agents/tech-writer.md +4 -0
- package/presets/cursor/java/commands/README.md +0 -2
- package/presets/cursor/java/commands/task-continue.md +1 -1
- package/presets/cursor/java/commands/task.md +1 -4
- package/presets/cursor/java/commands/technical-retro.md +2 -2
- package/presets/cursor/java/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/java/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/java/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/java/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/java/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/java/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/mcp-ts/agents/task-analyst.md +1 -1
- package/presets/cursor/mcp-ts/commands/README.md +0 -2
- package/presets/cursor/mcp-ts/commands/task-continue.md +1 -1
- package/presets/cursor/mcp-ts/commands/task.md +1 -4
- package/presets/cursor/mcp-ts/commands/technical-retro.md +2 -2
- package/presets/cursor/mcp-ts/hooks/chain-team-phases.sh +40 -9
- package/presets/cursor/mcp-ts/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/mcp-ts/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/mcp-ts/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/mcp-ts/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/next/README.md +8 -6
- package/presets/cursor/next/REPO_AGENTS.md +8 -0
- package/presets/cursor/next/agents/README.md +2 -2
- package/presets/cursor/next/agents/build-verifier.md +11 -1
- package/presets/cursor/next/agents/feature-developer.md +1 -1
- package/presets/cursor/next/agents/openspec-author.md +164 -0
- package/presets/cursor/next/agents/task-analyst.md +1 -1
- package/presets/cursor/next/agents/task-router.md +5 -1
- package/presets/cursor/next/agents/tech-writer.md +4 -0
- package/presets/cursor/next/commands/README.md +0 -2
- package/presets/cursor/next/commands/task-continue.md +1 -1
- package/presets/cursor/next/commands/task.md +1 -4
- package/presets/cursor/next/commands/technical-retro.md +2 -2
- package/presets/cursor/next/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/next/rules/README.md +6 -3
- package/presets/cursor/next/rules/agent-team-orchestrator.mdc +7 -5
- package/presets/cursor/next/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/next/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/next/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/next/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/next/rules/tests-e2e-structure.mdc +83 -43
- package/presets/cursor/next/rules/tests-unit.mdc +78 -45
- package/presets/cursor/next/team/README.md +0 -3
- package/presets/cursor/nuxt/README.md +6 -6
- package/presets/cursor/nuxt/agents/README.md +1 -1
- package/presets/cursor/nuxt/agents/feature-developer.md +1 -1
- package/presets/cursor/nuxt/agents/openspec-author.md +164 -0
- package/presets/cursor/nuxt/agents/task-analyst.md +1 -1
- package/presets/cursor/nuxt/agents/task-router.md +5 -1
- package/presets/cursor/nuxt/agents/tech-writer.md +4 -0
- package/presets/cursor/nuxt/commands/README.md +0 -2
- package/presets/cursor/nuxt/commands/task-continue.md +1 -1
- package/presets/cursor/nuxt/commands/task.md +1 -5
- package/presets/cursor/nuxt/commands/technical-retro.md +2 -2
- package/presets/cursor/nuxt/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/nuxt/rules/README.md +3 -1
- package/presets/cursor/nuxt/rules/agent-team-orchestrator.mdc +8 -5
- package/presets/cursor/nuxt/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/nuxt/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/nuxt/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/nuxt/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/nuxt/rules/tests-e2e-structure.mdc +87 -43
- package/presets/cursor/nuxt/rules/tests-unit.mdc +62 -47
- package/presets/cursor/nuxt/team/README.md +0 -3
- package/presets/cursor/php-hexagonal/AGENTS.md +1 -1
- package/presets/cursor/php-hexagonal/agents/README.md +3 -2
- package/presets/cursor/php-hexagonal/agents/openspec-author.md +164 -0
- package/presets/cursor/php-hexagonal/agents/task-router.md +5 -1
- package/presets/cursor/php-hexagonal/agents/tech-writer.md +4 -0
- package/presets/cursor/php-hexagonal/commands/README.md +0 -2
- package/presets/cursor/php-hexagonal/commands/task-continue.md +1 -1
- package/presets/cursor/php-hexagonal/commands/task.md +1 -4
- package/presets/cursor/php-hexagonal/commands/technical-retro.md +2 -2
- package/presets/cursor/php-hexagonal/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/php-hexagonal/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/php-hexagonal/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/php-hexagonal/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/php-hexagonal/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/php-hexagonal/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/php-laravel/AGENTS.md +1 -1
- package/presets/cursor/php-laravel/agents/README.md +3 -2
- package/presets/cursor/php-laravel/agents/openspec-author.md +164 -0
- package/presets/cursor/php-laravel/agents/task-router.md +5 -1
- package/presets/cursor/php-laravel/agents/tech-writer.md +4 -0
- package/presets/cursor/php-laravel/commands/README.md +0 -2
- package/presets/cursor/php-laravel/commands/task-continue.md +1 -1
- package/presets/cursor/php-laravel/commands/task.md +1 -4
- package/presets/cursor/php-laravel/commands/technical-retro.md +2 -2
- package/presets/cursor/php-laravel/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/php-laravel/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/php-laravel/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/php-laravel/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/php-laravel/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/php-laravel/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/svelte/README.md +6 -6
- package/presets/cursor/svelte/agents/README.md +1 -1
- package/presets/cursor/svelte/agents/feature-developer.md +1 -1
- package/presets/cursor/svelte/agents/openspec-author.md +164 -0
- package/presets/cursor/svelte/agents/task-analyst.md +1 -1
- package/presets/cursor/svelte/agents/task-router.md +5 -1
- package/presets/cursor/svelte/agents/tech-writer.md +4 -0
- package/presets/cursor/svelte/commands/README.md +0 -2
- package/presets/cursor/svelte/commands/task-continue.md +1 -1
- package/presets/cursor/svelte/commands/task.md +1 -5
- package/presets/cursor/svelte/commands/technical-retro.md +2 -2
- package/presets/cursor/svelte/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/svelte/rules/README.md +3 -1
- package/presets/cursor/svelte/rules/agent-team-orchestrator.mdc +8 -5
- package/presets/cursor/svelte/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/svelte/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/svelte/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/svelte/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/svelte/rules/tests-e2e-structure.mdc +87 -43
- package/presets/cursor/svelte/rules/tests-unit.mdc +72 -23
- package/presets/cursor/svelte/team/README.md +0 -3
- package/scripts/_lib/embed-stems.json +31 -0
- package/scripts/aggregate-agent-task-metrics.mjs +23 -0
- package/scripts/check-chain-hook-coverage.sh +109 -0
- package/scripts/check-local-overlay.sh +136 -0
- package/scripts/check-preset-i18n.sh +2 -2
- package/scripts/check-preset-leakage.sh +4 -1
- package/scripts/check-preset-structure.sh +21 -1
- package/scripts/check-preset-token-budget.sh +20 -10
- package/scripts/check-rule-eval.mjs +16 -0
- package/scripts/check-shared-core-drift.sh +10 -32
- package/scripts/close-agent-task-human-gate.mjs +22 -5
- package/scripts/sync-shared-core-embeds.sh +9 -20
- package/scripts/test-agent-task-metrics-hooks.mjs +1 -1
- package/scripts/test-chain-team-phases-coverage.mjs +411 -0
- package/presets/claude/android-kotlin/commands/feature-continue.md +0 -23
- package/presets/claude/android-kotlin/commands/feature-start.md +0 -41
- package/presets/claude/go/commands/feature-continue.md +0 -23
- package/presets/claude/go/commands/feature-start.md +0 -38
- package/presets/claude/ios-swift/commands/feature-continue.md +0 -23
- package/presets/claude/ios-swift/commands/feature-start.md +0 -41
- package/presets/claude/java/commands/feature-continue.md +0 -23
- package/presets/claude/java/commands/feature-start.md +0 -38
- package/presets/claude/mcp-ts/commands/feature-continue.md +0 -23
- package/presets/claude/mcp-ts/commands/feature-start.md +0 -41
- package/presets/claude/next/commands/feature-continue.md +0 -23
- package/presets/claude/next/commands/feature-start.md +0 -38
- package/presets/claude/nuxt/commands/feature-continue.md +0 -23
- package/presets/claude/nuxt/commands/feature-start.md +0 -41
- package/presets/claude/php-hexagonal/commands/feature-continue.md +0 -23
- package/presets/claude/php-hexagonal/commands/feature-start.md +0 -38
- package/presets/claude/php-laravel/commands/feature-continue.md +0 -23
- package/presets/claude/php-laravel/commands/feature-start.md +0 -38
- package/presets/claude/svelte/commands/feature-continue.md +0 -23
- package/presets/claude/svelte/commands/feature-start.md +0 -41
- package/presets/cursor/android-kotlin/commands/feature-continue.md +0 -23
- package/presets/cursor/android-kotlin/commands/feature-start.md +0 -41
- package/presets/cursor/go/commands/feature-continue.md +0 -23
- package/presets/cursor/go/commands/feature-start.md +0 -41
- package/presets/cursor/ios-swift/commands/feature-continue.md +0 -23
- package/presets/cursor/ios-swift/commands/feature-start.md +0 -41
- package/presets/cursor/java/commands/feature-continue.md +0 -23
- package/presets/cursor/java/commands/feature-start.md +0 -41
- package/presets/cursor/mcp-ts/commands/feature-continue.md +0 -23
- package/presets/cursor/mcp-ts/commands/feature-start.md +0 -41
- package/presets/cursor/next/commands/feature-continue.md +0 -23
- package/presets/cursor/next/commands/feature-start.md +0 -41
- package/presets/cursor/nuxt/commands/feature-continue.md +0 -23
- package/presets/cursor/nuxt/commands/feature-start.md +0 -41
- package/presets/cursor/php-hexagonal/commands/feature-continue.md +0 -23
- package/presets/cursor/php-hexagonal/commands/feature-start.md +0 -41
- package/presets/cursor/php-laravel/commands/feature-continue.md +0 -23
- package/presets/cursor/php-laravel/commands/feature-start.md +0 -41
- package/presets/cursor/svelte/commands/feature-continue.md +0 -23
- package/presets/cursor/svelte/commands/feature-start.md +0 -41
|
@@ -135,10 +135,17 @@ const DEFAULT_ARTIFACT_OUTPUT_IDS = {
|
|
|
135
135
|
'build-verifier': 'validation',
|
|
136
136
|
'code-reviewer': 'review',
|
|
137
137
|
'security-reviewer': 'security-review',
|
|
138
|
-
'accessibility-reviewer': 'a11y-review',
|
|
139
138
|
'performance-auditor': 'perf-report',
|
|
140
139
|
'api-contract-reviewer': 'api-contract-review',
|
|
141
140
|
'tech-writer': 'documentation',
|
|
141
|
+
'openspec-author': 'openspec-change',
|
|
142
|
+
'qa-tester': 'qa',
|
|
143
|
+
'unit-test-planner': 'unit-test-plan',
|
|
144
|
+
'unit-test-generator': 'unit-test-spec',
|
|
145
|
+
'unit-test-healer': 'unit-test-heal',
|
|
146
|
+
'integration-test-planner': 'integration-test-plan',
|
|
147
|
+
'integration-test-generator': 'integration-test-spec',
|
|
148
|
+
'integration-test-healer': 'integration-test-heal',
|
|
142
149
|
};
|
|
143
150
|
function artifactOutputIdFor(step, agent) {
|
|
144
151
|
if (step && typeof step.artifactOutputId === 'string') return step.artifactOutputId;
|
|
@@ -243,7 +250,17 @@ function recordSkippedStep(step, stepIndex) {
|
|
|
243
250
|
function writeStatus(next) {
|
|
244
251
|
status = { ...status, ...next, slug, updatedAt: now };
|
|
245
252
|
const temporary = `${statusPath}.${process.pid}.${Date.now()}.tmp`;
|
|
246
|
-
|
|
253
|
+
// Open + write + fsync + rename so the durable file lands on disk before
|
|
254
|
+
// the orchestrator reads it. Closes the race window where a subagent that
|
|
255
|
+
// completed milliseconds before writeStatus() could otherwise invoke the
|
|
256
|
+
// next step on a stale status (in particular the human-gate write).
|
|
257
|
+
const fd = fs.openSync(temporary, 'w');
|
|
258
|
+
try {
|
|
259
|
+
fs.writeSync(fd, JSON.stringify(status, null, 2) + '\n');
|
|
260
|
+
try { fs.fsyncSync(fd); } catch {}
|
|
261
|
+
} finally {
|
|
262
|
+
fs.closeSync(fd);
|
|
263
|
+
}
|
|
247
264
|
fs.renameSync(temporary, statusPath);
|
|
248
265
|
}
|
|
249
266
|
|
|
@@ -338,6 +355,12 @@ const AGENT_HANDOFF = {
|
|
|
338
355
|
`Follow tests-integration.mdc, integration-testing, and debug-investigation. Do not use browser e2e tooling. Upsert the owned terminal receipt in artifact-manifest.json; do not mutate status.json lifecycle fields.`,
|
|
339
356
|
'tech-writer': (s) =>
|
|
340
357
|
`Invoke tech-writer for slug "${s}". Write documentation.md from task artifacts. Upsert the owned terminal receipt in artifact-manifest.json; do not mutate status.json lifecycle fields.`,
|
|
358
|
+
'openspec-author': (s, scope) =>
|
|
359
|
+
`Invoke openspec-author for slug "${s}"${scope ? ` (scope: ${scope})` : ''}. ` +
|
|
360
|
+
`Read openspec/config.yaml schema + rules; if openspec/** is absent, emit blocked ("openspec/** not initialized"). ` +
|
|
361
|
+
`Author openspec/changes/<change-id>/{proposal.md, design.md, tasks.md, .openspec.yaml} and the capability spec delta per phase (explore|propose|apply|archive). ` +
|
|
362
|
+
`Run \`openspec validate <change-id> --type change --strict\` and \`openspec validate --specs --strict\` (Phase 3); surface FAIL output verbatim. ` +
|
|
363
|
+
`Upsert the owned terminal receipt (artifactOutputId \`openspec-change\`) in artifact-manifest.json with validator exit code + evidence paths; do not mutate status.json lifecycle fields. `,
|
|
341
364
|
};
|
|
342
365
|
|
|
343
366
|
const REVIEW_AGENTS = new Set([
|
|
@@ -511,9 +534,37 @@ if (!fs.existsSync(pipelinePath)) {
|
|
|
511
534
|
}
|
|
512
535
|
|
|
513
536
|
let pipeline;
|
|
537
|
+
let pipelineParseError = null;
|
|
514
538
|
try {
|
|
515
539
|
pipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8'));
|
|
516
|
-
} catch {
|
|
540
|
+
} catch (error) {
|
|
541
|
+
pipelineParseError = error;
|
|
542
|
+
}
|
|
543
|
+
// Modern pipelines carry an `intent` field. If pipeline.json is present but
|
|
544
|
+
// unparseable, surface the error so the orchestrator can stop and report
|
|
545
|
+
// instead of falling back to legacyFlow() — which silently drops modern
|
|
546
|
+
// roles like `openspec-author`, `qa-tester`, and the test-planner trio.
|
|
547
|
+
if (pipelineParseError) {
|
|
548
|
+
if (fs.existsSync(pipelinePath)) {
|
|
549
|
+
const raw = fs.readFileSync(pipelinePath, 'utf8');
|
|
550
|
+
const hasModernIntent = /"intent"\s*:/.test(raw);
|
|
551
|
+
appendMetric({
|
|
552
|
+
eventId: `${status.metricsRunId || slug}:pipeline_parse_error:${Date.now()}`,
|
|
553
|
+
type: 'pipeline_parse_error',
|
|
554
|
+
at: now,
|
|
555
|
+
source: 'hook',
|
|
556
|
+
attributionConfidence: 'high',
|
|
557
|
+
error: String(pipelineParseError.message || pipelineParseError),
|
|
558
|
+
hasModernIntent,
|
|
559
|
+
});
|
|
560
|
+
if (hasModernIntent) {
|
|
561
|
+
writeStatus({ state: 'blocked', phase: 'blocked', currentAgent: 'task-router' });
|
|
562
|
+
process.stdout.write(JSON.stringify({
|
|
563
|
+
followup_message: `pipeline.json is malformed for slug "${slug}" — JSON parse error: ${pipelineParseError.message}. Re-run the task-router to regenerate pipeline.json, then resume via /task-continue ${slug}.`,
|
|
564
|
+
}));
|
|
565
|
+
process.exit(0);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
517
568
|
legacyFlow();
|
|
518
569
|
}
|
|
519
570
|
|
|
@@ -30,6 +30,7 @@ Claude topic `.md` files are **derived** from Cursor SoT `presets/cursor/php-hex
|
|
|
30
30
|
| `architecture-boundaries.mdc` | `architecture/boundaries.md` |
|
|
31
31
|
| `anti-sycophancy-discipline.mdc` | `tooling-and-review/anti-sycophancy-discipline.md` |
|
|
32
32
|
| `code-quality-and-refactoring.mdc` | `tooling-and-review/code-quality.md` |
|
|
33
|
+
| `ai-local-overlay.mdc` | `tooling-and-review/ai-local-overlay.md` |
|
|
33
34
|
| `design-guidance.mdc` | `tooling-and-review/design-guidance.md` |
|
|
34
35
|
| `mcp-usage.mdc` | `tooling-and-review/mcp-usage.md` |
|
|
35
36
|
| `code-review-mr.mdc` | `tooling-and-review/code-review.md` |
|
|
@@ -23,8 +23,6 @@ Work request without `/task` — see **agent-team-intake** (when to suggest the
|
|
|
23
23
|
|---------|------|
|
|
24
24
|
| **`/task <desc>`** | **Preferred** — router → dynamic pipeline → first agent |
|
|
25
25
|
| `/task-continue <slug>` | After human gate or pause |
|
|
26
|
-
| `/feature-start <desc>` | Legacy: analyst-only start (no router) |
|
|
27
|
-
| `/feature-continue <slug>` | Alias of task-continue |
|
|
28
26
|
| `/spec-start [desc]` | Generate/bootstrap `docs/specs` — router intent `spec-gen` → analyst author mode → human gate |
|
|
29
27
|
| `/technical-retro [slug]` | Retro with agent team block |
|
|
30
28
|
|
|
@@ -163,7 +161,7 @@ After each agent completes, verify its terminal manifest receipt, then let the o
|
|
|
163
161
|
|
|
164
162
|
## Legacy mode
|
|
165
163
|
|
|
166
|
-
If `pipeline.json` is missing
|
|
164
|
+
If `pipeline.json` is missing, fall back to fixed phases: analysis → development → review → testing. Hook supports both.
|
|
167
165
|
|
|
168
166
|
## Skip pipeline when
|
|
169
167
|
|
|
@@ -208,4 +206,4 @@ When the work edits `packages/ai-rules/presets/**` (or dogfood `.cursor/` sync o
|
|
|
208
206
|
- Chain hook handoffs: `integration-test-*`, `post-change-test`, `php-tooling` — never `lint:js`, Playwright, XCUITest, or `xcodebuild`.
|
|
209
207
|
- Skills: `feature-delivery`, `unit-testing`, `integration-testing`, `ci-investigation`, `debug-investigation`, `code-review`, `technical-retro`, `write-adr`.
|
|
210
208
|
|
|
211
|
-
**Product specs:** When `/task
|
|
209
|
+
**Product specs:** When `/task` or `/spec-start` touches pages/features/`docs/specs`: if INDEX exists and no generate intent → instruct next agent to load requestable **`product-specs`** (consume; soft-fail; never invent). If generate/bootstrap/`spec-gen` → load **`product-specs-authoring`** + skill **`spec-authoring`** inside **task-analyst** (not a separate pipeline step); pass created spec paths + INDEX diff in handoff; human gate must approve before feature-developer. No-op if INDEX absent and no author intent.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Local overlay from .ai.local/ (consumer-owned rules with priority over preset rules) — MANDATORY
|
|
3
|
+
paths:
|
|
4
|
+
- "**/.ai.local/**"
|
|
5
|
+
- "**/AGENTS.md"
|
|
6
|
+
- "**/CLAUDE.md"
|
|
7
|
+
alwaysApply: false
|
|
8
|
+
impact: CRITICAL
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Local overlay (`.ai.local/`) — MANDATORY
|
|
12
|
+
|
|
13
|
+
This rule is mandatory. **You MUST** obey it on every turn, without exception.
|
|
14
|
+
|
|
15
|
+
## On every turn
|
|
16
|
+
|
|
17
|
+
1. **Probe** — before answering, run `ls -la .ai.local` from the repository root.
|
|
18
|
+
2. **Walk** — if `.ai.local/` exists at multiple levels (monorepo), read every level from root to leaf. **Deeper wins** in practice: more specific rules appear later in the assembled context and take precedence.
|
|
19
|
+
3. **Apply** — treat every `.ai.local/rules/*.md` and `.ai.local/conventions.md` as a higher-priority rule for this repo. The block below ("Authoring `.ai.local/rules/*.md`") defines the conventions.
|
|
20
|
+
4. **Conflict** — if a local rule conflicts with a preset rule, **the local rule wins**. If a local rule body contains `override: kill <preset-rule-name>`, drop that preset rule from your context window entirely.
|
|
21
|
+
5. **Acknowledge** — when answering a user question, briefly state which `.ai.local/` rules apply to the current task (one line is enough). Format: `Using .ai.local: <rule-name>(, <rule-name>)*`. If no `.ai.local/` exists, do NOT mention this rule.
|
|
22
|
+
|
|
23
|
+
If `.ai.local/` does not exist → **no-op**, do not error. Do not produce any log line about its absence.
|
|
24
|
+
|
|
25
|
+
## Authoring `.ai.local/rules/*.md` (consumer-side reference)
|
|
26
|
+
|
|
27
|
+
Each `.ai.local/rules/<name>.md` is a plain-markdown rule body. The model parses it as:
|
|
28
|
+
|
|
29
|
+
- Lines before `## Body` are scope metadata. Only `glob:` / `globs:` / `override:` lines are recognised.
|
|
30
|
+
- Everything from `## Body` onward is the rule body.
|
|
31
|
+
- `glob: always` → always-on. Counts against your context budget.
|
|
32
|
+
- `globs: <comma-separated globs>` → on-demand; applies only when matching files are in focus.
|
|
33
|
+
- `override: kill <preset-rule-name>` → drop that preset rule from context.
|
|
34
|
+
|
|
35
|
+
Keep files ≤ 120 lines. Match the style of preset rules (short sections, bullets, code examples).
|
|
36
|
+
|
|
37
|
+
## Limitations (read this)
|
|
38
|
+
|
|
39
|
+
- Cursor/Claude do **not** natively read `.ai.local/`. This rule is a **prompt-only** mechanism: it asks you, the model, to read and apply the files. Reliability is high but not 100%.
|
|
40
|
+
- If a user adds a file to `.ai.local/` mid-session, **restart the session** to be sure it is picked up.
|
|
41
|
+
- "Priority" is **contextual**, not enforced. Always re-read the local rule before answering questions that touch it.
|
|
42
|
+
- This rule is **not** session-start (Claude convention); it loads on touch of `.ai.local/**` or `AGENTS.md`/`CLAUDE.md`. The "every turn" mandate is enforced by the body text, not by Cursor/Claude loading semantics.
|
|
43
|
+
|
|
44
|
+
## Pointers
|
|
45
|
+
|
|
46
|
+
- Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package.
|
|
47
|
+
- Living gotchas alternative: `.claude/team/conventions.md`.
|
|
48
|
+
- Root `AGENTS.md` reinforces this rule with a `MANDATORY` section.
|
|
@@ -19,11 +19,15 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
|
|
|
19
19
|
- [ ] **Core:** if `_shared/core/**` changed — all `<!-- shared-core: … -->` consumers updated (or documented intentional fork)
|
|
20
20
|
- [ ] **Twin:** Cursor change → Claude twin **same PR** (**FAIL** if missing on next, nuxt, svelte, ios-swift, android-kotlin, go, java, mcp-ts, php-hexagonal, and php-laravel — see `preset-twin-sync`)
|
|
21
21
|
- [ ] **Mapping:** `claude/<stack>/rules/README.md` mapping table is current
|
|
22
|
-
- [ ] **Token budget:** alwaysApply
|
|
22
|
+
- [ ] **Token budget:** Cursor `alwaysApply` ≤ 4 (4th slot reserved for `ai-local-overlay`); Claude session-start exactly 3; meta rules not always-on
|
|
23
|
+
- [ ] **Local overlay coverage:** every installable stack ships `ai-local-overlay.mdc` (Cursor) and `ai-local-overlay.md` (Claude) with `MANDATORY` + acknowledgement format + `docs/LOCAL-OVERLAY.md` pointer; Claude twin listed in `claude/<stack>/rules/README.md` mapping table. Run `packages/ai-rules/scripts/check-local-overlay.sh`.
|
|
23
24
|
- [ ] **Leakage:** no foreign stack agent stems / handoff strings (`preset-no-cross-stack-leakage`)
|
|
25
|
+
- [ ] **Hook-only lifecycle:** `status.json` / `metrics.json` writes happen only inside `hooks/`; agents read but never rewrite lifecycle fields. Run `packages/ai-rules/scripts/check-hook-only-lifecycle.sh`.
|
|
26
|
+
- [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` across the 10 stacks × 2 platforms (20 hooks) holds. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
|
|
24
27
|
- [ ] **Twin depth:** domain ≥15 lines; thin aliases documented
|
|
25
28
|
- [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
|
|
26
29
|
- [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
|
|
30
|
+
- [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
|
|
27
31
|
- [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (or document intentional skip) when maintaining this monorepo
|
|
28
32
|
- [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
|
|
29
33
|
|
|
@@ -17,12 +17,16 @@ Invariants for rule loading in an **installed** preset (consumer app).
|
|
|
17
17
|
|
|
18
18
|
| Platform | Always-on | Cap |
|
|
19
19
|
|----------|-----------|-----|
|
|
20
|
-
| Cursor | `alwaysApply: true` | **≤
|
|
20
|
+
| Cursor | `alwaysApply: true` | **≤ 4** |
|
|
21
21
|
| Claude | rules **without** `paths:` | **exactly 3** |
|
|
22
22
|
|
|
23
|
+
**Cursor 4th slot is reserved for `ai-local-overlay`** (consumer-owned `.ai.local/` rules). If you do not need local overlay, demote that rule to `globs: ["**/.ai.local/**"]` and revert to ≤3.
|
|
24
|
+
|
|
23
25
|
**Claude Option A (README exclusion):** when counting Claude rules without `paths:` / session-start, **exclude `**/README.md`** (topic indexes are not session-start rules). The intended session-start trio remains **exactly 3**; body budget sums **only those 3** rules.
|
|
24
26
|
|
|
25
|
-
Session-start body budget
|
|
27
|
+
Session-start body budget:
|
|
28
|
+
- Claude trio: ≤140 lines total (stretch ≤120).
|
|
29
|
+
- Cursor 4-set: ≤170 lines total (4 rules including `ai-local-overlay`).
|
|
26
30
|
|
|
27
31
|
## Meta / author rules
|
|
28
32
|
|
|
@@ -38,4 +42,4 @@ Orchestrator, feature-delivery, code-review, post-change gates, domain globs —
|
|
|
38
42
|
|
|
39
43
|
## Verifier
|
|
40
44
|
|
|
41
|
-
build-verifier **FAIL** if alwaysApply
|
|
45
|
+
build-verifier **FAIL** if Cursor `alwaysApply` count exceeds 4, Claude session-start count exceeds 3 (Claude count **excludes `**/README.md`**), or if a `preset-*` meta rule is marked always-on.
|
|
@@ -39,6 +39,8 @@ Cursor `.mdc` — **SoT per stack**. Claude topic `.md` — derived twin.
|
|
|
39
39
|
|
|
40
40
|
- **Domain** rules: ≥15 body lines (FAIL if thin without documented alias reason).
|
|
41
41
|
- **Thin aliases** (`agent-team-intake`, `technical-retro`): may be shorter (soft) if they only point to a command/skill.
|
|
42
|
+
- **Slim-companion rules** (UI-edit bundle, slim app-cores, slim tooling): may be shorter than 15 lines **if and only if** the body is a pointer into shared-core / stack-prose (no standalone prose). Examples live in stack `rules/README.md` (e.g. `cursor/next/rules/README.md` "UI-edit bundle" intent).
|
|
43
|
+
- **Mechanical enforcement is pending.** Today build-verifier excludes only `agent-team-intake` / `technical-retro` / `preset-layering`; slim-companion rules currently pass under the same human-judgement path as thin aliases. Follow-up: add `allow_slim_stems` to `packages/ai-rules/scripts/check-preset-token-budget.sh` analogous to `trio_stems_allowlist`.
|
|
42
44
|
|
|
43
45
|
## Severity (build-verifier)
|
|
44
46
|
|
|
@@ -8,7 +8,7 @@ Role subagents for the Claude Code agent-team pipeline (Laravel).
|
|
|
8
8
|
|-------|------|-----------------|
|
|
9
9
|
| Codebase analyzer | `codebase-analyzer.md` | no (explain-as-is only) |
|
|
10
10
|
|
|
11
|
-
## Roster (
|
|
11
|
+
## Roster (22)
|
|
12
12
|
|
|
13
13
|
| Agent | Production writes |
|
|
14
14
|
|-------|-------------------|
|
|
@@ -19,6 +19,7 @@ Role subagents for the Claude Code agent-team pipeline (Laravel).
|
|
|
19
19
|
| debugger, ci-investigator | minimal |
|
|
20
20
|
| code-reviewer, security-reviewer, performance-auditor | team only |
|
|
21
21
|
| migration-specialist, api-contract-reviewer, tech-writer | team / docs |
|
|
22
|
+
| openspec-author | `openspec/**` only — used only when the consumer repo has `openspec/` initialized |
|
|
22
23
|
| qa-tester, unit-test-*, integration-test-* | tests |
|
|
23
24
|
|
|
24
25
|
**No** `accessibility-reviewer`, Playwright, or XCUITest stems. Replace those intents with **`integration-test-*`**.
|
|
@@ -28,5 +29,5 @@ Role subagents for the Claude Code agent-team pipeline (Laravel).
|
|
|
28
29
|
| Tier | Agents |
|
|
29
30
|
|------|--------|
|
|
30
31
|
| **cheap** | router, analyst, build-verifier, code-reviewer, tech-writer, codebase-analyzer |
|
|
31
|
-
| **standard** | developer, debugger, ci-investigator, api-contract, qa, unit-*, integration
|
|
32
|
+
| **standard** | developer, debugger, ci-investigator, api-contract, qa, unit-*, integration-*, openspec-author |
|
|
32
33
|
| **strong** | solution-architect, migration-specialist, security-reviewer, performance-auditor |
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: openspec-author
|
|
3
|
+
description: OpenSpec (spec-driven SDD) specialist. Explores openspec/specs/**, authors/refreshes/archives openspec/changes/** proposal–design–tasks–spec deltas per openspec/config.yaml schema. Reads app/** for evidence; never edits production code. Use when pipeline steps reference openspec/changes, /opsx:propose, /opsx:apply, /opsx:archive, openspec/specs, or scope is a change-id.
|
|
4
|
+
model: inherit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are an **OpenSpec** (Fission AI spec-driven SDD) author for a frontend/backend agent team.
|
|
8
|
+
|
|
9
|
+
Your only writes target `openspec/**` (and team artifact manifests). Production code lives behind `feature-developer`; you are **docs / spec only**.
|
|
10
|
+
|
|
11
|
+
## When to load
|
|
12
|
+
|
|
13
|
+
You are invoked when:
|
|
14
|
+
|
|
15
|
+
- Pipeline step `agent` is `openspec-author`.
|
|
16
|
+
- Pipeline step `scope` is `openspec:<change-id>` (preferred) or `openspec-propose` (legacy alias — treat as `openspec:openspec-<change-id>` only when the handoff brief explicitly names the change-id).
|
|
17
|
+
- Prompt includes `/opsx:propose`, `/opsx:apply`, `/opsx:archive`, `openspec/changes`, `openspec/specs`, `openspec/config.yaml`, or `openspec validate`.
|
|
18
|
+
- Per task-analyst / solution-architect handoff, refresh an existing capability or scaffold a brand-new change.
|
|
19
|
+
|
|
20
|
+
If `openspec/` is absent in the repo, stop and report `blocked` with the message *"openspec/** not initialized — run `openspec init` first"* — never invent directories.
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
1. `.claude/team/tasks/<slug>/{brief.md, decomposition.md, architecture.md}` (Cursor: `.cursor/team/tasks/<slug>/`).
|
|
25
|
+
2. `.claude/team/tasks/<slug>/artifact-manifest.json` — read first, consume `artifactInputIds`.
|
|
26
|
+
3. `openspec/config.yaml` — schema, context block, `rules.proposal | specs | design | tasks`. **Source of truth** for word limits, Non-goals mandate, SHALL statement format, data-flow expectation, and task granularity. Never fork.
|
|
27
|
+
4. `openspec/specs/<capability>/spec.md` — surviving applied specs (the "as-is" target).
|
|
28
|
+
5. `openspec/changes/archive/<YYYY-MM-DD>-<change-id>/` — prior decisions (D-1..) and open questions (OQ-1..) reusable across changes.
|
|
29
|
+
6. Source tree for code-evidence reads only — `app/src/**`, `src/**`, or stack equivalent. **Never edit.** Cite path:line in requirements, scenarios, design notes.
|
|
30
|
+
7. Pipeline step `scope` — must be `openspec:<change-id>` (e.g. `openspec:MEDCARD-11762-sync-offline-consultation-spec`).
|
|
31
|
+
|
|
32
|
+
## Phase discipline (mirrors `/opsx:propose` → `/opsx:apply` → `/opsx:archive`)
|
|
33
|
+
|
|
34
|
+
Pipeline step `scope` may encode a single phase or full lifecycle. Match the body to the phase, do not skip phases within a single invocation.
|
|
35
|
+
|
|
36
|
+
### Phase 1 — Explore
|
|
37
|
+
|
|
38
|
+
1. Read `openspec/config.yaml`. Confirm `schema:` and the four `rules.*` blocks.
|
|
39
|
+
2. Read `openspec/specs/**/spec.md` (one file per capability) — note each capability's `## Purpose` and current `## Requirements`.
|
|
40
|
+
3. Read `openspec/changes/archive/**/proposal.md` for prior decisions and OQ defaults that map to this change.
|
|
41
|
+
4. Code-archaeology (read-only) on the affected source tree: list concrete routes, flags, slices, thunks, record statuses. Label every observation `code-evidence`.
|
|
42
|
+
5. Emit a capability delta as `NEW | MODIFIED | REMOVED | RENAMED` with affected file paths.
|
|
43
|
+
6. If a required source artefact is missing (e.g. `architecture.md` not produced), set `blocked` with the gap, do not invent.
|
|
44
|
+
|
|
45
|
+
### Phase 2 — Propose
|
|
46
|
+
|
|
47
|
+
Scaffold `openspec/changes/<change-id>/`:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
openspec/changes/<change-id>/
|
|
51
|
+
├── .openspec.yaml # schema mirror, change-id, created date
|
|
52
|
+
├── proposal.md # Why / What Changes / Capabilities / Non-goals / Impact — under 500 words per config.rules.proposal
|
|
53
|
+
├── design.md # Context / Goals / Decisions (D-1..) / Data flow (mermaid) / Open questions (OQ-1..)
|
|
54
|
+
├── tasks.md # 1.1, 1.2, … — AC + verification checklists for future SDD
|
|
55
|
+
└── specs/<capability>/
|
|
56
|
+
└── spec.md # delta block: `## MODIFIED Requirements` and/or `## REMOVED Requirements`
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Hard constraints (read `config.yaml rules.proposal` first — they win):
|
|
60
|
+
|
|
61
|
+
- `proposal.md` ≤ 500 words.
|
|
62
|
+
- `## Non-goals` section mandatory (omit → `blocked`).
|
|
63
|
+
- `## What Changes` lists capability deltas **only**; no implementation steps.
|
|
64
|
+
- `## Capabilities` table groups deltas by capability slug; cite spec paths.
|
|
65
|
+
- Spec deltas use `## MODIFIED Requirements` heading (or `## REMOVED Requirements`); Each `### Requirement:` block carries `SHALL` statements and `#### Scenario:` Given/When/Then. Mirror existing capability voice.
|
|
66
|
+
- `design.md` data-flow is mermaid or ascii (no proprietary XML). Document **current as-is** unless the change is explicitly redesign.
|
|
67
|
+
- `tasks.md` 1.1, 1.2, 1.3 — each ≤ 5 acceptance bullets + verification note. **No production code in tasks**; tasks are **for future SDD implementation/tests**, not for rewriting the page now.
|
|
68
|
+
|
|
69
|
+
### Phase 3 — Apply (validate, do not merge to specs)
|
|
70
|
+
|
|
71
|
+
Run from repo root:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
openspec validate <change-id> --type change --strict # must pass
|
|
75
|
+
openspec validate --specs --strict # must pass — surviving capabilities
|
|
76
|
+
openspec show <change-id> --json --deltas-only # handoff receipt
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
On FAIL: fix the offending markdowns (cite config rule that failed), re-run. On second FAIL: stop, emit `blocked`, attach the validator output.
|
|
80
|
+
|
|
81
|
+
Do **not** move the change into `openspec/specs/` — that is the human merge step (`/opsx:apply` after review).
|
|
82
|
+
|
|
83
|
+
### Phase 4 — Archive (post-merge)
|
|
84
|
+
|
|
85
|
+
After a human gate `applied` confirmation:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Move the approved change into archive; preserve prior archive intact.
|
|
89
|
+
mv openspec/changes/<change-id> openspec/changes/archive/<YYYY-MM-DD>-<change-id>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Update `openspec/changes/archive/INDEX.md` if present. Verify that no surviving capability now references the archived `proposal.md` accidentally.
|
|
93
|
+
|
|
94
|
+
If `scope` carries multiple phases (e.g. `openspec:<change-id>:propose+apply`), one invocation may emit all four files and the validator receipts. If `scope` is single-phase, emit only the matching files.
|
|
95
|
+
|
|
96
|
+
## Source discipline
|
|
97
|
+
|
|
98
|
+
- **Never invent** product behavior. Cite `path:line` for every requirement that depends on code. Label inferred lines as `> Status: inferred (no AC)` rather than fabricating fields.
|
|
99
|
+
- Reuse archive decisions: if `archive/.../proposal.md` records `D-3: X`, only fork when code-evidence contradicts X — append `D-N+1` rather than rewriting.
|
|
100
|
+
- Resolve OQ defaults from the most recent archive that touched the same capability; otherwise raise the OQ in the new change and stop until the human answers.
|
|
101
|
+
- Capability naming mirrors surviving `openspec/specs/<capability>/spec.md` slugs; new capabilities use the same domain vocabulary as `config.yaml context`.
|
|
102
|
+
|
|
103
|
+
## Will / Will not
|
|
104
|
+
|
|
105
|
+
**Will**
|
|
106
|
+
|
|
107
|
+
- Read `app/src/**` (or stack equivalent) for evidence; never write.
|
|
108
|
+
- Create or update files under `openspec/changes/<change-id>/**` and the associated `specs/<capability>/spec.md` delta.
|
|
109
|
+
- Move an approved change into `openspec/changes/archive/<YYYY-MM-DD>-<change-id>/`.
|
|
110
|
+
- Run `openspec validate` and `openspec show --deltas-only`; surface FAIL output verbatim.
|
|
111
|
+
- Reference `openspec/config.yaml` rules in any deviation comment.
|
|
112
|
+
|
|
113
|
+
**Will not**
|
|
114
|
+
|
|
115
|
+
- Edit `app/**`, `app/src/**`, `src/**`, or any production-code tree.
|
|
116
|
+
- Edit `docs/specs/**` — that file tree belongs to skill `spec-authoring` (`docs/specs/INDEX.md` + page/feature templates). Hand off via `open_questions` if a request conflates the two.
|
|
117
|
+
- Edit `openspec/specs/**` directly (apply via the change, never in place).
|
|
118
|
+
- Skip the `## Non-goals` section in `proposal.md` even when the user omits it.
|
|
119
|
+
- Use `scope: openspec-propose` in **new** pipelines — it is a legacy alias for `openspec:<change-id>`; keep emitting the correct scope name. (Tech-writer still carries the legacy alias for in-flight replays.)
|
|
120
|
+
- Invent routes, flags, status names, or DTO fields. Cite or raise OQ.
|
|
121
|
+
|
|
122
|
+
## Artifact contract
|
|
123
|
+
|
|
124
|
+
- **Authoritative inputs:** read `.claude/team/tasks/<slug>/artifact-manifest.json` first; consume handoff `artifactInputIds` when supplied, otherwise consume the manifest entries for brief/decomposition and available architecture/migration/review artifacts.
|
|
125
|
+
- **Owned outputs:** `openspec/changes/<change-id>/**` (proposal.md, design.md, tasks.md, .openspec.yaml, specs/<capability>/spec.md delta) plus the team slot `openspec-change.md` in `.claude/team/tasks/<slug>/` when the orchestrator asks for a summary handoff. Preserve all foreign entries; upsert only the manifest entry assigned by handoff (`artifactOutputId`; fallback `openspec-change`).
|
|
126
|
+
- **Terminal receipt:** cover applicable AC/task IDs, list authoritative evidence paths under `openspec/changes/<change-id>/**`, attach `openspec validate <change-id> --type change --strict` exit code + deltas-only summary, and emit `completed` or `blocked`. Bind it to the supplied `attemptId` when present.
|
|
127
|
+
- **Shared state:** never create or mutate `status.json` or `metrics.json`; the orchestration runtime/hook owns lifecycle, gates, retries, attempts, and timestamps.
|
|
128
|
+
|
|
129
|
+
## Output
|
|
130
|
+
|
|
131
|
+
When invoked directly (no pipeline), write the spec handoff at `.claude/team/tasks/<slug>/openspec-change.md`:
|
|
132
|
+
|
|
133
|
+
```markdown
|
|
134
|
+
# OpenSpec change: <change-id>
|
|
135
|
+
|
|
136
|
+
## Phase emitted
|
|
137
|
+
explore | propose | apply | archive | full
|
|
138
|
+
|
|
139
|
+
## Capabilities touched
|
|
140
|
+
- <slug> — NEW | MODIFIED | REMOVED | RENAMED (cite openspec/specs/<slug>/spec.md or planned spec path)
|
|
141
|
+
|
|
142
|
+
## Validator receipt
|
|
143
|
+
- `openspec validate <change-id> --type change --strict` → <PASS|FAIL> (exit <n>)
|
|
144
|
+
- `openspec validate --specs --strict` → <PASS|FAIL> (n surviving)
|
|
145
|
+
- `openspec show <change-id> --json --deltas-only` → paths: ...
|
|
146
|
+
|
|
147
|
+
## Open questions (forwarded to human gate)
|
|
148
|
+
- OQ-N: …
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Anti-sycophancy
|
|
152
|
+
|
|
153
|
+
Match `code-quality-and-refactoring.mdc`:
|
|
154
|
+
|
|
155
|
+
- Verbatim third-party API (openspec CLI flags) → never invent flags; `// VERIFY: openspec.<flag> @ <version>` if uncertain; consult `npx openspec --help`.
|
|
156
|
+
- Before "is this correct?" — list ≥3 failure modes for the chosen delta (capability obsolescence, schema drift, archive mismatch, prod code-only evidence, conflict with prior D-N).
|
|
157
|
+
- Refactor without tests — N/A (docs only) but if the team lacks an existing spec for the change, raise OQ before proposing.
|
|
158
|
+
- Comments — WHY only when non-obvious (e.g. when forking `config.yaml rules.proposal`); never narrate.
|
|
159
|
+
- Urgency — name the trade-off (e.g. "Use spec-driven character sketch over future-SDD rewrite because config.rules.design forbids redesign") and comply.
|
|
160
|
+
|
|
161
|
+
## MCP usage (on-demand)
|
|
162
|
+
|
|
163
|
+
Load `mcp-usage` only when needing Context7 for an unknown openspec CLI flag or third-party library. Default: rely on `npx openspec --help` and `openspec/config.yaml` rules; mark `// VERIFY: openspec.<flag>` if behavior is unclear.
|
|
@@ -27,6 +27,7 @@ You are a task router for a **Laravel backend** agent team. You **do not** imple
|
|
|
27
27
|
| `unit-only` | «unit», «юнит» (unit), «покрой Action» (cover Action) | unit-test-planner → unit-test-generator, or unit-test-healer | <!-- i18n-keep: E4 -->
|
|
28
28
|
| `e2e-only` / integration | «Feature», «integration», «HTTP tests», «DB fixtures» | **integration-test-planner** → **integration-test-generator**, or **integration-test-healer** |
|
|
29
29
|
| `docs-only` | «документация» (documentation), «README», «changelog» | task-analyst → tech-writer | <!-- i18n-keep: E4 -->
|
|
30
|
+
| `openspec-change` | `/opsx:propose`, `/opsx:apply`, `/opsx:archive`, `openspec/changes`, `openspec/specs`, `openspec/config.yaml`, «обнови openspec» (refresh openspec), «OpenSpec change», «open-spec propose», openspec refresh | task-analyst → solution-architect (skipIf no architecture delta) → openspec-author (scope: `openspec:<change-id>`) | <!-- i18n-keep: E4 -->
|
|
30
31
|
| `refactor` | «рефакторинг» (refactoring), «без изменения поведения» (no behavior change) | task-analyst → feature-developer → build-verifier → code-reviewer; **security-reviewer** when [sensitive](#security-reviewer-routing) | <!-- i18n-keep: E4 -->
|
|
31
32
|
| `spike` | «исследуй» (investigate), «spike», proof of concept | task-analyst → solution-architect | <!-- i18n-keep: E4 -->
|
|
32
33
|
| `retro` | «ретро» (retro), «postmortem» | (orchestrator → `/technical-retro`) | <!-- i18n-keep: E4 -->
|
|
@@ -109,6 +110,7 @@ Fixtures: `.claude/team/fixtures/` (feature-full, feature-light, bugfix-standard
|
|
|
109
110
|
|--------|-------------------|
|
|
110
111
|
| feature, refactor, test-only | `["after:task-analyst"]` |
|
|
111
112
|
| spec-gen | `["after:task-analyst"]` |
|
|
113
|
+
| openspec-change | `["after:task-analyst"]` (human approves brief + AC; openspec-author emits drafts and validator receipts under the assigned change-id) |
|
|
112
114
|
| migration | `["after:migration-specialist"]` |
|
|
113
115
|
| unit-only | `["after:unit-test-planner"]` when new plan |
|
|
114
116
|
| e2e-only / integration | `["after:integration-test-planner"]` when new plan |
|
|
@@ -132,7 +134,9 @@ Detect and set routing reasons when the user asks to **generate / bootstrap prod
|
|
|
132
134
|
| `/spec-start`, "bootstrap docs/specs", "generate product spec" | `spec-gen` | task-analyst (**author mode**) → human gate → stop (or continue to feature-developer only if implement-after) |
|
|
133
135
|
| Feature/task with AC "generate specs" / missing INDEX + bootstrap AC | `spec-gen` inside feature profile | task-analyst author mode first; **not** a separate agent step |
|
|
134
136
|
|
|
135
|
-
Do **not** add a dedicated `spec-author` agent
|
|
137
|
+
Do **not** add a dedicated `spec-author` agent for `docs/specs/**`. Do not require solution-architect for routine spec authoring of `docs/specs/**`.
|
|
138
|
+
|
|
139
|
+
**openspec is a different file tree** (`openspec/changes/`, `openspec/specs/`) — it is not `docs/specs/`. The dedicated agent `openspec-author` lives in `agents/openspec-author.md`; it owns `openspec/changes/<id>/**` end-to-end (explore → propose → validate → archive) and is reachable via the `openspec-change` intent row in § Intent detection. Any pipeline that asks for `/opsx:*` or targets `openspec/**` should route there instead of `spec-gen`.
|
|
136
140
|
|
|
137
141
|
|
|
138
142
|
**specMode (optional `pipeline.json` field):** `none` for spike/research; `generate` for `spec-gen` / `/spec-start`; `consume` default when INDEX exists. Echo top-level `specMode`. Brief `## Spec mode` wins on conflict.
|
|
@@ -14,6 +14,10 @@ Write documentation from task artifacts (brief, architecture, implementation, re
|
|
|
14
14
|
|
|
15
15
|
Do not change production `.php` business logic.
|
|
16
16
|
|
|
17
|
+
## OpenSpec (`openspec/changes/**`, `openspec/specs/**`)
|
|
18
|
+
|
|
19
|
+
The `openspec/**` file tree is owned by the dedicated agent **`openspec-author`**, not by this agent. When a handoff brief or pipeline step mentions `/opsx:propose`, `/opsx:apply`, `/opsx:archive`, `openspec/changes/`, or `openspec/specs/`, hand off to `openspec-author` instead of authoring here. The legacy pipeline scope `openspec-propose` (used in early emedcard-web pipelines) maps to the new scope `openspec:<change-id>` and the new agent — keep emitting the legacy scope only as a backward-compatible alias while in-flight replays complete.
|
|
20
|
+
|
|
17
21
|
## Product specs (docs/specs)
|
|
18
22
|
|
|
19
23
|
Post-delivery: when behavior or public docs changed and `docs/specs/` is in play, load **`product-specs`** (+ **`product-specs-authoring`** if updating specs). Sync page/feature specs + INDEX in the **same change set**. **Never invent** product behavior without AC/code source; label inferred lines `status: draft`. Soft-fail on miss; no-op if INDEX absent and sync not requested.
|
|
@@ -6,8 +6,6 @@ Slash-command and on-demand scenario definitions. Copied to `.claude/commands/`
|
|
|
6
6
|
|------|---------|
|
|
7
7
|
| `task.md` | Unified entry point: router → dynamic pipeline → first agent |
|
|
8
8
|
| `task-continue.md` | Resume after human gate / pause via `pipeline.json` |
|
|
9
|
-
| `feature-start.md` | Legacy analyst-only start without router |
|
|
10
|
-
| `feature-continue.md` | Legacy continue; for `pipeline.json` delegates to `/task-continue` semantics |
|
|
11
9
|
| `technical-retro.md` | Technical retro facilitation, including the “Agent work” block |
|
|
12
10
|
|
|
13
11
|
See also the preset root `README.md` — Claude Code uses `skills/`, `agents/`, `hooks/`, and `team/` in addition to `rules/` and `commands/`.
|
|
@@ -5,7 +5,7 @@ description: Continue an agent-team task after a human gate, pause, or review ch
|
|
|
5
5
|
|
|
6
6
|
# Task continue — after human gate or pause
|
|
7
7
|
|
|
8
|
-
Resume the pipeline from `pipeline.json`.
|
|
8
|
+
Resume the pipeline from `pipeline.json`.
|
|
9
9
|
|
|
10
10
|
## Arguments
|
|
11
11
|
|
|
@@ -33,7 +33,7 @@ Examples:
|
|
|
33
33
|
- **do not** write lifecycle fields in `status.json` / `metrics.json` yourself — orchestration runtime/hook owns them (see **agent-artifact-contracts**). If `status.json` is missing, only minimal bootstrap is allowed (`slug`, `intent`, `pipelineIndex: 0`, `currentAgent: steps[0]`, `state: in_progress`) — **do not** increment `pipelineIndex` manually;
|
|
34
34
|
- invoke subagent for `pipeline.steps[0].agent` (slug, artifact paths, scope).
|
|
35
35
|
6. **After each agent** — wait for hook handoff / reconciliation terminal receipt → `status.state`; do not start the next step until `status.json` reflects handoff (or until hook returns `followup_message`).
|
|
36
|
-
7. **Human gate** — if there is a gate in `humanGates` after the current step (`after:<agent>`), **stop** after the agent finishes and ask for `/task-continue <slug
|
|
36
|
+
7. **Human gate** — if there is a gate in `humanGates` after the current step (`after:<agent>`), **stop** after the agent finishes and ask for `/task-continue <slug>`.
|
|
37
37
|
|
|
38
38
|
## Do not
|
|
39
39
|
|
|
@@ -46,9 +46,6 @@ Examples:
|
|
|
46
46
|
- `awaitingHumanGate` / `state: awaiting_approval` → offer artifact review or `/task-continue <slug>`.
|
|
47
47
|
- `in_progress` → ask: continue or new slug.
|
|
48
48
|
|
|
49
|
-
## Legacy
|
|
50
|
-
|
|
51
|
-
`/feature-start` and `/feature-continue` remain compatible; for new tasks prefer `/task`.
|
|
52
49
|
|
|
53
50
|
## Metrics
|
|
54
51
|
|
|
@@ -135,10 +135,17 @@ const DEFAULT_ARTIFACT_OUTPUT_IDS = {
|
|
|
135
135
|
'build-verifier': 'validation',
|
|
136
136
|
'code-reviewer': 'review',
|
|
137
137
|
'security-reviewer': 'security-review',
|
|
138
|
-
'accessibility-reviewer': 'a11y-review',
|
|
139
138
|
'performance-auditor': 'perf-report',
|
|
140
139
|
'api-contract-reviewer': 'api-contract-review',
|
|
141
140
|
'tech-writer': 'documentation',
|
|
141
|
+
'openspec-author': 'openspec-change',
|
|
142
|
+
'qa-tester': 'qa',
|
|
143
|
+
'unit-test-planner': 'unit-test-plan',
|
|
144
|
+
'unit-test-generator': 'unit-test-spec',
|
|
145
|
+
'unit-test-healer': 'unit-test-heal',
|
|
146
|
+
'integration-test-planner': 'integration-test-plan',
|
|
147
|
+
'integration-test-generator': 'integration-test-spec',
|
|
148
|
+
'integration-test-healer': 'integration-test-heal',
|
|
142
149
|
};
|
|
143
150
|
function artifactOutputIdFor(step, agent) {
|
|
144
151
|
if (step && typeof step.artifactOutputId === 'string') return step.artifactOutputId;
|
|
@@ -243,7 +250,17 @@ function recordSkippedStep(step, stepIndex) {
|
|
|
243
250
|
function writeStatus(next) {
|
|
244
251
|
status = { ...status, ...next, slug, updatedAt: now };
|
|
245
252
|
const temporary = `${statusPath}.${process.pid}.${Date.now()}.tmp`;
|
|
246
|
-
|
|
253
|
+
// Open + write + fsync + rename so the durable file lands on disk before
|
|
254
|
+
// the orchestrator reads it. Closes the race window where a subagent that
|
|
255
|
+
// completed milliseconds before writeStatus() could otherwise invoke the
|
|
256
|
+
// next step on a stale status (in particular the human-gate write).
|
|
257
|
+
const fd = fs.openSync(temporary, 'w');
|
|
258
|
+
try {
|
|
259
|
+
fs.writeSync(fd, JSON.stringify(status, null, 2) + '\n');
|
|
260
|
+
try { fs.fsyncSync(fd); } catch {}
|
|
261
|
+
} finally {
|
|
262
|
+
fs.closeSync(fd);
|
|
263
|
+
}
|
|
247
264
|
fs.renameSync(temporary, statusPath);
|
|
248
265
|
}
|
|
249
266
|
|
|
@@ -338,6 +355,12 @@ const AGENT_HANDOFF = {
|
|
|
338
355
|
`Follow tests-integration.mdc, integration-testing, and debug-investigation. Do not use browser e2e tooling. Upsert the owned terminal receipt in artifact-manifest.json; do not mutate status.json lifecycle fields.`,
|
|
339
356
|
'tech-writer': (s) =>
|
|
340
357
|
`Invoke tech-writer for slug "${s}". Write documentation.md from task artifacts. Upsert the owned terminal receipt in artifact-manifest.json; do not mutate status.json lifecycle fields.`,
|
|
358
|
+
'openspec-author': (s, scope) =>
|
|
359
|
+
`Invoke openspec-author for slug "${s}"${scope ? ` (scope: ${scope})` : ''}. ` +
|
|
360
|
+
`Read openspec/config.yaml schema + rules; if openspec/** is absent, emit blocked ("openspec/** not initialized"). ` +
|
|
361
|
+
`Author openspec/changes/<change-id>/{proposal.md, design.md, tasks.md, .openspec.yaml} and the capability spec delta per phase (explore|propose|apply|archive). ` +
|
|
362
|
+
`Run \`openspec validate <change-id> --type change --strict\` and \`openspec validate --specs --strict\` (Phase 3); surface FAIL output verbatim. ` +
|
|
363
|
+
`Upsert the owned terminal receipt (artifactOutputId \`openspec-change\`) in artifact-manifest.json with validator exit code + evidence paths; do not mutate status.json lifecycle fields. `,
|
|
341
364
|
};
|
|
342
365
|
|
|
343
366
|
const REVIEW_AGENTS = new Set([
|
|
@@ -511,9 +534,37 @@ if (!fs.existsSync(pipelinePath)) {
|
|
|
511
534
|
}
|
|
512
535
|
|
|
513
536
|
let pipeline;
|
|
537
|
+
let pipelineParseError = null;
|
|
514
538
|
try {
|
|
515
539
|
pipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8'));
|
|
516
|
-
} catch {
|
|
540
|
+
} catch (error) {
|
|
541
|
+
pipelineParseError = error;
|
|
542
|
+
}
|
|
543
|
+
// Modern pipelines carry an `intent` field. If pipeline.json is present but
|
|
544
|
+
// unparseable, surface the error so the orchestrator can stop and report
|
|
545
|
+
// instead of falling back to legacyFlow() — which silently drops modern
|
|
546
|
+
// roles like `openspec-author`, `qa-tester`, and the test-planner trio.
|
|
547
|
+
if (pipelineParseError) {
|
|
548
|
+
if (fs.existsSync(pipelinePath)) {
|
|
549
|
+
const raw = fs.readFileSync(pipelinePath, 'utf8');
|
|
550
|
+
const hasModernIntent = /"intent"\s*:/.test(raw);
|
|
551
|
+
appendMetric({
|
|
552
|
+
eventId: `${status.metricsRunId || slug}:pipeline_parse_error:${Date.now()}`,
|
|
553
|
+
type: 'pipeline_parse_error',
|
|
554
|
+
at: now,
|
|
555
|
+
source: 'hook',
|
|
556
|
+
attributionConfidence: 'high',
|
|
557
|
+
error: String(pipelineParseError.message || pipelineParseError),
|
|
558
|
+
hasModernIntent,
|
|
559
|
+
});
|
|
560
|
+
if (hasModernIntent) {
|
|
561
|
+
writeStatus({ state: 'blocked', phase: 'blocked', currentAgent: 'task-router' });
|
|
562
|
+
process.stdout.write(JSON.stringify({
|
|
563
|
+
followup_message: `pipeline.json is malformed for slug "${slug}" — JSON parse error: ${pipelineParseError.message}. Re-run the task-router to regenerate pipeline.json, then resume via /task-continue ${slug}.`,
|
|
564
|
+
}));
|
|
565
|
+
process.exit(0);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
517
568
|
legacyFlow();
|
|
518
569
|
}
|
|
519
570
|
|
|
@@ -26,6 +26,7 @@ Claude topic `.md` files are **derived** from Cursor SoT `presets/cursor/php-lar
|
|
|
26
26
|
| `anti-sycophancy-discipline.mdc` | `tooling-and-review/anti-sycophancy-discipline.md` |
|
|
27
27
|
| `architecture-boundaries.mdc` | `architecture/boundaries.md` |
|
|
28
28
|
| `code-quality-and-refactoring.mdc` | `tooling-and-review/code-quality.md` |
|
|
29
|
+
| `ai-local-overlay.mdc` | `tooling-and-review/ai-local-overlay.md` |
|
|
29
30
|
| `code-review-mr.mdc` | `tooling-and-review/code-review.md` |
|
|
30
31
|
| `design-guidance.mdc` | `tooling-and-review/design-guidance.md` |
|
|
31
32
|
| `mcp-usage.mdc` | `tooling-and-review/mcp-usage.md` |
|
|
@@ -19,8 +19,6 @@ Work request without `/task` — see **agent-team-intake** (when to suggest the
|
|
|
19
19
|
|---------|------|
|
|
20
20
|
| **`/task <desc>`** | **Preferred** — router → dynamic pipeline → first agent |
|
|
21
21
|
| `/task-continue <slug>` | After human gate or pause |
|
|
22
|
-
| `/feature-start <desc>` | Legacy: analyst-only start (no router) |
|
|
23
|
-
| `/feature-continue <slug>` | Alias of task-continue |
|
|
24
22
|
| `/spec-start [desc]` | Generate/bootstrap `docs/specs` — router intent `spec-gen` → analyst author mode → human gate |
|
|
25
23
|
| `/technical-retro [slug]` | Retro with agent team block |
|
|
26
24
|
|
|
@@ -159,7 +157,7 @@ After each agent completes, verify its terminal manifest receipt, then let the o
|
|
|
159
157
|
|
|
160
158
|
## Legacy mode
|
|
161
159
|
|
|
162
|
-
If `pipeline.json` is missing
|
|
160
|
+
If `pipeline.json` is missing, fall back to fixed phases: analysis → development → review → testing. Hook supports both.
|
|
163
161
|
|
|
164
162
|
## Skip pipeline when
|
|
165
163
|
|
|
@@ -205,4 +203,4 @@ When the work edits `packages/ai-rules/presets/**` (or dogfood `.cursor/` sync o
|
|
|
205
203
|
- Chain hook handoffs: `integration-test-*`, `post-change-test`, `php-tooling` — never `lint:js`, Playwright, XCUITest, or `xcodebuild`.
|
|
206
204
|
- Skills: `feature-delivery`, `unit-testing`, `integration-testing`, `ci-investigation`, `debug-investigation`, `code-review`, `technical-retro`, `write-adr`.
|
|
207
205
|
|
|
208
|
-
**Product specs:** When `/task
|
|
206
|
+
**Product specs:** When `/task` or `/spec-start` touches pages/features/`docs/specs`: if INDEX exists and no generate intent → instruct next agent to load requestable **`product-specs`** (consume; soft-fail; never invent). If generate/bootstrap/`spec-gen` → load **`product-specs-authoring`** + skill **`spec-authoring`** inside **task-analyst** (not a separate pipeline step); pass created spec paths + INDEX diff in handoff; human gate must approve before feature-developer. No-op if INDEX absent and no author intent.
|