@event4u/agent-config 6.0.0 → 6.1.0

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 (378) hide show
  1. package/.claude-plugin/marketplace.json +5 -5
  2. package/CHANGELOG.md +167 -440
  3. package/README.md +3 -3
  4. package/dist/agent-src/commands/agent-handoff.md +5 -4
  5. package/dist/agent-src/commands/agent-status.md +1 -0
  6. package/dist/agent-src/commands/agents/audit.md +1 -0
  7. package/dist/agent-src/commands/agents/init.md +3 -0
  8. package/dist/agent-src/commands/agents/optimize.md +1 -0
  9. package/dist/agent-src/commands/agents/user/accept.md +1 -0
  10. package/dist/agent-src/commands/agents/user/init.md +1 -0
  11. package/dist/agent-src/commands/agents/user/review.md +1 -0
  12. package/dist/agent-src/commands/agents/user/show.md +1 -0
  13. package/dist/agent-src/commands/agents/user/update.md +1 -0
  14. package/dist/agent-src/commands/agents/user.md +1 -0
  15. package/dist/agent-src/commands/agents.md +1 -0
  16. package/dist/agent-src/commands/analytics/prune.md +3 -2
  17. package/dist/agent-src/commands/analytics/show.md +3 -2
  18. package/dist/agent-src/commands/analytics.md +3 -2
  19. package/dist/agent-src/commands/analyze-reference-repo.md +1 -0
  20. package/dist/agent-src/commands/bug-fix.md +1 -0
  21. package/dist/agent-src/commands/bug-investigate.md +1 -0
  22. package/dist/agent-src/commands/challenge-me/vision.md +3 -2
  23. package/dist/agent-src/commands/challenge-me/with-docs.md +3 -2
  24. package/dist/agent-src/commands/challenge-me.md +3 -2
  25. package/dist/agent-src/commands/chat-history/import.md +9 -9
  26. package/dist/agent-src/commands/chat-history.md +32 -30
  27. package/dist/agent-src/commands/check-current-md.md +1 -0
  28. package/dist/agent-src/commands/commit/in-chunks.md +1 -0
  29. package/dist/agent-src/commands/commit.md +1 -0
  30. package/dist/agent-src/commands/condense.md +1 -0
  31. package/dist/agent-src/commands/context/create.md +1 -0
  32. package/dist/agent-src/commands/context/refactor.md +1 -0
  33. package/dist/agent-src/commands/context.md +1 -0
  34. package/dist/agent-src/commands/cost-report.md +5 -4
  35. package/dist/agent-src/commands/council/analysis.md +3 -2
  36. package/dist/agent-src/commands/council/debate.md +5 -4
  37. package/dist/agent-src/commands/council/default.md +3 -2
  38. package/dist/agent-src/commands/council/design.md +3 -2
  39. package/dist/agent-src/commands/council/optimize.md +3 -2
  40. package/dist/agent-src/commands/council/pr.md +3 -2
  41. package/dist/agent-src/commands/council.md +4 -3
  42. package/dist/agent-src/commands/e2e-heal.md +1 -0
  43. package/dist/agent-src/commands/e2e-plan.md +1 -0
  44. package/dist/agent-src/commands/estimate-ticket.md +1 -0
  45. package/dist/agent-src/commands/feature/dev.md +1 -0
  46. package/dist/agent-src/commands/feature/explore.md +1 -0
  47. package/dist/agent-src/commands/feature/plan.md +6 -6
  48. package/dist/agent-src/commands/feature/refactor.md +1 -0
  49. package/dist/agent-src/commands/feature/roadmap.md +1 -0
  50. package/dist/agent-src/commands/feature.md +1 -0
  51. package/dist/agent-src/commands/fix/ci.md +1 -0
  52. package/dist/agent-src/commands/fix/portability.md +1 -0
  53. package/dist/agent-src/commands/fix/pr-comments.md +147 -15
  54. package/dist/agent-src/commands/fix/refs.md +1 -0
  55. package/dist/agent-src/commands/fix/seeder.md +1 -0
  56. package/dist/agent-src/commands/fix.md +8 -8
  57. package/dist/agent-src/commands/ghostwriter/delete.md +1 -0
  58. package/dist/agent-src/commands/ghostwriter/fetch.md +1 -0
  59. package/dist/agent-src/commands/ghostwriter/list.md +1 -0
  60. package/dist/agent-src/commands/ghostwriter/show.md +1 -0
  61. package/dist/agent-src/commands/ghostwriter/write.md +1 -0
  62. package/dist/agent-src/commands/ghostwriter.md +1 -0
  63. package/dist/agent-src/commands/grill-me.md +3 -2
  64. package/dist/agent-src/commands/image/analyse.md +1 -0
  65. package/dist/agent-src/commands/image/create.md +1 -0
  66. package/dist/agent-src/commands/image/verify.md +1 -0
  67. package/dist/agent-src/commands/image.md +1 -0
  68. package/dist/agent-src/commands/implement-ticket.md +1 -0
  69. package/dist/agent-src/commands/jira-ticket.md +1 -0
  70. package/dist/agent-src/commands/judge/on-diff.md +1 -0
  71. package/dist/agent-src/commands/judge/solo.md +1 -0
  72. package/dist/agent-src/commands/judge/steps.md +1 -0
  73. package/dist/agent-src/commands/judge.md +1 -0
  74. package/dist/agent-src/commands/knowledge/cross-repo.md +1 -0
  75. package/dist/agent-src/commands/knowledge/forget.md +1 -0
  76. package/dist/agent-src/commands/knowledge/ingest.md +1 -0
  77. package/dist/agent-src/commands/knowledge/list.md +1 -0
  78. package/dist/agent-src/commands/knowledge.md +1 -0
  79. package/dist/agent-src/commands/memory/add.md +8 -6
  80. package/dist/agent-src/commands/memory/learn-low-impact.md +3 -2
  81. package/dist/agent-src/commands/memory/load.md +7 -7
  82. package/dist/agent-src/commands/memory/mine-session.md +39 -12
  83. package/dist/agent-src/commands/memory/promote.md +3 -2
  84. package/dist/agent-src/commands/memory/propose.md +7 -6
  85. package/dist/agent-src/commands/memory.md +3 -2
  86. package/dist/agent-src/commands/mode.md +1 -0
  87. package/dist/agent-src/commands/module/create.md +1 -0
  88. package/dist/agent-src/commands/module/explore.md +1 -0
  89. package/dist/agent-src/commands/module.md +1 -0
  90. package/dist/agent-src/commands/optimize/agents-dir.md +1 -0
  91. package/dist/agent-src/commands/optimize/augmentignore.md +1 -0
  92. package/dist/agent-src/commands/optimize/rtk.md +1 -0
  93. package/dist/agent-src/commands/optimize/skills.md +1 -0
  94. package/dist/agent-src/commands/optimize-prompt.md +1 -0
  95. package/dist/agent-src/commands/optimize.md +1 -0
  96. package/dist/agent-src/commands/orchestrate.md +1 -0
  97. package/dist/agent-src/commands/override/create.md +1 -0
  98. package/dist/agent-src/commands/override/manage.md +1 -0
  99. package/dist/agent-src/commands/override.md +1 -0
  100. package/dist/agent-src/commands/package-reset.md +1 -0
  101. package/dist/agent-src/commands/package-test.md +1 -0
  102. package/dist/agent-src/commands/post-as/ghostwriter.md +1 -0
  103. package/dist/agent-src/commands/post-as/me.md +1 -0
  104. package/dist/agent-src/commands/post-as.md +1 -0
  105. package/dist/agent-src/commands/pr/create/description-only.md +1 -0
  106. package/dist/agent-src/commands/pr/create.md +25 -0
  107. package/dist/agent-src/commands/prediction-pool.md +1 -0
  108. package/dist/agent-src/commands/prepare-for-review.md +1 -0
  109. package/dist/agent-src/commands/profile/activate.md +1 -0
  110. package/dist/agent-src/commands/profile/deactivate.md +1 -0
  111. package/dist/agent-src/commands/profile/show.md +1 -0
  112. package/dist/agent-src/commands/profile.md +1 -0
  113. package/dist/agent-src/commands/project-analyze.md +1 -0
  114. package/dist/agent-src/commands/project-health.md +1 -0
  115. package/dist/agent-src/commands/quality-fix.md +1 -0
  116. package/dist/agent-src/commands/refine-ticket.md +1 -0
  117. package/dist/agent-src/commands/research/deep.md +1 -0
  118. package/dist/agent-src/commands/research/report.md +1 -0
  119. package/dist/agent-src/commands/research.md +1 -0
  120. package/dist/agent-src/commands/review-changes.md +1 -0
  121. package/dist/agent-src/commands/review-routing.md +1 -0
  122. package/dist/agent-src/commands/roadmap/ai-council.md +1 -0
  123. package/dist/agent-src/commands/roadmap/create.md +1 -0
  124. package/dist/agent-src/commands/roadmap/process-full.md +1 -0
  125. package/dist/agent-src/commands/roadmap/process-phase.md +1 -0
  126. package/dist/agent-src/commands/roadmap/process-step.md +1 -0
  127. package/dist/agent-src/commands/roadmap.md +1 -0
  128. package/dist/agent-src/commands/rule-compliance-audit.md +1 -0
  129. package/dist/agent-src/commands/security-audit-config.md +84 -0
  130. package/dist/agent-src/commands/set-cost-profile.md +1 -0
  131. package/dist/agent-src/commands/skill/preview.md +1 -0
  132. package/dist/agent-src/commands/skill.md +1 -0
  133. package/dist/agent-src/commands/skills/discover.md +1 -0
  134. package/dist/agent-src/commands/skills.md +1 -0
  135. package/dist/agent-src/commands/sync-agent-settings.md +1 -0
  136. package/dist/agent-src/commands/sync-gitignore/fix.md +1 -0
  137. package/dist/agent-src/commands/sync-gitignore.md +1 -0
  138. package/dist/agent-src/commands/tests/create.md +1 -0
  139. package/dist/agent-src/commands/tests/execute.md +1 -0
  140. package/dist/agent-src/commands/tests.md +1 -0
  141. package/dist/agent-src/commands/threat-model.md +1 -0
  142. package/dist/agent-src/commands/update-form-request-messages.md +1 -0
  143. package/dist/agent-src/commands/upstream-contribute.md +1 -0
  144. package/dist/agent-src/commands/video/from-script.md +1 -0
  145. package/dist/agent-src/commands/video/from-song.md +1 -0
  146. package/dist/agent-src/commands/video/scene.md +1 -0
  147. package/dist/agent-src/commands/video/stitch.md +1 -0
  148. package/dist/agent-src/commands/video/storyboard.md +1 -0
  149. package/dist/agent-src/commands/video.md +1 -0
  150. package/dist/agent-src/commands/work.md +1 -0
  151. package/dist/agent-src/contexts/augment-infrastructure.md +1 -1
  152. package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
  153. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +2 -2
  154. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +6 -6
  155. package/dist/agent-src/contexts/contracts/consumer-agents-md-guide.md +2 -2
  156. package/dist/agent-src/contexts/execution/rdp-gate.md +75 -0
  157. package/dist/agent-src/contexts/subagent-configuration.md +1 -0
  158. package/dist/agent-src/personas/advisors/contrarian.md +1 -1
  159. package/dist/agent-src/personas/advisors/executor.md +1 -1
  160. package/dist/agent-src/personas/advisors/expansionist.md +1 -1
  161. package/dist/agent-src/personas/advisors/first-principles.md +1 -1
  162. package/dist/agent-src/personas/advisors/outsider.md +1 -1
  163. package/dist/agent-src/rules/autonomous-execution.md +12 -0
  164. package/dist/agent-src/rules/external-reference-deep-dive.md +1 -1
  165. package/dist/agent-src/rules/git-history-discipline.md +47 -1
  166. package/dist/agent-src/rules/improve-before-implement.md +12 -0
  167. package/dist/agent-src/rules/lethal-trifecta-guard.md +80 -0
  168. package/dist/agent-src/rules/no-pr-progress-comments.md +3 -4
  169. package/dist/agent-src/rules/notes-first-reasoning.md +71 -0
  170. package/dist/agent-src/rules/roadmap-progress-sync.md +48 -31
  171. package/dist/agent-src/rules/security-sensitive-stop.md +14 -1
  172. package/dist/agent-src/rules/source-confidentiality.md +97 -0
  173. package/dist/agent-src/rules/think-before-action.md +9 -1
  174. package/dist/agent-src/rules/untrusted-input-defense.md +76 -0
  175. package/dist/agent-src/scripts/archive_completed_roadmaps.py +171 -0
  176. package/dist/agent-src/skills/adversarial-review/SKILL.md +14 -0
  177. package/dist/agent-src/skills/agent-security-review/SKILL.md +113 -0
  178. package/dist/agent-src/skills/agent-security-review/evals/triggers.json +51 -0
  179. package/dist/agent-src/skills/ai-council/SKILL.md +3 -3
  180. package/dist/agent-src/skills/async-python-patterns/SKILL.md +1 -1
  181. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +12 -11
  182. package/dist/agent-src/skills/command-routing/SKILL.md +1 -1
  183. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +96 -0
  184. package/dist/agent-src/skills/complexity-first-planning/evals/triggers.json +16 -0
  185. package/dist/agent-src/skills/copilot-config/SKILL.md +3 -4
  186. package/dist/agent-src/skills/defense-in-depth/SKILL.md +1 -1
  187. package/dist/agent-src/skills/developer-like-execution/SKILL.md +5 -4
  188. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
  189. package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
  190. package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
  191. package/dist/agent-src/skills/memory-consolidation/SKILL.md +63 -17
  192. package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
  193. package/dist/agent-src/skills/readme-writing-package/SKILL.md +1 -1
  194. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +119 -0
  195. package/dist/agent-src/skills/reasoning-orchestrator/evals/triggers.json +16 -0
  196. package/dist/agent-src/skills/receiving-code-review/SKILL.md +6 -6
  197. package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
  198. package/dist/agent-src/skills/refine-ticket/SKILL.md +1 -1
  199. package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
  200. package/dist/agent-src/skills/secrets-management/SKILL.md +1 -1
  201. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +10 -3
  202. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  203. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
  204. package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
  205. package/dist/agent-src/templates/agents/.gitattributes.fragment +0 -1
  206. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +4 -4
  207. package/dist/agent-src/templates/scripts/check_memory.py +1 -2
  208. package/dist/agent-src/templates/scripts/check_memory_proposal.py +1 -1
  209. package/dist/agent-src/templates/scripts/memory_lookup.py +148 -289
  210. package/dist/agent-src/templates/scripts/memory_report.py +132 -2
  211. package/dist/agent-src/templates/scripts/memory_signal.py +7 -9
  212. package/dist/agent-src/templates/scripts/memory_status.py +25 -206
  213. package/dist/agent-src/templates/scripts/work_engine/directives/backend/memory.py +6 -6
  214. package/dist/agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +3 -3
  215. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +0 -1
  216. package/dist/cli/agent-config.js +31 -300
  217. package/dist/cli/agent-config.js.map +1 -1
  218. package/dist/cli/commands/commands.js +10 -5
  219. package/dist/cli/commands/commands.js.map +1 -1
  220. package/dist/cli/discovery/loadManifest.js.map +1 -1
  221. package/dist/cli/main.js +309 -0
  222. package/dist/cli/main.js.map +1 -0
  223. package/dist/discovery/deprecation-report.md +1 -1
  224. package/dist/discovery/discovery-manifest.json +645 -342
  225. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  226. package/dist/discovery/discovery-manifest.summary.md +8 -5
  227. package/dist/discovery/orphan-report.md +1 -1
  228. package/dist/discovery/packs.json +149 -37
  229. package/dist/discovery/trust-report.md +3 -3
  230. package/dist/discovery/workspaces.json +61 -36
  231. package/dist/mcp/registry-manifest.json +4 -4
  232. package/dist/router.json +1 -1
  233. package/dist/server/routes/wizard.js +4 -3
  234. package/dist/server/routes/wizard.js.map +1 -1
  235. package/dist/server/schemas/settings.js +18 -0
  236. package/dist/server/schemas/settings.js.map +1 -1
  237. package/docs/MIGRATION.md +1 -1
  238. package/docs/adrs/cost/0001-hard-stop-hook.md +5 -5
  239. package/docs/adrs/memory/0001-consumer-side-snapshot.md +15 -7
  240. package/docs/adrs/memory/README.md +6 -5
  241. package/docs/adrs/router/0001-three-tier-routing.md +2 -2
  242. package/docs/adrs/schema/0001-json-schema-frontmatter.md +2 -2
  243. package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +5 -5
  244. package/docs/adrs/telegraph/0001-default-off-until-bench.md +3 -3
  245. package/docs/architecture.md +9 -9
  246. package/docs/archive/CHANGELOG-pre-2.2.0.md +30 -30
  247. package/docs/archive/CHANGELOG-pre-2.25.0.md +1 -1
  248. package/docs/archive/CHANGELOG-pre-4.5.0.md +1 -1
  249. package/docs/archive/CHANGELOG-pre-6.0.0.md +473 -0
  250. package/docs/benchmark.md +54 -53
  251. package/docs/benchmarks.md +2 -2
  252. package/docs/case-studies/{frontend-design-vs-ui-ux-pro-max.md → frontend-design-positioning.md} +4 -4
  253. package/docs/catalog.md +20 -13
  254. package/docs/command-flows.md +90 -92
  255. package/docs/contracts/adr-layout.md +2 -3
  256. package/docs/contracts/adr-level-6-productization.md +1 -1
  257. package/docs/contracts/ai-council-config.md +42 -7
  258. package/docs/contracts/command-clusters.md +1 -1
  259. package/docs/contracts/cost-enforcement.md +1 -1
  260. package/docs/contracts/cost-summary-schema.md +1 -1
  261. package/docs/contracts/daily-workspace.md +1 -0
  262. package/docs/contracts/discovery-manifest.schema.json +4 -2
  263. package/docs/contracts/explain-modes.md +1 -1
  264. package/docs/contracts/implement-ticket-flow.md +6 -7
  265. package/docs/contracts/mcp-tool-inventory.md +10 -10
  266. package/docs/contracts/measurement-baseline.md +1 -1
  267. package/docs/contracts/memory-visibility-v1.md +1 -5
  268. package/docs/contracts/namespace.md +1 -1
  269. package/docs/contracts/persona-schema.md +1 -1
  270. package/docs/contracts/rule-interactions.md +1 -1
  271. package/docs/contracts/smoke-contracts.md +1 -1
  272. package/docs/contracts/universal-skills.md +0 -1
  273. package/docs/contracts/workspace-boundary.md +84 -0
  274. package/docs/customization.md +3 -3
  275. package/docs/decisions/ADR-009-event4u-namespace.md +1 -1
  276. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +1 -1
  277. package/docs/decisions/ADR-026-explain-mode-translation.md +1 -1
  278. package/docs/decisions/ADR-088-no-external-runtime-federation.md +26 -27
  279. package/docs/decisions/ADR-090-visibility-command-frontmatter-field.md +95 -0
  280. package/docs/decisions/ADR-091-split-meta-capability-packs.md +113 -0
  281. package/docs/decisions/ADR-092-defer-command-tier-alias-removal.md +93 -0
  282. package/docs/decisions/ADR-093-ai-council-config-user-global.md +111 -0
  283. package/docs/decisions/ADR-094-agent-memory-layer-removal.md +94 -0
  284. package/docs/decisions/ADR-095-workspace-boundary-contract.md +108 -0
  285. package/docs/decisions/INDEX.md +6 -0
  286. package/docs/development.md +5 -7
  287. package/docs/getting-started.md +4 -4
  288. package/docs/guidelines/agent-infra/5w2h-analysis.md +1 -1
  289. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  290. package/docs/guidelines/agent-infra/corpus-grounding-authoring.md +1 -1
  291. package/docs/guidelines/agent-infra/critical-thinking.md +1 -1
  292. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +1 -5
  293. package/docs/guidelines/agent-infra/first-principles.md +1 -1
  294. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +164 -0
  295. package/docs/guidelines/agent-infra/inversion-thinking.md +1 -1
  296. package/docs/guidelines/agent-infra/ios-simulator-guide.md +9 -14
  297. package/docs/guidelines/agent-infra/mcp-request-signing.md +19 -22
  298. package/docs/guidelines/agent-infra/memory-access.md +25 -31
  299. package/docs/guidelines/agent-infra/mental-models.md +1 -1
  300. package/docs/guidelines/agent-infra/model-recommendation.md +29 -0
  301. package/docs/guidelines/agent-infra/scqa-framework.md +3 -3
  302. package/docs/guidelines/agent-infra/security-lint-containment.md +81 -0
  303. package/docs/guidelines/agent-infra/six-hats.md +1 -1
  304. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  305. package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +72 -0
  306. package/docs/installation.md +1 -1
  307. package/docs/mcp.md +2 -2
  308. package/docs/parity/{bench-ruflo.json → bench-external.json} +10 -10
  309. package/docs/parity/{ruflo.md → external-runtime.md} +9 -9
  310. package/docs/quality.md +3 -3
  311. package/docs/safety.md +3 -3
  312. package/docs/skills-catalog.md +4 -1
  313. package/llms.txt +3 -0
  314. package/package.json +1 -1
  315. package/src/config/agent-settings.template.yml +65 -3
  316. package/src/config/discovery/packs.yml +29 -0
  317. package/src/config/discovery/workspaces.yml +3 -1
  318. package/src/config/gitignore-block.txt +6 -0
  319. package/src/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
  320. package/src/scripts/_cli/cmd_doctor.py +99 -13
  321. package/src/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
  322. package/src/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
  323. package/src/scripts/_lib/bench_ab_scoring_v2.py +227 -0
  324. package/src/scripts/_lib/global_deploy_inventory.py +39 -9
  325. package/src/scripts/_lib/link_crypto.py +206 -0
  326. package/src/scripts/_lib/security_lint.py +228 -0
  327. package/src/scripts/ai_council/clients.py +2 -2
  328. package/src/scripts/ai_council/config.py +55 -0
  329. package/src/scripts/audit_adr_coverage.py +0 -2
  330. package/src/scripts/audit_command_surface.py +18 -5
  331. package/src/scripts/audit_mcp_tools.py +2 -2
  332. package/src/scripts/audit_skill_descriptions.py +2 -2
  333. package/src/scripts/bench_ab_clone.py +62 -12
  334. package/src/scripts/bench_ab_task_runner.py +475 -30
  335. package/src/scripts/bench_ab_v2_run.py +247 -0
  336. package/src/scripts/bench_ab_v2_stats.py +347 -0
  337. package/src/scripts/bench_run.py +1 -1
  338. package/src/scripts/build_discovery_manifest.py +10 -0
  339. package/src/scripts/check_bite_sized_granularity.py +1 -2
  340. package/src/scripts/check_memory.py +49 -63
  341. package/src/scripts/check_memory_proposal.py +1 -1
  342. package/src/scripts/check_no_external_sources.py +101 -0
  343. package/src/scripts/check_references.py +2 -0
  344. package/src/scripts/cost_by_conversation.py +1 -1
  345. package/src/scripts/council_cli.py +28 -14
  346. package/src/scripts/external_sources_denylist.json +91 -0
  347. package/src/scripts/hook_manifest.yaml +14 -6
  348. package/src/scripts/injection_scan_hook.py +145 -0
  349. package/src/scripts/install-hooks.sh +11 -0
  350. package/src/scripts/install.py +88 -13
  351. package/src/scripts/lint_agent_security.py +112 -0
  352. package/src/scripts/lint_bench_ab.py +5 -4
  353. package/src/scripts/lint_command_tiers.py +63 -22
  354. package/src/scripts/lint_discovery_vocabulary.py +2 -0
  355. package/src/scripts/lint_empty_roadmaps.py +80 -0
  356. package/src/scripts/lint_hidden_unicode.py +132 -0
  357. package/src/scripts/lint_instruction_smuggling.py +107 -0
  358. package/src/scripts/lint_marketplace.py +1 -1
  359. package/src/scripts/lint_mcp_config_security.py +124 -0
  360. package/src/scripts/lint_skill_frontmatter_safety.py +144 -0
  361. package/src/scripts/lint_workspace_boundary.py +122 -0
  362. package/src/scripts/mcp_server/consumer_tool_catalog.json +2 -3
  363. package/src/scripts/mcp_server/tools.py +8 -32
  364. package/src/scripts/memory_lookup.py +27 -296
  365. package/src/scripts/memory_report.py +1 -23
  366. package/src/scripts/memory_signal.py +6 -53
  367. package/src/scripts/memory_status.py +25 -206
  368. package/src/scripts/mine_session.py +118 -41
  369. package/src/scripts/pack_dependency_allowlist.json +2 -2
  370. package/src/scripts/render_benchmark_md.py +141 -52
  371. package/src/scripts/schemas/command.schema.json +6 -1
  372. package/src/scripts/security_audit_config.py +153 -0
  373. package/dist/agent-src/commands/chat-history/learn.md +0 -184
  374. package/dist/agent-src/commands/chat-history/show.md +0 -113
  375. package/dist/agent-src/commands/fix/pr-bot-comments.md +0 -157
  376. package/dist/agent-src/commands/fix/pr-developer-comments.md +0 -163
  377. package/dist/agent-src/templates/agents/memory/architecture-decisions.example.yml +0 -95
  378. package/docs/contracts/agent-memory-contract.md +0 -159
@@ -1,28 +1,23 @@
1
1
  #!/usr/bin/env python3
2
- """Hybrid retrieval — file-first with optional package augmentation.
2
+ """File-first memory retrieval.
3
3
 
4
4
  Implements the shared `retrieve(types, keys, limit)` abstraction used
5
5
  by skills. Reads YAML under `agents/memory/<type>/` (curated, hand-
6
6
  reviewed) and JSONL under `agents/memory/intake/*.jsonl` (agent-written,
7
- append-only, supersede-chain aware).
7
+ append-only, supersede-chain aware), plus user-ingested `knowledge`
8
+ chunks and opted-in `cross-repo` matches.
8
9
 
9
- When the `@event4u/agent-memory` package is present (see
10
- `scripts/memory_status.py`), callers can pass the result of
11
- :func:`package_operational_provider` to route additional retrieval
12
- through the package's semantic CLI. Repo entries always win on
13
- conflict — see `_apply_conflict_rule`.
10
+ Retrieval is entirely repo-side and file-backed — there is no external
11
+ backend. (The former optional `@event4u/agent-memory` package routing
12
+ was removed; see `docs/decisions/` for the agent-memory removal ADR.)
14
13
 
15
14
  Usage:
16
15
  python3 scripts/memory_lookup.py --types domain-invariants,ownership \\
17
16
  --key "app/Http/Controllers/Foo" --limit 5
18
17
  python3 scripts/memory_lookup.py --types incident-learnings --format json
19
- python3 scripts/memory_lookup.py --types ownership --key billing --auto
20
18
 
21
- from scripts.memory_lookup import retrieve, package_operational_provider
22
- hits = retrieve(
23
- types=["ownership"], keys=["app/Http"], limit=3,
24
- operational_provider=package_operational_provider(),
25
- )
19
+ from scripts.memory_lookup import retrieve
20
+ hits = retrieve(types=["ownership"], keys=["app/Http"], limit=3)
26
21
  """
27
22
 
28
23
  from __future__ import annotations
@@ -30,12 +25,10 @@ from __future__ import annotations
30
25
  import argparse
31
26
  import fnmatch
32
27
  import json
33
- import os
34
- import subprocess
35
28
  import sys
36
29
  from dataclasses import dataclass, asdict, field
37
30
  from pathlib import Path
38
- from typing import Any, Callable, Iterable, Optional, Union
31
+ from typing import Iterable, Union
39
32
 
40
33
  MEMORY_ROOT = Path("agents/memory")
41
34
  INTAKE_ROOT = MEMORY_ROOT / "intake"
@@ -45,15 +38,13 @@ CURATED_TYPES = {
45
38
  "ownership",
46
39
  "historical-patterns",
47
40
  "domain-invariants",
48
- "architecture-decisions",
49
41
  "incident-learnings",
50
42
  "product-rules",
51
43
  }
52
44
 
53
45
  # `knowledge` is its own type: user-ingested local documents that live
54
46
  # under `agents/memory/knowledge/<ingest-id>/chunks/*.md`. They are
55
- # repo-side (file-backed) but not "curated" and not intake — the
56
- # conflict rule still treats them as repo entries against operational.
47
+ # repo-side (file-backed) but not "curated" and not intake.
57
48
  KNOWLEDGE_TYPE = "knowledge"
58
49
 
59
50
  # Cross-repo retrieval (road-to-leaner-core-and-discovery Phase 4). When this
@@ -70,7 +61,7 @@ CROSS_REPO_TYPE = "cross-repo"
70
61
  class Hit:
71
62
  id: str
72
63
  type: str
73
- source: str # "curated" | "intake" | "operational" | "knowledge" | "cross-repo"
64
+ source: str # "curated" | "intake" | "knowledge" | "cross-repo"
74
65
  path: str # file (or logical locator) that produced the hit
75
66
  score: float # naive, content-match based [0..1]
76
67
  entry: dict = field(default_factory=dict)
@@ -79,36 +70,13 @@ class Hit:
79
70
  return asdict(self)
80
71
 
81
72
 
82
- @dataclass
83
- class Shadow:
84
- """An operational entry suppressed by the conflict rule."""
85
- id: str
86
- type: str
87
- reason: str # "same-id" | "repo-deprecated"
88
- operational_path: str # where the suppressed entry came from
89
- repo_path: str # repo entry that shadowed it
90
-
91
- def as_dict(self) -> dict:
92
- return asdict(self)
93
-
94
-
95
73
  @dataclass
96
74
  class RetrievalResult:
97
- """Full retrieval payload with conflict-rule observability."""
75
+ """Full retrieval payload."""
98
76
  hits: list
99
- shadows: list = field(default_factory=list)
100
77
 
101
78
  def as_dict(self) -> dict:
102
- return {
103
- "hits": [h.as_dict() for h in self.hits],
104
- "shadows": [s.as_dict() for s in self.shadows],
105
- }
106
-
107
-
108
- # An operational provider returns repo-shaped Hit objects with
109
- # source="operational". Backend adapters (e.g. @event4u/agent-memory)
110
- # are expected to translate their native payload into this shape.
111
- OperationalProvider = Callable[[list[str], list[str]], Iterable[Hit]]
79
+ return {"hits": [h.as_dict() for h in self.hits]}
112
80
 
113
81
 
114
82
  def _load_yaml(path: Path):
@@ -238,8 +206,7 @@ def _iter_knowledge_entries() -> Iterable[tuple[Path, dict]]:
238
206
  def _score(entry: dict, keys: list[str]) -> float:
239
207
  """Naive relevance score: max over keys of (glob-match | substring).
240
208
 
241
- Good enough for the `absent` path where retrieval is best-effort.
242
- The `present` path returns a real score from agent-memory.
209
+ Good enough for best-effort file retrieval.
243
210
  """
244
211
  if not keys:
245
212
  return 0.1 # any hit beats no hit when there is no key
@@ -261,170 +228,6 @@ def _score(entry: dict, keys: list[str]) -> float:
261
228
  return best
262
229
 
263
230
 
264
- def _apply_conflict_rule(
265
- repo_hits: list[Hit],
266
- operational_hits: list[Hit],
267
- ) -> tuple[list[Hit], list[Shadow]]:
268
- """Enforce REPO WINS / OPERATIONAL AUGMENTS / NEVER CONTRADICTS SILENTLY.
269
-
270
- Reference: `agents/roadmaps/road-to-memory-self-consumption.md` §
271
- "Conflict rule: repo vs. operational". The four cases mapped below
272
- are covered by `tests/test_conflict_rule.py`.
273
- """
274
- # Repo entries index — curated AND intake both count as "repo" for
275
- # the conflict rule. The operational store is the only non-repo side.
276
- repo_by_id: dict[str, Hit] = {h.id: h for h in repo_hits if h.id}
277
-
278
- merged: list[Hit] = list(repo_hits)
279
- shadows: list[Shadow] = []
280
-
281
- for op in operational_hits:
282
- if op.id and op.id in repo_by_id:
283
- # Case 1+2: same id → repo wins (including when repo is
284
- # status:deprecated — operational cannot revive a retired
285
- # entry). Suppress the operational entry and record shadow.
286
- repo = repo_by_id[op.id]
287
- reason = (
288
- "repo-deprecated"
289
- if repo.entry.get("status") == "deprecated"
290
- else "same-id"
291
- )
292
- shadows.append(Shadow(
293
- id=op.id,
294
- type=op.type,
295
- reason=reason,
296
- operational_path=op.path,
297
- repo_path=repo.path,
298
- ))
299
- continue
300
- # Case 3 (different ids on same logical key) and Case 4 (repo
301
- # has no entry) — both simply include the operational hit.
302
- # Repo entries naturally rank higher because their score is not
303
- # discounted (see _score / operational scoring in retrieve()).
304
- merged.append(op)
305
-
306
- return merged, shadows
307
-
308
-
309
- # ---------------------------------------------------------------------------
310
- # Package-backed operational provider (the `present` path)
311
- # ---------------------------------------------------------------------------
312
- #
313
- # When `memory_status.status() == "present"` the consumer-facing contract
314
- # says retrieval should route through `@event4u/agent-memory`. The package
315
- # CLI is purely **semantic** (`memory retrieve <query> --type T …`); the
316
- # shared `retrieve(types, keys, …)` API is **key-based**. The hybrid
317
- # resolution agreed in `docs/contracts/agent-memory-contract.md` synthesises
318
- # `keys` into a single natural-language query for the package call, while
319
- # the file fallback continues to do glob/substring matching on the same
320
- # keys. Both legs land in the same `Hit` shape so the conflict rule can
321
- # merge them transparently.
322
-
323
- _CLI_TIMEOUT_SECONDS = 5.0
324
- _CLI_RETRIEVE_LIMIT_DEFAULT = 20
325
-
326
-
327
- def _synthesize_query(keys: list[str]) -> str:
328
- """Turn a list of retrieval keys into one natural-language query.
329
-
330
- Keys are typically file paths (`app/Http/Controllers/Foo`), feature
331
- names (`billing`), or short identifiers — joining them with spaces
332
- gives the package's semantic search enough surface to score against
333
- without inventing structure. Empty or whitespace-only keys are
334
- dropped; if nothing remains the caller falls back to the file path.
335
- """
336
- cleaned = [k.strip() for k in keys if isinstance(k, str) and k.strip()]
337
- return " ".join(cleaned)
338
-
339
-
340
- def _cli_operational_provider(
341
- types: list[str],
342
- keys: list[str],
343
- *,
344
- cli_path: str = "memory",
345
- timeout: float = _CLI_TIMEOUT_SECONDS,
346
- limit: int = _CLI_RETRIEVE_LIMIT_DEFAULT,
347
- ) -> Iterable[Hit]:
348
- """Run `memory retrieve` and yield operational `Hit` objects.
349
-
350
- Pino structured logs from the package go to stderr; stdout is a
351
- clean v1 retrieval envelope. Any non-zero exit, timeout, or parse
352
- failure degrades to "no operational hits" — `retrieve()` already
353
- treats provider exceptions as a soft warning, so the caller still
354
- gets the file-fallback result.
355
- """
356
- query = _synthesize_query(keys)
357
- if not query:
358
- return
359
- cmd: list[str] = [cli_path, "retrieve", query, "--limit", str(limit)]
360
- for t in types:
361
- cmd.extend(["--type", t])
362
- try:
363
- out = subprocess.run(
364
- cmd,
365
- capture_output=True, text=True, timeout=timeout,
366
- )
367
- except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
368
- return
369
- if out.returncode != 0:
370
- return
371
- try:
372
- envelope = json.loads(out.stdout)
373
- except (ValueError, TypeError):
374
- return
375
- entries = envelope.get("entries") if isinstance(envelope, dict) else None
376
- if not isinstance(entries, list):
377
- return
378
- for e in entries:
379
- if not isinstance(e, dict):
380
- continue
381
- eid = e.get("id")
382
- etype = e.get("type")
383
- if not isinstance(eid, str) or not isinstance(etype, str):
384
- continue
385
- # The package returns `confidence` (0..1) per the v1 envelope;
386
- # map it onto our internal `score` field so the conflict rule
387
- # and ranking work uniformly across providers.
388
- try:
389
- score = float(e.get("confidence", 0.0))
390
- except (TypeError, ValueError):
391
- score = 0.0
392
- body = e.get("body") if isinstance(e.get("body"), dict) else {}
393
- yield Hit(
394
- id=eid,
395
- type=etype,
396
- source="operational",
397
- path=f"agent-memory:{eid}",
398
- score=score,
399
- entry=body,
400
- )
401
-
402
-
403
- def package_operational_provider() -> Optional[OperationalProvider]:
404
- """Return a CLI-backed provider when the package is `present`, else None.
405
-
406
- Callers who want automatic backend routing pass the result directly
407
- to :func:`retrieve` — `None` is a safe value that yields file-only
408
- retrieval, so this is the recommended one-liner for skills:
409
-
410
- retrieve(types, keys, operational_provider=package_operational_provider())
411
-
412
- The status probe is bounded (≤ 2s, cached per process) — see
413
- `scripts/memory_status.py`. We import lazily so pure file-fallback
414
- callers never pay for the probe.
415
- """
416
- # Late import: keeps `memory_lookup` importable even when
417
- # `memory_status` is missing in stripped consumer installs.
418
- try:
419
- sys.path.insert(0, str(Path(__file__).resolve().parent))
420
- import memory_status # type: ignore[import-not-found]
421
- except ImportError:
422
- return None
423
- if memory_status.status().status != "present":
424
- return None
425
- return _cli_operational_provider
426
-
427
-
428
231
  def _cross_repo_hits(keys: list[str], limit: int) -> list[Hit]:
429
232
  """Project cross-repo matches into discounted, tagged Hits.
430
233
 
@@ -468,20 +271,13 @@ def retrieve(
468
271
  types: list[str],
469
272
  keys: list[str],
470
273
  limit: int = 5,
471
- operational_provider: Optional[OperationalProvider] = None,
472
- with_shadows: bool = False,
473
- ) -> Union[list[Hit], RetrievalResult]:
274
+ ) -> list[Hit]:
474
275
  """Return up to `limit` hits across the requested types, highest score first.
475
276
 
476
277
  Repo entries (curated + intake) are preferred on ties — they are
477
- hand-reviewed or session-captured against the repo itself. When an
478
- `operational_provider` is supplied (the `present` path of the
479
- backend-detection contract), its results are merged under the
480
- REPO WINS conflict rule; suppressed operational entries surface as
481
- `shadows` when `with_shadows=True`.
482
-
483
- The return type stays `list[Hit]` by default for backward
484
- compatibility with existing skill call sites.
278
+ hand-reviewed or session-captured against the repo itself. Knowledge
279
+ and cross-repo hits are discounted so the project's own truth wins on
280
+ equal relevance.
485
281
  """
486
282
  repo_hits: list[Hit] = []
487
283
  for mtype in types:
@@ -527,27 +323,9 @@ def retrieve(
527
323
  entry=entry,
528
324
  ))
529
325
 
530
- operational_hits: list[Hit] = []
531
- if operational_provider is not None:
532
- try:
533
- for oh in operational_provider(list(types), list(keys)) or []:
534
- # Discount operational vs curated/intake so repo ranks
535
- # higher on equal relevance. Providers may already return
536
- # trust-adjusted scores; we only apply a floor discount.
537
- oh.score = min(oh.score, 0.85)
538
- operational_hits.append(oh)
539
- except Exception as exc: # noqa: BLE001 — providers are external
540
- print(f"warning: operational_provider raised "
541
- f"{exc.__class__.__name__}: {exc}", file=sys.stderr)
542
-
543
- merged, shadows = _apply_conflict_rule(repo_hits, operational_hits)
544
- merged.sort(key=lambda h: (h.score, h.source == "curated"), reverse=True)
545
- positives = [h for h in merged if h.score > 0]
546
- final_hits = (positives or merged)[:limit]
547
-
548
- if with_shadows:
549
- return RetrievalResult(hits=final_hits, shadows=shadows)
550
- return final_hits
326
+ repo_hits.sort(key=lambda h: (h.score, h.source == "curated"), reverse=True)
327
+ positives = [h for h in repo_hits if h.score > 0]
328
+ return (positives or repo_hits)[:limit]
551
329
 
552
330
 
553
331
  CONTRACT_VERSION = 1
@@ -561,7 +339,6 @@ def retrieve_v1(
561
339
  types: list[str],
562
340
  keys: list[str],
563
341
  limit: int = 20,
564
- operational_provider: Optional[OperationalProvider] = None,
565
342
  ) -> dict:
566
343
  """Return a v1 retrieval-contract envelope.
567
344
 
@@ -569,49 +346,27 @@ def retrieve_v1(
569
346
  the shape defined by
570
347
  ``internal/schemas/retrieval-v1.schema.json``. Unknown types are reported as
571
348
  ``status: unknown_type`` for that slice only, rather than failing
572
- the whole call.
349
+ the whole call. All entries are file-backed (``source: "repo"``).
573
350
  """
574
351
  known = [t for t in types if t in _KNOWN_TYPES]
575
352
  unknown = [t for t in types if t not in _KNOWN_TYPES]
576
353
 
577
- result = retrieve(known, keys, limit=limit,
578
- operational_provider=operational_provider,
579
- with_shadows=True)
580
- assert isinstance(result, RetrievalResult)
581
- hits, shadows = result.hits, result.shadows
582
- shadow_by_id = {s.id: s for s in shadows if s.id}
354
+ hits = retrieve(known, keys, limit=limit)
583
355
 
584
356
  slice_counts: dict[str, int] = {t: 0 for t in known}
585
357
  entries: list[dict] = []
586
358
  for h in hits:
587
- source = "operational" if h.source == "operational" else "repo"
588
359
  envelope_entry: dict = {
589
360
  "id": h.id,
590
361
  "type": h.type,
591
- "source": source,
362
+ "source": "repo",
592
363
  "confidence": round(float(h.score), 4),
593
364
  "body": dict(h.entry) if isinstance(h.entry, dict) else {},
594
- "shadowed_by": None,
595
365
  }
596
366
  if h.type in slice_counts:
597
367
  slice_counts[h.type] += 1
598
368
  entries.append(envelope_entry)
599
369
 
600
- # Surface shadowed operational entries as additional entries carrying
601
- # `shadowed_by`. The conformance harness checks that only
602
- # source="operational" entries ever set this field.
603
- for sid, s in shadow_by_id.items():
604
- entries.append({
605
- "id": sid,
606
- "type": s.type,
607
- "source": "operational",
608
- "confidence": 0.0,
609
- "body": {},
610
- "shadowed_by": f"repo:{sid}",
611
- })
612
- if s.type in slice_counts:
613
- slice_counts[s.type] += 1
614
-
615
370
  slices: dict[str, dict] = {
616
371
  t: {"status": "ok", "count": slice_counts.get(t, 0)}
617
372
  for t in known
@@ -655,35 +410,18 @@ def main() -> int:
655
410
  ap.add_argument("--envelope", choices=["legacy", "v1"], default="legacy",
656
411
  help="Output shape: `legacy` (Hit list) or `v1` "
657
412
  "(retrieval contract v1 envelope). `v1` implies JSON output.")
658
- ap.add_argument("--with-shadows", action="store_true",
659
- help="Include shadowed-operational entries in the output "
660
- "(no-op until an operational backend is wired)")
661
- ap.add_argument("--auto", action="store_true",
662
- help="Auto-route to the @event4u/agent-memory package "
663
- "when memory_status.status() == 'present'; "
664
- "falls through to file-only retrieval otherwise")
665
413
  args = ap.parse_args()
666
414
  types = [t.strip() for t in args.types.split(",") if t.strip()]
667
415
  if not types:
668
416
  print("error: --types is required", file=sys.stderr)
669
417
  return 2
670
- op_provider = package_operational_provider() if args.auto else None
671
418
  if args.envelope == "v1":
672
- envelope = retrieve_v1(types, args.key, args.limit,
673
- operational_provider=op_provider)
419
+ envelope = retrieve_v1(types, args.key, args.limit)
674
420
  print(json.dumps(envelope, indent=2, default=str))
675
421
  return 0
676
- result = retrieve(types, args.key, args.limit,
677
- operational_provider=op_provider,
678
- with_shadows=args.with_shadows)
679
- if args.with_shadows:
680
- assert isinstance(result, RetrievalResult)
681
- hits, shadows = result.hits, result.shadows
682
- else:
683
- hits, shadows = result, [] # type: ignore[assignment]
422
+ hits = retrieve(types, args.key, args.limit)
684
423
  if args.format == "json":
685
- payload = {"hits": [h.as_dict() for h in hits],
686
- "shadows": [s.as_dict() for s in shadows]}
424
+ payload = {"hits": [h.as_dict() for h in hits]}
687
425
  print(json.dumps(payload, indent=2, default=str))
688
426
  else:
689
427
  if not hits:
@@ -691,13 +429,6 @@ def main() -> int:
691
429
  for h in hits:
692
430
  print(f" [{h.source}] {h.type} score={h.score:.2f} "
693
431
  f"id={h.id or '-'} path={h.path}")
694
- if shadows:
695
- print(f"\n shadows: {len(shadows)} operational entr"
696
- f"{'y' if len(shadows) == 1 else 'ies'} suppressed by "
697
- f"the conflict rule")
698
- for s in shadows:
699
- print(f" [{s.reason}] {s.type} id={s.id} "
700
- f"op={s.operational_path} repo={s.repo_path}")
701
432
  return 0
702
433
 
703
434
 
@@ -34,7 +34,7 @@ MEMORY_ROOT = Path("agents/memory")
34
34
  INTAKE_ROOT = MEMORY_ROOT / "intake"
35
35
  CURATED_TYPES = (
36
36
  "ownership", "historical-patterns", "domain-invariants",
37
- "architecture-decisions", "incident-learnings", "product-rules",
37
+ "incident-learnings", "product-rules",
38
38
  )
39
39
 
40
40
  # Role-mode marker grepped from session captures / reports / handoffs.
@@ -204,24 +204,6 @@ def _quarterly_stats() -> dict:
204
204
  }
205
205
 
206
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
207
  def _role_mode_stats() -> dict:
226
208
  """Count structured mode markers across session/report/handoff dirs.
227
209
 
@@ -263,13 +245,11 @@ def build_report() -> dict:
263
245
  "status": status.status,
264
246
  "backend": status.backend,
265
247
  "reason": status.reason,
266
- "cli_path": status.cli_path,
267
248
  },
268
249
  "intake": _intake_stats(),
269
250
  "staleness": _staleness_report(),
270
251
  "quarterly": _quarterly_stats(),
271
252
  "role_modes": _role_mode_stats(),
272
- "operational_store": _operational_store_stats(status.status),
273
253
  }
274
254
 
275
255
 
@@ -316,8 +296,6 @@ def _print_text(report: dict) -> None:
316
296
  if rm.get("unknown_modes"):
317
297
  print(f" unknown: {', '.join(rm['unknown_modes'])} "
318
298
  "(not in the six reserved slugs)")
319
- if report["operational_store"]:
320
- print("Operational-store: present (stats via agent-memory CLI)")
321
299
 
322
300
 
323
301
  def main() -> int:
@@ -2,10 +2,10 @@
2
2
  """Write-side helper: drop an engineering-memory signal.
3
3
 
4
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`).
5
+ incident role exit). Appends an intake line under
6
+ `agents/memory/intake/signals-YYYY-MM.jsonl` append-only JSONL with
7
+ `merge=union` (see `road-to-memory-merge-safety.md`). Memory is entirely
8
+ file-backed (no external backend).
9
9
 
10
10
  Rate limiting:
11
11
  - Per-path, per-type, within a rolling window (default 7 days).
@@ -37,49 +37,11 @@ VALID_TYPES = {
37
37
  "incident-learnings",
38
38
  "ownership",
39
39
  "domain-invariants",
40
- "architecture-decisions",
41
40
  "product-rules",
42
41
  }
43
42
  RATE_LIMIT_WINDOW_DAYS = 7
44
43
 
45
44
 
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
- Centralized loader (road-to-portable-dev-preferences P3): tolerance
54
- contract handles missing file / malformed YAML / no PyYAML uniformly.
55
- """
56
- try:
57
- from scripts._lib.agent_settings import load_agent_settings
58
- except ImportError: # pragma: no cover — script-style invocation
59
- import sys as _sys
60
- from pathlib import Path as _Path
61
- _sys.path.insert(0, str(_Path(__file__).resolve().parent))
62
- from _lib.agent_settings import load_agent_settings # type: ignore[import-not-found]
63
-
64
- data = load_agent_settings(project_path=SETTINGS_FILE)
65
- mem = data.get("memory")
66
- if not isinstance(mem, dict):
67
- return False
68
- intake = mem.get("intake")
69
- if not isinstance(intake, dict):
70
- return False
71
- return bool(intake.get("skip_when_present", False))
72
-
73
-
74
- def _backend_status() -> str:
75
- """Return the current backend status: 'present' | 'absent' | 'unknown'."""
76
- try:
77
- import memory_status # type: ignore
78
- return memory_status.status().status
79
- except Exception:
80
- return "unknown"
81
-
82
-
83
45
  def _now_iso() -> str:
84
46
  return dt.datetime.now(dt.timezone.utc).isoformat(timespec="seconds")
85
47
 
@@ -137,10 +99,8 @@ def emit(entry_type: str, path: str, body: str,
137
99
  force: bool = False) -> dict[str, Any] | None:
138
100
  """Append a signal entry. Returns the written record, or None when skipped.
139
101
 
140
- On `present` backend, routing to the package is a no-op here today
141
- the package adapter is wired in `road-to-agent-memory-integration.md`
142
- Phase 3. For now, the file path is the single source of truth so
143
- merge-safety is preserved in every mode.
102
+ The intake JSONL file is the single source of truth memory is
103
+ entirely file-backed (no external backend).
144
104
  """
145
105
  if entry_type not in VALID_TYPES:
146
106
  raise ValueError(f"unknown memory type: {entry_type}")
@@ -160,13 +120,6 @@ def emit(entry_type: str, path: str, body: str,
160
120
  # Reserved keys stay intact; extras only fill unclaimed slots.
161
121
  for k, v in extra.items():
162
122
  record.setdefault(k, v)
163
- # Backend routing: when the `agent-memory` package is present AND
164
- # the consumer opted out of the debug trail, skip the JSONL write.
165
- # Otherwise the intake file stays the source of truth (and, when a
166
- # backend is present, a replayable debug trail).
167
- if _backend_status() == "present" and _skip_intake_when_present():
168
- record["_backend"] = "package-only"
169
- return record
170
123
  INTAKE_ROOT.mkdir(parents=True, exist_ok=True)
171
124
  target = _monthly_file()
172
125
  with target.open("a", encoding="utf-8") as fh: