@event4u/agent-config 1.9.1
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/.agent-src/README.md +64 -0
- package/.agent-src/commands/agent-handoff.md +64 -0
- package/.agent-src/commands/agent-status.md +83 -0
- package/.agent-src/commands/agents-audit.md +243 -0
- package/.agent-src/commands/agents-cleanup.md +169 -0
- package/.agent-src/commands/agents-prepare.md +137 -0
- package/.agent-src/commands/analyze-reference-repo.md +191 -0
- package/.agent-src/commands/bug-fix.md +181 -0
- package/.agent-src/commands/bug-investigate.md +175 -0
- package/.agent-src/commands/commit.md +121 -0
- package/.agent-src/commands/compress.md +177 -0
- package/.agent-src/commands/config-agent-settings.md +126 -0
- package/.agent-src/commands/context-create.md +167 -0
- package/.agent-src/commands/context-refactor.md +170 -0
- package/.agent-src/commands/copilot-agents-init.md +150 -0
- package/.agent-src/commands/copilot-agents-optimize.md +251 -0
- package/.agent-src/commands/create-pr-description.md +112 -0
- package/.agent-src/commands/create-pr.md +76 -0
- package/.agent-src/commands/do-and-judge.md +114 -0
- package/.agent-src/commands/do-in-steps.md +84 -0
- package/.agent-src/commands/e2e-heal.md +98 -0
- package/.agent-src/commands/e2e-plan.md +85 -0
- package/.agent-src/commands/estimate-ticket.md +80 -0
- package/.agent-src/commands/feature-dev.md +111 -0
- package/.agent-src/commands/feature-explore.md +180 -0
- package/.agent-src/commands/feature-plan.md +288 -0
- package/.agent-src/commands/feature-refactor.md +181 -0
- package/.agent-src/commands/feature-roadmap.md +184 -0
- package/.agent-src/commands/fix-ci.md +48 -0
- package/.agent-src/commands/fix-portability.md +97 -0
- package/.agent-src/commands/fix-pr-bot-comments.md +146 -0
- package/.agent-src/commands/fix-pr-comments.md +58 -0
- package/.agent-src/commands/fix-pr-developer-comments.md +152 -0
- package/.agent-src/commands/fix-references.md +94 -0
- package/.agent-src/commands/fix-seeder.md +146 -0
- package/.agent-src/commands/implement-ticket.md +133 -0
- package/.agent-src/commands/jira-ticket.md +71 -0
- package/.agent-src/commands/judge.md +86 -0
- package/.agent-src/commands/memory-add.md +130 -0
- package/.agent-src/commands/memory-full.md +97 -0
- package/.agent-src/commands/memory-promote.md +144 -0
- package/.agent-src/commands/mode.md +121 -0
- package/.agent-src/commands/module-create.md +132 -0
- package/.agent-src/commands/module-explore.md +157 -0
- package/.agent-src/commands/optimize-agents.md +139 -0
- package/.agent-src/commands/optimize-augmentignore.md +262 -0
- package/.agent-src/commands/optimize-rtk-filters.md +120 -0
- package/.agent-src/commands/optimize-skills.md +121 -0
- package/.agent-src/commands/override-create.md +97 -0
- package/.agent-src/commands/override-manage.md +96 -0
- package/.agent-src/commands/package-reset.md +154 -0
- package/.agent-src/commands/package-test.md +154 -0
- package/.agent-src/commands/prepare-for-review.md +91 -0
- package/.agent-src/commands/project-analyze.md +300 -0
- package/.agent-src/commands/project-health.md +95 -0
- package/.agent-src/commands/propose-memory.md +108 -0
- package/.agent-src/commands/quality-fix.md +106 -0
- package/.agent-src/commands/refine-ticket.md +81 -0
- package/.agent-src/commands/review-changes.md +130 -0
- package/.agent-src/commands/review-routing.md +111 -0
- package/.agent-src/commands/roadmap-create.md +110 -0
- package/.agent-src/commands/roadmap-execute.md +68 -0
- package/.agent-src/commands/rule-compliance-audit.md +139 -0
- package/.agent-src/commands/tests-create.md +73 -0
- package/.agent-src/commands/tests-execute.md +58 -0
- package/.agent-src/commands/threat-model.md +115 -0
- package/.agent-src/commands/update-form-request-messages.md +189 -0
- package/.agent-src/commands/upstream-contribute.md +171 -0
- package/.agent-src/contexts/augment-infrastructure.md +181 -0
- package/.agent-src/contexts/documentation-hierarchy.md +142 -0
- package/.agent-src/contexts/model-recommendations.md +142 -0
- package/.agent-src/contexts/override-system.md +187 -0
- package/.agent-src/contexts/skills-and-commands.md +154 -0
- package/.agent-src/contexts/subagent-configuration.md +62 -0
- package/.agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +110 -0
- package/.agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
- package/.agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
- package/.agent-src/guidelines/agent-infra/engineering-memory-data-format.md +117 -0
- package/.agent-src/guidelines/agent-infra/layered-settings.md +158 -0
- package/.agent-src/guidelines/agent-infra/memory-access.md +121 -0
- package/.agent-src/guidelines/agent-infra/naming.md +69 -0
- package/.agent-src/guidelines/agent-infra/output-patterns.md +117 -0
- package/.agent-src/guidelines/agent-infra/review-routing-data-format.md +144 -0
- package/.agent-src/guidelines/agent-infra/role-contracts.md +211 -0
- package/.agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
- package/.agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
- package/.agent-src/guidelines/agent-infra/self-improvement-pipeline.md +135 -0
- package/.agent-src/guidelines/agent-infra/size-and-scope.md +189 -0
- package/.agent-src/guidelines/agent-infra/tool-integration.md +73 -0
- package/.agent-src/guidelines/docs/readme-size-and-splitting.md +153 -0
- package/.agent-src/guidelines/e2e/playwright.md +363 -0
- package/.agent-src/guidelines/php/api-design.md +115 -0
- package/.agent-src/guidelines/php/artisan-commands.md +81 -0
- package/.agent-src/guidelines/php/blade-ui.md +78 -0
- package/.agent-src/guidelines/php/controllers.md +90 -0
- package/.agent-src/guidelines/php/database.md +111 -0
- package/.agent-src/guidelines/php/eloquent.md +208 -0
- package/.agent-src/guidelines/php/flux.md +80 -0
- package/.agent-src/guidelines/php/general.md +191 -0
- package/.agent-src/guidelines/php/git.md +96 -0
- package/.agent-src/guidelines/php/jobs.md +111 -0
- package/.agent-src/guidelines/php/livewire.md +71 -0
- package/.agent-src/guidelines/php/logging.md +79 -0
- package/.agent-src/guidelines/php/naming.md +89 -0
- package/.agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
- package/.agent-src/guidelines/php/patterns/dtos.md +199 -0
- package/.agent-src/guidelines/php/patterns/events.md +67 -0
- package/.agent-src/guidelines/php/patterns/factory.md +53 -0
- package/.agent-src/guidelines/php/patterns/pipelines.md +66 -0
- package/.agent-src/guidelines/php/patterns/policies.md +66 -0
- package/.agent-src/guidelines/php/patterns/repositories.md +122 -0
- package/.agent-src/guidelines/php/patterns/service-layer.md +64 -0
- package/.agent-src/guidelines/php/patterns/strategy.md +69 -0
- package/.agent-src/guidelines/php/patterns.md +28 -0
- package/.agent-src/guidelines/php/performance.md +92 -0
- package/.agent-src/guidelines/php/resources.md +100 -0
- package/.agent-src/guidelines/php/security.md +110 -0
- package/.agent-src/guidelines/php/sql.md +97 -0
- package/.agent-src/guidelines/php/validations.md +119 -0
- package/.agent-src/guidelines/php/websocket.md +100 -0
- package/.agent-src/personas/README.md +104 -0
- package/.agent-src/personas/ai-agent.md +77 -0
- package/.agent-src/personas/critical-challenger.md +73 -0
- package/.agent-src/personas/developer.md +73 -0
- package/.agent-src/personas/product-owner.md +78 -0
- package/.agent-src/personas/qa.md +67 -0
- package/.agent-src/personas/senior-engineer.md +77 -0
- package/.agent-src/personas/stakeholder.md +78 -0
- package/.agent-src/rules/agent-docs.md +61 -0
- package/.agent-src/rules/analysis-skill-routing.md +48 -0
- package/.agent-src/rules/architecture.md +62 -0
- package/.agent-src/rules/artifact-drafting-protocol.md +73 -0
- package/.agent-src/rules/ask-when-uncertain.md +52 -0
- package/.agent-src/rules/augment-portability.md +38 -0
- package/.agent-src/rules/augment-source-of-truth.md +128 -0
- package/.agent-src/rules/capture-learnings.md +89 -0
- package/.agent-src/rules/cli-output-handling.md +94 -0
- package/.agent-src/rules/commit-conventions.md +64 -0
- package/.agent-src/rules/context-hygiene.md +90 -0
- package/.agent-src/rules/docker-commands.md +55 -0
- package/.agent-src/rules/docs-sync.md +79 -0
- package/.agent-src/rules/downstream-changes.md +70 -0
- package/.agent-src/rules/e2e-testing.md +53 -0
- package/.agent-src/rules/guidelines.md +90 -0
- package/.agent-src/rules/improve-before-implement.md +94 -0
- package/.agent-src/rules/language-and-tone.md +104 -0
- package/.agent-src/rules/laravel-translations.md +48 -0
- package/.agent-src/rules/markdown-safe-codeblocks.md +18 -0
- package/.agent-src/rules/minimal-safe-diff.md +87 -0
- package/.agent-src/rules/missing-tool-handling.md +62 -0
- package/.agent-src/rules/model-recommendation.md +70 -0
- package/.agent-src/rules/package-ci-checks.md +80 -0
- package/.agent-src/rules/php-coding.md +63 -0
- package/.agent-src/rules/preservation-guard.md +29 -0
- package/.agent-src/rules/review-routing-awareness.md +125 -0
- package/.agent-src/rules/reviewer-awareness.md +92 -0
- package/.agent-src/rules/roadmap-progress-sync.md +56 -0
- package/.agent-src/rules/role-mode-adherence.md +54 -0
- package/.agent-src/rules/rule-type-governance.md +46 -0
- package/.agent-src/rules/runtime-safety.md +42 -0
- package/.agent-src/rules/scope-control.md +40 -0
- package/.agent-src/rules/security-sensitive-stop.md +77 -0
- package/.agent-src/rules/size-enforcement.md +29 -0
- package/.agent-src/rules/skill-improvement-trigger.md +58 -0
- package/.agent-src/rules/skill-quality.md +110 -0
- package/.agent-src/rules/slash-commands.md +30 -0
- package/.agent-src/rules/think-before-action.md +91 -0
- package/.agent-src/rules/token-efficiency.md +99 -0
- package/.agent-src/rules/tool-safety.md +36 -0
- package/.agent-src/rules/upstream-proposal.md +76 -0
- package/.agent-src/rules/user-interaction.md +79 -0
- package/.agent-src/rules/verify-before-complete.md +120 -0
- package/.agent-src/scripts/scan-seeder-violations.php +145 -0
- package/.agent-src/scripts/update_roadmap_progress.py +244 -0
- package/.agent-src/skills/adversarial-review/SKILL.md +149 -0
- package/.agent-src/skills/agent-docs-writing/SKILL.md +234 -0
- package/.agent-src/skills/analysis-autonomous-mode/SKILL.md +197 -0
- package/.agent-src/skills/analysis-skill-router/SKILL.md +134 -0
- package/.agent-src/skills/api-design/SKILL.md +104 -0
- package/.agent-src/skills/api-endpoint/SKILL.md +185 -0
- package/.agent-src/skills/api-testing/SKILL.md +206 -0
- package/.agent-src/skills/artisan-commands/SKILL.md +78 -0
- package/.agent-src/skills/authz-review/SKILL.md +171 -0
- package/.agent-src/skills/aws-infrastructure/SKILL.md +152 -0
- package/.agent-src/skills/blade-ui/SKILL.md +75 -0
- package/.agent-src/skills/blast-radius-analyzer/SKILL.md +185 -0
- package/.agent-src/skills/bug-analyzer/SKILL.md +256 -0
- package/.agent-src/skills/check-refs/SKILL.md +72 -0
- package/.agent-src/skills/code-refactoring/SKILL.md +200 -0
- package/.agent-src/skills/code-review/SKILL.md +214 -0
- package/.agent-src/skills/command-routing/SKILL.md +96 -0
- package/.agent-src/skills/command-writing/SKILL.md +143 -0
- package/.agent-src/skills/composer-packages/SKILL.md +172 -0
- package/.agent-src/skills/context-authoring/SKILL.md +157 -0
- package/.agent-src/skills/context-document/SKILL.md +153 -0
- package/.agent-src/skills/conventional-commits-writing/SKILL.md +70 -0
- package/.agent-src/skills/copilot-agents-optimization/SKILL.md +220 -0
- package/.agent-src/skills/copilot-config/SKILL.md +203 -0
- package/.agent-src/skills/dashboard-design/SKILL.md +116 -0
- package/.agent-src/skills/data-flow-mapper/SKILL.md +160 -0
- package/.agent-src/skills/database/SKILL.md +91 -0
- package/.agent-src/skills/dependency-upgrade/SKILL.md +204 -0
- package/.agent-src/skills/description-assist/SKILL.md +169 -0
- package/.agent-src/skills/design-review/SKILL.md +228 -0
- package/.agent-src/skills/devcontainer/SKILL.md +121 -0
- package/.agent-src/skills/developer-like-execution/SKILL.md +276 -0
- package/.agent-src/skills/docker/SKILL.md +245 -0
- package/.agent-src/skills/dto-creator/SKILL.md +117 -0
- package/.agent-src/skills/eloquent/SKILL.md +92 -0
- package/.agent-src/skills/eloquent/evals/last-run.json +99 -0
- package/.agent-src/skills/eloquent/evals/triggers.json +16 -0
- package/.agent-src/skills/estimate-ticket/SKILL.md +186 -0
- package/.agent-src/skills/estimate-ticket/evals/output-schema.yml +20 -0
- package/.agent-src/skills/estimate-ticket/evals/triggers.json +18 -0
- package/.agent-src/skills/fe-design/SKILL.md +223 -0
- package/.agent-src/skills/feature-planning/SKILL.md +226 -0
- package/.agent-src/skills/file-editor/SKILL.md +129 -0
- package/.agent-src/skills/finishing-a-development-branch/SKILL.md +200 -0
- package/.agent-src/skills/flux/SKILL.md +64 -0
- package/.agent-src/skills/git-workflow/SKILL.md +102 -0
- package/.agent-src/skills/github-ci/SKILL.md +122 -0
- package/.agent-src/skills/grafana/SKILL.md +168 -0
- package/.agent-src/skills/guideline-writing/SKILL.md +147 -0
- package/.agent-src/skills/jira-integration/SKILL.md +182 -0
- package/.agent-src/skills/jobs-events/SKILL.md +87 -0
- package/.agent-src/skills/judge-bug-hunter/SKILL.md +157 -0
- package/.agent-src/skills/judge-code-quality/SKILL.md +158 -0
- package/.agent-src/skills/judge-security-auditor/SKILL.md +167 -0
- package/.agent-src/skills/judge-test-coverage/SKILL.md +154 -0
- package/.agent-src/skills/laravel/SKILL.md +195 -0
- package/.agent-src/skills/laravel-horizon/SKILL.md +169 -0
- package/.agent-src/skills/laravel-mail/SKILL.md +193 -0
- package/.agent-src/skills/laravel-middleware/SKILL.md +185 -0
- package/.agent-src/skills/laravel-notifications/SKILL.md +168 -0
- package/.agent-src/skills/laravel-pennant/SKILL.md +188 -0
- package/.agent-src/skills/laravel-pulse/SKILL.md +160 -0
- package/.agent-src/skills/laravel-reverb/SKILL.md +205 -0
- package/.agent-src/skills/laravel-scheduling/SKILL.md +167 -0
- package/.agent-src/skills/laravel-validation/SKILL.md +71 -0
- package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +249 -0
- package/.agent-src/skills/lint-skills/SKILL.md +72 -0
- package/.agent-src/skills/livewire/SKILL.md +79 -0
- package/.agent-src/skills/logging-monitoring/SKILL.md +100 -0
- package/.agent-src/skills/mcp/SKILL.md +193 -0
- package/.agent-src/skills/merge-conflicts/SKILL.md +158 -0
- package/.agent-src/skills/migration-creator/SKILL.md +160 -0
- package/.agent-src/skills/module-management/SKILL.md +154 -0
- package/.agent-src/skills/multi-tenancy/SKILL.md +129 -0
- package/.agent-src/skills/openapi/SKILL.md +154 -0
- package/.agent-src/skills/override-management/SKILL.md +186 -0
- package/.agent-src/skills/performance/SKILL.md +69 -0
- package/.agent-src/skills/performance-analysis/SKILL.md +118 -0
- package/.agent-src/skills/pest-testing/SKILL.md +321 -0
- package/.agent-src/skills/php-coder/SKILL.md +78 -0
- package/.agent-src/skills/php-coder/evals/triggers.json +16 -0
- package/.agent-src/skills/php-debugging/SKILL.md +184 -0
- package/.agent-src/skills/php-service/SKILL.md +96 -0
- package/.agent-src/skills/playwright-testing/SKILL.md +244 -0
- package/.agent-src/skills/project-analysis-core/SKILL.md +138 -0
- package/.agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +130 -0
- package/.agent-src/skills/project-analysis-laravel/SKILL.md +119 -0
- package/.agent-src/skills/project-analysis-nextjs/SKILL.md +123 -0
- package/.agent-src/skills/project-analysis-node-express/SKILL.md +111 -0
- package/.agent-src/skills/project-analysis-react/SKILL.md +119 -0
- package/.agent-src/skills/project-analysis-symfony/SKILL.md +111 -0
- package/.agent-src/skills/project-analysis-zend-laminas/SKILL.md +108 -0
- package/.agent-src/skills/project-analyzer/SKILL.md +341 -0
- package/.agent-src/skills/project-docs/SKILL.md +137 -0
- package/.agent-src/skills/quality-tools/SKILL.md +411 -0
- package/.agent-src/skills/readme-reviewer/SKILL.md +187 -0
- package/.agent-src/skills/readme-writing/SKILL.md +142 -0
- package/.agent-src/skills/readme-writing-package/SKILL.md +185 -0
- package/.agent-src/skills/receiving-code-review/SKILL.md +190 -0
- package/.agent-src/skills/refine-ticket/SKILL.md +310 -0
- package/.agent-src/skills/refine-ticket/detection-map.yml +124 -0
- package/.agent-src/skills/refine-ticket/evals/output-schema.yml +16 -0
- package/.agent-src/skills/refine-ticket/evals/triggers.json +16 -0
- package/.agent-src/skills/requesting-code-review/SKILL.md +199 -0
- package/.agent-src/skills/review-routing/SKILL.md +195 -0
- package/.agent-src/skills/roadmap-management/SKILL.md +303 -0
- package/.agent-src/skills/rtk-output-filtering/SKILL.md +184 -0
- package/.agent-src/skills/rule-writing/SKILL.md +148 -0
- package/.agent-src/skills/security/SKILL.md +79 -0
- package/.agent-src/skills/security-audit/SKILL.md +123 -0
- package/.agent-src/skills/sentry-integration/SKILL.md +170 -0
- package/.agent-src/skills/sequential-thinking/SKILL.md +158 -0
- package/.agent-src/skills/skill-improvement-pipeline/SKILL.md +155 -0
- package/.agent-src/skills/skill-management/SKILL.md +121 -0
- package/.agent-src/skills/skill-reviewer/SKILL.md +218 -0
- package/.agent-src/skills/skill-writing/SKILL.md +291 -0
- package/.agent-src/skills/skill-writing/evals/triggers.json +16 -0
- package/.agent-src/skills/sql-writing/SKILL.md +74 -0
- package/.agent-src/skills/subagent-orchestration/SKILL.md +190 -0
- package/.agent-src/skills/systematic-debugging/SKILL.md +244 -0
- package/.agent-src/skills/technical-specification/SKILL.md +185 -0
- package/.agent-src/skills/terraform/SKILL.md +137 -0
- package/.agent-src/skills/terragrunt/SKILL.md +217 -0
- package/.agent-src/skills/test-driven-development/SKILL.md +252 -0
- package/.agent-src/skills/test-performance/SKILL.md +172 -0
- package/.agent-src/skills/threat-modeling/SKILL.md +189 -0
- package/.agent-src/skills/traefik/SKILL.md +319 -0
- package/.agent-src/skills/universal-project-analysis/SKILL.md +179 -0
- package/.agent-src/skills/upstream-contribute/SKILL.md +255 -0
- package/.agent-src/skills/using-git-worktrees/SKILL.md +148 -0
- package/.agent-src/skills/validate-feature-fit/SKILL.md +113 -0
- package/.agent-src/skills/verify-before-complete/SKILL.md +188 -0
- package/.agent-src/skills/websocket/SKILL.md +75 -0
- package/.agent-src/templates/AGENTS.md +146 -0
- package/.agent-src/templates/agent-settings.md +256 -0
- package/.agent-src/templates/agents/.gitattributes.fragment +16 -0
- package/.agent-src/templates/agents/agent-project-settings.example.yml +138 -0
- package/.agent-src/templates/agents/memory/architecture-decisions.example.yml +95 -0
- package/.agent-src/templates/agents/memory/domain-invariants.example.yml +80 -0
- package/.agent-src/templates/agents/memory/historical-patterns.example.yml +82 -0
- package/.agent-src/templates/agents/memory/incident-learnings.example.yml +113 -0
- package/.agent-src/templates/agents/memory/ownership.example.yml +75 -0
- package/.agent-src/templates/agents/memory/product-rules.example.yml +87 -0
- package/.agent-src/templates/agents/proposal.example.md +143 -0
- package/.agent-src/templates/command.md +84 -0
- package/.agent-src/templates/contexts/auth-model.md +59 -0
- package/.agent-src/templates/contexts/data-sensitivity.md +60 -0
- package/.agent-src/templates/contexts/deployment-order.md +72 -0
- package/.agent-src/templates/contexts/observability.md +64 -0
- package/.agent-src/templates/contexts/tenant-boundaries.md +68 -0
- package/.agent-src/templates/contexts.md +116 -0
- package/.agent-src/templates/copilot-instructions.md +115 -0
- package/.agent-src/templates/features.md +125 -0
- package/.agent-src/templates/github-workflows/memory-hygiene.yml +133 -0
- package/.agent-src/templates/github-workflows/pr-risk-review.yml +123 -0
- package/.agent-src/templates/github-workflows/proposal-drift.yml +118 -0
- package/.agent-src/templates/overrides/command.md +24 -0
- package/.agent-src/templates/overrides/guideline.md +21 -0
- package/.agent-src/templates/overrides/rule.md +19 -0
- package/.agent-src/templates/overrides/skill.md +24 -0
- package/.agent-src/templates/overrides/template.md +21 -0
- package/.agent-src/templates/persona.md +99 -0
- package/.agent-src/templates/roadmaps.md +109 -0
- package/.agent-src/templates/scripts/README.md +195 -0
- package/.agent-src/templates/scripts/check_memory.py +283 -0
- package/.agent-src/templates/scripts/check_memory_proposal.py +180 -0
- package/.agent-src/templates/scripts/historical-bug-patterns.example.yml +84 -0
- package/.agent-src/templates/scripts/implement_ticket/__init__.py +57 -0
- package/.agent-src/templates/scripts/implement_ticket/__main__.py +9 -0
- package/.agent-src/templates/scripts/implement_ticket/cli.py +171 -0
- package/.agent-src/templates/scripts/implement_ticket/delivery_state.py +130 -0
- package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +134 -0
- package/.agent-src/templates/scripts/implement_ticket/persona_policy.py +85 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +49 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/analyze.py +98 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/implement.py +145 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/memory.py +136 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/plan.py +175 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +140 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/report.py +195 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/test.py +180 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/verify.py +170 -0
- package/.agent-src/templates/scripts/memory_hash.py +75 -0
- package/.agent-src/templates/scripts/memory_lookup.py +216 -0
- package/.agent-src/templates/scripts/memory_report.py +184 -0
- package/.agent-src/templates/scripts/memory_signal.py +167 -0
- package/.agent-src/templates/scripts/memory_status.py +156 -0
- package/.agent-src/templates/scripts/ownership-map.example.yml +87 -0
- package/.agent-src/templates/scripts/pr-risk-config.example.yml +76 -0
- package/.agent-src/templates/scripts/pr_review_routing.py +340 -0
- package/.agent-src/templates/scripts/pr_risk_review.py +211 -0
- package/.agent-src/templates/skill.md +136 -0
- package/.augment-plugin/marketplace.json +32 -0
- package/.augment-plugin/plugin.json +21 -0
- package/.claude-plugin/marketplace.json +119 -0
- package/AGENTS.md +121 -0
- package/CHANGELOG.md +279 -0
- package/CONTRIBUTING.md +176 -0
- package/LICENSE +21 -0
- package/README.md +357 -0
- package/bin/install.php +38 -0
- package/composer.json +29 -0
- package/config/agent-settings.template.yml +96 -0
- package/config/profiles/balanced.ini +10 -0
- package/config/profiles/full.ini +10 -0
- package/config/profiles/minimal.ini +10 -0
- package/docs/architecture.md +144 -0
- package/docs/customization.md +88 -0
- package/docs/development.md +171 -0
- package/docs/getting-started.md +130 -0
- package/docs/github-topics.md +84 -0
- package/docs/installation.md +376 -0
- package/docs/mcp.md +133 -0
- package/docs/quality.md +98 -0
- package/docs/skills-catalog.md +136 -0
- package/docs/troubleshooting.md +167 -0
- package/llms.txt +130 -0
- package/package.json +31 -0
- package/scripts/audit_skill_descriptions.py +168 -0
- package/scripts/check_compression.py +221 -0
- package/scripts/check_memory.py +341 -0
- package/scripts/check_memory_proposal.py +180 -0
- package/scripts/check_portability.py +320 -0
- package/scripts/check_proposal.py +269 -0
- package/scripts/check_references.py +400 -0
- package/scripts/ci_summary.py +131 -0
- package/scripts/compress.py +671 -0
- package/scripts/compress.sh +18 -0
- package/scripts/first-run.sh +109 -0
- package/scripts/generate_catalog.py +116 -0
- package/scripts/install +151 -0
- package/scripts/install-hooks.sh +29 -0
- package/scripts/install.py +487 -0
- package/scripts/install.sh +637 -0
- package/scripts/install_anthropic_key.sh +101 -0
- package/scripts/inventory_frontmatter.py +164 -0
- package/scripts/lint_marketplace.py +142 -0
- package/scripts/lint_regression.py +232 -0
- package/scripts/mcp_render.py +159 -0
- package/scripts/measure_patterns.py +376 -0
- package/scripts/memory_hash.py +75 -0
- package/scripts/memory_lookup.py +441 -0
- package/scripts/memory_report.py +336 -0
- package/scripts/memory_signal.py +210 -0
- package/scripts/memory_status.py +195 -0
- package/scripts/postinstall.sh +60 -0
- package/scripts/readme_linter.py +580 -0
- package/scripts/refine_ticket_detect.py +623 -0
- package/scripts/requirements-evals.txt +7 -0
- package/scripts/runtime_dispatcher.py +265 -0
- package/scripts/runtime_handler.py +148 -0
- package/scripts/runtime_registry.py +166 -0
- package/scripts/schemas/command.schema.json +32 -0
- package/scripts/schemas/persona.schema.json +42 -0
- package/scripts/schemas/rule.schema.json +28 -0
- package/scripts/schemas/skill.schema.json +73 -0
- package/scripts/setup.sh +230 -0
- package/scripts/setup_eval_venv.sh +58 -0
- package/scripts/skill_linter.py +2175 -0
- package/scripts/skill_trigger_eval.py +651 -0
- package/scripts/tool_registry.py +146 -0
- package/scripts/tools/__init__.py +1 -0
- package/scripts/tools/adapter_errors.py +63 -0
- package/scripts/tools/base_adapter.py +91 -0
- package/scripts/tools/github_adapter.py +128 -0
- package/scripts/tools/jira_adapter.py +115 -0
- package/scripts/update_counts.py +147 -0
- package/scripts/validate_frontmatter.py +424 -0
- package/templates/consumer-settings/README.md +46 -0
- package/templates/consumer-settings/augment-settings.json +12 -0
- package/templates/consumer-settings/claude-settings.json +9 -0
- package/templates/consumer-settings/copilot-settings.json +14 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"""``report`` step — delivery report renderer.
|
|
2
|
+
|
|
3
|
+
Produces the markdown block described in
|
|
4
|
+
``agents/contexts/implement-ticket-flow.md#delivery-report-schema``.
|
|
5
|
+
All nine headings are present on every run — the schema is stable
|
|
6
|
+
for consumers — but section bodies are omitted when the matching
|
|
7
|
+
slice of ``DeliveryState`` is empty. The single exception is the
|
|
8
|
+
**Memory that mattered** section, which per contract is dropped
|
|
9
|
+
entirely (heading included) when no hit carries a
|
|
10
|
+
``changed_outcome`` marker.
|
|
11
|
+
|
|
12
|
+
The step is pure and deterministic: no I/O, no subprocess, no
|
|
13
|
+
randomness. It reads ``DeliveryState``, writes ``state.report``,
|
|
14
|
+
and always returns ``SUCCESS``.
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import Any, Iterable
|
|
19
|
+
|
|
20
|
+
from ..delivery_state import DeliveryState, Outcome, StepResult
|
|
21
|
+
from ..persona_policy import resolve_policy
|
|
22
|
+
|
|
23
|
+
AMBIGUITIES: tuple[dict[str, str], ...] = ()
|
|
24
|
+
"""Report rendering is pure and always succeeds — no blocked paths."""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def run(state: DeliveryState) -> StepResult:
|
|
28
|
+
"""Render the delivery report into ``state.report`` and return SUCCESS."""
|
|
29
|
+
state.report = _render(state)
|
|
30
|
+
return StepResult(outcome=Outcome.SUCCESS)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _render(state: DeliveryState) -> str:
|
|
34
|
+
sections = [
|
|
35
|
+
_ticket_section(state),
|
|
36
|
+
_persona_section(state),
|
|
37
|
+
_plan_section(state),
|
|
38
|
+
_changes_section(state),
|
|
39
|
+
_tests_section(state),
|
|
40
|
+
_verify_section(state),
|
|
41
|
+
_memory_section(state),
|
|
42
|
+
_followups_section(state),
|
|
43
|
+
_next_commands_section(state),
|
|
44
|
+
]
|
|
45
|
+
# Drop sections that opted out (memory-that-mattered returns "" when no
|
|
46
|
+
# hit influenced an outcome — per the report schema drop-rule).
|
|
47
|
+
return "\n\n".join(section for section in sections if section)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _ticket_section(state: DeliveryState) -> str:
|
|
51
|
+
ticket = state.ticket or {}
|
|
52
|
+
ticket_id = ticket.get("id") or "(no id)"
|
|
53
|
+
title = ticket.get("title") or "(no title)"
|
|
54
|
+
return f"## Ticket\n\n{ticket_id} — {title}"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _persona_section(state: DeliveryState) -> str:
|
|
58
|
+
return f"## Persona\n\n{state.persona or '(unset)'}"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _plan_section(state: DeliveryState) -> str:
|
|
62
|
+
body = _format_plan(state.plan)
|
|
63
|
+
return "## Plan\n\n" + (body or "_(no plan recorded)_")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _format_plan(plan: Any) -> str:
|
|
67
|
+
"""Render whatever shape ``state.plan`` carries.
|
|
68
|
+
|
|
69
|
+
Accepts a list of step strings, a list of ``{title, detail}`` dicts,
|
|
70
|
+
or a single string — the contract doc intentionally leaves the
|
|
71
|
+
plan shape loose until ``feature-plan`` wiring lands in a later
|
|
72
|
+
phase.
|
|
73
|
+
"""
|
|
74
|
+
if not plan:
|
|
75
|
+
return ""
|
|
76
|
+
if isinstance(plan, str):
|
|
77
|
+
return plan.strip()
|
|
78
|
+
if isinstance(plan, list):
|
|
79
|
+
lines = []
|
|
80
|
+
for idx, item in enumerate(plan, start=1):
|
|
81
|
+
if isinstance(item, dict):
|
|
82
|
+
title = item.get("title") or item.get("step") or f"Step {idx}"
|
|
83
|
+
detail = item.get("detail") or item.get("note") or ""
|
|
84
|
+
lines.append(
|
|
85
|
+
f"{idx}. **{title}**" + (f" — {detail}" if detail else ""),
|
|
86
|
+
)
|
|
87
|
+
else:
|
|
88
|
+
lines.append(f"{idx}. {item}")
|
|
89
|
+
return "\n".join(lines)
|
|
90
|
+
# Last resort: string-coerce an unknown shape so the renderer never
|
|
91
|
+
# crashes on experimental plan structures.
|
|
92
|
+
return str(plan)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _changes_section(state: DeliveryState) -> str:
|
|
96
|
+
if not state.changes:
|
|
97
|
+
return "## Changes\n\n_(no file changes recorded)_"
|
|
98
|
+
lines = ["## Changes", ""]
|
|
99
|
+
for change in state.changes:
|
|
100
|
+
path = change.get("path") or change.get("file") or "(unknown file)"
|
|
101
|
+
lines_range = change.get("lines") or change.get("range") or ""
|
|
102
|
+
purpose = change.get("purpose") or change.get("why") or ""
|
|
103
|
+
prefix = f"- `{path}`"
|
|
104
|
+
if lines_range:
|
|
105
|
+
prefix += f" ({lines_range})"
|
|
106
|
+
if purpose:
|
|
107
|
+
prefix += f" — {purpose}"
|
|
108
|
+
lines.append(prefix)
|
|
109
|
+
return "\n".join(lines)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _tests_section(state: DeliveryState) -> str:
|
|
113
|
+
return "## Tests\n\n" + _format_kv_block(state.tests, "_(no tests ran)_")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _verify_section(state: DeliveryState) -> str:
|
|
117
|
+
return "## Verify\n\n" + _format_kv_block(state.verify, "_(no verify verdict)_")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _memory_section(state: DeliveryState) -> str:
|
|
121
|
+
"""Render **only** hits that changed an outcome (per report schema)."""
|
|
122
|
+
influential = [
|
|
123
|
+
hit for hit in (state.memory or [])
|
|
124
|
+
if isinstance(hit, dict) and hit.get("changed_outcome")
|
|
125
|
+
]
|
|
126
|
+
if not influential:
|
|
127
|
+
return "" # drop the whole section — heading included
|
|
128
|
+
lines = ["## Memory that mattered", ""]
|
|
129
|
+
for hit in influential:
|
|
130
|
+
hit_id = hit.get("id") or "(no id)"
|
|
131
|
+
hit_type = hit.get("type") or "(no type)"
|
|
132
|
+
note = hit.get("note") or hit.get("why") or ""
|
|
133
|
+
suffix = f" — {note}" if note else ""
|
|
134
|
+
lines.append(f"- `{hit_id}` ({hit_type}){suffix}")
|
|
135
|
+
return "\n".join(lines)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _followups_section(state: DeliveryState) -> str:
|
|
139
|
+
followups = _extract_followups(state)
|
|
140
|
+
if not followups:
|
|
141
|
+
return "## Follow-ups\n\n_(none)_"
|
|
142
|
+
lines = ["## Follow-ups", ""]
|
|
143
|
+
for item in followups:
|
|
144
|
+
anchor = item.get("anchor") or ""
|
|
145
|
+
note = item.get("note") or item.get("title") or "(untitled)"
|
|
146
|
+
prefix = f"- {note}"
|
|
147
|
+
if anchor:
|
|
148
|
+
prefix += f" — `{anchor}`"
|
|
149
|
+
lines.append(prefix)
|
|
150
|
+
return "\n".join(lines)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _extract_followups(state: DeliveryState) -> list[dict[str, Any]]:
|
|
154
|
+
"""Follow-ups may live on any slice; aggregate them in reading order."""
|
|
155
|
+
collected: list[dict[str, Any]] = []
|
|
156
|
+
for source in (state.plan, state.verify, state.tests):
|
|
157
|
+
if isinstance(source, dict):
|
|
158
|
+
for item in source.get("followups") or []:
|
|
159
|
+
if isinstance(item, dict):
|
|
160
|
+
collected.append(item)
|
|
161
|
+
return collected
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _next_commands_section(state: DeliveryState) -> str:
|
|
165
|
+
if not resolve_policy(state.persona).suggests_next_commands:
|
|
166
|
+
# Advisory personas produce a plan-only report; suggesting a
|
|
167
|
+
# commit or PR would mislead the reader — nothing was changed.
|
|
168
|
+
return ""
|
|
169
|
+
commands = _suggest_commands(state)
|
|
170
|
+
lines = ["## Suggested next commands", ""]
|
|
171
|
+
lines.extend(f"- `{cmd}`" for cmd in commands)
|
|
172
|
+
return "\n".join(lines)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _suggest_commands(state: DeliveryState) -> list[str]:
|
|
176
|
+
"""Always suggest ``/commit`` and ``/create-pr`` when verify was successful."""
|
|
177
|
+
if state.outcomes.get("verify") == Outcome.SUCCESS.value:
|
|
178
|
+
return ["/commit", "/create-pr"]
|
|
179
|
+
return ["/commit"]
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _format_kv_block(value: Any, empty_placeholder: str) -> str:
|
|
183
|
+
"""Render a dict-ish slice as a bullet list; fall back to placeholder."""
|
|
184
|
+
if not value:
|
|
185
|
+
return empty_placeholder
|
|
186
|
+
if isinstance(value, dict):
|
|
187
|
+
return "\n".join(_render_kv_lines(value.items()))
|
|
188
|
+
if isinstance(value, str):
|
|
189
|
+
return value.strip() or empty_placeholder
|
|
190
|
+
return str(value)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _render_kv_lines(pairs: Iterable[tuple[str, Any]]) -> list[str]:
|
|
194
|
+
"""Render ``(key, value)`` pairs as one Markdown bullet per pair."""
|
|
195
|
+
return [f"- **{key}:** {value}" for key, value in pairs]
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""``test`` step — gate + Option-A delegation for running the test suite.
|
|
2
|
+
|
|
3
|
+
The dispatcher never spawns subprocesses. Test execution is handed
|
|
4
|
+
to the agent via ``@agent-directive: run-tests scope=targeted``; the
|
|
5
|
+
agent drives the project's test runner (pytest, Pest, phpunit, …),
|
|
6
|
+
captures the verdict onto ``state.tests``, marks
|
|
7
|
+
``outcomes['test'] = 'success'``, and re-invokes the dispatcher.
|
|
8
|
+
|
|
9
|
+
Contract for ``state.tests`` when populated:
|
|
10
|
+
|
|
11
|
+
- Must be a dict.
|
|
12
|
+
- Must carry a ``verdict`` key \u2014 one of ``success``, ``failed``,
|
|
13
|
+
or ``mixed`` (targeted vs full-suite split). Anything else blocks.
|
|
14
|
+
- ``failed`` or ``mixed`` verdicts halt with the verdict as part of
|
|
15
|
+
the surfaced message so the user decides whether to continue or
|
|
16
|
+
stop. This follows the ``verify-before-complete`` rule: a bad test
|
|
17
|
+
outcome must never be silently skipped.
|
|
18
|
+
- Optional keys (``targeted``, ``full``, ``duration_ms``,
|
|
19
|
+
``followups``) feed the delivery report.
|
|
20
|
+
"""
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from typing import Any
|
|
24
|
+
|
|
25
|
+
from ..delivery_state import (
|
|
26
|
+
DeliveryState,
|
|
27
|
+
Outcome,
|
|
28
|
+
StepResult,
|
|
29
|
+
agent_directive,
|
|
30
|
+
)
|
|
31
|
+
from ..persona_policy import resolve_policy
|
|
32
|
+
|
|
33
|
+
_ALLOWED_VERDICTS = ("success", "failed", "mixed")
|
|
34
|
+
|
|
35
|
+
AMBIGUITIES: tuple[dict[str, str], ...] = (
|
|
36
|
+
{
|
|
37
|
+
"code": "upstream_implement_failed",
|
|
38
|
+
"trigger": "`implement` outcome is not `success`",
|
|
39
|
+
"resolution": "re-run `/implement-ticket` from the start",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"code": "empty_tests_delegate",
|
|
43
|
+
"trigger": "`state.tests` empty — test runner not invoked yet",
|
|
44
|
+
"resolution": (
|
|
45
|
+
"agent directive `run-tests scope=targeted|full` → "
|
|
46
|
+
"`/tests-execute` (qa persona widens to full suite)"
|
|
47
|
+
),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"code": "malformed_tests",
|
|
51
|
+
"trigger": (
|
|
52
|
+
"`state.tests` is not a dict or `verdict` is not one of "
|
|
53
|
+
"success / failed / mixed"
|
|
54
|
+
),
|
|
55
|
+
"resolution": "re-run tests and record a clean verdict",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"code": "bad_test_verdict",
|
|
59
|
+
"trigger": "`state.tests['verdict']` is `failed` or `mixed`",
|
|
60
|
+
"resolution": "fix failures and re-run, or abort",
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
"""Declared ambiguity surfaces. Advisory personas skip this step entirely."""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def run(state: DeliveryState) -> StepResult:
|
|
67
|
+
"""Gate on ``implement``, then either delegate or validate ``state.tests``."""
|
|
68
|
+
policy = resolve_policy(state.persona)
|
|
69
|
+
if not policy.allows_test:
|
|
70
|
+
return StepResult(
|
|
71
|
+
outcome=Outcome.SUCCESS,
|
|
72
|
+
message=f"test skipped: persona `{policy.name}` is plan-only.",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if state.outcomes.get("implement") != Outcome.SUCCESS.value:
|
|
76
|
+
return _blocked_on_precondition(state)
|
|
77
|
+
|
|
78
|
+
tests = state.tests
|
|
79
|
+
if not tests:
|
|
80
|
+
return _delegate_to_run_tests(state, policy.widen_tests)
|
|
81
|
+
|
|
82
|
+
shape_issues = _diagnose_tests(tests)
|
|
83
|
+
if shape_issues:
|
|
84
|
+
return _blocked_on_shape(state, shape_issues)
|
|
85
|
+
|
|
86
|
+
# At this point ``tests`` is a dict with a recognised verdict.
|
|
87
|
+
verdict = tests.get("verdict")
|
|
88
|
+
if verdict != "success":
|
|
89
|
+
return _blocked_on_bad_verdict(state, verdict)
|
|
90
|
+
|
|
91
|
+
return StepResult(outcome=Outcome.SUCCESS)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _diagnose_tests(tests: Any) -> list[str]:
|
|
95
|
+
if not isinstance(tests, dict):
|
|
96
|
+
return [f"state.tests must be a dict, got {type(tests).__name__}"]
|
|
97
|
+
verdict = tests.get("verdict")
|
|
98
|
+
if verdict not in _ALLOWED_VERDICTS:
|
|
99
|
+
return [
|
|
100
|
+
f"state.tests['verdict'] must be one of "
|
|
101
|
+
f"{', '.join(_ALLOWED_VERDICTS)}; got {verdict!r}",
|
|
102
|
+
]
|
|
103
|
+
return []
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _delegate_to_run_tests(state: DeliveryState, widen: bool) -> StepResult:
|
|
107
|
+
"""Emit the ``run-tests`` directive.
|
|
108
|
+
|
|
109
|
+
``widen`` comes from the persona policy (``qa`` widens to the full
|
|
110
|
+
suite). The directive scope becomes the first thing an orchestrator
|
|
111
|
+
reads, so the widened case is visible without parsing the options.
|
|
112
|
+
"""
|
|
113
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
114
|
+
scope = "full" if widen else "targeted"
|
|
115
|
+
description = (
|
|
116
|
+
"full suite (qa persona widens to catch regressions outside "
|
|
117
|
+
"the changed paths)"
|
|
118
|
+
if widen
|
|
119
|
+
else "targeted first (`--filter` on the changed paths), full "
|
|
120
|
+
"suite only if targeted passes"
|
|
121
|
+
)
|
|
122
|
+
return StepResult(
|
|
123
|
+
outcome=Outcome.BLOCKED,
|
|
124
|
+
questions=[
|
|
125
|
+
agent_directive("run-tests", ticket=ticket_id, scope=scope),
|
|
126
|
+
f"> Ticket {ticket_id} \u2014 running tests: {description}.",
|
|
127
|
+
f"> 1. Continue \u2014 run {scope} tests now",
|
|
128
|
+
"> 2. Abort \u2014 skip testing (NOT recommended)",
|
|
129
|
+
],
|
|
130
|
+
message=f"Ticket {ticket_id} needs its tests run before verification.",
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _blocked_on_precondition(state: DeliveryState) -> StepResult:
|
|
135
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
136
|
+
return StepResult(
|
|
137
|
+
outcome=Outcome.BLOCKED,
|
|
138
|
+
questions=[
|
|
139
|
+
f"> Ticket {ticket_id} \u2014 test gate refused: "
|
|
140
|
+
"`implement` step did not complete successfully.",
|
|
141
|
+
"> 1. Re-run `/implement-ticket` from the start",
|
|
142
|
+
"> 2. Abort",
|
|
143
|
+
],
|
|
144
|
+
message=(
|
|
145
|
+
f"Ticket {ticket_id} cannot test: implement gate did not pass."
|
|
146
|
+
),
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _blocked_on_shape(state: DeliveryState, issues: list[str]) -> StepResult:
|
|
151
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
152
|
+
return StepResult(
|
|
153
|
+
outcome=Outcome.BLOCKED,
|
|
154
|
+
questions=[
|
|
155
|
+
f"> Ticket {ticket_id} \u2014 recorded test output is malformed: "
|
|
156
|
+
+ "; ".join(issues)
|
|
157
|
+
+ ".",
|
|
158
|
+
"> 1. Re-run tests and resume",
|
|
159
|
+
"> 2. Abort \u2014 test verdict cannot be trusted",
|
|
160
|
+
],
|
|
161
|
+
message=f"Ticket {ticket_id} tests shape invalid: {'; '.join(issues)}.",
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _blocked_on_bad_verdict(state: DeliveryState, verdict: Any) -> StepResult:
|
|
166
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
167
|
+
return StepResult(
|
|
168
|
+
outcome=Outcome.BLOCKED,
|
|
169
|
+
questions=[
|
|
170
|
+
f"> Ticket {ticket_id} \u2014 tests reported `{verdict}`. "
|
|
171
|
+
"Verification cannot proceed on a non-success verdict.",
|
|
172
|
+
"> 1. Fix the failing tests and re-run `run-tests`",
|
|
173
|
+
"> 2. Continue anyway \u2014 override (NOT recommended)",
|
|
174
|
+
"> 3. Abort",
|
|
175
|
+
],
|
|
176
|
+
message=f"Ticket {ticket_id} test verdict was `{verdict}`, not success.",
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
__all__ = ["AMBIGUITIES", "run"]
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""``verify`` step — gate + Option-A delegation to ``review-changes``.
|
|
2
|
+
|
|
3
|
+
The dispatcher does not run the review-changes judges itself; the
|
|
4
|
+
agent invokes the composite review (bug-hunter + security +
|
|
5
|
+
test-coverage + code-quality) and captures the consolidated
|
|
6
|
+
verdict onto ``state.verify``.
|
|
7
|
+
|
|
8
|
+
``state.verify`` contract when populated:
|
|
9
|
+
|
|
10
|
+
- Must be a dict.
|
|
11
|
+
- Must carry a ``verdict`` key — one of ``success``, ``blocked``,
|
|
12
|
+
``partial``. Matches the ``Outcome`` vocabulary used everywhere
|
|
13
|
+
else in the flow.
|
|
14
|
+
- A ``success`` verdict advances the flow to ``report``.
|
|
15
|
+
- A ``blocked`` or ``partial`` verdict halts with numbered options
|
|
16
|
+
so the user decides whether to address the findings, override
|
|
17
|
+
(rarely appropriate), or abort.
|
|
18
|
+
- Optional keys (``confidence``, ``findings``, ``followups``) feed
|
|
19
|
+
the delivery report.
|
|
20
|
+
"""
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from typing import Any
|
|
24
|
+
|
|
25
|
+
from ..delivery_state import (
|
|
26
|
+
DeliveryState,
|
|
27
|
+
Outcome,
|
|
28
|
+
StepResult,
|
|
29
|
+
agent_directive,
|
|
30
|
+
)
|
|
31
|
+
from ..persona_policy import resolve_policy
|
|
32
|
+
|
|
33
|
+
_ALLOWED_VERDICTS = ("success", "blocked", "partial")
|
|
34
|
+
|
|
35
|
+
AMBIGUITIES: tuple[dict[str, str], ...] = (
|
|
36
|
+
{
|
|
37
|
+
"code": "upstream_test_failed",
|
|
38
|
+
"trigger": "`test` outcome is not `success`",
|
|
39
|
+
"resolution": "re-run `/implement-ticket` from the start",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"code": "empty_verify_delegate",
|
|
43
|
+
"trigger": "`state.verify` empty — four-judge review not run yet",
|
|
44
|
+
"resolution": "agent directive `review-changes` → `/review-changes`",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"code": "malformed_verify",
|
|
48
|
+
"trigger": (
|
|
49
|
+
"`state.verify` is not a dict or `verdict` is not one of "
|
|
50
|
+
"success / blocked / partial"
|
|
51
|
+
),
|
|
52
|
+
"resolution": "re-run `/review-changes` and record a clean verdict",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"code": "bad_verify_verdict",
|
|
56
|
+
"trigger": "`state.verify['verdict']` is `blocked` or `partial`",
|
|
57
|
+
"resolution": (
|
|
58
|
+
"address findings and re-run `/review-changes` — never bypass "
|
|
59
|
+
"(see `verify-before-complete`)"
|
|
60
|
+
),
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
"""Declared ambiguity surfaces. Advisory personas skip this step entirely."""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def run(state: DeliveryState) -> StepResult:
|
|
67
|
+
"""Gate on ``test``, then either delegate or validate ``state.verify``."""
|
|
68
|
+
policy = resolve_policy(state.persona)
|
|
69
|
+
if not policy.allows_verify:
|
|
70
|
+
return StepResult(
|
|
71
|
+
outcome=Outcome.SUCCESS,
|
|
72
|
+
message=f"verify skipped: persona `{policy.name}` is plan-only.",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if state.outcomes.get("test") != Outcome.SUCCESS.value:
|
|
76
|
+
return _blocked_on_precondition(state)
|
|
77
|
+
|
|
78
|
+
verify = state.verify
|
|
79
|
+
if not verify:
|
|
80
|
+
return _delegate_to_review_changes(state)
|
|
81
|
+
|
|
82
|
+
shape_issues = _diagnose_verify(verify)
|
|
83
|
+
if shape_issues:
|
|
84
|
+
return _blocked_on_shape(state, shape_issues)
|
|
85
|
+
|
|
86
|
+
verdict = verify.get("verdict")
|
|
87
|
+
if verdict != "success":
|
|
88
|
+
return _blocked_on_bad_verdict(state, verdict)
|
|
89
|
+
|
|
90
|
+
return StepResult(outcome=Outcome.SUCCESS)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _diagnose_verify(verify: Any) -> list[str]:
|
|
94
|
+
if not isinstance(verify, dict):
|
|
95
|
+
return [f"state.verify must be a dict, got {type(verify).__name__}"]
|
|
96
|
+
verdict = verify.get("verdict")
|
|
97
|
+
if verdict not in _ALLOWED_VERDICTS:
|
|
98
|
+
return [
|
|
99
|
+
f"state.verify['verdict'] must be one of "
|
|
100
|
+
f"{', '.join(_ALLOWED_VERDICTS)}; got {verdict!r}",
|
|
101
|
+
]
|
|
102
|
+
return []
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _delegate_to_review_changes(state: DeliveryState) -> StepResult:
|
|
106
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
107
|
+
return StepResult(
|
|
108
|
+
outcome=Outcome.BLOCKED,
|
|
109
|
+
questions=[
|
|
110
|
+
agent_directive("review-changes", ticket=ticket_id),
|
|
111
|
+
f"> Ticket {ticket_id} \u2014 running the four-judge review "
|
|
112
|
+
"(bugs, security, tests, code quality) before the delivery "
|
|
113
|
+
"report is written.",
|
|
114
|
+
"> 1. Continue \u2014 run `review-changes` now",
|
|
115
|
+
"> 2. Abort \u2014 skip review (NOT recommended)",
|
|
116
|
+
],
|
|
117
|
+
message=(
|
|
118
|
+
f"Ticket {ticket_id} needs `review-changes` before the report."
|
|
119
|
+
),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _blocked_on_precondition(state: DeliveryState) -> StepResult:
|
|
124
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
125
|
+
return StepResult(
|
|
126
|
+
outcome=Outcome.BLOCKED,
|
|
127
|
+
questions=[
|
|
128
|
+
f"> Ticket {ticket_id} \u2014 verify gate refused: "
|
|
129
|
+
"`test` step did not complete successfully.",
|
|
130
|
+
"> 1. Re-run `/implement-ticket` from the start",
|
|
131
|
+
"> 2. Abort",
|
|
132
|
+
],
|
|
133
|
+
message=f"Ticket {ticket_id} cannot verify: test gate did not pass.",
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _blocked_on_shape(state: DeliveryState, issues: list[str]) -> StepResult:
|
|
138
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
139
|
+
return StepResult(
|
|
140
|
+
outcome=Outcome.BLOCKED,
|
|
141
|
+
questions=[
|
|
142
|
+
f"> Ticket {ticket_id} \u2014 recorded verify output is malformed: "
|
|
143
|
+
+ "; ".join(issues)
|
|
144
|
+
+ ".",
|
|
145
|
+
"> 1. Re-run `review-changes` and resume",
|
|
146
|
+
"> 2. Abort \u2014 verify verdict cannot be trusted",
|
|
147
|
+
],
|
|
148
|
+
message=f"Ticket {ticket_id} verify shape invalid: {'; '.join(issues)}.",
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _blocked_on_bad_verdict(state: DeliveryState, verdict: Any) -> StepResult:
|
|
153
|
+
ticket_id = (state.ticket or {}).get("id") or "(no id)"
|
|
154
|
+
return StepResult(
|
|
155
|
+
outcome=Outcome.BLOCKED,
|
|
156
|
+
questions=[
|
|
157
|
+
f"> Ticket {ticket_id} \u2014 `review-changes` reported "
|
|
158
|
+
f"`{verdict}`. The delivery report cannot claim completion on a "
|
|
159
|
+
"non-success verdict (see `verify-before-complete`).",
|
|
160
|
+
"> 1. Address the findings and re-run `review-changes`",
|
|
161
|
+
"> 2. Continue anyway \u2014 override (NOT recommended)",
|
|
162
|
+
"> 3. Abort",
|
|
163
|
+
],
|
|
164
|
+
message=(
|
|
165
|
+
f"Ticket {ticket_id} verify verdict was `{verdict}`, not success."
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
__all__ = ["AMBIGUITIES", "run"]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Content-addressed hash for a curated memory entry.
|
|
3
|
+
|
|
4
|
+
The hash is SHA-256 over the canonical-JSON-serialized entry, truncated
|
|
5
|
+
to the first 12 hex chars. Canonical JSON sorts object keys, uses no
|
|
6
|
+
extra whitespace, and normalises types so two equivalent entries hash
|
|
7
|
+
identically regardless of YAML formatting.
|
|
8
|
+
|
|
9
|
+
Used by `/memory-promote` to pick the filename
|
|
10
|
+
`agents/memory/<type>/<hash>.yml` so the same entry promoted on two
|
|
11
|
+
branches converges to a single file after `git merge`.
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
python3 scripts/memory_hash.py --yaml path/to/entry.yml
|
|
15
|
+
echo '{"id":"x"}' | python3 scripts/memory_hash.py --json-stdin
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import argparse
|
|
21
|
+
import hashlib
|
|
22
|
+
import json
|
|
23
|
+
import sys
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
HASH_LEN = 12
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def canonical_json(obj: Any) -> bytes:
|
|
31
|
+
return json.dumps(
|
|
32
|
+
obj,
|
|
33
|
+
sort_keys=True,
|
|
34
|
+
separators=(",", ":"),
|
|
35
|
+
ensure_ascii=False,
|
|
36
|
+
default=str,
|
|
37
|
+
).encode("utf-8")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def hash_entry(obj: Any) -> str:
|
|
41
|
+
return hashlib.sha256(canonical_json(obj)).hexdigest()[:HASH_LEN]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _load_yaml(path: Path) -> Any:
|
|
45
|
+
try:
|
|
46
|
+
import yaml
|
|
47
|
+
except ImportError:
|
|
48
|
+
print("error: PyYAML not installed. `pip install pyyaml`.",
|
|
49
|
+
file=sys.stderr)
|
|
50
|
+
sys.exit(2)
|
|
51
|
+
with path.open(encoding="utf-8") as fh:
|
|
52
|
+
return yaml.safe_load(fh)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def main() -> int:
|
|
56
|
+
ap = argparse.ArgumentParser(description=__doc__)
|
|
57
|
+
grp = ap.add_mutually_exclusive_group(required=True)
|
|
58
|
+
grp.add_argument("--yaml", help="YAML file containing one entry")
|
|
59
|
+
grp.add_argument("--json-stdin", action="store_true",
|
|
60
|
+
help="Read JSON object from stdin")
|
|
61
|
+
args = ap.parse_args()
|
|
62
|
+
if args.yaml:
|
|
63
|
+
entry = _load_yaml(Path(args.yaml))
|
|
64
|
+
else:
|
|
65
|
+
entry = json.load(sys.stdin)
|
|
66
|
+
if not isinstance(entry, (dict, list)):
|
|
67
|
+
print(f"error: expected object/array, got {type(entry).__name__}",
|
|
68
|
+
file=sys.stderr)
|
|
69
|
+
return 1
|
|
70
|
+
print(hash_entry(entry))
|
|
71
|
+
return 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if __name__ == "__main__":
|
|
75
|
+
sys.exit(main())
|