@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
@@ -79,6 +79,16 @@ def safe_load(path: Path | None) -> dict:
79
79
  return {}
80
80
 
81
81
 
82
+ def latest_trackb_with_rdp() -> dict:
83
+ """Latest Track B report for the third condition (`with-rdp`), or {}."""
84
+ reports = sorted(REPORTS_DIR.glob("*-ab-trackb-with-rdp.json"))
85
+ return safe_load(reports[-1]) if reports else {}
86
+
87
+
88
+ def _delta_pct(a: float | None, b: float | None) -> str:
89
+ return fmt_pct((a or 0) - (b or 0))
90
+
91
+
82
92
  def fmt_pct(value: float | None) -> str:
83
93
  if value is None:
84
94
  return "—"
@@ -91,33 +101,79 @@ def fmt_num(value: float | None, places: int = 2) -> str:
91
101
  return f"{value:.{places}f}"
92
102
 
93
103
 
94
- def render_headline(track_a: dict, track_b: dict) -> str:
95
- a_results = (track_a.get("with") or {}).get("results", {})
96
- a_without = (track_a.get("without") or {}).get("results", {})
97
- b_results = (track_b.get("with") or {}).get("results", {})
98
- b_without = (track_b.get("without") or {}).get("results", {})
99
- a_with_acc = a_results.get("trigger_accuracy")
100
- a_wo_acc = a_without.get("trigger_accuracy")
101
- b_with_comp = b_results.get("completion_rate")
102
- b_wo_comp = b_without.get("completion_rate")
104
+ def fmt_int(value: float | None) -> str:
105
+ if value is None:
106
+ return ""
107
+ return f"{int(value):,}"
108
+
109
+
110
+ def _delta_num(a: float | None, b: float | None, places: int = 3) -> str:
111
+ d = (a or 0) - (b or 0)
112
+ return f"{d:+.{places}f}"
113
+
114
+
115
+ def render_headline(track_a: dict, track_b: dict, track_b_rdp: dict) -> str:
116
+ wo = (track_b.get("without") or {}).get("results", {})
117
+ wi = (track_b.get("with") or {}).get("results", {})
118
+ rd = (track_b_rdp or {}).get("results", {})
119
+ mode = wi.get("mode") or wo.get("mode") or rd.get("mode") or "—"
120
+ total = wi.get("total") or wo.get("total") or rd.get("total") or 0
121
+ dry = mode != "live"
103
122
  lines = [
104
123
  "## Headline",
105
124
  "",
106
- "> **Track A confirms surface availability** a precondition, not an impact metric. "
107
- "For the impact view (cost-ladder + behaviour with vs. without), see "
108
- "[`docs/value.md`](value.md).",
125
+ "> **Lift of agent-config on the host model NOT a model-vs-model benchmark.** "
126
+ "This measures what the package + the RDP reasoning lift do to a *fixed* host "
127
+ "model on a neutral fixture; it is not comparable to public SWE-bench / "
128
+ "Fable-5 model scores (different question entirely).",
129
+ "",
130
+ ]
131
+ if dry:
132
+ lines += [
133
+ "> ⚠️ **DRY RUN — no model calls were made; every cell is 0/N by construction.** "
134
+ "This shows the *shape* the real numbers will fill. Run `task bench:ab:live` "
135
+ "(billable) for actual results.",
136
+ "",
137
+ ]
138
+ err_bits = []
139
+ for name, res in (("without", wo), ("with", wi), ("with-rdp", rd)):
140
+ e = res.get("errored") or 0
141
+ if e:
142
+ err_bits.append(f"{name}: {e}/{res.get('total', 0)}")
143
+ lines += [
144
+ f"> ⚠️ **Low statistical power: corpus N={total} (< 40).** Directional only; "
145
+ "per-cell N is shown below. The `long × mechanical` cell is intentionally "
146
+ "empty (documented hole, not an error).",
147
+ "",
148
+ ]
149
+ if err_bits:
150
+ lines += [
151
+ "> ⚠️ **Some tasks errored (rate-limit / budget-cap / timeout) and are "
152
+ "excluded from the hit-rate** — they are NOT content failures. Errored "
153
+ f"counts — {'; '.join(err_bits)}. Hit-rate is computed over completed tasks only.",
154
+ "",
155
+ ]
156
+ lines += [
157
+ "_Host model + inference config (temp / top-p / max-tokens) are recorded in "
158
+ "Methodology and must be cited with any quoted number._",
159
+ "",
160
+ "### Table 1 — Package value (without → with)",
161
+ "",
162
+ "| Metric | without | with | delta |",
163
+ "|---|---|---|---|",
164
+ f"| Success / hit-rate | {fmt_pct(wo.get('completion_rate'))} | {fmt_pct(wi.get('completion_rate'))} | {_delta_pct(wi.get('completion_rate'), wo.get('completion_rate'))} |",
165
+ f"| Mean wall-time | {fmt_num(wo.get('mean_wall_time'))}s | {fmt_num(wi.get('mean_wall_time'))}s | {fmt_num((wi.get('mean_wall_time') or 0) - (wo.get('mean_wall_time') or 0))}s |",
166
+ f"| Ask-vs-act ratio | {fmt_num(wo.get('ask_vs_act_ratio'), 3)} | {fmt_num(wi.get('ask_vs_act_ratio'), 3)} | {_delta_num(wi.get('ask_vs_act_ratio'), wo.get('ask_vs_act_ratio'))} |",
167
+ f"| Total tokens | {fmt_int(wo.get('total_tokens'))} | {fmt_int(wi.get('total_tokens'))} | {fmt_int((wi.get('total_tokens') or 0) - (wo.get('total_tokens') or 0))} |",
168
+ "",
169
+ "### Table 2 — RDP reasoning lift (with → with-rdp)",
109
170
  "",
110
- "| Metric | with | without | delta |",
171
+ "| Metric | with | with-rdp | delta |",
111
172
  "|---|---|---|---|",
112
- f"| Track A surface-availability | {fmt_pct(a_with_acc)} | {fmt_pct(a_wo_acc)} | "
113
- f"{fmt_pct((a_with_acc or 0) - (a_wo_acc or 0))} _(structural — files present)_ |",
114
- f"| Track B completion-rate | {fmt_pct(b_with_comp)} | {fmt_pct(b_wo_comp)} | "
115
- f"{fmt_pct((b_with_comp or 0) - (b_wo_comp or 0))} |",
116
- f"| Track B mean wall-time | {fmt_num(b_results.get('mean_wall_time'))}s "
117
- f"| {fmt_num(b_without.get('mean_wall_time'))}s | "
118
- f"{fmt_num((b_results.get('mean_wall_time') or 0) - (b_without.get('mean_wall_time') or 0))}s |",
119
- f"| Track B ask-vs-act ratio | {fmt_num(b_results.get('ask_vs_act_ratio'), 3)} "
120
- f"| {fmt_num(b_without.get('ask_vs_act_ratio'), 3)} | — |",
173
+ f"| Success / hit-rate | {fmt_pct(wi.get('completion_rate'))} | {fmt_pct(rd.get('completion_rate'))} | {_delta_pct(rd.get('completion_rate'), wi.get('completion_rate'))} |",
174
+ f"| Mean wall-time | {fmt_num(wi.get('mean_wall_time'))}s | {fmt_num(rd.get('mean_wall_time'))}s | {fmt_num((rd.get('mean_wall_time') or 0) - (wi.get('mean_wall_time') or 0))}s |",
175
+ f"| Ask-vs-act ratio | {fmt_num(wi.get('ask_vs_act_ratio'), 3)} | {fmt_num(rd.get('ask_vs_act_ratio'), 3)} | {_delta_num(rd.get('ask_vs_act_ratio'), wi.get('ask_vs_act_ratio'))} |",
176
+ f"| Total tokens | {fmt_int(wi.get('total_tokens'))} | {fmt_int(rd.get('total_tokens'))} | {fmt_int((rd.get('total_tokens') or 0) - (wi.get('total_tokens') or 0))} |",
121
177
  "",
122
178
  ]
123
179
  return "\n".join(lines)
@@ -153,37 +209,68 @@ def render_track_a(track_a: dict) -> str:
153
209
  return "\n".join(lines)
154
210
 
155
211
 
156
- def render_track_b(track_b: dict) -> str:
212
+ def render_track_b(track_b: dict, track_b_rdp: dict) -> str:
157
213
  lines = ["## Track B — Task completion", ""]
158
- with_data = (track_b.get("with") or {}).get("results", {})
159
- without_data = (track_b.get("without") or {}).get("results", {})
160
- mode = with_data.get("mode") or without_data.get("mode") or "—"
214
+ wo = (track_b.get("without") or {}).get("results", {})
215
+ wi = (track_b.get("with") or {}).get("results", {})
216
+ rd = (track_b_rdp or {}).get("results", {})
217
+ mode = wi.get("mode") or wo.get("mode") or rd.get("mode") or "—"
161
218
  lines.append(f"- Mode: `{mode}`")
162
- if not with_data and not without_data:
163
- lines.append("")
164
- lines.append("_No Track B reports yet. Run `task bench:ab:track-b`._")
165
- lines.append("")
219
+ if not (wo or wi or rd):
220
+ lines += ["", "_No Track B reports yet. Run `task bench:ab:track-b`._", ""]
166
221
  return "\n".join(lines)
167
- lines.extend(
168
- [
169
- f"- with → **{fmt_pct(with_data.get('completion_rate'))}** "
170
- f"({with_data.get('passed', 0)}/{with_data.get('total', 0)})",
171
- f"- without → **{fmt_pct(without_data.get('completion_rate'))}** "
172
- f"({without_data.get('passed', 0)}/{without_data.get('total', 0)})",
173
- "",
174
- "Per-category:",
175
- "",
176
- "| Category | with | without | delta |",
177
- "|---|---|---|---|",
178
- ]
179
- )
180
- with_cats = with_data.get("per_category", {})
181
- without_cats = without_data.get("per_category", {})
182
- for cat in sorted(set(with_cats) | set(without_cats)):
183
- w = with_cats.get(cat, {}).get("completion_rate") or 0
184
- wo = without_cats.get(cat, {}).get("completion_rate") or 0
222
+ lines += [
223
+ f"- without → **{fmt_pct(wo.get('completion_rate'))}** ({wo.get('passed', 0)}/{wo.get('total', 0)})",
224
+ f"- with → **{fmt_pct(wi.get('completion_rate'))}** ({wi.get('passed', 0)}/{wi.get('total', 0)})",
225
+ f"- with-rdp → **{fmt_pct(rd.get('completion_rate'))}** ({rd.get('passed', 0)}/{rd.get('total', 0)})",
226
+ "",
227
+ "### Per 2×2 cell (success-rate per condition; per-cell N in parens)",
228
+ "",
229
+ "| Cell (duration × cognitive) | N | without | with | with-rdp |",
230
+ "|---|---|---|---|---|",
231
+ ]
232
+ wo_c, wi_c, rd_c = wo.get("per_cell", {}), wi.get("per_cell", {}), rd.get("per_cell", {})
233
+ cells = sorted(set(wo_c) | set(wi_c) | set(rd_c)) or [
234
+ "short/reasoning-heavy", "short/mechanical",
235
+ "long/reasoning-heavy", "long/mechanical",
236
+ ]
237
+ for cell in cells:
238
+ n = (wi_c.get(cell) or wo_c.get(cell) or rd_c.get(cell) or {}).get("total", 0)
239
+ lines.append(
240
+ f"| {cell} | {n} | {fmt_pct(wo_c.get(cell, {}).get('completion_rate'))} "
241
+ f"| {fmt_pct(wi_c.get(cell, {}).get('completion_rate'))} "
242
+ f"| {fmt_pct(rd_c.get(cell, {}).get('completion_rate'))} |"
243
+ )
244
+ lines += [
245
+ "",
246
+ "### Per 2×2 cell — mean tokens per condition",
247
+ "",
248
+ "| Cell (duration × cognitive) | without | with | with-rdp |",
249
+ "|---|---|---|---|",
250
+ ]
251
+ for cell in cells:
252
+ lines.append(
253
+ f"| {cell} | {fmt_int(wo_c.get(cell, {}).get('mean_tokens'))} "
254
+ f"| {fmt_int(wi_c.get(cell, {}).get('mean_tokens'))} "
255
+ f"| {fmt_int(rd_c.get(cell, {}).get('mean_tokens'))} |"
256
+ )
257
+ lines += [
258
+ "",
259
+ "_`short × mechanical` mean-tokens across conditions answers \"are short "
260
+ "tasks more expensive?\"; `long × reasoning-heavy` answers \"do long tasks "
261
+ "get cheaper / better?\"._",
262
+ "",
263
+ "### Per category",
264
+ "",
265
+ "| Category | without | with | with-rdp |",
266
+ "|---|---|---|---|",
267
+ ]
268
+ wo_cat, wi_cat, rd_cat = wo.get("per_category", {}), wi.get("per_category", {}), rd.get("per_category", {})
269
+ for cat in sorted(set(wo_cat) | set(wi_cat) | set(rd_cat)):
185
270
  lines.append(
186
- f"| {cat} | {fmt_pct(w)} | {fmt_pct(wo)} | {fmt_pct(w - wo)} |"
271
+ f"| {cat} | {fmt_pct(wo_cat.get(cat, {}).get('completion_rate'))} "
272
+ f"| {fmt_pct(wi_cat.get(cat, {}).get('completion_rate'))} "
273
+ f"| {fmt_pct(rd_cat.get(cat, {}).get('completion_rate'))} |"
187
274
  )
188
275
  lines.append("")
189
276
  return "\n".join(lines)
@@ -265,8 +352,10 @@ def render(quiet: bool = False) -> int:
265
352
  b_with, b_without = latest_pair("ab-trackb")
266
353
  track_a = {"with": safe_load(a_with), "without": safe_load(a_without)}
267
354
  track_b = {"with": safe_load(b_with), "without": safe_load(b_without)}
355
+ track_b_rdp = latest_trackb_with_rdp()
268
356
  have_data = bool(
269
- track_a["with"] or track_a["without"] or track_b["with"] or track_b["without"]
357
+ track_a["with"] or track_a["without"]
358
+ or track_b["with"] or track_b["without"] or track_b_rdp
270
359
  )
271
360
  if not have_data:
272
361
  OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
@@ -282,9 +371,9 @@ def render(quiet: bool = False) -> int:
282
371
  "> Generated by `scripts/render_benchmark_md.py`. Source of truth: "
283
372
  "`internal/bench/reports/ab/`. Re-render anytime with `task bench:ab:diff`.",
284
373
  "",
285
- render_headline(track_a, track_b),
374
+ render_headline(track_a, track_b, track_b_rdp),
286
375
  render_track_a(track_a),
287
- render_track_b(track_b),
376
+ render_track_b(track_b, track_b_rdp),
288
377
  render_methodology(track_a, track_b),
289
378
  render_history(),
290
379
  ]
@@ -16,7 +16,12 @@
16
16
  "tier": {
17
17
  "type": "integer",
18
18
  "enum": [0, 1, 2],
19
- "description": "Command-surface tier per docs/contracts/command-surface-tiers.md. 0 = daily-driver (rendered in default `./agent-config --help`), 1 = power-user (rendered with `--tier=1`), 2 = maintenance/internal (rendered only with `--tier=all`). Default for new commands is 2 — promotion is gated by ADR criteria, never by author preference."
19
+ "description": "Command-surface tier per docs/contracts/command-surface-tiers.md. 0 = daily-driver (rendered in default `./agent-config --help`), 1 = power-user (rendered with `--tier=1`), 2 = maintenance/internal (rendered only with `--tier=all`). Default for new commands is 2 — promotion is gated by ADR criteria, never by author preference. BACK-COMPAT ALIAS since ADR-090: `visibility:` is the named source of truth (visible↔0, advanced↔1, internal↔2); `tier:` is retained as a derived integer alias and dual-emitted in the discovery manifest during the deprecation window. When both are present they MUST agree (enforced by lint_command_tiers.py)."
20
+ },
21
+ "visibility": {
22
+ "type": "string",
23
+ "enum": ["visible", "advanced", "internal"],
24
+ "description": "Command-surface visibility (ADR-090) — the NAMED source of truth that supersedes the integer `tier:` proxy. `visible` = daily-driver (default `./agent-config --help`, ↔ tier 0), `advanced` = power-user (`--tier=1`, ↔ tier 1), `internal` = maintenance/hidden (`--tier=all` only, ↔ tier 2). Read by the surface classifier (commands ls/explain), the per-pack visible-command budget audit, and the discovery-manifest builder, each preferring `visibility:` and falling back to `tier:`. Default for new commands is `internal`; promotion is gated by ADR criteria per docs/contracts/command-surface-tiers.md."
20
25
  },
21
26
  "description": {
22
27
  "type": "string",
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env python3
2
+ """P3.1 — consumer-facing agent-config security audit (road-to-security-pillar.md).
3
+
4
+ Points the Phase-1 detection logic at a *consumer's assembled* agent config —
5
+ instruction files (CLAUDE.md, AGENTS.md, .cursor/rules, copilot-instructions),
6
+ MCP configs (.mcp.json, .cursor/mcp.json, claude_desktop_config.json), settings
7
+ + hooks (.claude/settings.json), and installed skills — and emits an A–F score
8
+ with a per-category breakdown mapped to the OWASP Top 10 for Agentic
9
+ Applications (ASI).
10
+
11
+ Detection is the same library as the self-audit gate (so there is one source of
12
+ truth for the patterns) under the same false-positive containment convention.
13
+ This is decision-support, not a guarantee: detection is probabilistic.
14
+
15
+ Usage:
16
+ python3 src/scripts/security_audit_config.py [--root DIR] [--json]
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import argparse
21
+ import sys
22
+ from pathlib import Path
23
+
24
+ HERE = Path(__file__).resolve().parent
25
+ sys.path.insert(0, str(HERE))
26
+ from _lib import security_lint as sl # noqa: E402
27
+ import lint_hidden_unicode as p11 # noqa: E402
28
+ import lint_instruction_smuggling as p12 # noqa: E402
29
+ import lint_mcp_config_security as p13 # noqa: E402
30
+ import lint_skill_frontmatter_safety as p14 # noqa: E402
31
+
32
+ # Consumer config surfaces (globs relative to --root).
33
+ SURFACES = [
34
+ "CLAUDE.md", "AGENTS.md", "GEMINI.md", ".clinerules", ".windsurfrules",
35
+ ".github/copilot-instructions.md",
36
+ ".cursor/rules/**/*", ".cursorrules",
37
+ ".claude/skills/**/SKILL.md", ".claude/commands/**/*.md",
38
+ ".claude/settings.json", ".claude/settings.local.json",
39
+ ".mcp.json", ".cursor/mcp.json", "claude_desktop_config.json",
40
+ ]
41
+
42
+ # check id → (category, OWASP-ASI tag)
43
+ CATEGORY = {
44
+ "hidden-unicode": ("Agents/Rules", "ASI01 Goal Hijack"),
45
+ "instruction-smuggling": ("Agents/Rules", "ASI01 Goal Hijack"),
46
+ "mcp-config-security": ("MCP", "ASI04 Supply Chain"),
47
+ "dangerous-frontmatter": ("Permissions", "ASI03 Privilege Abuse"),
48
+ }
49
+ SECRET_HINT = "secret" # mcp finding mentioning a secret → Secrets category
50
+ CATEGORIES = ["Secrets", "Permissions", "Hooks", "MCP", "Agents/Rules"]
51
+
52
+ # Deduction per finding (full weight); weighted findings scale by their weight.
53
+ _DEDUCT = {"HIGH": 25.0, "MED": 5.0, "LOW": 2.0}
54
+
55
+
56
+ def _grade(score: float) -> str:
57
+ return ("A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70
58
+ else "D" if score >= 60 else "F")
59
+
60
+
61
+ def _category(f) -> str:
62
+ if f.check == "mcp-config-security" and SECRET_HINT in f.message.lower():
63
+ return "Secrets"
64
+ return CATEGORY.get(f.check, ("Agents/Rules", ""))[0]
65
+
66
+
67
+ def _iter_targets(root: Path):
68
+ seen = set()
69
+ for pattern in SURFACES:
70
+ for p in root.glob(pattern):
71
+ if p.is_file() and p not in seen:
72
+ seen.add(p)
73
+ yield p
74
+
75
+
76
+ def audit(root: Path) -> dict:
77
+ findings = []
78
+ for p in _iter_targets(root):
79
+ try:
80
+ sf = sl.scan_path(p, root)
81
+ except (UnicodeDecodeError, OSError):
82
+ continue
83
+ for mod in (p11, p12, p13, p14):
84
+ try:
85
+ findings.extend(mod._scan(sf))
86
+ except Exception:
87
+ pass
88
+
89
+ per_cat = {c: 100.0 for c in CATEGORIES}
90
+ cat_findings = {c: [] for c in CATEGORIES}
91
+ for f in findings:
92
+ cat = _category(f)
93
+ per_cat[cat] -= _DEDUCT.get(f.severity, 2.0) * float(f.weight)
94
+ cat_findings[cat].append(f)
95
+ for c in per_cat:
96
+ per_cat[c] = max(0.0, per_cat[c])
97
+
98
+ overall = round(sum(per_cat.values()) / len(CATEGORIES), 1)
99
+ return {
100
+ "root": str(root),
101
+ "overall_score": overall,
102
+ "overall_grade": _grade(overall),
103
+ "categories": {
104
+ c: {
105
+ "score": round(per_cat[c], 1),
106
+ "grade": _grade(per_cat[c]),
107
+ "owasp": next((CATEGORY[fl.check][1] for fl in cat_findings[c]
108
+ if fl.check in CATEGORY), ""),
109
+ "findings": [
110
+ {"path": fl.path, "line": fl.line, "check": fl.check,
111
+ "severity": fl.severity, "message": fl.message,
112
+ "weight": fl.weight}
113
+ for fl in cat_findings[c]
114
+ ],
115
+ }
116
+ for c in CATEGORIES
117
+ },
118
+ }
119
+
120
+
121
+ def _print(report: dict) -> None:
122
+ print(f"Agent-config security audit — {report['root']}")
123
+ print(f"Overall: {report['overall_grade']} ({report['overall_score']}/100)\n")
124
+ for c in CATEGORIES:
125
+ cat = report["categories"][c]
126
+ tag = f" · {cat['owasp']}" if cat["owasp"] else ""
127
+ print(f" {cat['grade']} {c:<12} {cat['score']:>5}/100{tag}")
128
+ for f in cat["findings"]:
129
+ loc = f"{f['path']}:{f['line']}" if f["line"] else f["path"]
130
+ w = "" if f["weight"] >= 1.0 else f" (weight {f['weight']:g})"
131
+ print(f" [{f['severity']}] {loc}{w}: {f['message']}")
132
+ print("\n> Decision support, not a guarantee — detection is probabilistic. "
133
+ "Pair with /threat-model and judge-security-auditor for a deep pass.")
134
+
135
+
136
+ def main() -> int:
137
+ ap = argparse.ArgumentParser(description=__doc__, epilog=sl.GUIDELINE_EPILOG)
138
+ ap.add_argument("--root", default=".", help="consumer repo root to audit (default: cwd)")
139
+ ap.add_argument("--json", action="store_true")
140
+ args = ap.parse_args()
141
+
142
+ report = audit(Path(args.root))
143
+ if args.json:
144
+ import json
145
+ print(json.dumps(report, indent=2))
146
+ else:
147
+ _print(report)
148
+ # Audit is advisory: always exit 0 (it informs, it does not gate the consumer).
149
+ return 0
150
+
151
+
152
+ if __name__ == "__main__":
153
+ raise SystemExit(main())
@@ -1,184 +0,0 @@
1
- ---
2
- model_tier: medium
3
- name: chat-history-learn
4
- pack: meta
5
- tier: 2
6
- cluster: chat-history
7
- sub: learn
8
- skills: [learning-to-rule-or-skill]
9
- description: Pick a prior chat-history session and mine it for project-improving learnings — runs learning-to-rule-or-skill on the picked session, drafts proposal(s) under agents/proposals/
10
- suggestion:
11
- eligible: true
12
- trigger_description: "extract a learning from a past session, mine chat-history for proposals, what did we learn last session, codify a pattern from a prior session"
13
- trigger_context: "user wants to derive a rule/skill/guideline proposal from the content of one prior session"
14
- workspaces:
15
- - agent-config-maintainer
16
- packs:
17
- - meta
18
- ---
19
- <!-- cloud_safe: noop -->
20
-
21
- # /chat-history learn
22
-
23
- User-driven **learning extraction** from a prior session. Surfaces
24
- prior sessions logged in `agents/runtime/.agent-chat-history` as numbered options,
25
- the user picks **one**, the agent reads that session's entries and
26
- runs the [`learning-to-rule-or-skill`](../../skills/learning-to-rule-or-skill/SKILL.md)
27
- workflow on the content — surfacing repeated mistakes, successful
28
- patterns, or constraints worth codifying as a rule, skill, or
29
- guideline proposal.
30
-
31
- This is the **project-improvement** counterpart to
32
- [`/chat-history import`](import.md): `import` renders a session
33
- verbatim into the current chat for the user to act on; `learn`
34
- mines a session for proposals that improve the agent or the
35
- project itself.
36
-
37
- ## When NOT to use
38
-
39
- - Pull a prior session into the current chat verbatim — use
40
- [`/chat-history import`](import.md).
41
- - Capture a learning that originated **in the current** session —
42
- invoke the [`learning-to-rule-or-skill`](../../skills/learning-to-rule-or-skill/SKILL.md)
43
- skill directly. `learn` is for prior-session mining only.
44
- - Bulk-mine all sessions — out of scope for v1. One session per
45
- invocation; multi-pick is v2.
46
-
47
- ## Steps
48
-
49
- ### 1. Check if enabled
50
-
51
- Read `chat_history.enabled` from `.agent-settings.yml`. If `false`
52
- or the section is missing, say so and stop:
53
-
54
- ```
55
- > 📒 chat-history is disabled (chat_history.enabled = false).
56
- > Set it to true in .agent-settings.yml to start logging.
57
- ```
58
-
59
- ### 2. List sessions
60
-
61
- Run `scripts/chat_history.py sessions --json --limit 20 --summary`.
62
- The helper returns an array of
63
- `{id, count, first_ts, last_ts, preview, summary}` sorted by
64
- `last_ts` desc. The `summary` field is built inside the helper
65
- from ≤10 sampled entries per session (5 oldest + 5 newest) —
66
- token-cheap, no full-body read needed for the picker. Empty
67
- buckets are excluded by default.
68
-
69
- If the array is empty, stop:
70
-
71
- ```
72
- > 📒 No prior sessions found in agents/runtime/.agent-chat-history.
73
- ```
74
-
75
- ### 3. Surface as numbered options
76
-
77
- Render each session as a numbered option (per the `user-interaction`
78
- rule — Iron Law: numbered options for any picker). Lead with the
79
- helper's `summary` field — the rough arc the user picks by
80
- (`<first user msg> → <last user msg>`, or
81
- `(N entries — no user prompts; t-mix: …)` for tool-only sessions).
82
- Keep the session `id` **internal** for step 5's `read --session <id>`
83
- call; never render it in the listing. Format:
84
-
85
- ```
86
- > Pick a session to mine for learnings:
87
- >
88
- > 1. {summary}
89
- > {YYYY-MM-DD HH:MM} · {count} entries
90
- > 2. ...
91
- > ...
92
- > N. abort — do not extract any learning
93
- ```
94
-
95
- Format the timestamp as `YYYY-MM-DD HH:MM` (drop seconds + timezone
96
- — orientation, not forensics). Do not truncate or rewrite `summary`
97
- — the helper already shapes it. Always include an explicit abort
98
- option last. Track option-number → `id` internally so step 5 calls
99
- `scripts/chat_history.py read --session <id>` with the right id.
100
-
101
- ### 4. Wait for the pick
102
-
103
- **One question per turn** (per `ask-when-uncertain`). Do not chain
104
- the listing with anything else; do not auto-pick; do not surface a
105
- default. Wait for the user's response.
106
-
107
- If the user picks the abort option, stop without reading.
108
-
109
- ### 5. Read the picked session
110
-
111
- Run `scripts/chat_history.py read --session <id>` with the picked
112
- `id`. Hold the entries in working memory — do **not** render them
113
- verbatim into the chat. The verbatim path is `import`'s job; here
114
- the entries are input to step 6.
115
-
116
- ### 6. Run `learning-to-rule-or-skill`
117
-
118
- Apply the [`learning-to-rule-or-skill`](../../skills/learning-to-rule-or-skill/SKILL.md)
119
- procedure on the session content:
120
-
121
- 1. **Scan** the entries for candidate learnings — repeated
122
- mistakes, successful patterns, friction points, or constraints
123
- stated by the user.
124
- 2. **Pass each candidate through the Promotion Gate** (§ 0 of the
125
- skill): repetition, impact, failure pattern, non-duplication,
126
- scope fit, minimal. Drop candidates that fail any gate.
127
- 3. **For each surviving candidate**, run § 4 (search protocol — all
128
- four steps), then decide rule / skill / guideline / update / no
129
- action per § 3 of the skill.
130
- 4. **Draft a proposal** for every candidate that warrants one,
131
- following § 8 of the skill (proposal template under
132
- `agents/proposals/<id>.md`).
133
-
134
- If multiple candidates survive, draft them as **separate**
135
- proposals — do not merge unrelated learnings into one.
136
-
137
- ### 7. Surface the result
138
-
139
- Hand back to the user with a structured summary per surviving
140
- candidate:
141
-
142
- ```
143
- > 📒 Mined session {id} — {N} candidate(s) surfaced
144
-
145
- > 1. {learning title}
146
- > Decision: {rule|skill|guideline|update|no action}
147
- > Proposal: agents/proposals/{proposal_id}.md
148
- > Gate: {pass|fail — reason}
149
- > 2. ...
150
- ```
151
-
152
- If no candidate cleared the Promotion Gate, say so explicitly:
153
-
154
- ```
155
- > 📒 Mined session {id} — no candidate cleared the Promotion Gate.
156
- ```
157
-
158
- Do **not** open a PR, do **not** commit the proposals — proposal
159
- files land in `agents/proposals/` (gitignored or curated per
160
- project policy) for the user to review and route via
161
- `upstream-contribute` or merge into `agents/overrides/`.
162
-
163
- ## Gotchas
164
-
165
- - **Promotion Gate is hard.** A grep miss is not proof of
166
- non-duplication — § 4 of the skill mandates the four-step search
167
- protocol. Do not skip it.
168
- - **One pick per invocation.** Multi-pick is v2. If the user wants
169
- to mine a second session, run `/chat-history learn` again.
170
- - **Read-only on the log.** This command never writes to
171
- `agents/runtime/.agent-chat-history`. It writes proposal drafts under
172
- `agents/proposals/` only.
173
- - **No auto-promotion.** Drafted proposals stay in `proposals/`
174
- until the user routes them. `learn` never invokes
175
- `upstream-contribute` itself.
176
-
177
- ## See also
178
-
179
- - [`/chat-history import`](import.md) — verbatim render of a prior session
180
- - [`learning-to-rule-or-skill`](../../skills/learning-to-rule-or-skill/SKILL.md) — the workflow this command orchestrates
181
- - [`upstream-contribute`](../../skills/upstream-contribute/SKILL.md) — promote a project-scoped proposal upstream
182
- - [`scripts/chat_history.py`](../../../scripts/chat_history.py) — `sessions` and `read --session` CLI surface
183
- - [`user-interaction`](../../rules/user-interaction.md) — numbered-options Iron Law
184
- - [`ask-when-uncertain`](../../rules/ask-when-uncertain.md) — one-question-per-turn Iron Law