@event4u/agent-config 1.15.0 → 1.16.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 (244) hide show
  1. package/.agent-src/commands/bug-fix.md +1 -1
  2. package/.agent-src/commands/bug-investigate.md +2 -2
  3. package/.agent-src/commands/chat-history-checkpoint.md +1 -1
  4. package/.agent-src/commands/chat-history-clear.md +1 -1
  5. package/.agent-src/commands/chat-history.md +1 -1
  6. package/.agent-src/commands/check-current-md.md +1 -1
  7. package/.agent-src/commands/council-design.md +96 -0
  8. package/.agent-src/commands/council-optimize.md +115 -0
  9. package/.agent-src/commands/council-pr.md +123 -0
  10. package/.agent-src/commands/council.md +219 -0
  11. package/.agent-src/commands/create-pr.md +23 -0
  12. package/.agent-src/commands/do-and-judge.md +3 -3
  13. package/.agent-src/commands/do-in-steps.md +4 -4
  14. package/.agent-src/commands/e2e-heal.md +1 -1
  15. package/.agent-src/commands/e2e-plan.md +1 -1
  16. package/.agent-src/commands/feature-dev.md +8 -0
  17. package/.agent-src/commands/feature-explore.md +6 -1
  18. package/.agent-src/commands/feature-plan.md +33 -2
  19. package/.agent-src/commands/feature-refactor.md +5 -0
  20. package/.agent-src/commands/feature-roadmap.md +6 -1
  21. package/.agent-src/commands/feature.md +58 -0
  22. package/.agent-src/commands/fix-ci.md +5 -0
  23. package/.agent-src/commands/fix-portability.md +5 -0
  24. package/.agent-src/commands/fix-pr-bot-comments.md +5 -0
  25. package/.agent-src/commands/fix-pr-comments.md +5 -0
  26. package/.agent-src/commands/fix-pr-developer-comments.md +5 -0
  27. package/.agent-src/commands/fix-references.md +5 -0
  28. package/.agent-src/commands/fix-seeder.md +5 -0
  29. package/.agent-src/commands/fix.md +60 -0
  30. package/.agent-src/commands/jira-ticket.md +1 -1
  31. package/.agent-src/commands/judge.md +1 -1
  32. package/.agent-src/commands/memory-add.md +3 -3
  33. package/.agent-src/commands/memory-full.md +2 -2
  34. package/.agent-src/commands/memory-promote.md +2 -2
  35. package/.agent-src/commands/mode.md +5 -5
  36. package/.agent-src/commands/onboard.md +3 -3
  37. package/.agent-src/commands/optimize-agents.md +6 -1
  38. package/.agent-src/commands/optimize-augmentignore.md +5 -0
  39. package/.agent-src/commands/optimize-rtk-filters.md +5 -0
  40. package/.agent-src/commands/optimize-skills.md +6 -1
  41. package/.agent-src/commands/optimize.md +54 -0
  42. package/.agent-src/commands/propose-memory.md +2 -2
  43. package/.agent-src/commands/review-changes.md +26 -1
  44. package/.agent-src/commands/review-routing.md +1 -1
  45. package/.agent-src/commands/roadmap-create.md +29 -2
  46. package/.agent-src/commands/set-cost-profile.md +3 -3
  47. package/.agent-src/commands/sync-agent-settings.md +2 -2
  48. package/.agent-src/commands/tests-create.md +1 -1
  49. package/.agent-src/commands/upstream-contribute.md +1 -1
  50. package/.agent-src/contexts/authority/commit-mechanics.md +57 -0
  51. package/.agent-src/contexts/authority/destructive-mechanics.md +66 -0
  52. package/.agent-src/contexts/authority/scope-mechanics.md +87 -0
  53. package/.agent-src/contexts/execution/autonomy-detection.md +54 -0
  54. package/.agent-src/contexts/execution/autonomy-examples.md +90 -0
  55. package/.agent-src/contexts/execution/autonomy-mechanics.md +29 -0
  56. package/.agent-src/contexts/execution/verification-mechanics.md +80 -0
  57. package/.agent-src/personas/README.md +1 -1
  58. package/.agent-src/rules/agent-authority.md +24 -0
  59. package/.agent-src/rules/architecture.md +1 -1
  60. package/.agent-src/rules/artifact-drafting-protocol.md +1 -1
  61. package/.agent-src/rules/artifact-engagement-recording.md +1 -1
  62. package/.agent-src/rules/ask-when-uncertain.md +1 -1
  63. package/.agent-src/rules/autonomous-execution.md +78 -114
  64. package/.agent-src/rules/capture-learnings.md +1 -1
  65. package/.agent-src/rules/chat-history-cadence.md +3 -3
  66. package/.agent-src/rules/chat-history-ownership.md +3 -3
  67. package/.agent-src/rules/chat-history-visibility.md +3 -3
  68. package/.agent-src/rules/{command-suggestion.md → command-suggestion-policy.md} +7 -7
  69. package/.agent-src/rules/commit-conventions.md +1 -1
  70. package/.agent-src/rules/commit-policy.md +14 -42
  71. package/.agent-src/rules/context-hygiene.md +3 -3
  72. package/.agent-src/rules/direct-answers.md +1 -1
  73. package/.agent-src/rules/docs-sync.md +1 -1
  74. package/.agent-src/rules/e2e-testing.md +1 -1
  75. package/.agent-src/rules/guidelines.md +4 -4
  76. package/.agent-src/rules/improve-before-implement.md +2 -2
  77. package/.agent-src/rules/language-and-tone.md +37 -96
  78. package/.agent-src/rules/minimal-safe-diff.md +3 -3
  79. package/.agent-src/rules/model-recommendation.md +4 -4
  80. package/.agent-src/rules/no-cheap-questions.md +89 -0
  81. package/.agent-src/rules/non-destructive-by-default.md +15 -49
  82. package/.agent-src/rules/onboarding-gate.md +5 -5
  83. package/.agent-src/rules/review-routing-awareness.md +9 -9
  84. package/.agent-src/rules/roadmap-progress-sync.md +26 -33
  85. package/.agent-src/rules/role-mode-adherence.md +2 -2
  86. package/.agent-src/rules/scope-control.md +65 -46
  87. package/.agent-src/rules/security-sensitive-stop.md +2 -2
  88. package/.agent-src/rules/size-enforcement.md +1 -1
  89. package/.agent-src/rules/think-before-action.md +5 -5
  90. package/.agent-src/rules/token-efficiency.md +4 -4
  91. package/.agent-src/rules/{ui-audit-before-build.md → ui-audit-gate.md} +3 -3
  92. package/.agent-src/rules/user-interaction.md +3 -3
  93. package/.agent-src/rules/verify-before-complete.md +12 -67
  94. package/.agent-src/scripts/update_roadmap_progress.py +9 -4
  95. package/.agent-src/skills/ai-council/SKILL.md +333 -0
  96. package/.agent-src/skills/api-endpoint/SKILL.md +2 -2
  97. package/.agent-src/skills/blade-ui/SKILL.md +1 -1
  98. package/.agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
  99. package/.agent-src/skills/bug-analyzer/SKILL.md +1 -1
  100. package/.agent-src/skills/command-routing/SKILL.md +1 -1
  101. package/.agent-src/skills/command-writing/SKILL.md +1 -1
  102. package/.agent-src/skills/conventional-commits-writing/SKILL.md +1 -1
  103. package/.agent-src/skills/copilot-agents-optimization/SKILL.md +2 -2
  104. package/.agent-src/skills/developer-like-execution/SKILL.md +2 -2
  105. package/.agent-src/skills/flux/SKILL.md +1 -1
  106. package/.agent-src/skills/git-workflow/SKILL.md +1 -1
  107. package/.agent-src/skills/guideline-writing/SKILL.md +11 -11
  108. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +4 -4
  109. package/.agent-src/skills/livewire/SKILL.md +1 -1
  110. package/.agent-src/skills/override-management/SKILL.md +2 -2
  111. package/.agent-src/skills/php-coder/SKILL.md +1 -1
  112. package/.agent-src/skills/playwright-testing/SKILL.md +2 -2
  113. package/.agent-src/skills/readme-reviewer/SKILL.md +1 -1
  114. package/.agent-src/skills/readme-writing/SKILL.md +1 -1
  115. package/.agent-src/skills/readme-writing-package/SKILL.md +1 -1
  116. package/.agent-src/skills/receiving-code-review/SKILL.md +1 -1
  117. package/.agent-src/skills/review-routing/SKILL.md +2 -2
  118. package/.agent-src/skills/rule-writing/SKILL.md +1 -1
  119. package/.agent-src/skills/skill-reviewer/SKILL.md +1 -1
  120. package/.agent-src/skills/skill-writing/SKILL.md +3 -3
  121. package/.agent-src/skills/subagent-orchestration/SKILL.md +1 -0
  122. package/.agent-src/skills/systematic-debugging/SKILL.md +1 -1
  123. package/.agent-src/skills/upstream-contribute/SKILL.md +1 -1
  124. package/.agent-src/skills/validate-feature-fit/SKILL.md +2 -2
  125. package/.agent-src/skills/{verify-before-complete → verify-completion-evidence}/SKILL.md +2 -2
  126. package/.agent-src/templates/agent-settings.md +8 -8
  127. package/.agent-src/templates/contexts/auth-model.md +1 -1
  128. package/.agent-src/templates/scripts/README.md +2 -2
  129. package/.agent-src/templates/scripts/telemetry/aggregator.py +16 -1
  130. package/.agent-src/templates/scripts/telemetry/engagement.py +59 -0
  131. package/.agent-src/templates/scripts/telemetry/report_renderer.py +28 -1
  132. package/.agent-src/templates/scripts/telemetry_record.py +14 -1
  133. package/.claude-plugin/marketplace.json +10 -2
  134. package/AGENTS.md +11 -9
  135. package/CHANGELOG.md +123 -1
  136. package/README.md +28 -30
  137. package/config/agent-settings.template.yml +58 -1
  138. package/config/gitignore-block.txt +3 -0
  139. package/docs/architecture.md +4 -4
  140. package/docs/catalog.md +331 -0
  141. package/docs/contracts/STABILITY.md +39 -0
  142. package/docs/contracts/adr-command-suggestion.md +3 -3
  143. package/docs/contracts/adr-product-ui-track.md +2 -2
  144. package/docs/contracts/agent-memory-contract.md +2 -2
  145. package/docs/contracts/artifact-engagement-flow.md +1 -1
  146. package/docs/contracts/command-clusters.md +2 -2
  147. package/docs/contracts/command-suggestion-flow.md +3 -3
  148. package/docs/contracts/implement-ticket-flow.md +2 -2
  149. package/docs/contracts/linear-ai-rules-inclusion.md +1 -1
  150. package/docs/contracts/load-context-schema.md +186 -0
  151. package/docs/contracts/rule-interactions.yml +96 -0
  152. package/docs/contracts/rule-priority-hierarchy.md +87 -0
  153. package/docs/contracts/ui-track-flow.md +1 -1
  154. package/docs/customization.md +14 -0
  155. package/docs/end-to-end-walkthroughs.md +165 -0
  156. package/docs/getting-started.md +26 -8
  157. package/docs/github-topics.md +12 -3
  158. package/docs/guidelines/agent-infra/language-and-tone-examples.md +79 -0
  159. package/{.agent-src → docs}/guidelines/docs/readme-size-and-splitting.md +26 -25
  160. package/docs/guidelines/php/git.md +164 -0
  161. package/docs/migrations/commands-1.15.0.md +1 -1
  162. package/docs/showcase.md +9 -4
  163. package/docs/skills-catalog.md +14 -8
  164. package/docs/ui-track-mental-model.md +2 -2
  165. package/llms.txt +13 -7
  166. package/package.json +1 -1
  167. package/scripts/agent-config +23 -0
  168. package/scripts/ai_council/__init__.py +39 -0
  169. package/scripts/ai_council/_default_prices.py +41 -0
  170. package/scripts/ai_council/_one_off_rebalancing_audit.py +149 -0
  171. package/scripts/ai_council/_one_off_roundtrip.py +106 -0
  172. package/scripts/ai_council/budget_guard.py +172 -0
  173. package/scripts/ai_council/bundler.py +261 -0
  174. package/scripts/ai_council/clients.py +381 -0
  175. package/scripts/ai_council/modes.py +127 -0
  176. package/scripts/ai_council/orchestrator.py +350 -0
  177. package/scripts/ai_council/pricing.py +213 -0
  178. package/scripts/ai_council/project_context.py +159 -0
  179. package/scripts/ai_council/prompts.py +232 -0
  180. package/scripts/ai_council/session.py +144 -0
  181. package/scripts/check_always_budget.py +126 -0
  182. package/scripts/check_augmentignore.py +69 -0
  183. package/scripts/check_command_count_messaging.py +120 -0
  184. package/scripts/check_portability.py +55 -0
  185. package/scripts/check_public_catalog_links.py +122 -0
  186. package/scripts/check_references.py +4 -1
  187. package/scripts/check_roadmap_trackable.py +111 -0
  188. package/scripts/command_suggester/cooldown.py +1 -1
  189. package/scripts/generate_index.py +266 -0
  190. package/scripts/install_anthropic_key.sh +5 -0
  191. package/scripts/install_openai_key.sh +106 -0
  192. package/scripts/lint_load_context.py +163 -0
  193. package/scripts/schemas/command.schema.json +20 -0
  194. package/scripts/schemas/rule.schema.json +10 -0
  195. package/scripts/skill_linter.py +12 -4
  196. package/scripts/sync_agent_settings.py +1 -1
  197. package/scripts/update_counts.py +9 -4
  198. package/scripts/update_prices.py +124 -0
  199. package/.agent-src/guidelines/php/git.md +0 -96
  200. /package/.agent-src/rules/{slash-commands.md → slash-command-routing-policy.md} +0 -0
  201. /package/{.agent-src → docs}/guidelines/agent-infra/agent-interaction-and-decision-quality.md +0 -0
  202. /package/{.agent-src → docs}/guidelines/agent-infra/break-glass-usage.md +0 -0
  203. /package/{.agent-src → docs}/guidelines/agent-infra/developer-judgment.md +0 -0
  204. /package/{.agent-src → docs}/guidelines/agent-infra/engineering-memory-data-format.md +0 -0
  205. /package/{.agent-src → docs}/guidelines/agent-infra/layered-settings.md +0 -0
  206. /package/{.agent-src → docs}/guidelines/agent-infra/memory-access.md +0 -0
  207. /package/{.agent-src → docs}/guidelines/agent-infra/naming.md +0 -0
  208. /package/{.agent-src → docs}/guidelines/agent-infra/output-patterns.md +0 -0
  209. /package/{.agent-src → docs}/guidelines/agent-infra/review-routing-data-format.md +0 -0
  210. /package/{.agent-src → docs}/guidelines/agent-infra/role-contracts.md +0 -0
  211. /package/{.agent-src → docs}/guidelines/agent-infra/role-mode-router.md +0 -0
  212. /package/{.agent-src → docs}/guidelines/agent-infra/runtime-layer.md +0 -0
  213. /package/{.agent-src → docs}/guidelines/agent-infra/self-improvement-pipeline.md +0 -0
  214. /package/{.agent-src → docs}/guidelines/agent-infra/size-and-scope.md +0 -0
  215. /package/{.agent-src → docs}/guidelines/agent-infra/tool-integration.md +0 -0
  216. /package/{.agent-src → docs}/guidelines/e2e/playwright.md +0 -0
  217. /package/{.agent-src → docs}/guidelines/php/api-design.md +0 -0
  218. /package/{.agent-src → docs}/guidelines/php/artisan-commands.md +0 -0
  219. /package/{.agent-src → docs}/guidelines/php/blade-ui.md +0 -0
  220. /package/{.agent-src → docs}/guidelines/php/controllers.md +0 -0
  221. /package/{.agent-src → docs}/guidelines/php/database.md +0 -0
  222. /package/{.agent-src → docs}/guidelines/php/eloquent.md +0 -0
  223. /package/{.agent-src → docs}/guidelines/php/flux.md +0 -0
  224. /package/{.agent-src → docs}/guidelines/php/general.md +0 -0
  225. /package/{.agent-src → docs}/guidelines/php/jobs.md +0 -0
  226. /package/{.agent-src → docs}/guidelines/php/livewire.md +0 -0
  227. /package/{.agent-src → docs}/guidelines/php/logging.md +0 -0
  228. /package/{.agent-src → docs}/guidelines/php/naming.md +0 -0
  229. /package/{.agent-src → docs}/guidelines/php/patterns/dependency-injection.md +0 -0
  230. /package/{.agent-src → docs}/guidelines/php/patterns/dtos.md +0 -0
  231. /package/{.agent-src → docs}/guidelines/php/patterns/events.md +0 -0
  232. /package/{.agent-src → docs}/guidelines/php/patterns/factory.md +0 -0
  233. /package/{.agent-src → docs}/guidelines/php/patterns/pipelines.md +0 -0
  234. /package/{.agent-src → docs}/guidelines/php/patterns/policies.md +0 -0
  235. /package/{.agent-src → docs}/guidelines/php/patterns/repositories.md +0 -0
  236. /package/{.agent-src → docs}/guidelines/php/patterns/service-layer.md +0 -0
  237. /package/{.agent-src → docs}/guidelines/php/patterns/strategy.md +0 -0
  238. /package/{.agent-src → docs}/guidelines/php/patterns.md +0 -0
  239. /package/{.agent-src → docs}/guidelines/php/performance.md +0 -0
  240. /package/{.agent-src → docs}/guidelines/php/resources.md +0 -0
  241. /package/{.agent-src → docs}/guidelines/php/security.md +0 -0
  242. /package/{.agent-src → docs}/guidelines/php/sql.md +0 -0
  243. /package/{.agent-src → docs}/guidelines/php/validations.md +0 -0
  244. /package/{.agent-src → docs}/guidelines/php/websocket.md +0 -0
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Advisory check for `.augmentignore` (road-to-governance-cleanup F6.3).
4
+
5
+ Runs as part of `task ci` to surface `/optimize augmentignore` as a
6
+ periodic reminder. Always exits 0 — this is a warn-only advisory, not
7
+ a gate. Failures here never block CI.
8
+
9
+ Checks performed:
10
+ 1. Does `.augmentignore` exist at repo root?
11
+ 2. Is its mtime older than 90 days? (stale reminder)
12
+ 3. Is it suspiciously short (<5 non-blank, non-comment lines)?
13
+
14
+ If any check trips, prints a friendly hint and exits 0. If all clean,
15
+ prints a single-line OK and exits 0.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import sys
20
+ import time
21
+ from pathlib import Path
22
+
23
+ STALE_DAYS = 90
24
+ MIN_USEFUL_LINES = 5
25
+ REPO_ROOT = Path(__file__).resolve().parent.parent
26
+
27
+
28
+ def check() -> int:
29
+ target = REPO_ROOT / ".augmentignore"
30
+ notes: list[str] = []
31
+
32
+ if not target.exists():
33
+ notes.append("⚠️ .augmentignore is missing — run `/optimize augmentignore` to scaffold it.")
34
+ _emit(notes)
35
+ return 0
36
+
37
+ age_days = (time.time() - target.stat().st_mtime) / 86400
38
+ if age_days > STALE_DAYS:
39
+ notes.append(
40
+ f"ℹ️ .augmentignore is {int(age_days)} days old (threshold: {STALE_DAYS}) — "
41
+ "consider running `/optimize augmentignore` to refresh."
42
+ )
43
+
44
+ useful = [
45
+ ln for ln in target.read_text().splitlines()
46
+ if ln.strip() and not ln.strip().startswith("#")
47
+ ]
48
+ if len(useful) < MIN_USEFUL_LINES:
49
+ notes.append(
50
+ f"ℹ️ .augmentignore has only {len(useful)} active entries — "
51
+ "run `/optimize augmentignore` to detect tech-stack ignores you may be missing."
52
+ )
53
+
54
+ _emit(notes)
55
+ return 0
56
+
57
+
58
+ def _emit(notes: list[str]) -> None:
59
+ if not notes:
60
+ print("✅ .augmentignore advisory: nothing to suggest.")
61
+ return
62
+ print("📒 .augmentignore advisory (non-blocking):")
63
+ for n in notes:
64
+ print(f" {n}")
65
+ print(" (This is a reminder, not a CI failure.)")
66
+
67
+
68
+ if __name__ == "__main__":
69
+ sys.exit(check())
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Command-count messaging gate (regression guard for road-to-pr-34-followups 1.2).
4
+
5
+ Public surfaces (README.md, AGENTS.md, docs/getting-started.md) advertise
6
+ the size of the command catalog. PR #34 collapses atomic commands into
7
+ clusters via deprecation shims — the externally meaningful number is the
8
+ **active** command count (non-shim files), not the raw file count. This
9
+ gate sources canonical counts from `.agent-src.uncompressed/commands/`
10
+ frontmatter and fails when any documented number drifts from those.
11
+
12
+ Canonical counts:
13
+ total = number of *.md files under .agent-src.uncompressed/commands/
14
+ shims = files whose frontmatter declares `superseded_by:`
15
+ active = total - shims
16
+
17
+ Patterns checked (per file):
18
+
19
+ README.md
20
+ hero row "<strong>{N} Commands</strong>" → active
21
+ browse line "Browse all {N} active commands" → active
22
+ browse meta "{N} files total" → total
23
+ browse meta "{N} are deprecation shims" → shims
24
+ tools blurb "{N} native commands" → active
25
+
26
+ AGENTS.md
27
+ tree "commands/ ({N} files — {A} active + {S} deprecation shims)"
28
+
29
+ docs/getting-started.md
30
+ browse line "Browse all {N} active commands" → active
31
+
32
+ Exit codes: 0 = clean, 1 = drift detected.
33
+ """
34
+
35
+ from __future__ import annotations
36
+
37
+ import re
38
+ import sys
39
+ from pathlib import Path
40
+
41
+ ROOT = Path(__file__).resolve().parent.parent
42
+ COMMANDS_DIR = ROOT / ".agent-src.uncompressed" / "commands"
43
+ README = ROOT / "README.md"
44
+ AGENTS = ROOT / "AGENTS.md"
45
+ GETTING_STARTED = ROOT / "docs" / "getting-started.md"
46
+
47
+ FM_RE = re.compile(r"^---\s*\n(.*?)\n---", re.DOTALL)
48
+ SUPERSEDED_RE = re.compile(r"^superseded_by:\s*\S", re.MULTILINE)
49
+
50
+
51
+ def canonical_counts() -> tuple[int, int, int]:
52
+ if not COMMANDS_DIR.is_dir():
53
+ print(f"❌ {COMMANDS_DIR.relative_to(ROOT)} not found", file=sys.stderr)
54
+ sys.exit(1)
55
+ total = shims = 0
56
+ for f in COMMANDS_DIR.glob("*.md"):
57
+ total += 1
58
+ m = FM_RE.match(f.read_text(encoding="utf-8"))
59
+ fm = m.group(1) if m else ""
60
+ if SUPERSEDED_RE.search(fm):
61
+ shims += 1
62
+ return total, shims, total - shims
63
+
64
+
65
+ def _check(path: Path, pattern: str, expected: int, label: str) -> str | None:
66
+ if not path.exists():
67
+ return f"missing file: {path.relative_to(ROOT)}"
68
+ m = re.search(pattern, path.read_text(encoding="utf-8"))
69
+ if not m:
70
+ return f"{path.relative_to(ROOT)}: pattern not found for `{label}` — /{pattern}/"
71
+ found = int(m.group(1))
72
+ if found != expected:
73
+ return f"{path.relative_to(ROOT)}: `{label}` says {found}, expected {expected}"
74
+ return None
75
+
76
+
77
+ def main() -> int:
78
+ total, shims, active = canonical_counts()
79
+ print(f"Canonical counts: {total} files · {shims} shims · {active} active")
80
+
81
+ checks = [
82
+ # README.md
83
+ (README, r"<strong>(\d+) Commands</strong>", active, "hero row"),
84
+ (README, r"Browse all (\d+) active commands", active, "browse line"),
85
+ (README, r"\((\d+) files total ", total, "browse meta · total files"),
86
+ (README, r"— (\d+) are deprecation shims", shims, "browse meta · shims"),
87
+ (README, r"\+ (\d+) native commands\)", active, "tools blurb"),
88
+ # AGENTS.md (`commands/ (84 files — 69 active + 15 deprecation shims)`)
89
+ (AGENTS, r"commands/\s+\((\d+) files —", total, "tree · total files"),
90
+ (AGENTS, r"files — (\d+) active", active, "tree · active"),
91
+ (AGENTS, r"active \+ (\d+) deprecation shims", shims, "tree · shims"),
92
+ # docs/getting-started.md
93
+ (GETTING_STARTED, r"Browse all (\d+) active commands", active, "browse line"),
94
+ ]
95
+
96
+ errors: list[str] = []
97
+ for path, pattern, expected, label in checks:
98
+ err = _check(path, pattern, expected, label)
99
+ if err:
100
+ errors.append(err)
101
+
102
+ if not errors:
103
+ print("✅ All command-count messaging in sync with registry.")
104
+ return 0
105
+
106
+ print(f"❌ Command-count messaging drift — {len(errors)} mismatch(es):")
107
+ for e in errors:
108
+ print(f" {e}")
109
+ print(
110
+ "\nFix: update the documented numbers above, or run "
111
+ "`task check-command-count` after editing."
112
+ )
113
+ print(
114
+ "Why this gate exists: see `agents/roadmaps/road-to-pr-34-followups.md` § 1.2."
115
+ )
116
+ return 1
117
+
118
+
119
+ if __name__ == "__main__":
120
+ sys.exit(main())
@@ -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
@@ -467,6 +516,12 @@ def scan_all(root: Path) -> tuple[List[Violation], list[str]]:
467
516
  if not any(path_str.endswith(skip) for skip in _CLI_DETECTOR_SKIP):
468
517
  violations.extend(check_cli_invocations(f))
469
518
 
519
+ # Layer 5: identity-framing scan on the public identity surface
520
+ for rel in IDENTITY_SCAN_FILES:
521
+ f = root / rel
522
+ if f.is_file():
523
+ violations.extend(check_identity_framing(f))
524
+
470
525
  return violations, detected
471
526
 
472
527
 
@@ -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/`.
@@ -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())
@@ -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
  """