@event4u/agent-config 1.12.0 → 1.14.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 (260) hide show
  1. package/.agent-src/commands/agent-handoff.md +3 -0
  2. package/.agent-src/commands/agent-status.md +3 -0
  3. package/.agent-src/commands/agents-audit.md +4 -0
  4. package/.agent-src/commands/agents-cleanup.md +6 -1
  5. package/.agent-src/commands/agents-prepare.md +3 -0
  6. package/.agent-src/commands/analyze-reference-repo.md +4 -0
  7. package/.agent-src/commands/bug-fix.md +5 -1
  8. package/.agent-src/commands/bug-investigate.md +4 -0
  9. package/.agent-src/commands/chat-history-checkpoint.md +126 -0
  10. package/.agent-src/commands/chat-history-clear.md +5 -0
  11. package/.agent-src/commands/chat-history-resume.md +5 -0
  12. package/.agent-src/commands/chat-history.md +5 -0
  13. package/.agent-src/commands/check-current-md.md +126 -0
  14. package/.agent-src/commands/commit-in-chunks.md +98 -0
  15. package/.agent-src/commands/commit.md +4 -0
  16. package/.agent-src/commands/compress.md +3 -0
  17. package/.agent-src/commands/context-create.md +4 -0
  18. package/.agent-src/commands/context-refactor.md +4 -0
  19. package/.agent-src/commands/copilot-agents-init.md +3 -0
  20. package/.agent-src/commands/copilot-agents-optimize.md +3 -0
  21. package/.agent-src/commands/create-pr-description.md +4 -0
  22. package/.agent-src/commands/create-pr.md +4 -0
  23. package/.agent-src/commands/do-and-judge.md +4 -1
  24. package/.agent-src/commands/do-in-steps.md +3 -0
  25. package/.agent-src/commands/e2e-heal.md +4 -0
  26. package/.agent-src/commands/e2e-plan.md +4 -0
  27. package/.agent-src/commands/estimate-ticket.md +4 -1
  28. package/.agent-src/commands/feature-dev.md +4 -0
  29. package/.agent-src/commands/feature-explore.md +4 -0
  30. package/.agent-src/commands/feature-plan.md +4 -0
  31. package/.agent-src/commands/feature-refactor.md +4 -0
  32. package/.agent-src/commands/feature-roadmap.md +6 -0
  33. package/.agent-src/commands/fix-ci.md +4 -0
  34. package/.agent-src/commands/fix-portability.md +3 -0
  35. package/.agent-src/commands/fix-pr-bot-comments.md +4 -0
  36. package/.agent-src/commands/fix-pr-comments.md +4 -0
  37. package/.agent-src/commands/fix-pr-developer-comments.md +4 -0
  38. package/.agent-src/commands/fix-references.md +3 -0
  39. package/.agent-src/commands/fix-seeder.md +4 -0
  40. package/.agent-src/commands/implement-ticket.md +39 -13
  41. package/.agent-src/commands/jira-ticket.md +4 -0
  42. package/.agent-src/commands/judge.md +3 -0
  43. package/.agent-src/commands/memory-add.md +5 -3
  44. package/.agent-src/commands/memory-full.md +5 -2
  45. package/.agent-src/commands/memory-promote.md +7 -6
  46. package/.agent-src/commands/mode.md +3 -0
  47. package/.agent-src/commands/module-create.md +4 -0
  48. package/.agent-src/commands/module-explore.md +4 -0
  49. package/.agent-src/commands/onboard.md +24 -0
  50. package/.agent-src/commands/optimize-agents.md +4 -0
  51. package/.agent-src/commands/optimize-augmentignore.md +3 -0
  52. package/.agent-src/commands/optimize-rtk-filters.md +3 -0
  53. package/.agent-src/commands/optimize-skills.md +4 -0
  54. package/.agent-src/commands/override-create.md +4 -0
  55. package/.agent-src/commands/override-manage.md +4 -0
  56. package/.agent-src/commands/package-reset.md +3 -0
  57. package/.agent-src/commands/package-test.md +3 -0
  58. package/.agent-src/commands/prepare-for-review.md +4 -0
  59. package/.agent-src/commands/project-analyze.md +4 -0
  60. package/.agent-src/commands/project-health.md +4 -0
  61. package/.agent-src/commands/propose-memory.md +6 -8
  62. package/.agent-src/commands/quality-fix.md +4 -0
  63. package/.agent-src/commands/refine-ticket.md +4 -1
  64. package/.agent-src/commands/review-changes.md +4 -0
  65. package/.agent-src/commands/review-routing.md +4 -0
  66. package/.agent-src/commands/roadmap-create.md +7 -0
  67. package/.agent-src/commands/roadmap-execute.md +12 -1
  68. package/.agent-src/commands/rule-compliance-audit.md +4 -0
  69. package/.agent-src/commands/set-cost-profile.md +3 -0
  70. package/.agent-src/commands/sync-agent-settings.md +3 -0
  71. package/.agent-src/commands/sync-gitignore.md +3 -0
  72. package/.agent-src/commands/tests-create.md +4 -0
  73. package/.agent-src/commands/tests-execute.md +4 -0
  74. package/.agent-src/commands/threat-model.md +4 -0
  75. package/.agent-src/commands/update-form-request-messages.md +4 -0
  76. package/.agent-src/commands/upstream-contribute.md +4 -0
  77. package/.agent-src/commands/work.md +161 -0
  78. package/.agent-src/guidelines/agent-infra/engineering-memory-data-format.md +2 -6
  79. package/.agent-src/guidelines/agent-infra/layered-settings.md +0 -1
  80. package/.agent-src/guidelines/agent-infra/memory-access.md +0 -7
  81. package/.agent-src/guidelines/agent-infra/role-contracts.md +2 -4
  82. package/.agent-src/guidelines/agent-infra/self-improvement-pipeline.md +0 -1
  83. package/.agent-src/guidelines/php/patterns/strategy.md +180 -2
  84. package/.agent-src/personas/README.md +0 -1
  85. package/.agent-src/rules/artifact-drafting-protocol.md +7 -2
  86. package/.agent-src/rules/artifact-engagement-recording.md +133 -0
  87. package/.agent-src/rules/ask-when-uncertain.md +18 -13
  88. package/.agent-src/rules/augment-portability.md +8 -0
  89. package/.agent-src/rules/autonomous-execution.md +158 -0
  90. package/.agent-src/rules/chat-history.md +147 -118
  91. package/.agent-src/rules/cli-output-handling.md +26 -3
  92. package/.agent-src/rules/command-suggestion.md +133 -0
  93. package/.agent-src/rules/commit-policy.md +99 -0
  94. package/.agent-src/rules/direct-answers.md +114 -0
  95. package/.agent-src/rules/docs-sync.md +36 -0
  96. package/.agent-src/rules/downstream-changes.md +10 -9
  97. package/.agent-src/rules/improve-before-implement.md +9 -6
  98. package/.agent-src/rules/language-and-tone.md +81 -6
  99. package/.agent-src/rules/non-destructive-by-default.md +117 -0
  100. package/.agent-src/rules/package-ci-checks.md +4 -0
  101. package/.agent-src/rules/preservation-guard.md +20 -0
  102. package/.agent-src/rules/roadmap-progress-sync.md +103 -30
  103. package/.agent-src/rules/scope-control.md +42 -1
  104. package/.agent-src/rules/size-enforcement.md +1 -3
  105. package/.agent-src/rules/skill-quality.md +3 -8
  106. package/.agent-src/rules/ui-audit-before-build.md +106 -0
  107. package/.agent-src/rules/user-interaction.md +81 -3
  108. package/.agent-src/scripts/update_roadmap_progress.py +48 -6
  109. package/.agent-src/skills/blade-ui/SKILL.md +30 -5
  110. package/.agent-src/skills/command-routing/SKILL.md +32 -0
  111. package/.agent-src/skills/command-writing/SKILL.md +41 -2
  112. package/.agent-src/skills/description-assist/SKILL.md +21 -0
  113. package/.agent-src/skills/estimate-ticket/SKILL.md +0 -1
  114. package/.agent-src/skills/existing-ui-audit/SKILL.md +187 -0
  115. package/.agent-src/skills/fe-design/SKILL.md +72 -60
  116. package/.agent-src/skills/finishing-a-development-branch/SKILL.md +4 -0
  117. package/.agent-src/skills/flux/SKILL.md +31 -4
  118. package/.agent-src/skills/guideline-writing/SKILL.md +24 -2
  119. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +51 -9
  120. package/.agent-src/skills/livewire/SKILL.md +30 -4
  121. package/.agent-src/skills/md-language-check/SKILL.md +103 -0
  122. package/.agent-src/skills/php-coder/SKILL.md +24 -0
  123. package/.agent-src/skills/react-shadcn-ui/SKILL.md +121 -0
  124. package/.agent-src/skills/refine-prompt/SKILL.md +220 -0
  125. package/.agent-src/skills/refine-ticket/SKILL.md +2 -4
  126. package/.agent-src/skills/roadmap-management/SKILL.md +10 -3
  127. package/.agent-src/skills/rule-writing/SKILL.md +23 -1
  128. package/.agent-src/skills/skill-writing/SKILL.md +1 -3
  129. package/.agent-src/skills/upstream-contribute/SKILL.md +1 -1
  130. package/.agent-src/skills/using-git-worktrees/SKILL.md +3 -1
  131. package/.agent-src/templates/AGENTS.md +24 -6
  132. package/.agent-src/templates/agent-settings.md +149 -0
  133. package/.agent-src/templates/github-workflows/roadmap-progress-check.yml +63 -0
  134. package/.agent-src/templates/hooks/pre-commit-roadmap-progress +60 -0
  135. package/.agent-src/templates/roadmaps.md +8 -2
  136. package/.agent-src/templates/scripts/implement_ticket/__init__.py +63 -26
  137. package/.agent-src/templates/scripts/implement_ticket/__main__.py +8 -2
  138. package/.agent-src/templates/scripts/memory_lookup.py +382 -21
  139. package/.agent-src/templates/scripts/memory_status.py +110 -9
  140. package/.agent-src/templates/scripts/telemetry/__init__.py +42 -0
  141. package/.agent-src/templates/scripts/telemetry/aggregator.py +154 -0
  142. package/.agent-src/templates/scripts/telemetry/boundary.py +171 -0
  143. package/.agent-src/templates/scripts/telemetry/engagement.py +238 -0
  144. package/.agent-src/templates/scripts/telemetry/report_renderer.py +170 -0
  145. package/.agent-src/templates/scripts/telemetry/settings.py +112 -0
  146. package/.agent-src/templates/scripts/telemetry_record.py +166 -0
  147. package/.agent-src/templates/scripts/telemetry_report.py +161 -0
  148. package/.agent-src/templates/scripts/telemetry_status.py +142 -0
  149. package/.agent-src/templates/scripts/work_engine/__init__.py +58 -0
  150. package/.agent-src/templates/scripts/work_engine/__main__.py +9 -0
  151. package/.agent-src/templates/scripts/work_engine/cli.py +592 -0
  152. package/.agent-src/templates/scripts/{implement_ticket → work_engine}/delivery_state.py +7 -0
  153. package/.agent-src/templates/scripts/work_engine/directives/__init__.py +33 -0
  154. package/.agent-src/templates/scripts/work_engine/directives/backend/__init__.py +98 -0
  155. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/analyze.py +1 -1
  156. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/implement.py +2 -2
  157. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/memory.py +1 -1
  158. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/plan.py +1 -1
  159. package/.agent-src/templates/scripts/work_engine/directives/backend/refine.py +396 -0
  160. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/report.py +36 -4
  161. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/test.py +2 -2
  162. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/verify.py +2 -2
  163. package/.agent-src/templates/scripts/work_engine/directives/mixed/__init__.py +116 -0
  164. package/.agent-src/templates/scripts/work_engine/directives/mixed/contract.py +254 -0
  165. package/.agent-src/templates/scripts/work_engine/directives/mixed/stitch.py +229 -0
  166. package/.agent-src/templates/scripts/work_engine/directives/mixed/ui.py +231 -0
  167. package/.agent-src/templates/scripts/work_engine/directives/ui/__init__.py +113 -0
  168. package/.agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +44 -0
  169. package/.agent-src/templates/scripts/work_engine/directives/ui/apply.py +241 -0
  170. package/.agent-src/templates/scripts/work_engine/directives/ui/audit.py +414 -0
  171. package/.agent-src/templates/scripts/work_engine/directives/ui/design.py +335 -0
  172. package/.agent-src/templates/scripts/work_engine/directives/ui/polish.py +510 -0
  173. package/.agent-src/templates/scripts/work_engine/directives/ui/review.py +468 -0
  174. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/__init__.py +119 -0
  175. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/_skipped.py +37 -0
  176. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/apply.py +165 -0
  177. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/refine.py +66 -0
  178. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/report.py +62 -0
  179. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/test.py +115 -0
  180. package/.agent-src/templates/scripts/work_engine/dispatcher.py +331 -0
  181. package/.agent-src/templates/scripts/work_engine/hooks/__init__.py +54 -0
  182. package/.agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +32 -0
  183. package/.agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.py +103 -0
  184. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.py +44 -0
  185. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.py +42 -0
  186. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_heartbeat.py +50 -0
  187. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_turn_check.py +49 -0
  188. package/.agent-src/templates/scripts/work_engine/hooks/builtin/directive_set_guard.py +53 -0
  189. package/.agent-src/templates/scripts/work_engine/hooks/builtin/halt_surface_audit.py +50 -0
  190. package/.agent-src/templates/scripts/work_engine/hooks/builtin/state_shape_validation.py +52 -0
  191. package/.agent-src/templates/scripts/work_engine/hooks/builtin/trace.py +84 -0
  192. package/.agent-src/templates/scripts/work_engine/hooks/context.py +66 -0
  193. package/.agent-src/templates/scripts/work_engine/hooks/events.py +44 -0
  194. package/.agent-src/templates/scripts/work_engine/hooks/exceptions.py +79 -0
  195. package/.agent-src/templates/scripts/work_engine/hooks/registry.py +60 -0
  196. package/.agent-src/templates/scripts/work_engine/hooks/runner.py +73 -0
  197. package/.agent-src/templates/scripts/work_engine/hooks/settings.py +141 -0
  198. package/.agent-src/templates/scripts/work_engine/intent/__init__.py +47 -0
  199. package/.agent-src/templates/scripts/work_engine/intent/classify.py +280 -0
  200. package/.agent-src/templates/scripts/work_engine/migration/__init__.py +8 -0
  201. package/.agent-src/templates/scripts/work_engine/migration/v0_to_v1.py +199 -0
  202. package/.agent-src/templates/scripts/work_engine/resolvers/__init__.py +22 -0
  203. package/.agent-src/templates/scripts/work_engine/resolvers/diff.py +106 -0
  204. package/.agent-src/templates/scripts/work_engine/resolvers/file.py +113 -0
  205. package/.agent-src/templates/scripts/work_engine/resolvers/prompt.py +90 -0
  206. package/.agent-src/templates/scripts/work_engine/scoring/__init__.py +14 -0
  207. package/.agent-src/templates/scripts/work_engine/scoring/confidence.py +300 -0
  208. package/.agent-src/templates/scripts/work_engine/stack/__init__.py +31 -0
  209. package/.agent-src/templates/scripts/work_engine/stack/detect.py +187 -0
  210. package/.agent-src/templates/scripts/work_engine/state.py +641 -0
  211. package/.claude-plugin/marketplace.json +105 -2
  212. package/AGENTS.md +36 -8
  213. package/CHANGELOG.md +558 -0
  214. package/README.md +146 -4
  215. package/composer.json +3 -0
  216. package/config/agent-settings.template.yml +45 -0
  217. package/config/gitignore-block.txt +4 -0
  218. package/docs/architecture.md +28 -1
  219. package/docs/development.md +1 -1
  220. package/docs/getting-started.md +3 -2
  221. package/docs/installation.md +86 -0
  222. package/docs/showcase.md +204 -0
  223. package/package.json +9 -1
  224. package/scripts/agent-config +274 -0
  225. package/scripts/audit_cloud_compatibility.py +288 -0
  226. package/scripts/build_cloud_bundle.py +458 -0
  227. package/scripts/build_linear_digest.py +263 -0
  228. package/scripts/chat_history.py +796 -7
  229. package/scripts/check_compression.py +139 -0
  230. package/scripts/check_iron_law_prominence.py +143 -0
  231. package/scripts/check_md_language.py +159 -0
  232. package/scripts/check_portability.py +36 -0
  233. package/scripts/check_reply_consistency.py +140 -0
  234. package/scripts/command_suggester/__init__.py +51 -0
  235. package/scripts/command_suggester/cooldown.py +132 -0
  236. package/scripts/command_suggester/loader.py +70 -0
  237. package/scripts/command_suggester/match.py +180 -0
  238. package/scripts/command_suggester/rank.py +120 -0
  239. package/scripts/command_suggester/render.py +86 -0
  240. package/scripts/command_suggester/sanitize.py +113 -0
  241. package/scripts/command_suggester/settings.py +125 -0
  242. package/scripts/command_suggester/types.py +78 -0
  243. package/scripts/hooks/augment-chat-history.sh +56 -0
  244. package/scripts/install-hooks.sh +67 -0
  245. package/scripts/install.py +150 -33
  246. package/scripts/lint_marketplace.py +27 -0
  247. package/scripts/memory_lookup.py +143 -7
  248. package/scripts/memory_status.py +76 -14
  249. package/scripts/migrate_command_suggestions.py +151 -0
  250. package/scripts/postinstall.sh +16 -0
  251. package/scripts/schemas/command.schema.json +41 -0
  252. package/scripts/skill_linter.py +67 -0
  253. package/scripts/sync_agent_settings.py +42 -12
  254. package/templates/consumer-settings/augment-cli-hooks.json +54 -0
  255. package/templates/consumer-settings/claude-settings.json +55 -1
  256. package/.agent-src/templates/scripts/implement_ticket/cli.py +0 -171
  257. package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +0 -134
  258. package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +0 -49
  259. package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +0 -140
  260. /package/.agent-src/templates/scripts/{implement_ticket → work_engine}/persona_policy.py +0 -0
@@ -7,22 +7,29 @@ source: package
7
7
 
8
8
  # Roadmap Progress Sync
9
9
 
10
- ## Rule
10
+ ## Iron Law
11
11
 
12
- **CRITICAL — ZERO TOLERANCE:** Whenever you change checkbox state in a
13
- roadmap file (`agents/roadmaps/*.md`, module or package equivalents)
14
- you MUST regenerate the dashboard **in the same response** not
15
- later, not batched across sessions, not "at the end of the roadmap".
12
+ ```
13
+ ANY ROADMAP TOUCH REGENERATE THE DASHBOARD, SAME RESPONSE.
14
+ NO EXCEPTIONS. NO "I'LL DO IT AT THE END". NO BATCHING ACROSS TURNS.
15
+ A ROADMAP NOT IN THE DASHBOARD IS A RULE VIOLATION, NOT AN OVERSIGHT.
16
+ ```
17
+
18
+ **Roadmap touch =** create file, rename, delete, move between
19
+ `roadmaps/` ↔ `archive/` ↔ `skipped/`, add/rename/remove phase,
20
+ **OR** flip any checkbox (`[ ]` ↔ `[x]` ↔ `[~]` ↔ `[-]`).
16
21
 
17
- `agents/roadmaps-progress.md` is the read-only dashboard. Every
18
- unsynced edit makes it lie to the next reader.
22
+ `agents/roadmaps-progress.md` is read-only dashboard. Every unsynced
23
+ edit lies to next reader. Created roadmap, no regen → dashboard
24
+ claims it does not exist. Marked 8 steps `[x]`, forgot regen →
25
+ dashboard says 0 done.
19
26
 
20
- **Completion = archival, same response.** When the edit takes a
21
- roadmap to `count_open == 0` (every item is `[x]`, `[~]`, or `[-]`),
22
- `git mv` it into `agents/roadmaps/archive/` (or `skipped/` if no
23
- `[x]` at all) **before** regenerating. A 100%-complete roadmap left
24
- in `agents/roadmaps/` is a rule violation. See `roadmap-management`
25
- for the archive vs skipped decision table.
27
+ **Completion = archival, same response.** Edit takes roadmap to
28
+ `count_open == 0` (every item `[x]`, `[~]`, or `[-]`) → `git mv` to
29
+ `agents/roadmaps/archive/` (or `skipped/` if no `[x]` at all)
30
+ **before** regen. 100%-complete roadmap left in `agents/roadmaps/`
31
+ is rule violation. See `roadmap-management` skill for archive vs
32
+ skipped table.
26
33
 
27
34
  ## How to regenerate
28
35
 
@@ -30,38 +37,104 @@ for the archive vs skipped decision table.
30
37
  ./agent-config roadmap:progress
31
38
  ```
32
39
 
33
- The `./agent-config` wrapper is written into the project root by the
34
- installer and delegates to the master CLI inside
35
- `node_modules/@event4u/agent-config/` or `vendor/event4u/agent-config/`.
36
- No global tooling required.
40
+ `./agent-config` wrapper sits in project root, written by installer,
41
+ delegates to master CLI in `node_modules/@event4u/agent-config/` or
42
+ `vendor/event4u/agent-config/`. No global tooling.
37
43
 
38
44
  ## Triggers
39
45
 
40
46
  | Edit | Must run, same response |
41
47
  |---|---|
48
+ | **Create new roadmap file** | regenerate dashboard |
49
+ | **Rename or delete roadmap file** | regenerate dashboard |
42
50
  | Mark step `[x]`, `[~]`, `[-]`, or unmark back to `[ ]` | regenerate dashboard |
43
- | Add, rename, or remove a phase | regenerate dashboard |
44
- | Create a new roadmap file | regenerate dashboard |
51
+ | Add, rename, or remove phase | regenerate dashboard |
45
52
  | **Last `[ ]` flips** — roadmap reaches `count_open == 0` | `git mv` → `archive/` (or `skipped/`) **then** regenerate dashboard |
46
53
  | Move roadmap between `roadmaps/` ↔ `archive/` ↔ `skipped/` | regenerate dashboard |
47
54
 
48
- **Batching:** multiple checkbox edits in one response → a **single**
49
- regeneration at the end is enough. If one closes a roadmap, archive
50
- it first, then run the single regen. But the response must not end
51
- without it.
55
+ **Batching:** multiple checkbox edits in one response → **single**
56
+ regen at end is enough. One edit closes a roadmap archive first,
57
+ then single regen. Response must not end without it.
58
+
59
+ ## Autonomous execution — checkbox cadence
60
+
61
+ Autonomous roadmap run (multi-turn, no per-step user prompt) → user
62
+ loses progress unless checkboxes flip **as work lands**, not at end.
63
+ Iron Law:
64
+
65
+ ```
66
+ EVERY DONE STEP FLIPS [ ] → [x] IN NEXT REPLY THAT ACKNOWLEDGES IT.
67
+ NO "I UPDATE ROADMAP AT END OF PHASE."
68
+ NO "FOUR STEPS DONE, ONE COMMIT, ONE REGEN."
69
+ ```
70
+
71
+ Step counts as done when:
72
+
73
+ - Code / docs change for step **written and saved** AND
74
+ - Verification cited in step (project CI command, targeted test, lint) **passed
75
+ in this response or earlier** — fresh output, not memory.
76
+
77
+ Then in **same reply**: flip checkbox, regen dashboard, commit if
78
+ commit policy allows.
79
+
80
+ **Forbidden pattern** (canonical failure):
81
+
82
+ > Turn 1: Step 1. Turn 2: Step 2. Turn 3: Step 3. Turn 4: Step 4.
83
+ > Turn 5: "all done, update roadmap and commit." → user spent four
84
+ > turns without dashboard movement.
85
+
86
+ **Required pattern:**
87
+
88
+ > Turn 1: Step 1, flip `[x]`, regen, commit.
89
+ > Turn 2: Step 2, flip `[x]`, regen, commit. …
90
+
91
+ Reply that lands verified step without flipping checkbox = rule violation.
92
+
93
+ **In-progress marker:** step takes more than one reply → mark `[~]`
94
+ moment work starts, regen. User sees row move `[ ]` → `[~]` → `[x]`
95
+ instead of silent rows. `[~]` open for `count_open` but moves phase
96
+ percentage forward.
97
+
98
+ ## Pre-send self-check — MANDATORY
99
+
100
+ Before sending any reply that touched `agents/roadmaps/`, silent gate:
101
+
102
+ 1. Did this turn create, rename, delete, or move a roadmap file? → regen MUST be in reply.
103
+ 2. Did this turn flip any checkbox in a roadmap file? → regen MUST be in reply.
104
+ 3. Did the regen output (`✅ Wrote agents/roadmaps-progress.md · …`) actually appear this turn? → no → run it now before sending.
105
+ 4. **Autonomous roadmap execution gate** — did this turn complete a roadmap step (code saved + verification passed) without flipping its checkbox? → flip `[x]` (or `[~]` if multi-turn) and regen before sending.
106
+
107
+ Any "yes" + no regen run = rule violation. Rerun before sending.
52
108
 
53
109
  ## Why this is a rule, not a skill tip
54
110
 
55
- The `roadmap-management` skill documents the command in several
56
- places, but skill body text is easy to miss under procedure pressure.
57
- A rule collapses the constraint into one line the model cannot skip:
58
- "checkbox edit → regenerate dashboard — same response".
111
+ `roadmap-management` skill documents command in several places, but
112
+ skill body text easy to miss under procedure pressure. Rule collapses
113
+ constraint into one line model cannot skip: "checkbox edit →
114
+ regenerate dashboard — same response".
59
115
 
60
116
  ## Do NOT
61
117
 
62
118
  - Do NOT edit `agents/roadmaps-progress.md` by hand — always regenerate.
63
119
  - Do NOT defer regen to "next commit" or "before push" — same response.
64
120
  - Do NOT rely on CI (`--check` mode) as first line of defence — CI is last-line, not real-time.
65
- - Do NOT skip regen because "only one checkbox changed" — the dashboard aggregates counts and phase percentages that shift on single edits.
66
- - Do NOT leave a 100%-complete roadmap in `agents/roadmaps/` "for review" — archive same response, ask the user afterwards if needed, not before.
67
- - Do NOT regenerate the dashboard before the `git mv` when a roadmap closes — otherwise it reappears in "Open roadmaps".
121
+ - Do NOT skip regen because "only one checkbox changed" — dashboard aggregates counts and phase percentages that shift on single edits.
122
+ - Do NOT leave 100%-complete roadmap in `agents/roadmaps/` "for review" — archive same response, ask user afterwards if needed.
123
+ - Do NOT regenerate dashboard before `git mv` when roadmap closes — otherwise it reappears in "Open roadmaps".
124
+
125
+ ## Failure modes
126
+
127
+ - **Created roadmap, marked Phase 1 done across multiple turns,
128
+ never regenerated** — dashboard silently lies "this roadmap does
129
+ not exist" to next reader. Canonical failure of this rule; rule
130
+ hardened in response to it.
131
+ - **Regenerated yesterday, edited today, "regen at session end"** —
132
+ session ends from crash, regen never lands.
133
+ - **Closed roadmap (last `[ ]` → `[x]`) and regenerated before
134
+ `git mv`** — closed roadmap reappears in "Open roadmaps".
135
+ - **Edited dashboard by hand to "fix it quickly"** — next regen
136
+ overwrites manual edit; no audit trail.
137
+ - **Autonomous run, four steps shipped across four turns, dashboard
138
+ flat whole time, single regen at end** — user lost progress
139
+ visibility for entire run. Each done step must flip checkbox in
140
+ reply that ships it.
@@ -18,7 +18,11 @@ source: package
18
18
 
19
19
  ## Git operations — permission-gated
20
20
 
21
- The user decides the git shape of the work.
21
+ The user decides the git shape of the work. Never improvise.
22
+
23
+ > **Commit specifics:** see [`commit-policy`](commit-policy.md) — narrower
24
+ > than the general "no git ops without permission" below (never-ask
25
+ > default + roadmap-authorized exception).
22
26
 
23
27
  - NEVER commit, push, merge, rebase, or force-push without explicit user permission.
24
28
  - NEVER create, switch, or delete a branch without explicit user permission.
@@ -26,6 +30,12 @@ The user decides the git shape of the work.
26
30
  - NEVER create, close, reopen, or retarget a pull request without explicit
27
31
  user permission.
28
32
  - NEVER push a tag or create a release without explicit user permission.
33
+ - NEVER include version numbers, releases, deprecation dates,
34
+ release-tied milestones, or git tags in roadmaps, plans, tickets, or
35
+ any planning artifact. Roadmaps plan **work**; releases are a
36
+ separate user decision. Never surface "which release" as a numbered
37
+ option, ADR field, or roadmap entry. If user wants a release pinned
38
+ to a milestone, they say so explicitly.
29
39
  - If a task seems to need a separate branch or PR, STOP and **brief
30
40
  first, ask second**. The brief MUST cover, in order:
31
41
  1. **Why** — what the new branch solves that the current one cannot.
@@ -38,3 +48,34 @@ The user decides the git shape of the work.
38
48
  "Explicit permission" = the user said so this turn or gave a standing
39
49
  instruction they have not revoked. Earlier permission for another op
40
50
  does not carry over.
51
+
52
+ ## Production, infrastructure, bulk-destructive — Hard Floor
53
+
54
+ Subset of the above is **never** autonomous and never auto-permitted
55
+ by a standing autonomy directive. Canonical rule:
56
+ [`non-destructive-by-default`](non-destructive-by-default.md).
57
+ Restated so this file remains the single read for git/scope concerns:
58
+
59
+ - **Production-branch merges** — `main`, `master`, `prod`, `production`, `release/*`, or any deployment-trunk branch. Always ask, even when the roadmap step says "merge".
60
+ - **Deploys / releases** — `terraform apply` / `kubectl apply` on prod, deploy scripts, release commands, tag pushes that trigger CI deployment. Always ask.
61
+ - **Production data / infrastructure** — prod DB writes / migrations, prod config edits, secrets rotation, IAM / role / policy, DNS, anything in a `prod`-scoped path or pipeline. Always ask.
62
+ - **Bulk-destructive ops** — wildcard or directory deletion (`rm -rf <dir>`, `git rm -r`), `DROP TABLE`, `TRUNCATE`, `git reset --hard` past unpushed work, mass class / module / migration deletion. Always ask.
63
+
64
+ A roadmap step or earlier turn does **not** count as authorization for
65
+ these. Authorization is "the user said so on this turn".
66
+
67
+ ## Decline = silence — no re-asking on the same task
68
+
69
+ After a declined proposal (branch switch, PR, tag/release entry,
70
+ worktree, version pinning in a roadmap), do **not** raise it again on
71
+ the same task. Decline stands until user reopens it.
72
+
73
+ Right moment to ask — at most **once**, only when genuinely useful —
74
+ is **before** work starts (writing roadmap, opening ticket), not
75
+ mid-execution. During roadmap execution the branch question is
76
+ settled; do not resurface it step by step.
77
+
78
+ A proposal that "might be sensible" is not enough reason to ask.
79
+ Default: stay on current branch, no release language. Only ask with
80
+ concrete evidence-based reason (e.g. risky migration → spike branch).
81
+ If in doubt, do not ask.
@@ -24,6 +24,4 @@ source: package
24
24
 
25
25
  → Size limits and details: `.augment/guidelines/agent-infra/size-and-scope.md`
26
26
 
27
- → Frontmatter contract (required/optional keys per type):
28
- [`agents/docs/frontmatter-contract.md`](../../../agents/docs/frontmatter-contract.md).
29
- Schemas live in `scripts/schemas/` and are enforced by `python3 scripts/validate_frontmatter.py`.
27
+ → Frontmatter contract: schemas live in `scripts/schemas/` and are enforced by `python3 scripts/validate_frontmatter.py`.
@@ -25,10 +25,8 @@ Every skill MUST have: `When to use`, `Procedure`, `Gotcha`, `Output format`, `D
25
25
  ## Frontmatter Contract
26
26
 
27
27
  Every skill's YAML frontmatter MUST validate against `scripts/schemas/skill.schema.json`.
28
- See [`agents/docs/frontmatter-contract.md`](../../../agents/docs/frontmatter-contract.md)
29
- for the human-readable contract across all artefact types. Violations are
30
- reported by `scripts/skill_linter.py` as `schema_<rule>` errors and fail
31
- `python3 scripts/validate_frontmatter.py` and the full CI pipeline.
28
+ Violations are reported by `scripts/skill_linter.py` as `schema_<rule>` errors
29
+ and fail `python3 scripts/validate_frontmatter.py` and the full CI pipeline.
32
30
 
33
31
  ## Description Triggering
34
32
 
@@ -47,10 +45,7 @@ Make descriptions "pushy" — explicit about when to fire:
47
45
  adjectives, drop the second example phrasing, or collapse a list — do
48
46
  **not** drop the trigger vocabulary or the `even if ...` tail.
49
47
 
50
- Source: [`skills/skill-creator` in `anthropics/skills`](https://github.com/anthropics/skills/blob/main/skills/skill-creator/SKILL.md)
51
- — description-optimization guidance adopted via
52
- [`agents/roadmaps/archive/road-to-anthropic-alignment.md`](../../../agents/roadmaps/archive/road-to-anthropic-alignment.md)
53
- Phase 2.
48
+ Source: [`skills/skill-creator` in `anthropics/skills`](https://github.com/anthropics/skills/blob/main/skills/skill-creator/SKILL.md).
54
49
 
55
50
  **Litmus test:** Read the description cold, without the skill's body. If you
56
51
  cannot name at least two phrasings a user would realistically type that should
@@ -0,0 +1,106 @@
1
+ ---
2
+ type: "always"
3
+ description: "UI work — never write a component, screen, or partial without existing-ui-audit findings populated in state.ui_audit; the audit is the gate, not a suggestion"
4
+ alwaysApply: true
5
+ source: package
6
+ ---
7
+
8
+ # UI-Audit Before Build
9
+
10
+ Defense-in-depth twin of the dispatcher gate in
11
+ [`directives/ui/audit.py`](../templates/scripts/work_engine/directives/ui/audit.py).
12
+ The dispatcher refuses to advance past `refine` without
13
+ `state.ui_audit`; this rule refuses the write even when the agent
14
+ acts outside the dispatcher (free-form edit, "add a tile" request,
15
+ side conversation that bypasses [`/work`](../commands/work.md) or
16
+ [`/implement-ticket`](../commands/implement-ticket.md)).
17
+
18
+ ## The Iron Law
19
+
20
+ ```
21
+ NO NEW COMPONENT, SCREEN, PARTIAL, OR PAGE WITHOUT AUDIT FINDINGS.
22
+ EXISTING-UI-AUDIT RUNS FIRST. ALWAYS.
23
+ ```
24
+
25
+ Skipping the audit is the single biggest source of duplicated
26
+ components and drift from project tokens. The audit is cheap (60 s
27
+ on a primed cache); the cost of skipping is a refactor.
28
+
29
+ ## When this rule activates
30
+
31
+ Before writing or editing any non-trivial UI surface:
32
+
33
+ - New page / screen / route component
34
+ - New Livewire / Flux / Blade / React / Vue / Svelte component or partial
35
+ - Major edit to an existing screen (new section, new state, new layout band)
36
+
37
+ Recognise the trigger from wording even when nobody says "audit":
38
+ "add a dashboard tile", "build a settings panel", "neue Komponente
39
+ für …", "render the orders table", "create the empty state for …".
40
+
41
+ ## Allow-list — when to skip
42
+
43
+ Skip only when **all** hold:
44
+
45
+ - `directive_set == "ui-trivial"` (set by Phase 1's intent classifier).
46
+ - The change is provably bounded: ≤ 1 file, ≤ 5 changed lines, no
47
+ new component, no new state, no new dependency.
48
+
49
+ Any precondition fails at edit time → stop, reclassify as
50
+ `ui-improve`, re-enter the gate. Backend-only edits and
51
+ documentation work were never in scope for this rule.
52
+
53
+ ## What "audit findings" means
54
+
55
+ `state.ui_audit` is a non-empty dict carrying at least one of:
56
+
57
+ - `components_found` — `{path, name, kind, similarity?}` inventory
58
+ entries from [`existing-ui-audit`](../skills/existing-ui-audit/SKILL.md).
59
+ - `greenfield: true` plus `greenfield_decision` ∈
60
+ `{scaffold, bare, external_reference}`.
61
+ - Legacy `components` alias — back-compat for the same shape.
62
+
63
+ `null`, `{}`, or a dict without those keys is **not** findings;
64
+ emit `@agent-directive: existing-ui-audit` instead of writing code.
65
+
66
+ ## What to do when the gate fires
67
+
68
+ 1. Stop. Do not open an editor on a component file.
69
+ 2. Run [`existing-ui-audit`](../skills/existing-ui-audit/SKILL.md);
70
+ it writes the result to `state.ui_audit`.
71
+ 3. On rebound, the dispatcher enters `design` with the audit as
72
+ defaults in the design-brief halt.
73
+ 4. Greenfield → present the numbered scaffold / bare /
74
+ external-reference halt **before** code; record the pick in
75
+ `state.ui_audit.greenfield_decision`.
76
+
77
+ ## Failure modes
78
+
79
+ - Writing the component first and "thinking about reuse later".
80
+ - Citing a similar-looking component from memory without verifying
81
+ it via the audit.
82
+ - Treating `state.ui_audit = {}` as "audit ran, found nothing" —
83
+ empty dict is rejected on purpose; an audit that finds nothing
84
+ must record either ≥1 `components_found` or the greenfield branch.
85
+ - Bypassing the gate for "just one tile".
86
+
87
+ ## Interactions
88
+
89
+ - [`improve-before-implement`](improve-before-implement.md) — runs
90
+ first when the request is ambiguous; this rule is the next gate.
91
+ - [`ask-when-uncertain`](ask-when-uncertain.md) — "just build it"
92
+ does **not** drop the audit; acknowledge, run audit, continue.
93
+ - [`directives/ui/audit.py`](../templates/scripts/work_engine/directives/ui/audit.py)
94
+ — code-layer twin; this rule covers the cases where the engine
95
+ is not in the loop.
96
+ - [`existing-ui-audit`](../skills/existing-ui-audit/SKILL.md) — the
97
+ skill that produces the findings.
98
+
99
+ ## Cloud Behavior
100
+
101
+ On cloud surfaces the engine is not shipped, so `state.ui_audit`
102
+ does not exist. The Iron Law still applies: take the visible
103
+ inventory of files in conversation context as the audit, and
104
+ surface a one-line audit summary in the reply before writing the
105
+ component. The gate is satisfied by an explicit summary, not by
106
+ silently skipping.
@@ -7,10 +7,72 @@ source: package
7
7
 
8
8
  # User Interaction
9
9
 
10
+ Two Iron Laws govern every reply that contains numbered options. They
11
+ override conversation momentum, brevity, and the urge to defer to the
12
+ user. **Missing a recommendation is a rule violation, not a slip.**
13
+
14
+ ## Iron Law 1 — Single-Source Recommendation
15
+
16
+ ```
17
+ EXACTLY ONE LINE NAMES THE RECOMMENDED NUMBER. NO INLINE TAG. NO SECOND PROSE NUMBER.
18
+ THE OPTION BLOCK STAYS NEUTRAL. THE RECOMMENDATION LINE IS THE ONLY SOURCE OF TRUTH.
19
+ DRIFT BETWEEN OPTION-BLOCK AND PROSE IS STRUCTURALLY IMPOSSIBLE WHEN THE TAG DOES NOT EXIST.
20
+ MISSING RECOMMENDATION = RULE VIOLATION, NOT A SLIP.
21
+ ```
22
+
23
+ The agent has read the code, the contracts, the trade-offs. Refusing
24
+ to take a position dumps that work back on the user. Take the
25
+ position; be wrong out loud if needed. "Egal, was bevorzugst Du?" /
26
+ "no preference" is NEVER acceptable.
27
+
28
+ **Format — non-negotiable:**
29
+
30
+ - Options block stays NEUTRAL — no `(recommended)`, no `(rec)`, no `←`, no bold, no checkmark.
31
+ - Directly after the options block, ONE line, bolded, in the user's language:
32
+ - English: `**Recommendation: N — <option-name>** — <why>. Caveat: <flip-condition>.`
33
+ - German: `**Empfehlung: N — <option-name>** — <warum>. Caveat: <flip-bedingung>.`
34
+ - Other numbers MAY appear later in the prose, but ONLY as caveats
35
+ (`escalate to 3 if …`, `flip to 1 when …`). NEVER as a primary recommendation.
36
+ - If the agent genuinely cannot pick (rare — true 50/50 with missing data),
37
+ say what data would break the tie and ask for that instead.
38
+
39
+ **What does NOT count as a recommendation:**
40
+
41
+ - "Both work" / "either is fine" / "depends on what you prefer"
42
+ - Listing pros and cons without picking a number
43
+ - "I'd lean towards X" without a reason
44
+ - Hiding behind "you know the project better"
45
+ - Inline `(recommended)` tag with no follow-up `Recommendation: N` line
46
+
47
+ **Slip handling — same protocol as [`language-and-tone`](language-and-tone.md#when-the-user-calls-out-a-language-slip).**
48
+ User calls out a missing or wrong recommendation → acknowledge once
49
+ in the user's language, rewrite the reply with a recommendation,
50
+ ship. No "from now on" promises — only the next reply proves
51
+ compliance.
52
+
53
+ ## Iron Law 2 — Pre-Send Self-Check
54
+
55
+ ```
56
+ EVERY REPLY WITH NUMBERED OPTIONS RUNS THE SELF-CHECK. NO EXCEPTIONS.
57
+ SKIPPING IT IS A RULE VIOLATION, NOT A SLIP.
58
+ ```
59
+
60
+ Before emitting any reply that contains numbered options, scan the
61
+ drafted text:
62
+
63
+ 1. Count occurrences of `(recommended)` / `(rec)` / `(empfohlen)` inline next to a numbered option → MUST be **zero**. Found one → rewrite, drop the tag.
64
+ 2. Count distinct `Recommendation:\s*N` / `Empfehlung:\s*N` lines (case-insensitive) → MUST be **exactly one**. Zero → add one. Two or more distinct numbers → rewrite, pick one.
65
+ 3. The number on the recommendation line MUST exist in the option block.
66
+
67
+ Mechanical backstop: `python3 scripts/check_reply_consistency.py --stdin < draft.md`
68
+ (non-zero exit on any rule above). Self-scan is the primary gate; the
69
+ script is the deterministic safety net for ambiguous cases.
70
+
10
71
  ## Numbered Options — Always
11
72
 
12
- When asking the user a question with predefined choices, **always present numbered options**.
13
- The user should be able to reply with just a number (e.g., `1`) instead of typing a sentence.
73
+ When asking the user a question with predefined choices, **always
74
+ present numbered options**. The user should be able to reply with
75
+ just a number (e.g., `1`) instead of typing a sentence.
14
76
 
15
77
  ### Format
16
78
 
@@ -18,6 +80,8 @@ The user should be able to reply with just a number (e.g., `1`) instead of typin
18
80
  > 1. First option — brief explanation
19
81
  > 2. Second option — brief explanation
20
82
  > 3. Third option — brief explanation
83
+
84
+ **Recommendation: 2 — Second option** — <one-sentence reason>. Caveat: <flip-condition>.
21
85
  ```
22
86
 
23
87
  ### Rules
@@ -25,31 +89,45 @@ The user should be able to reply with just a number (e.g., `1`) instead of typin
25
89
  - **Every question with choices** must use numbered options — no exceptions.
26
90
  - **Keep options short** — one line each, with a brief explanation after the dash.
27
91
  - **Always include a "skip" or "no change" option** when applicable.
28
- - **Default/recommended option** can be marked: `1. Do X (recommended)`.
92
+ - **Always state a recommendation** Iron Law 1 above.
29
93
  - **Use the user's language** for the question and options.
30
94
  - **Accept both** the number and a natural language answer (e.g., "1" or "the first one").
31
95
 
32
96
  ### Examples
33
97
 
34
98
  **Binary choice:**
99
+
35
100
  ```
36
101
  > 1. Interactive — ask before each comment
37
102
  > 2. Automatic — handle all independently
103
+
104
+ **Recommendation: 1 — Interactive** — the comments touch security-sensitive code,
105
+ so a wrong auto-fix is more expensive than approving each one. Caveat: flip to 2
106
+ if the comments turn out to be pure formatting.
38
107
  ```
39
108
 
40
109
  **Multiple choice with skip:**
110
+
41
111
  ```
42
112
  > 1. Fix the code
43
113
  > 2. Fix the test
44
114
  > 3. Skip
115
+
116
+ **Recommendation: 1 — Fix the code** — the test asserts the documented behaviour;
117
+ the production code drifted from the contract. Caveat: pick 2 only if the contract
118
+ itself is wrong.
45
119
  ```
46
120
 
47
121
  **Confirmation with context:**
122
+
48
123
  ```
49
124
  > Found PR #1399 on branch `chore/refactor-agent-setup-2`.
50
125
  >
51
126
  > 1. Yes, that's the right PR
52
127
  > 2. No, different PR — I'll provide the URL
128
+
129
+ **Recommendation: 1 — Yes** — the branch name matches the PR title exactly.
130
+ Caveat: flip to 2 if the PR was reopened from a different branch.
53
131
  ```
54
132
 
55
133
  ### When NOT to use numbered options
@@ -19,6 +19,12 @@ Percentage = done / (done + open). Deferred and cancelled do not count towards
19
19
  Invocation (from project root):
20
20
  python3 .augment/scripts/update_roadmap_progress.py # rewrite
21
21
  python3 .augment/scripts/update_roadmap_progress.py --check # CI: exit 1 if stale
22
+
23
+ `--check` mode also fails when a roadmap reaches `count_open == 0` but is
24
+ still under `agents/roadmaps/` instead of `agents/roadmaps/archive/` —
25
+ backstopping the `roadmap-progress-sync` rule's "completion = archival,
26
+ same response" requirement. The write path emits the same finding as a
27
+ warning on stderr and still regenerates the dashboard.
22
28
  """
23
29
 
24
30
  from __future__ import annotations
@@ -67,6 +73,10 @@ class PhaseStats:
67
73
  def total_active(self) -> int: # denominator for %
68
74
  return self.done + self.open_
69
75
 
76
+ @property
77
+ def total_all(self) -> int: # all checkboxes incl. deferred + cancelled
78
+ return self.done + self.open_ + self.deferred + self.cancelled
79
+
70
80
  @property
71
81
  def percent(self) -> int:
72
82
  return round(self.done * 100 / self.total_active) if self.total_active else 0
@@ -111,6 +121,10 @@ class RoadmapStats:
111
121
  def total_active(self) -> int:
112
122
  return self.done + self.open_
113
123
 
124
+ @property
125
+ def total_all(self) -> int:
126
+ return self.done + self.open_ + self.deferred + self.cancelled
127
+
114
128
  @property
115
129
  def percent(self) -> int:
116
130
  return round(self.done * 100 / self.total_active) if self.total_active else 0
@@ -176,6 +190,15 @@ def collect(roadmap_root: Path) -> list[RoadmapStats]:
176
190
  return results
177
191
 
178
192
 
193
+ def unarchived_complete(roadmaps: list[RoadmapStats]) -> list[RoadmapStats]:
194
+ # A roadmap is complete when every active checkbox is done and at least
195
+ # one active checkbox exists. The `roadmap-progress-sync` rule mandates
196
+ # that such a roadmap be moved to `agents/roadmaps/archive/` in the
197
+ # same response that closes its last open item; `collect()` already
198
+ # excludes that directory, so anything left here is unarchived.
199
+ return [r for r in roadmaps if r.total_active > 0 and r.open_ == 0]
200
+
201
+
179
202
  def render(roadmaps: list[RoadmapStats]) -> str:
180
203
  total_done = sum(r.done for r in roadmaps)
181
204
  total_active = sum(r.total_active for r in roadmaps)
@@ -198,12 +221,16 @@ def render(roadmaps: list[RoadmapStats]) -> str:
198
221
  lines.append("_No open roadmaps._\n")
199
222
  return "\n".join(lines) + "\n"
200
223
  lines.append("## Open roadmaps\n")
201
- lines.append("| # | Roadmap | Phases | Steps | Done | Open | Deferred | Cancelled | Progress |")
224
+ # Steps = ALL checkboxes (done + open + deferred + cancelled) so the row
225
+ # arithmetic adds up: Steps − Done − Deferred − Cancelled = Open. Open
226
+ # comes before Done by design — at-a-glance "what's left to do" first,
227
+ # historical "what's behind us" second.
228
+ lines.append("| # | Roadmap | Phases | Steps | Open | Done | Deferred | Cancelled | Progress |")
202
229
  lines.append("|---|---|---:|---:|---:|---:|---:|---:|---|")
203
230
  for i, r in enumerate(roadmaps, 1):
204
231
  lines.append(
205
- f"| {i} | [{r.rel}](roadmaps/{r.rel}) | {len(r.phases)} | {r.total_active} | "
206
- f"{r.done} | {r.open_} | {r.deferred} | {r.cancelled} | "
232
+ f"| {i} | [{r.rel}](roadmaps/{r.rel}) | {len(r.phases)} | {r.total_all} | "
233
+ f"{r.open_} | {r.done} | {r.deferred} | {r.cancelled} | "
207
234
  f"{bar(r.percent)} {r.percent}% |"
208
235
  )
209
236
  lines.append("")
@@ -212,11 +239,11 @@ def render(roadmaps: list[RoadmapStats]) -> str:
212
239
  for r in roadmaps:
213
240
  lines.append(f"### [{r.rel}](roadmaps/{r.rel})\n")
214
241
  lines.append(f"**{r.title}** — {r.done} / {r.total_active} done ({r.percent}%)\n")
215
- lines.append("| # | Phase | State | Done | Open | Deferred | Cancelled | % |")
242
+ lines.append("| # | Phase | State | Open | Done | Deferred | Cancelled | % |")
216
243
  lines.append("|---|---|---|---:|---:|---:|---:|---:|")
217
244
  for p in r.phases:
218
245
  lines.append(
219
- f"| {p.id} | {p.name} | {p.state} | {p.done} | {p.open_} | "
246
+ f"| {p.id} | {p.name} | {p.state} | {p.open_} | {p.done} | "
220
247
  f"{p.deferred} | {p.cancelled} | {p.percent}% |"
221
248
  )
222
249
  lines.append("")
@@ -241,12 +268,22 @@ def main() -> int:
241
268
  roadmaps = collect(roadmap_root)
242
269
  new_text = render(roadmaps)
243
270
  current = target.read_text(encoding="utf-8") if target.exists() else ""
271
+ complete = unarchived_complete(roadmaps)
244
272
  if args.check:
245
- if current != new_text:
273
+ stale = current != new_text
274
+ if stale:
246
275
  print(f"❌ {target.relative_to(args.repo_root)} is stale. "
247
276
  f"Run `python3 .augment/scripts/update_roadmap_progress.py` "
248
277
  f"to regenerate (or `task roadmap-progress` in Taskfile "
249
278
  f"projects).", file=sys.stderr)
279
+ if complete:
280
+ print("❌ Completed roadmaps are still in `agents/roadmaps/` — "
281
+ "move them to `agents/roadmaps/archive/` (per the "
282
+ "`roadmap-progress-sync` rule):", file=sys.stderr)
283
+ for r in complete:
284
+ print(f" - {r.rel} ({r.done}/{r.total_active} done)",
285
+ file=sys.stderr)
286
+ if stale or complete:
250
287
  return 1
251
288
  print(f"✅ {target.relative_to(args.repo_root)} is up to date.")
252
289
  return 0
@@ -254,6 +291,11 @@ def main() -> int:
254
291
  print(f"✅ Wrote {target.relative_to(args.repo_root)} · "
255
292
  f"{len(roadmaps)} roadmap(s) · "
256
293
  f"{sum(r.done for r in roadmaps)}/{sum(r.total_active for r in roadmaps)} steps done.")
294
+ if complete:
295
+ print("⚠️ Completed roadmaps not yet archived — move to "
296
+ "`agents/roadmaps/archive/`:", file=sys.stderr)
297
+ for r in complete:
298
+ print(f" - {r.rel}", file=sys.stderr)
257
299
  return 0
258
300
 
259
301