@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,159 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ MCP config renderer — one ``mcp.json`` → per-tool output files.
4
+
5
+ Reads ``mcp.json`` at repo root (``{ "servers": { <name>: { command, args,
6
+ env, cwd } } }``), substitutes ``${env:VAR}`` placeholders from the
7
+ environment, and writes each target tool's concrete config format.
8
+
9
+ Targets:
10
+ .cursor/mcp.json (in-project)
11
+ .windsurf/mcp.json (in-project)
12
+ ~/.config/claude-desktop/claude_desktop_config.json (user, opt-in)
13
+
14
+ All targets use the same ``mcpServers`` top-level key. The source file
15
+ uses ``servers`` to keep our internal schema stable if a downstream
16
+ format ever diverges.
17
+
18
+ Failure mode: unresolved ``${env:VAR}`` placeholders are collected first,
19
+ then reported together and a non-zero exit is raised. No target file is
20
+ written when any placeholder is missing.
21
+
22
+ See docs/mcp.md for schema, usage, and worked examples.
23
+ """
24
+ from __future__ import annotations
25
+
26
+ import argparse
27
+ import json
28
+ import os
29
+ import re
30
+ import sys
31
+ from pathlib import Path
32
+ from typing import Any
33
+
34
+ PROJECT_ROOT = Path(__file__).resolve().parent.parent
35
+ SOURCE_FILE = PROJECT_ROOT / "mcp.json"
36
+
37
+ ENV_PLACEHOLDER = re.compile(r"\$\{env:([^}]+)\}")
38
+
39
+ # In-project targets. Claude Desktop is user-scope, opt-in via --claude-desktop.
40
+ IN_PROJECT_TARGETS: dict[str, Path] = {
41
+ "cursor": PROJECT_ROOT / ".cursor" / "mcp.json",
42
+ "windsurf": PROJECT_ROOT / ".windsurf" / "mcp.json",
43
+ }
44
+ CLAUDE_DESKTOP_TARGET = Path.home() / ".config" / "claude-desktop" / "claude_desktop_config.json"
45
+
46
+
47
+ def substitute(value: Any, path: str, missing: list[tuple[str, str]]) -> Any:
48
+ """Recursively substitute ${env:VAR} in strings.
49
+
50
+ Missing variables are appended to ``missing`` as ``(var_name, json_path)``
51
+ instead of raising, so a single run surfaces *all* gaps at once.
52
+ """
53
+ if isinstance(value, str):
54
+ def repl(match: re.Match[str]) -> str:
55
+ name = match.group(1)
56
+ env_value = os.environ.get(name)
57
+ if env_value is None:
58
+ missing.append((name, path))
59
+ return match.group(0)
60
+ return env_value
61
+ return ENV_PLACEHOLDER.sub(repl, value)
62
+ if isinstance(value, dict):
63
+ return {k: substitute(v, f"{path}.{k}", missing) for k, v in value.items()}
64
+ if isinstance(value, list):
65
+ return [substitute(v, f"{path}[{i}]", missing) for i, v in enumerate(value)]
66
+ return value
67
+
68
+
69
+ def load_source(source: Path) -> dict[str, Any]:
70
+ if not source.exists():
71
+ raise SystemExit(f"❌ Source file not found: {source}")
72
+ try:
73
+ data = json.loads(source.read_text(encoding="utf-8"))
74
+ except json.JSONDecodeError as exc:
75
+ raise SystemExit(f"❌ Invalid JSON in {source}: {exc}") from exc
76
+ if not isinstance(data, dict) or "servers" not in data or not isinstance(data["servers"], dict):
77
+ raise SystemExit(f"❌ {source} must contain a top-level 'servers' object.")
78
+ return data
79
+
80
+
81
+ def render(data: dict[str, Any]) -> tuple[dict[str, Any], list[tuple[str, str]]]:
82
+ """Return (rendered, missing). Caller decides what to do on missing."""
83
+ missing: list[tuple[str, str]] = []
84
+ resolved_servers = substitute(data["servers"], "servers", missing)
85
+ return {"mcpServers": resolved_servers}, missing
86
+
87
+
88
+ def format_missing_report(missing: list[tuple[str, str]]) -> str:
89
+ grouped: dict[str, list[str]] = {}
90
+ for name, path in missing:
91
+ grouped.setdefault(name, []).append(path)
92
+ lines = [f"❌ Unresolved ${{env:VAR}} placeholders ({len(grouped)} variable(s)):"]
93
+ for name in sorted(grouped):
94
+ lines.append(f" - {name} used at:")
95
+ for path in grouped[name]:
96
+ lines.append(f" {path}")
97
+ lines.append("\nSet the variable(s) in your environment and re-run.")
98
+ return "\n".join(lines)
99
+
100
+
101
+ def write_target(path: Path, content: dict[str, Any]) -> None:
102
+ path.parent.mkdir(parents=True, exist_ok=True)
103
+ serialized = json.dumps(content, indent=2, sort_keys=True) + "\n"
104
+ path.write_text(serialized, encoding="utf-8")
105
+
106
+
107
+ def collect_targets(include_claude_desktop: bool) -> dict[str, Path]:
108
+ targets = dict(IN_PROJECT_TARGETS)
109
+ if include_claude_desktop:
110
+ targets["claude-desktop"] = CLAUDE_DESKTOP_TARGET
111
+ return targets
112
+
113
+
114
+ def cmd_render(args: argparse.Namespace) -> int:
115
+ data = load_source(Path(args.source))
116
+ rendered, missing = render(data)
117
+ if missing:
118
+ print(format_missing_report(missing), file=sys.stderr)
119
+ return 1
120
+ targets = collect_targets(args.claude_desktop)
121
+ for name, path in targets.items():
122
+ write_target(path, rendered)
123
+ print(f"✅ {name:16} → {path}")
124
+ return 0
125
+
126
+
127
+ def cmd_check(args: argparse.Namespace) -> int:
128
+ data = load_source(Path(args.source))
129
+ rendered, missing = render(data)
130
+ if missing:
131
+ print(format_missing_report(missing), file=sys.stderr)
132
+ return 1
133
+ serialized = json.dumps(rendered, indent=2, sort_keys=True) + "\n"
134
+ targets = collect_targets(args.claude_desktop)
135
+ diffs = []
136
+ for name, path in targets.items():
137
+ actual = path.read_text(encoding="utf-8") if path.exists() else ""
138
+ if actual != serialized:
139
+ diffs.append((name, path))
140
+ if diffs:
141
+ print("❌ Targets out of date (run `task mcp:render`):", file=sys.stderr)
142
+ for name, path in diffs:
143
+ print(f" - {name}: {path}", file=sys.stderr)
144
+ return 1
145
+ print("✅ All MCP targets match source.")
146
+ return 0
147
+
148
+
149
+ def main(argv: list[str] | None = None) -> int:
150
+ parser = argparse.ArgumentParser(description="Render mcp.json → per-tool config files.")
151
+ parser.add_argument("--source", default=str(SOURCE_FILE), help="Source mcp.json (default: repo root)")
152
+ parser.add_argument("--claude-desktop", action="store_true", help="Also write Claude Desktop user-scope config")
153
+ parser.add_argument("--check", action="store_true", help="Dry-run; exit non-zero if targets are stale")
154
+ args = parser.parse_args(argv)
155
+ return cmd_check(args) if args.check else cmd_render(args)
156
+
157
+
158
+ if __name__ == "__main__":
159
+ sys.exit(main())
@@ -0,0 +1,376 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Measure presence of the eight Phase-3.1 judge patterns across all skills.
4
+
5
+ Produces the before/after baseline for
6
+ `agents/roadmaps/road-to-stronger-skills.md`. Zero side-effects: this is a
7
+ read-only reporter. No skill file is ever mutated.
8
+
9
+ Patterns (see road-to-stronger-skills.md for definitions):
10
+ 1. System-prompt opening (blockquote role frame under the top heading)
11
+ 2. Scope routing (`route to [sibling]` inside "Do NOT use when")
12
+ 3. Validation gate (`## Validation` appears before `## Output format`)
13
+ 4. Ordered output fields (numbered required-fields list)
14
+ 5. Severity legend (🔴/🟡/🟢 with concrete definitions)
15
+ 6. References section with at least one URL
16
+ 7. Runtime boundary disclaimer
17
+ 8. Anti-sycophancy rules in "Do NOT"
18
+
19
+ Usage:
20
+ python3 scripts/measure_patterns.py # human table, grouped by tier
21
+ python3 scripts/measure_patterns.py --json # machine-readable summary
22
+ python3 scripts/measure_patterns.py --tier 1 # only Tier-1 skills
23
+ python3 scripts/measure_patterns.py --diff-baseline <file.json>
24
+ """
25
+ from __future__ import annotations
26
+
27
+ import argparse
28
+ import json
29
+ import re
30
+ import sys
31
+ from dataclasses import dataclass, asdict, field
32
+ from pathlib import Path
33
+ from typing import Iterable
34
+
35
+ ROOT = Path(__file__).resolve().parent.parent
36
+ SKILLS_DIR = ROOT / ".agent-src.uncompressed" / "skills"
37
+
38
+ # Tier assignments mirror agents/roadmaps/road-to-stronger-skills.md.
39
+ # "compliant" = already meets the target patterns (the four Phase-3.1 judges).
40
+ TIERS: dict[str, int | str] = {
41
+ # Tier 1 — Verdict / Review / Gate (patterns 1-8)
42
+ "adversarial-review": 1, "authz-review": 1, "code-review": 1,
43
+ "design-review": 1, "performance-analysis": 1, "project-analyzer": 1,
44
+ "readme-reviewer": 1, "receiving-code-review": 1,
45
+ "requesting-code-review": 1, "security-audit": 1, "skill-reviewer": 1,
46
+ "threat-modeling": 1, "validate-feature-fit": 1,
47
+ "verify-before-complete": 1,
48
+ # Tier 2 — Analysis / Investigation / Orchestration (patterns 1-4, +6)
49
+ "agent-docs-writing": 2, "analysis-autonomous-mode": 2,
50
+ "analysis-skill-router": 2, "blast-radius-analyzer": 2,
51
+ "bug-analyzer": 2, "code-refactoring": 2, "data-flow-mapper": 2,
52
+ "command-routing": 2, "copilot-agents-optimization": 2,
53
+ "description-assist": 2, "developer-like-execution": 2,
54
+ "feature-planning": 2, "learning-to-rule-or-skill": 2,
55
+ "project-analysis-core": 2, "project-analysis-hypothesis-driven": 2,
56
+ "project-analysis-laravel": 2, "project-analysis-nextjs": 2,
57
+ "project-analysis-node-express": 2, "project-analysis-react": 2,
58
+ "project-analysis-symfony": 2, "project-analysis-zend-laminas": 2,
59
+ "sequential-thinking": 2, "skill-improvement-pipeline": 2,
60
+ "subagent-orchestration": 2, "systematic-debugging": 2,
61
+ "universal-project-analysis": 2,
62
+ # Tier 3 — Coding / Authoring / Doing (patterns 1+2)
63
+ "api-design": 3, "api-endpoint": 3, "api-testing": 3,
64
+ "artisan-commands": 3, "blade-ui": 3, "command-writing": 3,
65
+ "composer-packages": 3, "context-document": 3,
66
+ "conventional-commits-writing": 3, "dashboard-design": 3,
67
+ "dependency-upgrade": 3, "dto-creator": 3, "eloquent": 3,
68
+ "fe-design": 3, "finishing-a-development-branch": 3, "flux": 3,
69
+ "git-workflow": 3, "guideline-writing": 3, "jobs-events": 3,
70
+ "laravel": 3, "laravel-horizon": 3, "laravel-mail": 3,
71
+ "laravel-middleware": 3, "laravel-notifications": 3,
72
+ "laravel-pennant": 3, "laravel-pulse": 3, "laravel-reverb": 3,
73
+ "laravel-scheduling": 3, "laravel-validation": 3, "livewire": 3,
74
+ "logging-monitoring": 3, "merge-conflicts": 3, "migration-creator": 3,
75
+ "module-management": 3, "openapi": 3, "override-management": 3,
76
+ "pest-testing": 3, "php-coder": 3, "php-debugging": 3,
77
+ "php-service": 3, "playwright-testing": 3, "readme-writing": 3,
78
+ "readme-writing-package": 3, "roadmap-management": 3, "rule-writing": 3,
79
+ "skill-management": 3, "skill-writing": 3, "sql-writing": 3,
80
+ "technical-specification": 3, "test-driven-development": 3,
81
+ "test-performance": 3, "upstream-contribute": 3,
82
+ "using-git-worktrees": 3,
83
+ # Tier 4 — Reference / Tooling / Integration (pattern 2 where siblings)
84
+ "aws-infrastructure": 4, "check-refs": 4, "copilot-config": 4,
85
+ "database": 4, "devcontainer": 4, "docker": 4, "file-editor": 4,
86
+ "github-ci": 4, "grafana": 4, "jira-integration": 4, "lint-skills": 4,
87
+ "mcp": 4, "multi-tenancy": 4, "performance": 4, "project-docs": 4,
88
+ "quality-tools": 4, "rtk-output-filtering": 4, "security": 4,
89
+ "sentry-integration": 4, "terraform": 4, "terragrunt": 4,
90
+ "traefik": 4, "websocket": 4,
91
+ # Already compliant (the four Phase-3.1 judges)
92
+ "judge-bug-hunter": "compliant", "judge-code-quality": "compliant",
93
+ "judge-security-auditor": "compliant",
94
+ "judge-test-coverage": "compliant",
95
+ }
96
+
97
+ # Which patterns count as "required" per tier. Skipped patterns are still
98
+ # reported (so we can see the footprint) but do not affect compliance score.
99
+ TIER_TARGETS: dict[int | str, set[int]] = {
100
+ 1: {1, 2, 3, 4, 5, 6, 7, 8},
101
+ 2: {1, 2, 3, 4}, # pattern 6 optional, measured separately
102
+ 3: {1, 2},
103
+ 4: {2},
104
+ "compliant": set(), # reference baseline — already green
105
+ }
106
+
107
+
108
+ @dataclass
109
+ class Detection:
110
+ skill: str
111
+ tier: int | str
112
+ patterns: dict[int, bool] = field(default_factory=dict)
113
+ score: float = 0.0
114
+ required: int = 0
115
+ present: int = 0
116
+
117
+
118
+ def _section_indices(text: str) -> dict[str, tuple[int, int]]:
119
+ """Return {section_title: (start_char, end_char)} for each ## heading."""
120
+ headings = [(m.start(), m.group(1).strip())
121
+ for m in re.finditer(r"^##\s+(.+?)\s*$", text, re.MULTILINE)]
122
+ sections: dict[str, tuple[int, int]] = {}
123
+ for i, (start, title) in enumerate(headings):
124
+ end = headings[i + 1][0] if i + 1 < len(headings) else len(text)
125
+ sections[title] = (start, end)
126
+ return sections
127
+
128
+
129
+
130
+ def _body_after_top_heading(text: str) -> str:
131
+ """Return the slice between the first `# ` heading and the first `## `."""
132
+ m = re.search(r"^#\s+.+$", text, re.MULTILINE)
133
+ if not m:
134
+ return ""
135
+ after = text[m.end():]
136
+ m2 = re.search(r"^##\s+", after, re.MULTILINE)
137
+ return after[:m2.start()] if m2 else after
138
+
139
+
140
+ def detect_pattern_1(text: str) -> bool:
141
+ """System-prompt opening: blockquote role frame under the top heading."""
142
+ body = _body_after_top_heading(text)
143
+ for line in body.splitlines():
144
+ s = line.strip()
145
+ if not s:
146
+ continue
147
+ if s.startswith(">"):
148
+ quote = s.lstrip("> ").strip()
149
+ return bool(re.match(r"You are (a|an|the)\s", quote))
150
+ return False
151
+ return False
152
+
153
+
154
+ def detect_pattern_2(text: str, sections: dict[str, tuple[int, int]]) -> bool:
155
+ """Scope routing with an explicit sibling link in the When/Do-NOT area."""
156
+ candidates = [t for t in sections
157
+ if re.match(r"(when to use|do\s*not\s*use\s*when)", t, re.I)]
158
+ chunk = text if not candidates else \
159
+ text[sections[candidates[0]][0]:sections[candidates[0]][1]]
160
+ return bool(re.search(
161
+ r"route to\s*\[`?[a-z0-9-]+`?\]\([^)]*SKILL\.md\)", chunk, re.I))
162
+
163
+
164
+ def detect_pattern_3(text: str, sections: dict[str, tuple[int, int]]) -> bool:
165
+ """Validation gate appears as its own section before Output format."""
166
+ val_start = next((s for t, (s, _) in sections.items()
167
+ if t.lower().startswith("validation")), None)
168
+ out_start = next((s for t, (s, _) in sections.items()
169
+ if t.lower().startswith("output")), None)
170
+ if val_start is None or out_start is None or val_start >= out_start:
171
+ return False
172
+ for title, (start, end) in sections.items():
173
+ if title.lower().startswith("validation"):
174
+ body = text[start:end]
175
+ if re.search(r"before finalizing", body, re.I):
176
+ return True
177
+ if len(re.findall(r"^\s*\d+\.\s+", body, re.MULTILINE)) >= 3:
178
+ return True
179
+ return False
180
+
181
+
182
+ def detect_pattern_4(text: str, sections: dict[str, tuple[int, int]]) -> bool:
183
+ """Ordered output fields — explicit required-fields list."""
184
+ for title, (start, end) in sections.items():
185
+ if title.lower().startswith("output"):
186
+ if re.search(r"required fields\s*\(ordered\)", text[start:end], re.I):
187
+ return True
188
+ return False
189
+
190
+
191
+ def detect_pattern_5(text: str) -> bool:
192
+ """Severity legend: all three of 🔴 🟡 🟢 with concrete definitions."""
193
+ return bool(re.search(
194
+ r"🔴[^🔴🟡🟢]{3,}🟡[^🔴🟡🟢]{3,}🟢[^🔴🟡🟢]{3,}", text))
195
+
196
+
197
+ def detect_pattern_6(text: str, sections: dict[str, tuple[int, int]]) -> bool:
198
+ """References section present and contains at least one URL."""
199
+ for title, (start, end) in sections.items():
200
+ if title.lower() == "references":
201
+ return bool(re.search(r"https?://", text[start:end]))
202
+ return False
203
+
204
+
205
+ def detect_pattern_7(text: str) -> bool:
206
+ """Runtime boundary disclaimer — names what the skill does NOT execute."""
207
+ patterns = [
208
+ r"runtime confirmation.*(follow[- ]up|implementer)",
209
+ r"(the judge|this skill) does not execute",
210
+ r"(leaves|defers) runtime.*(to|for) the implementer",
211
+ r"is a follow[- ]up for the implementer",
212
+ ]
213
+ return any(re.search(p, text, re.I) for p in patterns)
214
+
215
+
216
+ def detect_pattern_8(text: str, sections: dict[str, tuple[int, int]]) -> bool:
217
+ """Anti-sycophancy rules in Do NOT section."""
218
+ body = "".join(text[s:e] + "\n" for t, (s, e) in sections.items()
219
+ if t.lower().startswith("do not"))
220
+ if not body:
221
+ return False
222
+ patterns = [
223
+ r"NEVER\s+return\s+`?\w+`?\s+out of politeness",
224
+ r"NEVER\s+silently\s+fall\s+back",
225
+ r"NEVER\s+rubber[- ]stamp",
226
+ r"NEVER\s+accept.*as (a )?substitute",
227
+ ]
228
+ return any(re.search(p, body, re.I) for p in patterns)
229
+
230
+
231
+ DETECTORS = {
232
+ 1: detect_pattern_1, 2: detect_pattern_2, 3: detect_pattern_3,
233
+ 4: detect_pattern_4, 5: detect_pattern_5, 6: detect_pattern_6,
234
+ 7: detect_pattern_7, 8: detect_pattern_8,
235
+ }
236
+
237
+
238
+
239
+ def scan_skill(path: Path) -> Detection:
240
+ name = path.parent.name
241
+ tier = TIERS.get(name, "unclassified")
242
+ text = path.read_text(encoding="utf-8")
243
+ sections = _section_indices(text)
244
+ results: dict[int, bool] = {}
245
+ for n, fn in DETECTORS.items():
246
+ try:
247
+ results[n] = (fn(text, sections)
248
+ if fn.__code__.co_argcount == 2 else fn(text))
249
+ except Exception:
250
+ results[n] = False
251
+ required = TIER_TARGETS.get(tier, set())
252
+ present = sum(1 for p in required if results.get(p))
253
+ score = (present / len(required)) if required else 1.0
254
+ return Detection(
255
+ skill=name, tier=tier, patterns=results,
256
+ score=round(score, 3), required=len(required), present=present,
257
+ )
258
+
259
+
260
+ def collect(root: Path) -> list[Detection]:
261
+ results: list[Detection] = []
262
+ for skill_md in sorted(root.glob("*/SKILL.md")):
263
+ results.append(scan_skill(skill_md))
264
+ return results
265
+
266
+
267
+ def _render_table(rows: Iterable[Detection], tier_filter: int | None) -> str:
268
+ lines = []
269
+ tiers_order: list[int | str] = [1, 2, 3, 4, "compliant", "unclassified"]
270
+ by_tier: dict[int | str, list[Detection]] = {t: [] for t in tiers_order}
271
+ for r in rows:
272
+ by_tier.setdefault(r.tier, []).append(r)
273
+ for tier in tiers_order:
274
+ group = by_tier.get(tier, [])
275
+ if not group:
276
+ continue
277
+ if tier_filter is not None and tier != tier_filter:
278
+ continue
279
+ label = f"Tier {tier}" if isinstance(tier, int) else f"{tier}"
280
+ required = TIER_TARGETS.get(tier, set())
281
+ lines.append(f"\n## {label} ({len(group)} skills, "
282
+ f"required patterns: {sorted(required) or '—'})")
283
+ lines.append("| Skill | Score | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |")
284
+ lines.append("|---|---:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|")
285
+ for r in sorted(group, key=lambda d: (-d.score, d.skill)):
286
+ cells = []
287
+ for p in range(1, 9):
288
+ has = r.patterns.get(p, False)
289
+ is_req = p in required
290
+ cells.append(
291
+ "✅" if has and is_req else
292
+ "☑️" if has else
293
+ "·" if not is_req else "❌"
294
+ )
295
+ pct = f"{int(r.score * 100)}%" if required else "—"
296
+ lines.append(f"| `{r.skill}` | {pct} | " + " | ".join(cells) + " |")
297
+ lines.append("\nLegend: ✅ required + present · ❌ required + missing · "
298
+ "☑️ present but optional · · not required")
299
+ return "\n".join(lines)
300
+
301
+
302
+ def _summary(rows: list[Detection]) -> dict:
303
+ agg: dict = {"total_skills": len(rows), "by_tier": {}}
304
+ for tier in [1, 2, 3, 4]:
305
+ group = [r for r in rows if r.tier == tier]
306
+ if not group:
307
+ continue
308
+ fully = sum(1 for r in group if r.score >= 1.0)
309
+ avg = round(sum(r.score for r in group) / len(group), 3)
310
+ agg["by_tier"][str(tier)] = {
311
+ "count": len(group),
312
+ "fully_compliant": fully,
313
+ "avg_score": avg,
314
+ "required_patterns": sorted(TIER_TARGETS[tier]),
315
+ }
316
+ return agg
317
+
318
+
319
+ def main(argv: list[str] | None = None) -> int:
320
+ ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
321
+ ap.add_argument("--json", action="store_true",
322
+ help="emit machine-readable JSON")
323
+ ap.add_argument("--tier", type=int, choices=[1, 2, 3, 4],
324
+ help="only report one tier")
325
+ ap.add_argument("--diff-baseline", type=Path,
326
+ help="JSON file from an earlier run to diff against")
327
+ args = ap.parse_args(argv)
328
+
329
+ if not SKILLS_DIR.is_dir():
330
+ print(f"ERROR: {SKILLS_DIR} not found", file=sys.stderr)
331
+ return 3
332
+
333
+ rows = collect(SKILLS_DIR)
334
+
335
+ if args.json:
336
+ payload = {
337
+ "summary": _summary(rows),
338
+ "skills": [asdict(r) for r in rows],
339
+ }
340
+ print(json.dumps(payload, indent=2, sort_keys=True))
341
+ return 0
342
+
343
+ summary = _summary(rows)
344
+ print(f"# Pattern Presence — {summary['total_skills']} skills scanned\n")
345
+ print("## Per-tier summary\n")
346
+ print("| Tier | Skills | Fully compliant | Avg score | Required |")
347
+ print("|---|---:|---:|---:|---|")
348
+ for t in [1, 2, 3, 4]:
349
+ info = summary["by_tier"].get(str(t))
350
+ if not info:
351
+ continue
352
+ print(f"| {t} | {info['count']} | {info['fully_compliant']} | "
353
+ f"{int(info['avg_score'] * 100)}% | "
354
+ f"{info['required_patterns']} |")
355
+
356
+ print(_render_table(rows, args.tier))
357
+
358
+ if args.diff_baseline and args.diff_baseline.is_file():
359
+ prev = json.loads(args.diff_baseline.read_text())
360
+ prev_by = {s["skill"]: s for s in prev.get("skills", [])}
361
+ moves = []
362
+ for r in rows:
363
+ p = prev_by.get(r.skill)
364
+ if p and p["score"] != r.score:
365
+ moves.append((r.skill, p["score"], r.score))
366
+ if moves:
367
+ print("\n## Changes since baseline\n")
368
+ for skill, old, new in sorted(moves, key=lambda m: m[2] - m[1]):
369
+ arrow = "⬆️" if new > old else "⬇️"
370
+ print(f"- {arrow} `{skill}`: "
371
+ f"{int(old * 100)}% → {int(new * 100)}%")
372
+ return 0
373
+
374
+
375
+ if __name__ == "__main__":
376
+ sys.exit(main())
@@ -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())