@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.
Files changed (446) hide show
  1. package/.agent-src/README.md +64 -0
  2. package/.agent-src/commands/agent-handoff.md +64 -0
  3. package/.agent-src/commands/agent-status.md +83 -0
  4. package/.agent-src/commands/agents-audit.md +243 -0
  5. package/.agent-src/commands/agents-cleanup.md +169 -0
  6. package/.agent-src/commands/agents-prepare.md +137 -0
  7. package/.agent-src/commands/analyze-reference-repo.md +191 -0
  8. package/.agent-src/commands/bug-fix.md +181 -0
  9. package/.agent-src/commands/bug-investigate.md +175 -0
  10. package/.agent-src/commands/commit.md +121 -0
  11. package/.agent-src/commands/compress.md +177 -0
  12. package/.agent-src/commands/config-agent-settings.md +126 -0
  13. package/.agent-src/commands/context-create.md +167 -0
  14. package/.agent-src/commands/context-refactor.md +170 -0
  15. package/.agent-src/commands/copilot-agents-init.md +150 -0
  16. package/.agent-src/commands/copilot-agents-optimize.md +251 -0
  17. package/.agent-src/commands/create-pr-description.md +112 -0
  18. package/.agent-src/commands/create-pr.md +76 -0
  19. package/.agent-src/commands/do-and-judge.md +114 -0
  20. package/.agent-src/commands/do-in-steps.md +84 -0
  21. package/.agent-src/commands/e2e-heal.md +98 -0
  22. package/.agent-src/commands/e2e-plan.md +85 -0
  23. package/.agent-src/commands/estimate-ticket.md +80 -0
  24. package/.agent-src/commands/feature-dev.md +111 -0
  25. package/.agent-src/commands/feature-explore.md +180 -0
  26. package/.agent-src/commands/feature-plan.md +288 -0
  27. package/.agent-src/commands/feature-refactor.md +181 -0
  28. package/.agent-src/commands/feature-roadmap.md +184 -0
  29. package/.agent-src/commands/fix-ci.md +48 -0
  30. package/.agent-src/commands/fix-portability.md +97 -0
  31. package/.agent-src/commands/fix-pr-bot-comments.md +146 -0
  32. package/.agent-src/commands/fix-pr-comments.md +58 -0
  33. package/.agent-src/commands/fix-pr-developer-comments.md +152 -0
  34. package/.agent-src/commands/fix-references.md +94 -0
  35. package/.agent-src/commands/fix-seeder.md +146 -0
  36. package/.agent-src/commands/implement-ticket.md +133 -0
  37. package/.agent-src/commands/jira-ticket.md +71 -0
  38. package/.agent-src/commands/judge.md +86 -0
  39. package/.agent-src/commands/memory-add.md +130 -0
  40. package/.agent-src/commands/memory-full.md +97 -0
  41. package/.agent-src/commands/memory-promote.md +144 -0
  42. package/.agent-src/commands/mode.md +121 -0
  43. package/.agent-src/commands/module-create.md +132 -0
  44. package/.agent-src/commands/module-explore.md +157 -0
  45. package/.agent-src/commands/optimize-agents.md +139 -0
  46. package/.agent-src/commands/optimize-augmentignore.md +262 -0
  47. package/.agent-src/commands/optimize-rtk-filters.md +120 -0
  48. package/.agent-src/commands/optimize-skills.md +121 -0
  49. package/.agent-src/commands/override-create.md +97 -0
  50. package/.agent-src/commands/override-manage.md +96 -0
  51. package/.agent-src/commands/package-reset.md +154 -0
  52. package/.agent-src/commands/package-test.md +154 -0
  53. package/.agent-src/commands/prepare-for-review.md +91 -0
  54. package/.agent-src/commands/project-analyze.md +300 -0
  55. package/.agent-src/commands/project-health.md +95 -0
  56. package/.agent-src/commands/propose-memory.md +108 -0
  57. package/.agent-src/commands/quality-fix.md +106 -0
  58. package/.agent-src/commands/refine-ticket.md +81 -0
  59. package/.agent-src/commands/review-changes.md +130 -0
  60. package/.agent-src/commands/review-routing.md +111 -0
  61. package/.agent-src/commands/roadmap-create.md +110 -0
  62. package/.agent-src/commands/roadmap-execute.md +68 -0
  63. package/.agent-src/commands/rule-compliance-audit.md +139 -0
  64. package/.agent-src/commands/tests-create.md +73 -0
  65. package/.agent-src/commands/tests-execute.md +58 -0
  66. package/.agent-src/commands/threat-model.md +115 -0
  67. package/.agent-src/commands/update-form-request-messages.md +189 -0
  68. package/.agent-src/commands/upstream-contribute.md +171 -0
  69. package/.agent-src/contexts/augment-infrastructure.md +181 -0
  70. package/.agent-src/contexts/documentation-hierarchy.md +142 -0
  71. package/.agent-src/contexts/model-recommendations.md +142 -0
  72. package/.agent-src/contexts/override-system.md +187 -0
  73. package/.agent-src/contexts/skills-and-commands.md +154 -0
  74. package/.agent-src/contexts/subagent-configuration.md +62 -0
  75. package/.agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +110 -0
  76. package/.agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
  77. package/.agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
  78. package/.agent-src/guidelines/agent-infra/engineering-memory-data-format.md +117 -0
  79. package/.agent-src/guidelines/agent-infra/layered-settings.md +158 -0
  80. package/.agent-src/guidelines/agent-infra/memory-access.md +121 -0
  81. package/.agent-src/guidelines/agent-infra/naming.md +69 -0
  82. package/.agent-src/guidelines/agent-infra/output-patterns.md +117 -0
  83. package/.agent-src/guidelines/agent-infra/review-routing-data-format.md +144 -0
  84. package/.agent-src/guidelines/agent-infra/role-contracts.md +211 -0
  85. package/.agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
  86. package/.agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
  87. package/.agent-src/guidelines/agent-infra/self-improvement-pipeline.md +135 -0
  88. package/.agent-src/guidelines/agent-infra/size-and-scope.md +189 -0
  89. package/.agent-src/guidelines/agent-infra/tool-integration.md +73 -0
  90. package/.agent-src/guidelines/docs/readme-size-and-splitting.md +153 -0
  91. package/.agent-src/guidelines/e2e/playwright.md +363 -0
  92. package/.agent-src/guidelines/php/api-design.md +115 -0
  93. package/.agent-src/guidelines/php/artisan-commands.md +81 -0
  94. package/.agent-src/guidelines/php/blade-ui.md +78 -0
  95. package/.agent-src/guidelines/php/controllers.md +90 -0
  96. package/.agent-src/guidelines/php/database.md +111 -0
  97. package/.agent-src/guidelines/php/eloquent.md +208 -0
  98. package/.agent-src/guidelines/php/flux.md +80 -0
  99. package/.agent-src/guidelines/php/general.md +191 -0
  100. package/.agent-src/guidelines/php/git.md +96 -0
  101. package/.agent-src/guidelines/php/jobs.md +111 -0
  102. package/.agent-src/guidelines/php/livewire.md +71 -0
  103. package/.agent-src/guidelines/php/logging.md +79 -0
  104. package/.agent-src/guidelines/php/naming.md +89 -0
  105. package/.agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
  106. package/.agent-src/guidelines/php/patterns/dtos.md +199 -0
  107. package/.agent-src/guidelines/php/patterns/events.md +67 -0
  108. package/.agent-src/guidelines/php/patterns/factory.md +53 -0
  109. package/.agent-src/guidelines/php/patterns/pipelines.md +66 -0
  110. package/.agent-src/guidelines/php/patterns/policies.md +66 -0
  111. package/.agent-src/guidelines/php/patterns/repositories.md +122 -0
  112. package/.agent-src/guidelines/php/patterns/service-layer.md +64 -0
  113. package/.agent-src/guidelines/php/patterns/strategy.md +69 -0
  114. package/.agent-src/guidelines/php/patterns.md +28 -0
  115. package/.agent-src/guidelines/php/performance.md +92 -0
  116. package/.agent-src/guidelines/php/resources.md +100 -0
  117. package/.agent-src/guidelines/php/security.md +110 -0
  118. package/.agent-src/guidelines/php/sql.md +97 -0
  119. package/.agent-src/guidelines/php/validations.md +119 -0
  120. package/.agent-src/guidelines/php/websocket.md +100 -0
  121. package/.agent-src/personas/README.md +104 -0
  122. package/.agent-src/personas/ai-agent.md +77 -0
  123. package/.agent-src/personas/critical-challenger.md +73 -0
  124. package/.agent-src/personas/developer.md +73 -0
  125. package/.agent-src/personas/product-owner.md +78 -0
  126. package/.agent-src/personas/qa.md +67 -0
  127. package/.agent-src/personas/senior-engineer.md +77 -0
  128. package/.agent-src/personas/stakeholder.md +78 -0
  129. package/.agent-src/rules/agent-docs.md +61 -0
  130. package/.agent-src/rules/analysis-skill-routing.md +48 -0
  131. package/.agent-src/rules/architecture.md +62 -0
  132. package/.agent-src/rules/artifact-drafting-protocol.md +73 -0
  133. package/.agent-src/rules/ask-when-uncertain.md +52 -0
  134. package/.agent-src/rules/augment-portability.md +38 -0
  135. package/.agent-src/rules/augment-source-of-truth.md +128 -0
  136. package/.agent-src/rules/capture-learnings.md +89 -0
  137. package/.agent-src/rules/cli-output-handling.md +94 -0
  138. package/.agent-src/rules/commit-conventions.md +64 -0
  139. package/.agent-src/rules/context-hygiene.md +90 -0
  140. package/.agent-src/rules/docker-commands.md +55 -0
  141. package/.agent-src/rules/docs-sync.md +79 -0
  142. package/.agent-src/rules/downstream-changes.md +70 -0
  143. package/.agent-src/rules/e2e-testing.md +53 -0
  144. package/.agent-src/rules/guidelines.md +90 -0
  145. package/.agent-src/rules/improve-before-implement.md +94 -0
  146. package/.agent-src/rules/language-and-tone.md +104 -0
  147. package/.agent-src/rules/laravel-translations.md +48 -0
  148. package/.agent-src/rules/markdown-safe-codeblocks.md +18 -0
  149. package/.agent-src/rules/minimal-safe-diff.md +87 -0
  150. package/.agent-src/rules/missing-tool-handling.md +62 -0
  151. package/.agent-src/rules/model-recommendation.md +70 -0
  152. package/.agent-src/rules/package-ci-checks.md +80 -0
  153. package/.agent-src/rules/php-coding.md +63 -0
  154. package/.agent-src/rules/preservation-guard.md +29 -0
  155. package/.agent-src/rules/review-routing-awareness.md +125 -0
  156. package/.agent-src/rules/reviewer-awareness.md +92 -0
  157. package/.agent-src/rules/roadmap-progress-sync.md +56 -0
  158. package/.agent-src/rules/role-mode-adherence.md +54 -0
  159. package/.agent-src/rules/rule-type-governance.md +46 -0
  160. package/.agent-src/rules/runtime-safety.md +42 -0
  161. package/.agent-src/rules/scope-control.md +40 -0
  162. package/.agent-src/rules/security-sensitive-stop.md +77 -0
  163. package/.agent-src/rules/size-enforcement.md +29 -0
  164. package/.agent-src/rules/skill-improvement-trigger.md +58 -0
  165. package/.agent-src/rules/skill-quality.md +110 -0
  166. package/.agent-src/rules/slash-commands.md +30 -0
  167. package/.agent-src/rules/think-before-action.md +91 -0
  168. package/.agent-src/rules/token-efficiency.md +99 -0
  169. package/.agent-src/rules/tool-safety.md +36 -0
  170. package/.agent-src/rules/upstream-proposal.md +76 -0
  171. package/.agent-src/rules/user-interaction.md +79 -0
  172. package/.agent-src/rules/verify-before-complete.md +120 -0
  173. package/.agent-src/scripts/scan-seeder-violations.php +145 -0
  174. package/.agent-src/scripts/update_roadmap_progress.py +244 -0
  175. package/.agent-src/skills/adversarial-review/SKILL.md +149 -0
  176. package/.agent-src/skills/agent-docs-writing/SKILL.md +234 -0
  177. package/.agent-src/skills/analysis-autonomous-mode/SKILL.md +197 -0
  178. package/.agent-src/skills/analysis-skill-router/SKILL.md +134 -0
  179. package/.agent-src/skills/api-design/SKILL.md +104 -0
  180. package/.agent-src/skills/api-endpoint/SKILL.md +185 -0
  181. package/.agent-src/skills/api-testing/SKILL.md +206 -0
  182. package/.agent-src/skills/artisan-commands/SKILL.md +78 -0
  183. package/.agent-src/skills/authz-review/SKILL.md +171 -0
  184. package/.agent-src/skills/aws-infrastructure/SKILL.md +152 -0
  185. package/.agent-src/skills/blade-ui/SKILL.md +75 -0
  186. package/.agent-src/skills/blast-radius-analyzer/SKILL.md +185 -0
  187. package/.agent-src/skills/bug-analyzer/SKILL.md +256 -0
  188. package/.agent-src/skills/check-refs/SKILL.md +72 -0
  189. package/.agent-src/skills/code-refactoring/SKILL.md +200 -0
  190. package/.agent-src/skills/code-review/SKILL.md +214 -0
  191. package/.agent-src/skills/command-routing/SKILL.md +96 -0
  192. package/.agent-src/skills/command-writing/SKILL.md +143 -0
  193. package/.agent-src/skills/composer-packages/SKILL.md +172 -0
  194. package/.agent-src/skills/context-authoring/SKILL.md +157 -0
  195. package/.agent-src/skills/context-document/SKILL.md +153 -0
  196. package/.agent-src/skills/conventional-commits-writing/SKILL.md +70 -0
  197. package/.agent-src/skills/copilot-agents-optimization/SKILL.md +220 -0
  198. package/.agent-src/skills/copilot-config/SKILL.md +203 -0
  199. package/.agent-src/skills/dashboard-design/SKILL.md +116 -0
  200. package/.agent-src/skills/data-flow-mapper/SKILL.md +160 -0
  201. package/.agent-src/skills/database/SKILL.md +91 -0
  202. package/.agent-src/skills/dependency-upgrade/SKILL.md +204 -0
  203. package/.agent-src/skills/description-assist/SKILL.md +169 -0
  204. package/.agent-src/skills/design-review/SKILL.md +228 -0
  205. package/.agent-src/skills/devcontainer/SKILL.md +121 -0
  206. package/.agent-src/skills/developer-like-execution/SKILL.md +276 -0
  207. package/.agent-src/skills/docker/SKILL.md +245 -0
  208. package/.agent-src/skills/dto-creator/SKILL.md +117 -0
  209. package/.agent-src/skills/eloquent/SKILL.md +92 -0
  210. package/.agent-src/skills/eloquent/evals/last-run.json +99 -0
  211. package/.agent-src/skills/eloquent/evals/triggers.json +16 -0
  212. package/.agent-src/skills/estimate-ticket/SKILL.md +186 -0
  213. package/.agent-src/skills/estimate-ticket/evals/output-schema.yml +20 -0
  214. package/.agent-src/skills/estimate-ticket/evals/triggers.json +18 -0
  215. package/.agent-src/skills/fe-design/SKILL.md +223 -0
  216. package/.agent-src/skills/feature-planning/SKILL.md +226 -0
  217. package/.agent-src/skills/file-editor/SKILL.md +129 -0
  218. package/.agent-src/skills/finishing-a-development-branch/SKILL.md +200 -0
  219. package/.agent-src/skills/flux/SKILL.md +64 -0
  220. package/.agent-src/skills/git-workflow/SKILL.md +102 -0
  221. package/.agent-src/skills/github-ci/SKILL.md +122 -0
  222. package/.agent-src/skills/grafana/SKILL.md +168 -0
  223. package/.agent-src/skills/guideline-writing/SKILL.md +147 -0
  224. package/.agent-src/skills/jira-integration/SKILL.md +182 -0
  225. package/.agent-src/skills/jobs-events/SKILL.md +87 -0
  226. package/.agent-src/skills/judge-bug-hunter/SKILL.md +157 -0
  227. package/.agent-src/skills/judge-code-quality/SKILL.md +158 -0
  228. package/.agent-src/skills/judge-security-auditor/SKILL.md +167 -0
  229. package/.agent-src/skills/judge-test-coverage/SKILL.md +154 -0
  230. package/.agent-src/skills/laravel/SKILL.md +195 -0
  231. package/.agent-src/skills/laravel-horizon/SKILL.md +169 -0
  232. package/.agent-src/skills/laravel-mail/SKILL.md +193 -0
  233. package/.agent-src/skills/laravel-middleware/SKILL.md +185 -0
  234. package/.agent-src/skills/laravel-notifications/SKILL.md +168 -0
  235. package/.agent-src/skills/laravel-pennant/SKILL.md +188 -0
  236. package/.agent-src/skills/laravel-pulse/SKILL.md +160 -0
  237. package/.agent-src/skills/laravel-reverb/SKILL.md +205 -0
  238. package/.agent-src/skills/laravel-scheduling/SKILL.md +167 -0
  239. package/.agent-src/skills/laravel-validation/SKILL.md +71 -0
  240. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +249 -0
  241. package/.agent-src/skills/lint-skills/SKILL.md +72 -0
  242. package/.agent-src/skills/livewire/SKILL.md +79 -0
  243. package/.agent-src/skills/logging-monitoring/SKILL.md +100 -0
  244. package/.agent-src/skills/mcp/SKILL.md +193 -0
  245. package/.agent-src/skills/merge-conflicts/SKILL.md +158 -0
  246. package/.agent-src/skills/migration-creator/SKILL.md +160 -0
  247. package/.agent-src/skills/module-management/SKILL.md +154 -0
  248. package/.agent-src/skills/multi-tenancy/SKILL.md +129 -0
  249. package/.agent-src/skills/openapi/SKILL.md +154 -0
  250. package/.agent-src/skills/override-management/SKILL.md +186 -0
  251. package/.agent-src/skills/performance/SKILL.md +69 -0
  252. package/.agent-src/skills/performance-analysis/SKILL.md +118 -0
  253. package/.agent-src/skills/pest-testing/SKILL.md +321 -0
  254. package/.agent-src/skills/php-coder/SKILL.md +78 -0
  255. package/.agent-src/skills/php-coder/evals/triggers.json +16 -0
  256. package/.agent-src/skills/php-debugging/SKILL.md +184 -0
  257. package/.agent-src/skills/php-service/SKILL.md +96 -0
  258. package/.agent-src/skills/playwright-testing/SKILL.md +244 -0
  259. package/.agent-src/skills/project-analysis-core/SKILL.md +138 -0
  260. package/.agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +130 -0
  261. package/.agent-src/skills/project-analysis-laravel/SKILL.md +119 -0
  262. package/.agent-src/skills/project-analysis-nextjs/SKILL.md +123 -0
  263. package/.agent-src/skills/project-analysis-node-express/SKILL.md +111 -0
  264. package/.agent-src/skills/project-analysis-react/SKILL.md +119 -0
  265. package/.agent-src/skills/project-analysis-symfony/SKILL.md +111 -0
  266. package/.agent-src/skills/project-analysis-zend-laminas/SKILL.md +108 -0
  267. package/.agent-src/skills/project-analyzer/SKILL.md +341 -0
  268. package/.agent-src/skills/project-docs/SKILL.md +137 -0
  269. package/.agent-src/skills/quality-tools/SKILL.md +411 -0
  270. package/.agent-src/skills/readme-reviewer/SKILL.md +187 -0
  271. package/.agent-src/skills/readme-writing/SKILL.md +142 -0
  272. package/.agent-src/skills/readme-writing-package/SKILL.md +185 -0
  273. package/.agent-src/skills/receiving-code-review/SKILL.md +190 -0
  274. package/.agent-src/skills/refine-ticket/SKILL.md +310 -0
  275. package/.agent-src/skills/refine-ticket/detection-map.yml +124 -0
  276. package/.agent-src/skills/refine-ticket/evals/output-schema.yml +16 -0
  277. package/.agent-src/skills/refine-ticket/evals/triggers.json +16 -0
  278. package/.agent-src/skills/requesting-code-review/SKILL.md +199 -0
  279. package/.agent-src/skills/review-routing/SKILL.md +195 -0
  280. package/.agent-src/skills/roadmap-management/SKILL.md +303 -0
  281. package/.agent-src/skills/rtk-output-filtering/SKILL.md +184 -0
  282. package/.agent-src/skills/rule-writing/SKILL.md +148 -0
  283. package/.agent-src/skills/security/SKILL.md +79 -0
  284. package/.agent-src/skills/security-audit/SKILL.md +123 -0
  285. package/.agent-src/skills/sentry-integration/SKILL.md +170 -0
  286. package/.agent-src/skills/sequential-thinking/SKILL.md +158 -0
  287. package/.agent-src/skills/skill-improvement-pipeline/SKILL.md +155 -0
  288. package/.agent-src/skills/skill-management/SKILL.md +121 -0
  289. package/.agent-src/skills/skill-reviewer/SKILL.md +218 -0
  290. package/.agent-src/skills/skill-writing/SKILL.md +291 -0
  291. package/.agent-src/skills/skill-writing/evals/triggers.json +16 -0
  292. package/.agent-src/skills/sql-writing/SKILL.md +74 -0
  293. package/.agent-src/skills/subagent-orchestration/SKILL.md +190 -0
  294. package/.agent-src/skills/systematic-debugging/SKILL.md +244 -0
  295. package/.agent-src/skills/technical-specification/SKILL.md +185 -0
  296. package/.agent-src/skills/terraform/SKILL.md +137 -0
  297. package/.agent-src/skills/terragrunt/SKILL.md +217 -0
  298. package/.agent-src/skills/test-driven-development/SKILL.md +252 -0
  299. package/.agent-src/skills/test-performance/SKILL.md +172 -0
  300. package/.agent-src/skills/threat-modeling/SKILL.md +189 -0
  301. package/.agent-src/skills/traefik/SKILL.md +319 -0
  302. package/.agent-src/skills/universal-project-analysis/SKILL.md +179 -0
  303. package/.agent-src/skills/upstream-contribute/SKILL.md +255 -0
  304. package/.agent-src/skills/using-git-worktrees/SKILL.md +148 -0
  305. package/.agent-src/skills/validate-feature-fit/SKILL.md +113 -0
  306. package/.agent-src/skills/verify-before-complete/SKILL.md +188 -0
  307. package/.agent-src/skills/websocket/SKILL.md +75 -0
  308. package/.agent-src/templates/AGENTS.md +146 -0
  309. package/.agent-src/templates/agent-settings.md +256 -0
  310. package/.agent-src/templates/agents/.gitattributes.fragment +16 -0
  311. package/.agent-src/templates/agents/agent-project-settings.example.yml +138 -0
  312. package/.agent-src/templates/agents/memory/architecture-decisions.example.yml +95 -0
  313. package/.agent-src/templates/agents/memory/domain-invariants.example.yml +80 -0
  314. package/.agent-src/templates/agents/memory/historical-patterns.example.yml +82 -0
  315. package/.agent-src/templates/agents/memory/incident-learnings.example.yml +113 -0
  316. package/.agent-src/templates/agents/memory/ownership.example.yml +75 -0
  317. package/.agent-src/templates/agents/memory/product-rules.example.yml +87 -0
  318. package/.agent-src/templates/agents/proposal.example.md +143 -0
  319. package/.agent-src/templates/command.md +84 -0
  320. package/.agent-src/templates/contexts/auth-model.md +59 -0
  321. package/.agent-src/templates/contexts/data-sensitivity.md +60 -0
  322. package/.agent-src/templates/contexts/deployment-order.md +72 -0
  323. package/.agent-src/templates/contexts/observability.md +64 -0
  324. package/.agent-src/templates/contexts/tenant-boundaries.md +68 -0
  325. package/.agent-src/templates/contexts.md +116 -0
  326. package/.agent-src/templates/copilot-instructions.md +115 -0
  327. package/.agent-src/templates/features.md +125 -0
  328. package/.agent-src/templates/github-workflows/memory-hygiene.yml +133 -0
  329. package/.agent-src/templates/github-workflows/pr-risk-review.yml +123 -0
  330. package/.agent-src/templates/github-workflows/proposal-drift.yml +118 -0
  331. package/.agent-src/templates/overrides/command.md +24 -0
  332. package/.agent-src/templates/overrides/guideline.md +21 -0
  333. package/.agent-src/templates/overrides/rule.md +19 -0
  334. package/.agent-src/templates/overrides/skill.md +24 -0
  335. package/.agent-src/templates/overrides/template.md +21 -0
  336. package/.agent-src/templates/persona.md +99 -0
  337. package/.agent-src/templates/roadmaps.md +109 -0
  338. package/.agent-src/templates/scripts/README.md +195 -0
  339. package/.agent-src/templates/scripts/check_memory.py +283 -0
  340. package/.agent-src/templates/scripts/check_memory_proposal.py +180 -0
  341. package/.agent-src/templates/scripts/historical-bug-patterns.example.yml +84 -0
  342. package/.agent-src/templates/scripts/implement_ticket/__init__.py +57 -0
  343. package/.agent-src/templates/scripts/implement_ticket/__main__.py +9 -0
  344. package/.agent-src/templates/scripts/implement_ticket/cli.py +171 -0
  345. package/.agent-src/templates/scripts/implement_ticket/delivery_state.py +130 -0
  346. package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +134 -0
  347. package/.agent-src/templates/scripts/implement_ticket/persona_policy.py +85 -0
  348. package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +49 -0
  349. package/.agent-src/templates/scripts/implement_ticket/steps/analyze.py +98 -0
  350. package/.agent-src/templates/scripts/implement_ticket/steps/implement.py +145 -0
  351. package/.agent-src/templates/scripts/implement_ticket/steps/memory.py +136 -0
  352. package/.agent-src/templates/scripts/implement_ticket/steps/plan.py +175 -0
  353. package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +140 -0
  354. package/.agent-src/templates/scripts/implement_ticket/steps/report.py +195 -0
  355. package/.agent-src/templates/scripts/implement_ticket/steps/test.py +180 -0
  356. package/.agent-src/templates/scripts/implement_ticket/steps/verify.py +170 -0
  357. package/.agent-src/templates/scripts/memory_hash.py +75 -0
  358. package/.agent-src/templates/scripts/memory_lookup.py +216 -0
  359. package/.agent-src/templates/scripts/memory_report.py +184 -0
  360. package/.agent-src/templates/scripts/memory_signal.py +167 -0
  361. package/.agent-src/templates/scripts/memory_status.py +156 -0
  362. package/.agent-src/templates/scripts/ownership-map.example.yml +87 -0
  363. package/.agent-src/templates/scripts/pr-risk-config.example.yml +76 -0
  364. package/.agent-src/templates/scripts/pr_review_routing.py +340 -0
  365. package/.agent-src/templates/scripts/pr_risk_review.py +211 -0
  366. package/.agent-src/templates/skill.md +136 -0
  367. package/.augment-plugin/marketplace.json +32 -0
  368. package/.augment-plugin/plugin.json +21 -0
  369. package/.claude-plugin/marketplace.json +119 -0
  370. package/AGENTS.md +121 -0
  371. package/CHANGELOG.md +279 -0
  372. package/CONTRIBUTING.md +176 -0
  373. package/LICENSE +21 -0
  374. package/README.md +357 -0
  375. package/bin/install.php +38 -0
  376. package/composer.json +29 -0
  377. package/config/agent-settings.template.yml +96 -0
  378. package/config/profiles/balanced.ini +10 -0
  379. package/config/profiles/full.ini +10 -0
  380. package/config/profiles/minimal.ini +10 -0
  381. package/docs/architecture.md +144 -0
  382. package/docs/customization.md +88 -0
  383. package/docs/development.md +171 -0
  384. package/docs/getting-started.md +130 -0
  385. package/docs/github-topics.md +84 -0
  386. package/docs/installation.md +376 -0
  387. package/docs/mcp.md +133 -0
  388. package/docs/quality.md +98 -0
  389. package/docs/skills-catalog.md +136 -0
  390. package/docs/troubleshooting.md +167 -0
  391. package/llms.txt +130 -0
  392. package/package.json +31 -0
  393. package/scripts/audit_skill_descriptions.py +168 -0
  394. package/scripts/check_compression.py +221 -0
  395. package/scripts/check_memory.py +341 -0
  396. package/scripts/check_memory_proposal.py +180 -0
  397. package/scripts/check_portability.py +320 -0
  398. package/scripts/check_proposal.py +269 -0
  399. package/scripts/check_references.py +400 -0
  400. package/scripts/ci_summary.py +131 -0
  401. package/scripts/compress.py +671 -0
  402. package/scripts/compress.sh +18 -0
  403. package/scripts/first-run.sh +109 -0
  404. package/scripts/generate_catalog.py +116 -0
  405. package/scripts/install +151 -0
  406. package/scripts/install-hooks.sh +29 -0
  407. package/scripts/install.py +487 -0
  408. package/scripts/install.sh +637 -0
  409. package/scripts/install_anthropic_key.sh +101 -0
  410. package/scripts/inventory_frontmatter.py +164 -0
  411. package/scripts/lint_marketplace.py +142 -0
  412. package/scripts/lint_regression.py +232 -0
  413. package/scripts/mcp_render.py +159 -0
  414. package/scripts/measure_patterns.py +376 -0
  415. package/scripts/memory_hash.py +75 -0
  416. package/scripts/memory_lookup.py +441 -0
  417. package/scripts/memory_report.py +336 -0
  418. package/scripts/memory_signal.py +210 -0
  419. package/scripts/memory_status.py +195 -0
  420. package/scripts/postinstall.sh +60 -0
  421. package/scripts/readme_linter.py +580 -0
  422. package/scripts/refine_ticket_detect.py +623 -0
  423. package/scripts/requirements-evals.txt +7 -0
  424. package/scripts/runtime_dispatcher.py +265 -0
  425. package/scripts/runtime_handler.py +148 -0
  426. package/scripts/runtime_registry.py +166 -0
  427. package/scripts/schemas/command.schema.json +32 -0
  428. package/scripts/schemas/persona.schema.json +42 -0
  429. package/scripts/schemas/rule.schema.json +28 -0
  430. package/scripts/schemas/skill.schema.json +73 -0
  431. package/scripts/setup.sh +230 -0
  432. package/scripts/setup_eval_venv.sh +58 -0
  433. package/scripts/skill_linter.py +2175 -0
  434. package/scripts/skill_trigger_eval.py +651 -0
  435. package/scripts/tool_registry.py +146 -0
  436. package/scripts/tools/__init__.py +1 -0
  437. package/scripts/tools/adapter_errors.py +63 -0
  438. package/scripts/tools/base_adapter.py +91 -0
  439. package/scripts/tools/github_adapter.py +128 -0
  440. package/scripts/tools/jira_adapter.py +115 -0
  441. package/scripts/update_counts.py +147 -0
  442. package/scripts/validate_frontmatter.py +424 -0
  443. package/templates/consumer-settings/README.md +46 -0
  444. package/templates/consumer-settings/augment-settings.json +12 -0
  445. package/templates/consumer-settings/claude-settings.json +9 -0
  446. 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())