@event4u/agent-config 1.15.0 → 1.17.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 (354) hide show
  1. package/.agent-src/commands/{agents-audit.md → agents/audit.md} +4 -3
  2. package/.agent-src/commands/{agents-cleanup.md → agents/cleanup.md} +12 -6
  3. package/.agent-src/commands/{agents-prepare.md → agents/prepare.md} +4 -3
  4. package/.agent-src/commands/agents.md +46 -0
  5. package/.agent-src/commands/bug-fix.md +1 -1
  6. package/.agent-src/commands/bug-investigate.md +2 -2
  7. package/.agent-src/commands/{chat-history-checkpoint.md → chat-history/checkpoint.md} +5 -5
  8. package/.agent-src/commands/{chat-history-clear.md → chat-history/clear.md} +5 -5
  9. package/.agent-src/commands/{chat-history-resume.md → chat-history/resume.md} +4 -4
  10. package/.agent-src/commands/chat-history/show.md +107 -0
  11. package/.agent-src/commands/chat-history.md +33 -89
  12. package/.agent-src/commands/check-current-md.md +1 -1
  13. package/.agent-src/commands/{commit-in-chunks.md → commit/in-chunks.md} +15 -13
  14. package/.agent-src/commands/commit.md +22 -2
  15. package/.agent-src/commands/{context-create.md → context/create.md} +4 -3
  16. package/.agent-src/commands/{context-refactor.md → context/refactor.md} +4 -3
  17. package/.agent-src/commands/context.md +44 -0
  18. package/.agent-src/commands/{copilot-agents-init.md → copilot-agents/init.md} +4 -3
  19. package/.agent-src/commands/{copilot-agents-optimize.md → copilot-agents/optimize.md} +4 -3
  20. package/.agent-src/commands/copilot-agents.md +44 -0
  21. package/.agent-src/commands/council/default.md +221 -0
  22. package/.agent-src/commands/council/design.md +97 -0
  23. package/.agent-src/commands/council/optimize.md +116 -0
  24. package/.agent-src/commands/council/pr.md +124 -0
  25. package/.agent-src/commands/council.md +54 -0
  26. package/.agent-src/commands/{create-pr-description.md → create-pr/description-only.md} +4 -2
  27. package/.agent-src/commands/create-pr.md +49 -5
  28. package/.agent-src/commands/e2e-heal.md +1 -1
  29. package/.agent-src/commands/e2e-plan.md +1 -1
  30. package/.agent-src/commands/{feature-dev.md → feature/dev.md} +6 -3
  31. package/.agent-src/commands/{feature-explore.md → feature/explore.md} +5 -4
  32. package/.agent-src/commands/{feature-plan.md → feature/plan.md} +32 -5
  33. package/.agent-src/commands/{feature-refactor.md → feature/refactor.md} +4 -3
  34. package/.agent-src/commands/{feature-roadmap.md → feature/roadmap.md} +7 -6
  35. package/.agent-src/commands/feature.md +52 -0
  36. package/.agent-src/commands/{fix-ci.md → fix/ci.md} +4 -3
  37. package/.agent-src/commands/{fix-portability.md → fix/portability.md} +4 -3
  38. package/.agent-src/commands/{fix-pr-bot-comments.md → fix/pr-bots.md} +4 -3
  39. package/.agent-src/commands/{fix-pr-developer-comments.md → fix/pr-developers.md} +4 -3
  40. package/.agent-src/commands/{fix-pr-comments.md → fix/pr.md} +7 -6
  41. package/.agent-src/commands/{fix-references.md → fix/refs.md} +4 -3
  42. package/.agent-src/commands/{fix-seeder.md → fix/seeder.md} +4 -3
  43. package/.agent-src/commands/fix.md +54 -0
  44. package/.agent-src/commands/jira-ticket.md +1 -1
  45. package/.agent-src/commands/{do-and-judge.md → judge/on-diff.md} +7 -6
  46. package/.agent-src/commands/judge/solo.md +90 -0
  47. package/.agent-src/commands/{do-in-steps.md → judge/steps.md} +8 -7
  48. package/.agent-src/commands/judge.md +35 -70
  49. package/.agent-src/commands/{memory-add.md → memory/add.md} +7 -6
  50. package/.agent-src/commands/{memory-full.md → memory/load.md} +6 -5
  51. package/.agent-src/commands/{memory-promote.md → memory/promote.md} +6 -5
  52. package/.agent-src/commands/{propose-memory.md → memory/propose.md} +6 -5
  53. package/.agent-src/commands/memory.md +48 -0
  54. package/.agent-src/commands/mode.md +5 -5
  55. package/.agent-src/commands/{module-create.md → module/create.md} +4 -3
  56. package/.agent-src/commands/{module-explore.md → module/explore.md} +4 -3
  57. package/.agent-src/commands/module.md +44 -0
  58. package/.agent-src/commands/onboard.md +3 -3
  59. package/.agent-src/commands/{optimize-agents.md → optimize/agents.md} +5 -4
  60. package/.agent-src/commands/{optimize-augmentignore.md → optimize/augmentignore.md} +4 -4
  61. package/.agent-src/commands/{optimize-rtk-filters.md → optimize/rtk.md} +4 -3
  62. package/.agent-src/commands/{optimize-skills.md → optimize/skills.md} +5 -4
  63. package/.agent-src/commands/optimize.md +48 -0
  64. package/.agent-src/commands/{override-create.md → override/create.md} +4 -3
  65. package/.agent-src/commands/{override-manage.md → override/manage.md} +4 -3
  66. package/.agent-src/commands/override.md +44 -0
  67. package/.agent-src/commands/review-changes.md +26 -1
  68. package/.agent-src/commands/review-routing.md +1 -1
  69. package/.agent-src/commands/{roadmap-create.md → roadmap/create.md} +33 -5
  70. package/.agent-src/commands/{roadmap-execute.md → roadmap/execute.md} +4 -3
  71. package/.agent-src/commands/roadmap.md +44 -0
  72. package/.agent-src/commands/set-cost-profile.md +3 -3
  73. package/.agent-src/commands/sync-agent-settings.md +2 -2
  74. package/.agent-src/commands/{tests-create.md → tests/create.md} +5 -4
  75. package/.agent-src/commands/{tests-execute.md → tests/execute.md} +4 -3
  76. package/.agent-src/commands/tests.md +44 -0
  77. package/.agent-src/commands/upstream-contribute.md +1 -1
  78. package/.agent-src/contexts/authority/commit-mechanics.md +57 -0
  79. package/.agent-src/contexts/authority/destructive-mechanics.md +66 -0
  80. package/.agent-src/contexts/authority/scope-mechanics.md +87 -0
  81. package/.agent-src/contexts/communication/rules-auto/artifact-engagement-recording-mechanics.md +72 -0
  82. package/.agent-src/contexts/communication/rules-auto/augment-portability-mechanics.md +79 -0
  83. package/.agent-src/contexts/communication/rules-auto/augment-source-of-truth-mechanics.md +98 -0
  84. package/.agent-src/contexts/communication/rules-auto/cli-output-handling-mechanics.md +87 -0
  85. package/.agent-src/contexts/communication/rules-auto/command-suggestion-policy-mechanics.md +62 -0
  86. package/.agent-src/contexts/communication/rules-auto/docs-sync-mechanics.md +78 -0
  87. package/.agent-src/contexts/communication/rules-auto/package-ci-checks-mechanics.md +85 -0
  88. package/.agent-src/contexts/communication/rules-auto/review-routing-awareness-mechanics.md +65 -0
  89. package/.agent-src/contexts/communication/rules-auto/roadmap-progress-sync-mechanics.md +78 -0
  90. package/.agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +62 -0
  91. package/.agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +55 -0
  92. package/.agent-src/contexts/communication/rules-auto/ui-audit-gate-mechanics.md +53 -0
  93. package/.agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +77 -0
  94. package/.agent-src/contexts/execution/autonomy-detection.md +54 -0
  95. package/.agent-src/contexts/execution/autonomy-examples.md +90 -0
  96. package/.agent-src/contexts/execution/autonomy-mechanics.md +29 -0
  97. package/.agent-src/contexts/execution/verification-mechanics.md +80 -0
  98. package/.agent-src/contexts/judges/no-consolidate-rationale.md +102 -0
  99. package/.agent-src/contexts/judges/persona-voice-rubric.md +140 -0
  100. package/.agent-src/personas/README.md +1 -1
  101. package/.agent-src/rules/agent-authority.md +24 -0
  102. package/.agent-src/rules/architecture.md +1 -1
  103. package/.agent-src/rules/artifact-drafting-protocol.md +1 -1
  104. package/.agent-src/rules/artifact-engagement-recording.md +14 -70
  105. package/.agent-src/rules/ask-when-uncertain.md +28 -43
  106. package/.agent-src/rules/augment-portability.md +15 -61
  107. package/.agent-src/rules/augment-source-of-truth.md +27 -93
  108. package/.agent-src/rules/autonomous-execution.md +78 -114
  109. package/.agent-src/rules/capture-learnings.md +1 -1
  110. package/.agent-src/rules/chat-history-cadence.md +3 -3
  111. package/.agent-src/rules/chat-history-ownership.md +3 -3
  112. package/.agent-src/rules/chat-history-visibility.md +3 -3
  113. package/.agent-src/rules/cli-output-handling.md +10 -76
  114. package/.agent-src/rules/command-suggestion-policy.md +93 -0
  115. package/.agent-src/rules/commit-conventions.md +17 -14
  116. package/.agent-src/rules/commit-policy.md +14 -42
  117. package/.agent-src/rules/context-hygiene.md +3 -3
  118. package/.agent-src/rules/direct-answers.md +34 -49
  119. package/.agent-src/rules/docker-commands.md +5 -5
  120. package/.agent-src/rules/docs-sync.md +16 -70
  121. package/.agent-src/rules/e2e-testing.md +1 -1
  122. package/.agent-src/rules/guidelines.md +4 -4
  123. package/.agent-src/rules/improve-before-implement.md +2 -2
  124. package/.agent-src/rules/language-and-tone.md +50 -133
  125. package/.agent-src/rules/minimal-safe-diff.md +3 -3
  126. package/.agent-src/rules/missing-tool-handling.md +28 -22
  127. package/.agent-src/rules/model-recommendation.md +4 -4
  128. package/.agent-src/rules/no-cheap-questions.md +82 -0
  129. package/.agent-src/rules/no-roadmap-references.md +73 -0
  130. package/.agent-src/rules/non-destructive-by-default.md +15 -49
  131. package/.agent-src/rules/onboarding-gate.md +5 -5
  132. package/.agent-src/rules/package-ci-checks.md +21 -61
  133. package/.agent-src/rules/preservation-guard.md +64 -29
  134. package/.agent-src/rules/review-routing-awareness.md +26 -45
  135. package/.agent-src/rules/roadmap-progress-sync.md +28 -96
  136. package/.agent-src/rules/role-mode-adherence.md +2 -2
  137. package/.agent-src/rules/scope-control.md +65 -46
  138. package/.agent-src/rules/security-sensitive-stop.md +9 -9
  139. package/.agent-src/rules/size-enforcement.md +1 -1
  140. package/.agent-src/rules/skill-quality.md +16 -48
  141. package/.agent-src/rules/{slash-commands.md → slash-command-routing-policy.md} +7 -4
  142. package/.agent-src/rules/think-before-action.md +55 -45
  143. package/.agent-src/rules/token-efficiency.md +4 -4
  144. package/.agent-src/rules/tool-safety.md +19 -16
  145. package/.agent-src/rules/{ui-audit-before-build.md → ui-audit-gate.md} +27 -41
  146. package/.agent-src/rules/user-interaction.md +16 -71
  147. package/.agent-src/rules/verify-before-complete.md +12 -67
  148. package/.agent-src/scripts/update_roadmap_progress.py +9 -4
  149. package/.agent-src/skills/ai-council/SKILL.md +335 -0
  150. package/.agent-src/skills/api-endpoint/SKILL.md +2 -2
  151. package/.agent-src/skills/api-testing/SKILL.md +1 -1
  152. package/.agent-src/skills/blade-ui/SKILL.md +1 -1
  153. package/.agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
  154. package/.agent-src/skills/bug-analyzer/SKILL.md +1 -1
  155. package/.agent-src/skills/check-refs/SKILL.md +59 -40
  156. package/.agent-src/skills/command-routing/SKILL.md +1 -1
  157. package/.agent-src/skills/command-writing/SKILL.md +1 -1
  158. package/.agent-src/skills/conventional-commits-writing/SKILL.md +86 -28
  159. package/.agent-src/skills/copilot-agents-optimization/SKILL.md +7 -7
  160. package/.agent-src/skills/developer-like-execution/SKILL.md +6 -6
  161. package/.agent-src/skills/finishing-a-development-branch/SKILL.md +101 -65
  162. package/.agent-src/skills/flux/SKILL.md +31 -11
  163. package/.agent-src/skills/git-workflow/SKILL.md +1 -1
  164. package/.agent-src/skills/github-ci/SKILL.md +2 -2
  165. package/.agent-src/skills/guideline-writing/SKILL.md +11 -11
  166. package/.agent-src/skills/judge-code-quality/SKILL.md +7 -8
  167. package/.agent-src/skills/judge-security-auditor/SKILL.md +4 -5
  168. package/.agent-src/skills/judge-test-coverage/SKILL.md +3 -4
  169. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +4 -4
  170. package/.agent-src/skills/lint-skills/SKILL.md +57 -39
  171. package/.agent-src/skills/livewire/SKILL.md +1 -1
  172. package/.agent-src/skills/md-language-check/SKILL.md +61 -39
  173. package/.agent-src/skills/override-management/SKILL.md +7 -7
  174. package/.agent-src/skills/php-coder/SKILL.md +1 -1
  175. package/.agent-src/skills/playwright-testing/SKILL.md +2 -2
  176. package/.agent-src/skills/quality-tools/SKILL.md +2 -2
  177. package/.agent-src/skills/react-shadcn-ui/SKILL.md +116 -43
  178. package/.agent-src/skills/readme-reviewer/SKILL.md +31 -30
  179. package/.agent-src/skills/readme-writing/SKILL.md +79 -54
  180. package/.agent-src/skills/readme-writing-package/SKILL.md +51 -48
  181. package/.agent-src/skills/receiving-code-review/SKILL.md +53 -48
  182. package/.agent-src/skills/refine-prompt/SKILL.md +0 -1
  183. package/.agent-src/skills/requesting-code-review/SKILL.md +35 -30
  184. package/.agent-src/skills/review-routing/SKILL.md +2 -2
  185. package/.agent-src/skills/rule-writing/SKILL.md +1 -1
  186. package/.agent-src/skills/security/SKILL.md +7 -2
  187. package/.agent-src/skills/security-audit/SKILL.md +7 -3
  188. package/.agent-src/skills/skill-reviewer/SKILL.md +1 -1
  189. package/.agent-src/skills/skill-writing/SKILL.md +3 -3
  190. package/.agent-src/skills/subagent-orchestration/SKILL.md +1 -0
  191. package/.agent-src/skills/systematic-debugging/SKILL.md +69 -61
  192. package/.agent-src/skills/test-driven-development/SKILL.md +59 -57
  193. package/.agent-src/skills/test-performance/SKILL.md +0 -1
  194. package/.agent-src/skills/traefik/SKILL.md +4 -4
  195. package/.agent-src/skills/upstream-contribute/SKILL.md +1 -1
  196. package/.agent-src/skills/validate-feature-fit/SKILL.md +2 -2
  197. package/.agent-src/skills/{verify-before-complete → verify-completion-evidence}/SKILL.md +30 -28
  198. package/.agent-src/templates/agent-settings.md +8 -8
  199. package/.agent-src/templates/contexts/auth-model.md +1 -1
  200. package/.agent-src/templates/scripts/README.md +2 -2
  201. package/.agent-src/templates/scripts/telemetry/aggregator.py +16 -1
  202. package/.agent-src/templates/scripts/telemetry/engagement.py +59 -0
  203. package/.agent-src/templates/scripts/telemetry/report_renderer.py +28 -1
  204. package/.agent-src/templates/scripts/telemetry_record.py +14 -1
  205. package/.claude-plugin/marketplace.json +31 -12
  206. package/AGENTS.md +11 -9
  207. package/CHANGELOG.md +213 -2
  208. package/README.md +43 -44
  209. package/config/agent-settings.template.yml +58 -1
  210. package/config/gitignore-block.txt +3 -0
  211. package/docs/architecture.md +5 -7
  212. package/docs/catalog.md +359 -0
  213. package/docs/contracts/STABILITY.md +46 -1
  214. package/docs/contracts/adr-chat-history-split.md +1 -3
  215. package/docs/contracts/adr-command-suggestion.md +3 -5
  216. package/docs/contracts/adr-implement-ticket-runtime.md +1 -2
  217. package/docs/contracts/adr-product-ui-track.md +5 -8
  218. package/docs/contracts/adr-prompt-driven-execution.md +3 -4
  219. package/docs/contracts/agent-memory-contract.md +8 -13
  220. package/docs/contracts/artifact-engagement-flow.md +7 -10
  221. package/docs/contracts/command-clusters.md +56 -46
  222. package/docs/contracts/command-suggestion-flow.md +4 -6
  223. package/docs/contracts/context-paths.md +99 -0
  224. package/docs/contracts/file-ownership-matrix.json +6722 -0
  225. package/docs/contracts/file-ownership-matrix.md +134 -0
  226. package/docs/contracts/implement-ticket-flow.md +8 -11
  227. package/docs/contracts/linear-ai-rules-inclusion.md +1 -2
  228. package/docs/contracts/linear-ai-three-layers.md +0 -2
  229. package/docs/contracts/load-context-budget-model.md +178 -0
  230. package/docs/contracts/load-context-schema.md +184 -0
  231. package/docs/contracts/rule-interactions.md +0 -1
  232. package/docs/contracts/rule-interactions.yml +96 -0
  233. package/docs/contracts/rule-priority-hierarchy.md +87 -0
  234. package/docs/contracts/ui-track-flow.md +8 -18
  235. package/docs/customization.md +16 -0
  236. package/docs/end-to-end-walkthroughs.md +165 -0
  237. package/docs/getting-started.md +29 -10
  238. package/docs/github-topics.md +12 -3
  239. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +100 -0
  240. package/docs/guidelines/agent-infra/language-and-tone-examples.md +79 -0
  241. package/{.agent-src → docs}/guidelines/docs/readme-size-and-splitting.md +26 -25
  242. package/docs/guidelines/php/git.md +164 -0
  243. package/docs/migrations/commands-1.15.0.md +1 -1
  244. package/docs/showcase.md +9 -4
  245. package/docs/skills-catalog.md +14 -8
  246. package/docs/ui-track-mental-model.md +2 -2
  247. package/llms.txt +13 -7
  248. package/package.json +1 -1
  249. package/scripts/_one_off_phase4_dispatch_latency.py +108 -0
  250. package/scripts/_one_off_phase6_trigger_jaccard.py +92 -0
  251. package/scripts/_phase2_shim_helper.py +109 -0
  252. package/scripts/agent-config +33 -0
  253. package/scripts/ai_council/__init__.py +39 -0
  254. package/scripts/ai_council/_default_prices.py +41 -0
  255. package/scripts/ai_council/_one_off_2a4_acceptance.py +208 -0
  256. package/scripts/ai_council/_one_off_context_layer_v1_estimate.py +67 -0
  257. package/scripts/ai_council/_one_off_context_layer_v1_review.py +292 -0
  258. package/scripts/ai_council/_one_off_followups_review.py +259 -0
  259. package/scripts/ai_council/_one_off_nondestructive_inline_audit.py +209 -0
  260. package/scripts/ai_council/_one_off_phase_2a_budget_rebalance.py +257 -0
  261. package/scripts/ai_council/_one_off_phase_2a_post_revert.py +197 -0
  262. package/scripts/ai_council/_one_off_rebalancing_audit.py +149 -0
  263. package/scripts/ai_council/_one_off_roundtrip.py +106 -0
  264. package/scripts/ai_council/_one_off_rule_hardening_v1.py +251 -0
  265. package/scripts/ai_council/_one_off_structural_open_questions.py +232 -0
  266. package/scripts/ai_council/_one_off_structural_optimization.py +144 -0
  267. package/scripts/ai_council/_one_off_structural_v3_gaps.py +252 -0
  268. package/scripts/ai_council/_one_off_structural_v3_review.py +240 -0
  269. package/scripts/ai_council/budget_guard.py +172 -0
  270. package/scripts/ai_council/bundler.py +261 -0
  271. package/scripts/ai_council/clients.py +381 -0
  272. package/scripts/ai_council/modes.py +127 -0
  273. package/scripts/ai_council/orchestrator.py +350 -0
  274. package/scripts/ai_council/pricing.py +213 -0
  275. package/scripts/ai_council/project_context.py +159 -0
  276. package/scripts/ai_council/prompts.py +232 -0
  277. package/scripts/ai_council/session.py +144 -0
  278. package/scripts/check_always_budget.py +444 -0
  279. package/scripts/check_augmentignore.py +69 -0
  280. package/scripts/check_cluster_patterns.py +159 -0
  281. package/scripts/check_command_count_messaging.py +127 -0
  282. package/scripts/check_context_paths.py +201 -0
  283. package/scripts/check_no_roadmap_refs.py +155 -0
  284. package/scripts/check_phase_coupling.py +148 -0
  285. package/scripts/check_portability.py +57 -0
  286. package/scripts/check_public_catalog_links.py +122 -0
  287. package/scripts/check_references.py +33 -3
  288. package/scripts/check_roadmap_trackable.py +111 -0
  289. package/scripts/check_safety_floor_untouched.py +125 -0
  290. package/scripts/command_suggester/cooldown.py +1 -1
  291. package/scripts/command_suggester/loader.py +4 -1
  292. package/scripts/compress.py +59 -13
  293. package/scripts/generate_index.py +270 -0
  294. package/scripts/generate_ownership_matrix.py +323 -0
  295. package/scripts/hooks/augment-roadmap-progress.sh +57 -0
  296. package/scripts/install.py +49 -28
  297. package/scripts/install_anthropic_key.sh +5 -0
  298. package/scripts/install_openai_key.sh +106 -0
  299. package/scripts/lint_load_context.py +163 -0
  300. package/scripts/lint_no_new_atomic_commands.py +12 -11
  301. package/scripts/requirements-evals.txt +1 -0
  302. package/scripts/roadmap_progress_hook.py +159 -0
  303. package/scripts/schemas/command.schema.json +22 -1
  304. package/scripts/schemas/rule.schema.json +10 -0
  305. package/scripts/skill_linter.py +13 -4
  306. package/scripts/sync_agent_settings.py +26 -3
  307. package/scripts/update_counts.py +16 -4
  308. package/scripts/update_prices.py +124 -0
  309. package/.agent-src/guidelines/php/git.md +0 -96
  310. package/.agent-src/rules/command-suggestion.md +0 -134
  311. /package/{.agent-src → docs}/guidelines/agent-infra/agent-interaction-and-decision-quality.md +0 -0
  312. /package/{.agent-src → docs}/guidelines/agent-infra/break-glass-usage.md +0 -0
  313. /package/{.agent-src → docs}/guidelines/agent-infra/developer-judgment.md +0 -0
  314. /package/{.agent-src → docs}/guidelines/agent-infra/engineering-memory-data-format.md +0 -0
  315. /package/{.agent-src → docs}/guidelines/agent-infra/layered-settings.md +0 -0
  316. /package/{.agent-src → docs}/guidelines/agent-infra/memory-access.md +0 -0
  317. /package/{.agent-src → docs}/guidelines/agent-infra/naming.md +0 -0
  318. /package/{.agent-src → docs}/guidelines/agent-infra/output-patterns.md +0 -0
  319. /package/{.agent-src → docs}/guidelines/agent-infra/review-routing-data-format.md +0 -0
  320. /package/{.agent-src → docs}/guidelines/agent-infra/role-contracts.md +0 -0
  321. /package/{.agent-src → docs}/guidelines/agent-infra/role-mode-router.md +0 -0
  322. /package/{.agent-src → docs}/guidelines/agent-infra/runtime-layer.md +0 -0
  323. /package/{.agent-src → docs}/guidelines/agent-infra/self-improvement-pipeline.md +0 -0
  324. /package/{.agent-src → docs}/guidelines/agent-infra/size-and-scope.md +0 -0
  325. /package/{.agent-src → docs}/guidelines/agent-infra/tool-integration.md +0 -0
  326. /package/{.agent-src → docs}/guidelines/e2e/playwright.md +0 -0
  327. /package/{.agent-src → docs}/guidelines/php/api-design.md +0 -0
  328. /package/{.agent-src → docs}/guidelines/php/artisan-commands.md +0 -0
  329. /package/{.agent-src → docs}/guidelines/php/blade-ui.md +0 -0
  330. /package/{.agent-src → docs}/guidelines/php/controllers.md +0 -0
  331. /package/{.agent-src → docs}/guidelines/php/database.md +0 -0
  332. /package/{.agent-src → docs}/guidelines/php/eloquent.md +0 -0
  333. /package/{.agent-src → docs}/guidelines/php/flux.md +0 -0
  334. /package/{.agent-src → docs}/guidelines/php/general.md +0 -0
  335. /package/{.agent-src → docs}/guidelines/php/jobs.md +0 -0
  336. /package/{.agent-src → docs}/guidelines/php/livewire.md +0 -0
  337. /package/{.agent-src → docs}/guidelines/php/logging.md +0 -0
  338. /package/{.agent-src → docs}/guidelines/php/naming.md +0 -0
  339. /package/{.agent-src → docs}/guidelines/php/patterns/dependency-injection.md +0 -0
  340. /package/{.agent-src → docs}/guidelines/php/patterns/dtos.md +0 -0
  341. /package/{.agent-src → docs}/guidelines/php/patterns/events.md +0 -0
  342. /package/{.agent-src → docs}/guidelines/php/patterns/factory.md +0 -0
  343. /package/{.agent-src → docs}/guidelines/php/patterns/pipelines.md +0 -0
  344. /package/{.agent-src → docs}/guidelines/php/patterns/policies.md +0 -0
  345. /package/{.agent-src → docs}/guidelines/php/patterns/repositories.md +0 -0
  346. /package/{.agent-src → docs}/guidelines/php/patterns/service-layer.md +0 -0
  347. /package/{.agent-src → docs}/guidelines/php/patterns/strategy.md +0 -0
  348. /package/{.agent-src → docs}/guidelines/php/patterns.md +0 -0
  349. /package/{.agent-src → docs}/guidelines/php/performance.md +0 -0
  350. /package/{.agent-src → docs}/guidelines/php/resources.md +0 -0
  351. /package/{.agent-src → docs}/guidelines/php/security.md +0 -0
  352. /package/{.agent-src → docs}/guidelines/php/sql.md +0 -0
  353. /package/{.agent-src → docs}/guidelines/php/validations.md +0 -0
  354. /package/{.agent-src → docs}/guidelines/php/websocket.md +0 -0
@@ -250,6 +250,55 @@ def check_file(filepath: Path, patterns: list, allowlist: list) -> List[Violatio
250
250
  return violations
251
251
 
252
252
 
253
+ # ── Identity-framing detector ───────────────────────────────────────────
254
+ # The package's public identity surface (README, AGENTS, copilot-instructions)
255
+ # must read stack-neutral. Laravel is the deepest reference stack today, never
256
+ # the headline. This detector flags banned phrases that elevate any single
257
+ # stack to identity status. Source-of-truth list lives in the
258
+ # road-to-1-15-followups.md roadmap (P0 #1, F1.5).
259
+ _IDENTITY_FRAMING_PATTERNS: list[tuple[re.Pattern, str]] = [
260
+ (re.compile(r"\bLaravel-first\b", re.IGNORECASE), "identity-laravel-first"),
261
+ (re.compile(r"\bfor\s+PHP\s*/\s*Laravel\s+teams?\b", re.IGNORECASE), "identity-for-php-laravel-teams"),
262
+ (re.compile(r"\bfor\s+Laravel\s+teams?\b", re.IGNORECASE), "identity-for-laravel-teams"),
263
+ (re.compile(r"\bprimary\s+audience\s*[:=]\s*Laravel\b", re.IGNORECASE), "identity-primary-audience-laravel"),
264
+ (re.compile(r"\bbuilt\s+for\s+Laravel\b", re.IGNORECASE), "identity-built-for-laravel"),
265
+ (re.compile(r"\bLaravel\s*=\s*primary\b", re.IGNORECASE), "identity-laravel-equals-primary"),
266
+ (re.compile(r"\*\*Reference\s+implementation:\s*Laravel\.?\*\*", re.IGNORECASE), "identity-reference-implementation-laravel"),
267
+ ]
268
+
269
+ # Files whose identity framing must stay stack-neutral. Relative to repo root.
270
+ IDENTITY_SCAN_FILES = [
271
+ "README.md",
272
+ "AGENTS.md",
273
+ ".github/copilot-instructions.md",
274
+ ]
275
+
276
+
277
+ def check_identity_framing(filepath: Path) -> List[Violation]:
278
+ """Flag banned identity-framing phrases in README / AGENTS / copilot-instructions.
279
+
280
+ The package presents itself as a universal governance system; any phrase
281
+ that pins identity to a single stack (Laravel-first, built for Laravel,
282
+ Reference implementation: Laravel as a bolded headline) is a regression.
283
+ """
284
+ violations: List[Violation] = []
285
+ try:
286
+ lines = filepath.read_text(encoding="utf-8").splitlines()
287
+ except Exception:
288
+ return violations
289
+
290
+ for i, line in enumerate(lines, 1):
291
+ for pattern, name in _IDENTITY_FRAMING_PATTERNS:
292
+ m = pattern.search(line)
293
+ if m:
294
+ violations.append(Violation(
295
+ file=str(filepath), line=i, match=m.group(0),
296
+ pattern_name=name, severity="error",
297
+ context=line.strip(),
298
+ ))
299
+ return violations
300
+
301
+
253
302
  # ── Task-command detector ───────────────────────────────────────────────
254
303
  # Artefact files shipped in the package must not reference `task <name>`
255
304
  # invocations (per augment-portability rule). Consumer projects may not
@@ -266,6 +315,7 @@ _TASK_FENCE_RE = re.compile(r"^\s*task\s+([a-z][a-z0-9:_-]*)\b")
266
315
  # by the task-invocation detector (but still scanned for layer 1 + 2).
267
316
  _TASK_DETECTOR_SKIP = (
268
317
  "rules/augment-portability.md",
318
+ "contexts/communication/rules-auto/augment-portability-mechanics.md",
269
319
  )
270
320
 
271
321
 
@@ -373,6 +423,7 @@ _CLI_INVOCATION_MAP: list[tuple[re.Pattern, str]] = [
373
423
  # own help, the portability rule that defines the mapping).
374
424
  _CLI_DETECTOR_SKIP = (
375
425
  "rules/augment-portability.md",
426
+ "contexts/communication/rules-auto/augment-portability-mechanics.md",
376
427
  )
377
428
 
378
429
 
@@ -467,6 +518,12 @@ def scan_all(root: Path) -> tuple[List[Violation], list[str]]:
467
518
  if not any(path_str.endswith(skip) for skip in _CLI_DETECTOR_SKIP):
468
519
  violations.extend(check_cli_invocations(f))
469
520
 
521
+ # Layer 5: identity-framing scan on the public identity surface
522
+ for rel in IDENTITY_SCAN_FILES:
523
+ f = root / rel
524
+ if f.is_file():
525
+ violations.extend(check_identity_framing(f))
526
+
470
527
  return violations, detected
471
528
 
472
529
 
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Public-catalog link checker (regression guard for road-to-pr-34-followups 1.1).
4
+
5
+ `docs/catalog.md` is the consumer-facing catalog rendered by
6
+ `scripts/generate_index.py`. Consumers receive the package via npm /
7
+ Composer / archive surfaces — `.agent-src.uncompressed/` is **not**
8
+ shipped (see `package.json#files`). Every link in the public catalog
9
+ must therefore resolve to a shipped surface.
10
+
11
+ Checks:
12
+ 1. No link href contains `.agent-src.uncompressed/`.
13
+ 2. Every link href resolves on disk.
14
+ 3. Every link href starts with a path declared in `package.json#files`
15
+ (or one of the always-shipped root files).
16
+
17
+ Exit codes: 0 = clean, 1 = violations found.
18
+
19
+ Usage:
20
+ python3 scripts/check_public_catalog_links.py
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import json
26
+ import re
27
+ import sys
28
+ from pathlib import Path
29
+
30
+ ROOT = Path(__file__).resolve().parent.parent
31
+ CATALOG = ROOT / "docs" / "catalog.md"
32
+ PACKAGE_JSON = ROOT / "package.json"
33
+
34
+ LINK_RE = re.compile(r"\]\((?P<href>[^)\s]+)(?:\s+\"[^\"]*\")?\)")
35
+ FORBIDDEN_PREFIX = ".agent-src.uncompressed/"
36
+
37
+
38
+ def _shipped_roots() -> tuple[set[str], set[str]]:
39
+ """Return (shipped_dirs, shipped_files) from package.json#files."""
40
+ data = json.loads(PACKAGE_JSON.read_text(encoding="utf-8"))
41
+ dirs: set[str] = set()
42
+ files: set[str] = set()
43
+ for entry in data.get("files", []):
44
+ if entry.endswith("/"):
45
+ dirs.add(entry.rstrip("/"))
46
+ else:
47
+ files.add(entry)
48
+ return dirs, files
49
+
50
+
51
+ def _resolve(href: str) -> Path | None:
52
+ href = href.split("#", 1)[0]
53
+ if not href or href.startswith(("http://", "https://", "mailto:", "tel:")):
54
+ return None
55
+ target = (CATALOG.parent / href).resolve()
56
+ try:
57
+ return target.relative_to(ROOT.resolve())
58
+ except ValueError:
59
+ return None
60
+
61
+
62
+ def _under_shipped_surface(rel: Path, dirs: set[str], files: set[str]) -> bool:
63
+ s = str(rel)
64
+ if s in files:
65
+ return True
66
+ return any(s == d or s.startswith(d + "/") for d in dirs)
67
+
68
+
69
+ def main() -> int:
70
+ if not CATALOG.exists():
71
+ print(f"❌ {CATALOG.relative_to(ROOT)} not found")
72
+ return 1
73
+
74
+ dirs, files = _shipped_roots()
75
+ text = CATALOG.read_text(encoding="utf-8")
76
+
77
+ forbidden: list[tuple[int, str]] = []
78
+ missing: list[tuple[int, str]] = []
79
+ unshipped: list[tuple[int, str]] = []
80
+
81
+ for lineno, line in enumerate(text.splitlines(), 1):
82
+ for m in LINK_RE.finditer(line):
83
+ href = m.group("href")
84
+ if FORBIDDEN_PREFIX in href:
85
+ forbidden.append((lineno, href))
86
+ continue
87
+ rel = _resolve(href)
88
+ if rel is None:
89
+ continue # external / non-resolvable
90
+ if not (ROOT / rel).exists():
91
+ missing.append((lineno, href))
92
+ continue
93
+ if not _under_shipped_surface(rel, dirs, files):
94
+ unshipped.append((lineno, href))
95
+
96
+ total_violations = len(forbidden) + len(missing) + len(unshipped)
97
+ if not total_violations:
98
+ print(f"✅ docs/catalog.md — all links resolve to shipped surfaces.")
99
+ return 0
100
+
101
+ print(f"❌ docs/catalog.md — {total_violations} violation(s):")
102
+ if forbidden:
103
+ print(f"\n {len(forbidden)} link(s) point at unshipped `.agent-src.uncompressed/`:")
104
+ for ln, href in forbidden[:10]:
105
+ print(f" line {ln}: {href}")
106
+ if len(forbidden) > 10:
107
+ print(f" … and {len(forbidden) - 10} more")
108
+ if missing:
109
+ print(f"\n {len(missing)} link(s) do not resolve on disk:")
110
+ for ln, href in missing[:10]:
111
+ print(f" line {ln}: {href}")
112
+ if unshipped:
113
+ print(f"\n {len(unshipped)} link(s) point outside `package.json#files`:")
114
+ for ln, href in unshipped[:10]:
115
+ print(f" line {ln}: {href}")
116
+ print("\nFix: update `scripts/generate_index.py` _to_shipped_path() / catalog renderer,")
117
+ print("then re-run `python3 scripts/generate_index.py`.")
118
+ return 1
119
+
120
+
121
+ if __name__ == "__main__":
122
+ sys.exit(main())
@@ -32,7 +32,10 @@ class BrokenRef:
32
32
 
33
33
 
34
34
  SCAN_DIRS = [".agent-src", "agents"]
35
- SKIP_DIRS = ["agents/roadmaps/archive"] # archived roadmaps have historical refs
35
+ SKIP_DIRS = [
36
+ "agents/roadmaps/archive", # archived roadmaps have historical refs
37
+ "agents/council-sessions", # per-user audit trail (gitignored), captured provider output
38
+ ]
36
39
  ROOT = Path(".")
37
40
 
38
41
  # YAML memory files (engineering-memory layer) live under `agents/memory/`.
@@ -98,6 +101,14 @@ EXAMPLE_PATH_PATTERNS = [
98
101
  re.compile(r"skills/[\w-]+/SKILL\.md"), # example skill paths in commands
99
102
  re.compile(r"\{"), # template placeholders like {module}
100
103
  re.compile(r"\.compression-hashes\.json"), # JSON file, not .md
104
+ # Forward references inside in-flight planning docs (road-to-
105
+ # structural-optimization.md and its companion spike protocols).
106
+ # Each pattern below is removed once the matching phase lands.
107
+ re.compile(r"structural-optimization-3a-spike\.md"), # 3a.0.2
108
+ re.compile(r"contexts/judges/no-consolidate-rationale"), # 3a.0.2 abort
109
+ re.compile(r"contexts/judges/judge-shared-procedure"), # 3a.1
110
+ re.compile(r"contexts/analysis/project-analysis-core-procedure"), # 3b.1
111
+ re.compile(r"agents/roadmaps/phase6-non-overlap-evidence"), # 6.1 conditional
101
112
  ]
102
113
 
103
114
 
@@ -115,8 +126,20 @@ def collect_artifacts(root: Path) -> dict[str, set[str]]:
115
126
  arts["skills"].add(d.name)
116
127
  for f in (augment / "rules").glob("*.md") if (augment / "rules").exists() else []:
117
128
  arts["rules"].add(f.stem)
118
- for f in (augment / "commands").glob("*.md") if (augment / "commands").exists() else []:
119
- arts["commands"].add(f.stem)
129
+ cmd_dir = augment / "commands"
130
+ if cmd_dir.exists():
131
+ for f in cmd_dir.rglob("*.md"):
132
+ if f.name == "AGENTS.md":
133
+ continue
134
+ # Top-level: bare stem ("commit"). Nested: cluster-sub ("council-default")
135
+ # AND the cluster:sub form, since references may use either.
136
+ rel = f.relative_to(cmd_dir).with_suffix("")
137
+ parts = rel.parts
138
+ if len(parts) == 1:
139
+ arts["commands"].add(parts[0])
140
+ else:
141
+ arts["commands"].add("-".join(parts))
142
+ arts["commands"].add(":".join(parts))
120
143
  gdir = augment / "guidelines"
121
144
  if gdir.exists():
122
145
  for f in gdir.rglob("*.md"):
@@ -222,6 +245,13 @@ def check_file(filepath: Path, artifacts: dict[str, set[str]], root: Path) -> Li
222
245
  if any(p.search(raw_ref) for p in EXAMPLE_PATH_PATTERNS):
223
246
  continue
224
247
 
248
+ # Skip references into directories already excluded from scanning
249
+ # (gitignored audit trails, archived roadmaps). Files there are
250
+ # not committed, so existence checks would always fail in CI.
251
+ if any(raw_ref.startswith(skip + "/") or raw_ref == skip
252
+ for skip in SKIP_DIRS):
253
+ continue
254
+
225
255
  resolved = False
226
256
  # Try raw ref as-is from root (covers .agent-src/..., agents/..., etc.)
227
257
  if (root / raw_ref).exists():
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env python3
2
+ """CI guard for the `roadmap-progress-sync` rule's trackability Iron Law.
3
+
4
+ Every non-draft file under `agents/roadmaps/` (excluding `archive/`,
5
+ `skipped/`, template/README/open-questions) MUST:
6
+
7
+ 1. Be parseable by the dashboard's `PHASE_RE` — i.e. contain at least
8
+ one `## Phase <id>` or `### Phase <id>` heading.
9
+ 2. Have at least one trackable checkbox (`- [ ]`, `[x]`, `[~]`, `[-]`)
10
+ under every parsed phase.
11
+
12
+ A roadmap that fails (1) is invisible to `agents/roadmaps-progress.md`
13
+ and silently lies to the next reader. A phase that fails (2) shows as
14
+ `⬜ empty` and contributes nothing to progress percentages.
15
+
16
+ Both failure modes are rule violations per
17
+ `.augment/rules/roadmap-progress-sync.md` § "Iron Law — every active
18
+ roadmap is trackable". This script is the CI backstop so the rule
19
+ cannot be quietly broken again.
20
+
21
+ Exit codes:
22
+ 0 — every active roadmap has parseable phases with at least one
23
+ checkbox per phase.
24
+ 1 — at least one violation found; details printed to stdout.
25
+
26
+ Invocation (from project root):
27
+ python3 scripts/check_roadmap_trackable.py
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import sys
33
+ from pathlib import Path
34
+
35
+ # Reuse the dashboard's regexes and helpers — single source of truth so
36
+ # the linter cannot drift from what the dashboard actually parses.
37
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / ".augment" / "scripts"))
38
+ from update_roadmap_progress import ( # noqa: E402
39
+ CHECKBOX_RE,
40
+ PHASE_RE,
41
+ is_draft,
42
+ is_roadmap_candidate,
43
+ parse_frontmatter,
44
+ )
45
+
46
+ ROADMAP_ROOT = Path("agents/roadmaps")
47
+
48
+
49
+ def find_active_roadmaps(root: Path) -> list[Path]:
50
+ """Return every non-draft roadmap candidate under root."""
51
+ out: list[Path] = []
52
+ for path in sorted(root.rglob("*.md")):
53
+ if not path.is_file() or not is_roadmap_candidate(path):
54
+ continue
55
+ text = path.read_text(encoding="utf-8")
56
+ if is_draft(parse_frontmatter(text)):
57
+ continue
58
+ out.append(path)
59
+ return out
60
+
61
+
62
+ def violations_for(path: Path) -> list[str]:
63
+ """Return human-readable violation strings for a single roadmap."""
64
+ text = path.read_text(encoding="utf-8")
65
+ matches = list(PHASE_RE.finditer(text))
66
+ if not matches:
67
+ return [
68
+ f"{path}: no `## Phase <id>` or `### Phase <id>` heading "
69
+ "matched the dashboard's PHASE_RE — roadmap is invisible "
70
+ "to agents/roadmaps-progress.md. Either rename headings to "
71
+ "the canonical `Phase <id>` form or add `status: draft` to "
72
+ "the frontmatter."
73
+ ]
74
+ out: list[str] = []
75
+ for i, pm in enumerate(matches):
76
+ start = pm.end()
77
+ end = matches[i + 1].start() if i + 1 < len(matches) else len(text)
78
+ if not CHECKBOX_RE.search(text[start:end]):
79
+ phase_id = pm.group(2)
80
+ name = (pm.group(3) or "").strip() or f"Phase {phase_id}"
81
+ out.append(
82
+ f"{path}: Phase {phase_id} ({name[:60]}) has zero "
83
+ "trackable checkboxes — add at least one `- [ ]` (or "
84
+ "`[x]`/`[~]`/`[-]`) item or remove the phase."
85
+ )
86
+ return out
87
+
88
+
89
+ def main() -> int:
90
+ if not ROADMAP_ROOT.is_dir():
91
+ print(f"❌ {ROADMAP_ROOT} not found — run from project root.", file=sys.stderr)
92
+ return 1
93
+ findings: list[str] = []
94
+ for path in find_active_roadmaps(ROADMAP_ROOT):
95
+ findings.extend(violations_for(path))
96
+ if findings:
97
+ print("❌ Trackable-roadmap rule violations:\n")
98
+ for f in findings:
99
+ print(f" - {f}")
100
+ print(
101
+ "\nRule: .augment/rules/roadmap-progress-sync.md "
102
+ '§ "Iron Law — every active roadmap is trackable"'
103
+ )
104
+ return 1
105
+ count = len(find_active_roadmaps(ROADMAP_ROOT))
106
+ print(f"✅ {count} active roadmap(s) — all parseable, all phases have checkboxes.")
107
+ return 0
108
+
109
+
110
+ if __name__ == "__main__":
111
+ sys.exit(main())
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env python3
2
+ """Safety-floor exclusion linter (Phase 2A.0 of road-to-structural-optimization).
3
+
4
+ Per Q3=A locked decision (council Round 3, 2026-05-03), the four
5
+ safety-floor always-rules are out of scope for Phase 2A slimming:
6
+
7
+ - non-destructive-by-default
8
+ - commit-policy
9
+ - scope-control
10
+ - verify-before-complete
11
+
12
+ This linter compares HEAD against a baseline ref (default: ``main``)
13
+ and fails CI if any of those four rule files were modified by the
14
+ working branch.
15
+
16
+ Lift via the two-gate rollback documented in
17
+ ``agents/roadmaps/road-to-structural-optimization.md`` § Phase 2A
18
+ Abort/rollback.
19
+
20
+ Exit codes: 0 = clean (or skipped — see ``--skip-if-no-baseline``),
21
+ 1 = safety-floor file modified, 3 = internal error.
22
+ """
23
+ from __future__ import annotations
24
+
25
+ import argparse
26
+ import subprocess
27
+ import sys
28
+ from pathlib import Path
29
+
30
+ REPO_ROOT = Path(__file__).resolve().parent.parent
31
+ RULES_DIR_REL = ".agent-src.uncompressed/rules"
32
+ SAFETY_FLOOR = (
33
+ "non-destructive-by-default.md",
34
+ "commit-policy.md",
35
+ "scope-control.md",
36
+ "verify-before-complete.md",
37
+ )
38
+
39
+
40
+ def _run_git(args: list[str]) -> tuple[int, str]:
41
+ proc = subprocess.run(
42
+ ["git", *args],
43
+ cwd=REPO_ROOT,
44
+ capture_output=True,
45
+ text=True,
46
+ check=False,
47
+ )
48
+ return proc.returncode, (proc.stdout or "") + (proc.stderr or "")
49
+
50
+
51
+ def _baseline_exists(ref: str) -> bool:
52
+ code, _ = _run_git(["rev-parse", "--verify", "--quiet", ref])
53
+ return code == 0
54
+
55
+
56
+ def _changed_files(baseline: str) -> list[str]:
57
+ code, output = _run_git(["diff", "--name-only", f"{baseline}...HEAD"])
58
+ if code != 0:
59
+ raise RuntimeError(f"git diff failed: {output}")
60
+ return [line.strip() for line in output.splitlines() if line.strip()]
61
+
62
+
63
+ def main() -> int:
64
+ parser = argparse.ArgumentParser(description=__doc__)
65
+ parser.add_argument(
66
+ "--baseline",
67
+ default="origin/main",
68
+ help="Baseline ref (default: origin/main)",
69
+ )
70
+ parser.add_argument(
71
+ "--skip-if-no-baseline",
72
+ action="store_true",
73
+ help="Exit 0 silently if baseline ref does not exist (local dev)",
74
+ )
75
+ args = parser.parse_args()
76
+
77
+ if not _baseline_exists(args.baseline):
78
+ if args.skip_if_no_baseline:
79
+ print(f"ℹ️ baseline {args.baseline} not found — skipped")
80
+ return 0
81
+ # Fallback: try plain `main`
82
+ if _baseline_exists("main"):
83
+ args.baseline = "main"
84
+ else:
85
+ print(
86
+ f"❌ baseline {args.baseline} (and `main`) not found. "
87
+ "Pass --skip-if-no-baseline to silence in local dev.",
88
+ file=sys.stderr,
89
+ )
90
+ return 3
91
+
92
+ try:
93
+ changed = _changed_files(args.baseline)
94
+ except RuntimeError as exc:
95
+ print(f"❌ {exc}", file=sys.stderr)
96
+ return 3
97
+
98
+ floor_paths = {f"{RULES_DIR_REL}/{name}" for name in SAFETY_FLOOR}
99
+ breaches = sorted(p for p in changed if p in floor_paths)
100
+
101
+ if breaches:
102
+ print(
103
+ "❌ Safety-floor rule(s) modified — Phase 2A is not allowed to "
104
+ "touch these (Q3=A locked decision):",
105
+ file=sys.stderr,
106
+ )
107
+ for path in breaches:
108
+ print(f" {path}", file=sys.stderr)
109
+ print(
110
+ "\n Lift via the two-gate rollback documented in "
111
+ "agents/roadmaps/road-to-structural-optimization.md "
112
+ "§ Phase 2A Abort/rollback.",
113
+ file=sys.stderr,
114
+ )
115
+ return 1
116
+
117
+ print(
118
+ f"✅ Safety-floor untouched ({len(SAFETY_FLOOR)} rules guarded "
119
+ f"vs. {args.baseline})."
120
+ )
121
+ return 0
122
+
123
+
124
+ if __name__ == "__main__":
125
+ sys.exit(main())
@@ -31,7 +31,7 @@ def is_explicit_slash_invocation(message: str) -> bool:
31
31
 
32
32
  Per the `command-suggestion` rule, explicit slash invocations
33
33
  bypass the suggestion layer entirely \u2014 they're handled by
34
- `slash-commands` directly. The engine should not score in that
34
+ `slash-command-routing-policy` directly. The engine should not score in that
35
35
  case. Helper exposed for the runtime caller and the GT-CS4
36
36
  golden.
37
37
  """
@@ -26,7 +26,10 @@ def load_commands(commands_dir: Path) -> list[CommandSpec]:
26
26
  this loader.
27
27
  """
28
28
  specs: list[CommandSpec] = []
29
- for path in sorted(commands_dir.glob("*.md")):
29
+ for path in sorted(commands_dir.rglob("*.md")):
30
+ # Skip cluster authoring docs — not commands.
31
+ if path.name == "AGENTS.md":
32
+ continue
30
33
  text = path.read_text(encoding="utf-8")
31
34
  data, _offset = parse_frontmatter(text)
32
35
  if data is None:
@@ -312,6 +312,29 @@ def generate_gemini_md() -> None:
312
312
  print(" ✅ Created GEMINI.md → AGENTS.md symlink")
313
313
 
314
314
 
315
+ def _command_slug(source_file: Path) -> str:
316
+ """Return the flat .claude/skills/ slug for a command source file.
317
+
318
+ Top-level commands keep their stem (`commit.md` → `commit`). Nested
319
+ commands flatten the relative path with `-` (`council/default.md` →
320
+ `council-default`). Keeps slug collisions out of `.claude/skills/`
321
+ while preserving native nested invocation in `.agent-src/commands/`.
322
+ """
323
+ rel = source_file.relative_to(COMMANDS_SOURCE)
324
+ return "-".join(rel.with_suffix("").parts)
325
+
326
+
327
+ def _iter_commands():
328
+ """Yield (source_file, slug) for every command .md file (recursive)."""
329
+ if not COMMANDS_SOURCE.exists():
330
+ return
331
+ for source_file in sorted(COMMANDS_SOURCE.rglob("*.md")):
332
+ # Skip the cluster AGENTS.md authoring doc (not a command).
333
+ if source_file.name == "AGENTS.md":
334
+ continue
335
+ yield source_file, _command_slug(source_file)
336
+
337
+
315
338
  def generate_claude_skills() -> None:
316
339
  """Create .claude/skills/ symlinks for ALL skills in .agent-src/skills/.
317
340
  """
@@ -321,16 +344,14 @@ def generate_claude_skills() -> None:
321
344
 
322
345
  # All skill directories in .agent-src/skills/
323
346
  skills = sorted([d.name for d in SKILLS_SOURCE.iterdir() if d.is_dir()])
324
- # All command names (to protect from stale cleanup)
325
- command_names = set()
326
- if COMMANDS_SOURCE.exists():
327
- command_names = {f.stem for f in COMMANDS_SOURCE.glob("*.md")}
347
+ # All command slugs (to protect from stale cleanup)
348
+ command_slugs = {slug for _, slug in _iter_commands()}
328
349
 
329
350
  CLAUDE_SKILLS_DIR.mkdir(parents=True, exist_ok=True)
330
351
 
331
352
  # Clean stale symlinks (but not converted commands or README)
332
353
  for item in CLAUDE_SKILLS_DIR.iterdir():
333
- if item.is_symlink() and item.name not in skills and item.name not in command_names and item.name != "README.md":
354
+ if item.is_symlink() and item.name not in skills and item.name not in command_slugs and item.name != "README.md":
334
355
  item.unlink()
335
356
 
336
357
  count = 0
@@ -357,11 +378,15 @@ def extract_description_from_md(content: str) -> str:
357
378
 
358
379
 
359
380
  def generate_claude_commands() -> None:
360
- """Create .claude/skills/{name}/SKILL.md symlinks for ALL Augment commands.
381
+ """Create .claude/skills/{slug}/SKILL.md symlinks for ALL Augment commands.
361
382
 
362
383
  Commands in .agent-src/commands/ are the single source of truth.
363
384
  They must include name: and disable-model-invocation: true in frontmatter
364
385
  (added once, then maintained as part of the command file).
386
+
387
+ Top-level commands use their filename stem as the slug. Nested
388
+ cluster commands (e.g. `commands/council/default.md`) are flattened
389
+ to `council-default` so directories never collide in `.claude/skills/`.
365
390
  """
366
391
  if not COMMANDS_SOURCE.exists():
367
392
  print(" ⚠️ .agent-src/commands/ not found — skipping commands")
@@ -374,32 +399,53 @@ def generate_claude_commands() -> None:
374
399
  if SKILLS_SOURCE.exists():
375
400
  skill_names = {d.name for d in SKILLS_SOURCE.iterdir() if d.is_dir()}
376
401
 
402
+ # Track current command slugs for stale-directory cleanup
403
+ current_slugs: set[str] = set()
377
404
  count = 0
378
405
  skipped = 0
379
- for source_file in sorted(COMMANDS_SOURCE.glob("*.md")):
380
- name = source_file.stem
381
-
406
+ for source_file, slug in _iter_commands():
382
407
  # Skip if a real skill with the same name exists — skill takes priority
383
- if name in skill_names:
408
+ if slug in skill_names:
384
409
  skipped += 1
385
410
  continue
386
411
 
412
+ current_slugs.add(slug)
413
+
387
414
  # Create skill directory (real dir, symlinked SKILL.md inside)
388
- skill_dir = CLAUDE_SKILLS_DIR / name
415
+ skill_dir = CLAUDE_SKILLS_DIR / slug
389
416
  skill_dir.mkdir(parents=True, exist_ok=True)
390
417
 
391
418
  skill_file = skill_dir / "SKILL.md"
392
419
  if skill_file.exists() or skill_file.is_symlink():
393
420
  skill_file.unlink()
394
421
 
395
- # Symlink: .claude/skills/{name}/SKILL.md → ../../../.agent-src/commands/{name}.md
396
- rel_target = Path("../../../.agent-src/commands") / source_file.name
422
+ # Symlink: .claude/skills/{slug}/SKILL.md → ../../../.agent-src/commands/<rel-path>
423
+ rel_path = source_file.relative_to(COMMANDS_SOURCE)
424
+ rel_target = Path("../../../.agent-src/commands") / rel_path
397
425
  skill_file.symlink_to(rel_target)
398
426
  count += 1
399
427
 
428
+ # Clean stale command skill directories — real dirs from removed commands.
429
+ # Only delete if the directory contains exactly the SKILL.md symlink we created.
430
+ removed_dirs = 0
431
+ for item in CLAUDE_SKILLS_DIR.iterdir():
432
+ if not item.is_dir() or item.is_symlink():
433
+ continue
434
+ if item.name in skill_names or item.name in current_slugs:
435
+ continue
436
+ skill_md = item / "SKILL.md"
437
+ if skill_md.is_symlink():
438
+ entries = list(item.iterdir())
439
+ if len(entries) == 1 and entries[0].name == "SKILL.md":
440
+ skill_md.unlink()
441
+ item.rmdir()
442
+ removed_dirs += 1
443
+
400
444
  msg = f" ✅ Created {count} command symlinks in .claude/skills/"
401
445
  if skipped:
402
446
  msg += f" ({skipped} skipped — same-name skill exists)"
447
+ if removed_dirs:
448
+ msg += f" ({removed_dirs} stale dirs removed)"
403
449
  print(msg)
404
450
 
405
451