@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,336 @@
1
+ #!/usr/bin/env python3
2
+ """One-shot memory observability report.
3
+
4
+ Shows:
5
+ - Backend status (via `memory_status.status()`)
6
+ - Intake counts per entry type and per month
7
+ - Curated file staleness (files with `last_validated` older than
8
+ `review_after_days` for any entry)
9
+ - Supersede-chain totals
10
+
11
+ Exit code: 0 = report printed (green or otherwise); 2 = PyYAML missing.
12
+ `task memory:status` is the expected entry point, but the script is
13
+ usable standalone.
14
+
15
+ Usage:
16
+ python3 scripts/memory_report.py
17
+ python3 scripts/memory_report.py --format json
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import argparse
23
+ import datetime as dt
24
+ import json
25
+ import sys
26
+ from collections import Counter, defaultdict
27
+ from pathlib import Path
28
+ from typing import Any
29
+
30
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
31
+ import memory_status # noqa: E402
32
+
33
+ MEMORY_ROOT = Path("agents/memory")
34
+ INTAKE_ROOT = MEMORY_ROOT / "intake"
35
+ CURATED_TYPES = (
36
+ "ownership", "historical-patterns", "domain-invariants",
37
+ "architecture-decisions", "incident-learnings", "product-rules",
38
+ )
39
+
40
+ # Role-mode marker grepped from session captures / reports / handoffs.
41
+ # Matches `<!-- role-mode: <slug> | contract: ... -->` on any single line.
42
+ # See guidelines/agent-infra/role-contracts.md "Structured mode markers".
43
+ import re # noqa: E402
44
+
45
+ _MODE_MARKER_PATTERN = re.compile(
46
+ r"<!--\s*role-mode:\s*([a-z0-9][a-z0-9-]*)\s*\|"
47
+ r"\s*contract:[^>]*-->"
48
+ )
49
+ _MODE_SCAN_DIRS = (
50
+ Path("agents/sessions"),
51
+ Path("agents/reports"),
52
+ Path("agents/handoffs"),
53
+ Path("agents/learnings"),
54
+ )
55
+ _KNOWN_MODES = (
56
+ "developer", "reviewer", "tester", "po", "incident", "planner",
57
+ )
58
+
59
+
60
+ def _load_yaml(path: Path) -> dict:
61
+ try:
62
+ import yaml
63
+ except ImportError:
64
+ print("error: PyYAML not installed. `pip install pyyaml`.",
65
+ file=sys.stderr)
66
+ sys.exit(2)
67
+ with path.open(encoding="utf-8") as fh:
68
+ return yaml.safe_load(fh) or {}
69
+
70
+
71
+ def _iter_curated_entries() -> list[tuple[Path, str, dict]]:
72
+ """Yield (file, type, entry) across both curated layouts."""
73
+ out: list[tuple[Path, str, dict]] = []
74
+ for mtype in CURATED_TYPES:
75
+ single = MEMORY_ROOT / f"{mtype}.yml"
76
+ if single.is_file():
77
+ data = _load_yaml(single)
78
+ for e in data.get("entries") or []:
79
+ if isinstance(e, dict):
80
+ out.append((single, mtype, e))
81
+ type_dir = MEMORY_ROOT / mtype
82
+ if type_dir.is_dir():
83
+ for yml in sorted(type_dir.rglob("*.yml")):
84
+ data = _load_yaml(yml) or {}
85
+ entries = data.get("entries")
86
+ if isinstance(entries, list):
87
+ for e in entries:
88
+ if isinstance(e, dict):
89
+ out.append((yml, mtype, e))
90
+ elif isinstance(data, dict) and data.get("id"):
91
+ out.append((yml, mtype, data))
92
+ return out
93
+
94
+
95
+ def _intake_stats() -> dict:
96
+ total = 0
97
+ by_type: Counter = Counter()
98
+ by_month: Counter = Counter()
99
+ superseded = 0
100
+ if INTAKE_ROOT.is_dir():
101
+ for jsonl in sorted(INTAKE_ROOT.glob("*.jsonl")):
102
+ month = jsonl.stem.replace("signals-", "")
103
+ with jsonl.open(encoding="utf-8") as fh:
104
+ for line in fh:
105
+ line = line.strip()
106
+ if not line:
107
+ continue
108
+ try:
109
+ obj = json.loads(line)
110
+ except ValueError:
111
+ continue
112
+ if obj.get("type") == "supersede":
113
+ superseded += 1
114
+ continue
115
+ total += 1
116
+ t = obj.get("entry_type")
117
+ if isinstance(t, str):
118
+ by_type[t] += 1
119
+ by_month[month] += 1
120
+ return {
121
+ "total_active": total,
122
+ "superseded": superseded,
123
+ "by_type": dict(by_type),
124
+ "by_month": dict(by_month),
125
+ }
126
+
127
+
128
+ def _staleness_report() -> list[dict]:
129
+ today = dt.date.today()
130
+ stale: list[dict] = []
131
+ for path, mtype, entry in _iter_curated_entries():
132
+ lv = entry.get("last_validated")
133
+ review_after = entry.get("review_after_days")
134
+ if not isinstance(lv, (str, dt.date)) \
135
+ or not isinstance(review_after, int):
136
+ continue
137
+ try:
138
+ last = lv if isinstance(lv, dt.date) \
139
+ else dt.date.fromisoformat(str(lv))
140
+ except ValueError:
141
+ continue
142
+ due = last + dt.timedelta(days=review_after)
143
+ if due < today:
144
+ stale.append({
145
+ "file": str(path),
146
+ "type": mtype,
147
+ "id": entry.get("id", "?"),
148
+ "overdue_days": (today - due).days,
149
+ })
150
+ stale.sort(key=lambda r: r["overdue_days"], reverse=True)
151
+ return stale
152
+
153
+
154
+ def _quarter_of(d: dt.date | str) -> str:
155
+ if isinstance(d, str):
156
+ try:
157
+ d = dt.date.fromisoformat(d[:10])
158
+ except ValueError:
159
+ return "unknown"
160
+ if not isinstance(d, dt.date):
161
+ return "unknown"
162
+ return f"{d.year}Q{(d.month - 1) // 3 + 1}"
163
+
164
+
165
+ def _quarterly_stats() -> dict:
166
+ """Per-quarter breakdown: accepted curated entries, retired (supersede)
167
+ entries, and the curated-file staleness rate.
168
+
169
+ Feeds the Q2 outcome measurement for `road-to-agent-outcomes.md` /
170
+ `road-to-project-memory.md` Phase 5.
171
+ """
172
+ accepted: Counter = Counter()
173
+ for _, _, entry in _iter_curated_entries():
174
+ created = entry.get("created") or entry.get("last_validated")
175
+ if created is not None:
176
+ accepted[_quarter_of(created)] += 1
177
+ retired: Counter = Counter()
178
+ if INTAKE_ROOT.is_dir():
179
+ for jsonl in sorted(INTAKE_ROOT.glob("*.jsonl")):
180
+ with jsonl.open(encoding="utf-8") as fh:
181
+ for line in fh:
182
+ line = line.strip()
183
+ if not line:
184
+ continue
185
+ try:
186
+ obj = json.loads(line)
187
+ except ValueError:
188
+ continue
189
+ if obj.get("type") != "supersede":
190
+ continue
191
+ ts = obj.get("ts")
192
+ if isinstance(ts, str):
193
+ retired[_quarter_of(ts)] += 1
194
+ # Staleness rate = overdue / total curated entries (0..1).
195
+ total = sum(1 for _ in _iter_curated_entries())
196
+ overdue = len(_staleness_report())
197
+ rate = (overdue / total) if total else 0.0
198
+ return {
199
+ "accepted_by_quarter": dict(accepted),
200
+ "retired_by_quarter": dict(retired),
201
+ "staleness_rate": round(rate, 3),
202
+ "curated_total": total,
203
+ "curated_overdue": overdue,
204
+ }
205
+
206
+
207
+ def _operational_store_stats(backend_status: str) -> dict | None:
208
+ """Optional operational-store stats when the backend reports `present`.
209
+
210
+ Detection-only for now: the `agent-memory` CLI adapter is the owner
211
+ of real counts. We surface the status and a clear stub marker so a
212
+ future PR can replace the stub with CLI output without changing the
213
+ report schema shape.
214
+ """
215
+ if backend_status != "present":
216
+ return None
217
+ return {
218
+ "enabled": True,
219
+ "counts": {"entries": None, "recent_writes": None},
220
+ "note": "full operational-store probing is owned by the "
221
+ "agent-memory CLI adapter; stats stubbed here",
222
+ }
223
+
224
+
225
+ def _role_mode_stats() -> dict:
226
+ """Count structured mode markers across session/report/handoff dirs.
227
+
228
+ Feeds `road-to-role-modes` Phase 4 (contract-conformance signal)
229
+ and `road-to-curated-self-improvement` Phase 3 (outcome measurement).
230
+ Missing directories are silently skipped — the repo may not have
231
+ session captures yet.
232
+ """
233
+ counts: Counter[str] = Counter()
234
+ files_scanned = 0
235
+ unknown_modes: set[str] = set()
236
+ for root in _MODE_SCAN_DIRS:
237
+ if not root.exists():
238
+ continue
239
+ for md in root.rglob("*.md"):
240
+ try:
241
+ text = md.read_text(encoding="utf-8", errors="replace")
242
+ except OSError:
243
+ continue
244
+ files_scanned += 1
245
+ for match in _MODE_MARKER_PATTERN.finditer(text):
246
+ slug = match.group(1).lower()
247
+ counts[slug] += 1
248
+ if slug not in _KNOWN_MODES:
249
+ unknown_modes.add(slug)
250
+ total = sum(counts.values())
251
+ return {
252
+ "total_markers": total,
253
+ "files_scanned": files_scanned,
254
+ "by_mode": dict(counts),
255
+ "unknown_modes": sorted(unknown_modes),
256
+ }
257
+
258
+
259
+ def build_report() -> dict:
260
+ status = memory_status.status()
261
+ return {
262
+ "backend": {
263
+ "status": status.status,
264
+ "backend": status.backend,
265
+ "reason": status.reason,
266
+ "cli_path": status.cli_path,
267
+ },
268
+ "intake": _intake_stats(),
269
+ "staleness": _staleness_report(),
270
+ "quarterly": _quarterly_stats(),
271
+ "role_modes": _role_mode_stats(),
272
+ "operational_store": _operational_store_stats(status.status),
273
+ }
274
+
275
+
276
+ def _print_text(report: dict) -> None:
277
+ b = report["backend"]
278
+ print(f"Backend: {b['status']} (backend={b['backend']})")
279
+ if b["reason"]:
280
+ print(f" reason: {b['reason']}")
281
+ intake = report["intake"]
282
+ print(f"Intake: {intake['total_active']} active, "
283
+ f"{intake['superseded']} superseded")
284
+ for t, n in sorted(intake["by_type"].items()):
285
+ print(f" - {t}: {n}")
286
+ stale = report["staleness"]
287
+ if not stale:
288
+ print("Staleness: no curated entries past review_after_days")
289
+ else:
290
+ print(f"Staleness: {len(stale)} entrie(s) overdue")
291
+ for row in stale[:5]:
292
+ print(f" - {row['id']} ({row['type']}) "
293
+ f"+{row['overdue_days']}d {row['file']}")
294
+ if len(stale) > 5:
295
+ print(f" (+{len(stale) - 5} more)")
296
+ q = report["quarterly"]
297
+ print(f"Quarterly: staleness-rate={q['staleness_rate']:.1%} "
298
+ f"({q['curated_overdue']}/{q['curated_total']})")
299
+ if q["accepted_by_quarter"]:
300
+ acc = ", ".join(f"{k}:{v}" for k, v in
301
+ sorted(q["accepted_by_quarter"].items()))
302
+ print(f" accepted: {acc}")
303
+ if q["retired_by_quarter"]:
304
+ ret = ", ".join(f"{k}:{v}" for k, v in
305
+ sorted(q["retired_by_quarter"].items()))
306
+ print(f" retired: {ret}")
307
+ rm = report.get("role_modes") or {}
308
+ if rm.get("files_scanned"):
309
+ total = rm.get("total_markers", 0)
310
+ print(f"Role modes: {total} marker(s) in "
311
+ f"{rm['files_scanned']} file(s)")
312
+ if rm.get("by_mode"):
313
+ modes = ", ".join(f"{k}:{v}" for k, v in
314
+ sorted(rm["by_mode"].items()))
315
+ print(f" by mode: {modes}")
316
+ if rm.get("unknown_modes"):
317
+ print(f" unknown: {', '.join(rm['unknown_modes'])} "
318
+ "(not in the six reserved slugs)")
319
+ if report["operational_store"]:
320
+ print("Operational-store: present (stats via agent-memory CLI)")
321
+
322
+
323
+ def main() -> int:
324
+ ap = argparse.ArgumentParser(description=__doc__)
325
+ ap.add_argument("--format", choices=["text", "json"], default="text")
326
+ args = ap.parse_args()
327
+ report = build_report()
328
+ if args.format == "json":
329
+ print(json.dumps(report, indent=2, default=str))
330
+ else:
331
+ _print_text(report)
332
+ return 0
333
+
334
+
335
+ if __name__ == "__main__":
336
+ sys.exit(main())
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env python3
2
+ """Write-side helper: drop an engineering-memory signal.
3
+
4
+ Shared by producers (`/bug-fix`, `/do-and-judge`, `/propose-memory`,
5
+ incident role exit). Routes to the optional `agent-memory` package when
6
+ `memory_status.status() == "present"`; otherwise appends an intake
7
+ line under `agents/memory/intake/signals-YYYY-MM.jsonl` — append-only
8
+ JSONL with `merge=union` (see `road-to-memory-merge-safety.md`).
9
+
10
+ Rate limiting:
11
+ - Per-path, per-type, within a rolling window (default 7 days).
12
+ - Silent skip on duplicate — the producer's caller should not error,
13
+ since over-emission is a correctness bug, not a failure mode.
14
+
15
+ Usage:
16
+ python3 scripts/memory_signal.py \\
17
+ --type historical-patterns \\
18
+ --path "app/Http/Controllers/Billing/Checkout.php" \\
19
+ --body "Null deref when currency is missing — add guard."
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import argparse
25
+ import datetime as dt
26
+ import json
27
+ import os
28
+ import secrets
29
+ import sys
30
+ from pathlib import Path
31
+ from typing import Any
32
+
33
+ INTAKE_ROOT = Path("agents/memory/intake")
34
+ SETTINGS_FILE = Path(".agent-settings.yml")
35
+ VALID_TYPES = {
36
+ "historical-patterns",
37
+ "incident-learnings",
38
+ "ownership",
39
+ "domain-invariants",
40
+ "architecture-decisions",
41
+ "product-rules",
42
+ }
43
+ RATE_LIMIT_WINDOW_DAYS = 7
44
+
45
+
46
+ def _skip_intake_when_present() -> bool:
47
+ """Read `memory.intake.skip_when_present` from `.agent-settings.yml`.
48
+
49
+ Default: False — intake JSONL is always written as debug trail even
50
+ when the `agent-memory` backend is present (see
51
+ `road-to-memory-merge-safety.md` Phase 3).
52
+ """
53
+ if not SETTINGS_FILE.is_file():
54
+ return False
55
+ try:
56
+ import yaml # type: ignore
57
+ except ImportError:
58
+ return False
59
+ try:
60
+ data = yaml.safe_load(SETTINGS_FILE.read_text(encoding="utf-8")) or {}
61
+ except Exception:
62
+ return False
63
+ mem = data.get("memory") if isinstance(data, dict) else None
64
+ if not isinstance(mem, dict):
65
+ return False
66
+ intake = mem.get("intake")
67
+ if not isinstance(intake, dict):
68
+ return False
69
+ return bool(intake.get("skip_when_present", False))
70
+
71
+
72
+ def _backend_status() -> str:
73
+ """Return the current backend status: 'present' | 'absent' | 'unknown'."""
74
+ try:
75
+ import memory_status # type: ignore
76
+ return memory_status.status().status
77
+ except Exception:
78
+ return "unknown"
79
+
80
+
81
+ def _now_iso() -> str:
82
+ return dt.datetime.now(dt.timezone.utc).isoformat(timespec="seconds")
83
+
84
+
85
+ def _new_id() -> str:
86
+ # Short, URL-safe, stable enough for intake ids.
87
+ return f"sig-{secrets.token_hex(6)}"
88
+
89
+
90
+ def _monthly_file() -> Path:
91
+ ym = dt.datetime.now(dt.timezone.utc).strftime("%Y-%m")
92
+ return INTAKE_ROOT / f"signals-{ym}.jsonl"
93
+
94
+
95
+ def _recently_emitted(entry_type: str, path: str, body: str,
96
+ window_days: int = RATE_LIMIT_WINDOW_DAYS) -> bool:
97
+ """True if an identical (type, path, body) was written within the window."""
98
+ if not INTAKE_ROOT.is_dir():
99
+ return False
100
+ cutoff = dt.datetime.now(dt.timezone.utc) - dt.timedelta(days=window_days)
101
+ for jsonl in sorted(INTAKE_ROOT.glob("signals-*.jsonl")):
102
+ try:
103
+ with jsonl.open(encoding="utf-8") as fh:
104
+ for line in fh:
105
+ line = line.strip()
106
+ if not line:
107
+ continue
108
+ try:
109
+ obj = json.loads(line)
110
+ except ValueError:
111
+ continue
112
+ if obj.get("entry_type") != entry_type:
113
+ continue
114
+ if obj.get("path") != path:
115
+ continue
116
+ if obj.get("body") != body:
117
+ continue
118
+ ts = obj.get("ts")
119
+ if not isinstance(ts, str):
120
+ continue
121
+ try:
122
+ emitted = dt.datetime.fromisoformat(ts)
123
+ except ValueError:
124
+ continue
125
+ if emitted >= cutoff:
126
+ return True
127
+ except OSError:
128
+ continue
129
+ return False
130
+
131
+
132
+ def emit(entry_type: str, path: str, body: str,
133
+ extra: dict[str, Any] | None = None,
134
+ origin: str = "agent",
135
+ force: bool = False) -> dict[str, Any] | None:
136
+ """Append a signal entry. Returns the written record, or None when skipped.
137
+
138
+ On `present` backend, routing to the package is a no-op here today —
139
+ the package adapter is wired in `road-to-agent-memory-integration.md`
140
+ Phase 3. For now, the file path is the single source of truth so
141
+ merge-safety is preserved in every mode.
142
+ """
143
+ if entry_type not in VALID_TYPES:
144
+ raise ValueError(f"unknown memory type: {entry_type}")
145
+ if not path or not body:
146
+ raise ValueError("path and body are required")
147
+ if not force and _recently_emitted(entry_type, path, body):
148
+ return None
149
+ record: dict[str, Any] = {
150
+ "id": _new_id(),
151
+ "ts": _now_iso(),
152
+ "origin": origin,
153
+ "entry_type": entry_type,
154
+ "path": path,
155
+ "body": body,
156
+ }
157
+ if extra:
158
+ # Reserved keys stay intact; extras only fill unclaimed slots.
159
+ for k, v in extra.items():
160
+ record.setdefault(k, v)
161
+ # Backend routing: when the `agent-memory` package is present AND
162
+ # the consumer opted out of the debug trail, skip the JSONL write.
163
+ # Otherwise the intake file stays the source of truth (and, when a
164
+ # backend is present, a replayable debug trail).
165
+ if _backend_status() == "present" and _skip_intake_when_present():
166
+ record["_backend"] = "package-only"
167
+ return record
168
+ INTAKE_ROOT.mkdir(parents=True, exist_ok=True)
169
+ target = _monthly_file()
170
+ with target.open("a", encoding="utf-8") as fh:
171
+ fh.write(json.dumps(record, ensure_ascii=False) + "\n")
172
+ return record
173
+
174
+
175
+ def main() -> int:
176
+ ap = argparse.ArgumentParser(description=__doc__)
177
+ ap.add_argument("--type", dest="entry_type", required=True,
178
+ choices=sorted(VALID_TYPES))
179
+ ap.add_argument("--path", required=True,
180
+ help="Affected file/module path (e.g., app/Http/Foo.php)")
181
+ ap.add_argument("--body", required=True, help="One- to few-sentence finding")
182
+ ap.add_argument("--origin", default="agent",
183
+ help="Producer identifier, e.g., bug-fix, do-and-judge")
184
+ ap.add_argument("--extra", default="",
185
+ help="Optional JSON blob of extra keys (symptom, owner, ...)")
186
+ ap.add_argument("--force", action="store_true",
187
+ help="Bypass rate-limit dedupe")
188
+ args = ap.parse_args()
189
+ extra: dict[str, Any] = {}
190
+ if args.extra:
191
+ try:
192
+ extra = json.loads(args.extra)
193
+ if not isinstance(extra, dict):
194
+ raise ValueError
195
+ except ValueError:
196
+ print("error: --extra must be a JSON object", file=sys.stderr)
197
+ return 2
198
+ rec = emit(args.entry_type, args.path, args.body,
199
+ extra=extra, origin=args.origin, force=args.force)
200
+ if rec is None:
201
+ print(f" ℹ️ skipped (already emitted within "
202
+ f"{RATE_LIMIT_WINDOW_DAYS}d): {args.entry_type} @ {args.path}")
203
+ return 0
204
+ print(f" ✅ signal emitted: id={rec['id']} type={rec['entry_type']} "
205
+ f"path={rec['path']}")
206
+ return 0
207
+
208
+
209
+ if __name__ == "__main__":
210
+ sys.exit(main())