@event4u/agent-config 1.13.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 (252) 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 +82 -50
  108. package/.agent-src/scripts/update_roadmap_progress.py +17 -5
  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/roadmaps.md +8 -2
  134. package/.agent-src/templates/scripts/implement_ticket/__init__.py +63 -26
  135. package/.agent-src/templates/scripts/implement_ticket/__main__.py +8 -2
  136. package/.agent-src/templates/scripts/telemetry/__init__.py +42 -0
  137. package/.agent-src/templates/scripts/telemetry/aggregator.py +154 -0
  138. package/.agent-src/templates/scripts/telemetry/boundary.py +171 -0
  139. package/.agent-src/templates/scripts/telemetry/engagement.py +238 -0
  140. package/.agent-src/templates/scripts/telemetry/report_renderer.py +170 -0
  141. package/.agent-src/templates/scripts/telemetry/settings.py +112 -0
  142. package/.agent-src/templates/scripts/telemetry_record.py +166 -0
  143. package/.agent-src/templates/scripts/telemetry_report.py +161 -0
  144. package/.agent-src/templates/scripts/telemetry_status.py +142 -0
  145. package/.agent-src/templates/scripts/work_engine/__init__.py +58 -0
  146. package/.agent-src/templates/scripts/work_engine/__main__.py +9 -0
  147. package/.agent-src/templates/scripts/work_engine/cli.py +592 -0
  148. package/.agent-src/templates/scripts/{implement_ticket → work_engine}/delivery_state.py +7 -0
  149. package/.agent-src/templates/scripts/work_engine/directives/__init__.py +33 -0
  150. package/.agent-src/templates/scripts/work_engine/directives/backend/__init__.py +98 -0
  151. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/analyze.py +1 -1
  152. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/implement.py +2 -2
  153. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/memory.py +1 -1
  154. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/plan.py +1 -1
  155. package/.agent-src/templates/scripts/work_engine/directives/backend/refine.py +396 -0
  156. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/report.py +36 -4
  157. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/test.py +2 -2
  158. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/verify.py +2 -2
  159. package/.agent-src/templates/scripts/work_engine/directives/mixed/__init__.py +116 -0
  160. package/.agent-src/templates/scripts/work_engine/directives/mixed/contract.py +254 -0
  161. package/.agent-src/templates/scripts/work_engine/directives/mixed/stitch.py +229 -0
  162. package/.agent-src/templates/scripts/work_engine/directives/mixed/ui.py +231 -0
  163. package/.agent-src/templates/scripts/work_engine/directives/ui/__init__.py +113 -0
  164. package/.agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +44 -0
  165. package/.agent-src/templates/scripts/work_engine/directives/ui/apply.py +241 -0
  166. package/.agent-src/templates/scripts/work_engine/directives/ui/audit.py +414 -0
  167. package/.agent-src/templates/scripts/work_engine/directives/ui/design.py +335 -0
  168. package/.agent-src/templates/scripts/work_engine/directives/ui/polish.py +510 -0
  169. package/.agent-src/templates/scripts/work_engine/directives/ui/review.py +468 -0
  170. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/__init__.py +119 -0
  171. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/_skipped.py +37 -0
  172. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/apply.py +165 -0
  173. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/refine.py +66 -0
  174. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/report.py +62 -0
  175. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/test.py +115 -0
  176. package/.agent-src/templates/scripts/work_engine/dispatcher.py +331 -0
  177. package/.agent-src/templates/scripts/work_engine/hooks/__init__.py +54 -0
  178. package/.agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +32 -0
  179. package/.agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.py +103 -0
  180. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.py +44 -0
  181. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.py +42 -0
  182. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_heartbeat.py +50 -0
  183. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_turn_check.py +49 -0
  184. package/.agent-src/templates/scripts/work_engine/hooks/builtin/directive_set_guard.py +53 -0
  185. package/.agent-src/templates/scripts/work_engine/hooks/builtin/halt_surface_audit.py +50 -0
  186. package/.agent-src/templates/scripts/work_engine/hooks/builtin/state_shape_validation.py +52 -0
  187. package/.agent-src/templates/scripts/work_engine/hooks/builtin/trace.py +84 -0
  188. package/.agent-src/templates/scripts/work_engine/hooks/context.py +66 -0
  189. package/.agent-src/templates/scripts/work_engine/hooks/events.py +44 -0
  190. package/.agent-src/templates/scripts/work_engine/hooks/exceptions.py +79 -0
  191. package/.agent-src/templates/scripts/work_engine/hooks/registry.py +60 -0
  192. package/.agent-src/templates/scripts/work_engine/hooks/runner.py +73 -0
  193. package/.agent-src/templates/scripts/work_engine/hooks/settings.py +141 -0
  194. package/.agent-src/templates/scripts/work_engine/intent/__init__.py +47 -0
  195. package/.agent-src/templates/scripts/work_engine/intent/classify.py +280 -0
  196. package/.agent-src/templates/scripts/work_engine/migration/__init__.py +8 -0
  197. package/.agent-src/templates/scripts/work_engine/migration/v0_to_v1.py +199 -0
  198. package/.agent-src/templates/scripts/work_engine/resolvers/__init__.py +22 -0
  199. package/.agent-src/templates/scripts/work_engine/resolvers/diff.py +106 -0
  200. package/.agent-src/templates/scripts/work_engine/resolvers/file.py +113 -0
  201. package/.agent-src/templates/scripts/work_engine/resolvers/prompt.py +90 -0
  202. package/.agent-src/templates/scripts/work_engine/scoring/__init__.py +14 -0
  203. package/.agent-src/templates/scripts/work_engine/scoring/confidence.py +300 -0
  204. package/.agent-src/templates/scripts/work_engine/stack/__init__.py +31 -0
  205. package/.agent-src/templates/scripts/work_engine/stack/detect.py +187 -0
  206. package/.agent-src/templates/scripts/work_engine/state.py +641 -0
  207. package/.claude-plugin/marketplace.json +105 -2
  208. package/AGENTS.md +36 -8
  209. package/CHANGELOG.md +534 -0
  210. package/README.md +125 -4
  211. package/config/agent-settings.template.yml +45 -0
  212. package/config/gitignore-block.txt +4 -0
  213. package/docs/architecture.md +28 -1
  214. package/docs/development.md +1 -1
  215. package/docs/getting-started.md +2 -2
  216. package/docs/installation.md +86 -0
  217. package/docs/showcase.md +204 -0
  218. package/package.json +1 -1
  219. package/scripts/agent-config +199 -0
  220. package/scripts/audit_cloud_compatibility.py +288 -0
  221. package/scripts/build_cloud_bundle.py +458 -0
  222. package/scripts/build_linear_digest.py +263 -0
  223. package/scripts/chat_history.py +796 -7
  224. package/scripts/check_compression.py +139 -0
  225. package/scripts/check_iron_law_prominence.py +143 -0
  226. package/scripts/check_md_language.py +159 -0
  227. package/scripts/check_portability.py +36 -0
  228. package/scripts/check_reply_consistency.py +140 -0
  229. package/scripts/command_suggester/__init__.py +51 -0
  230. package/scripts/command_suggester/cooldown.py +132 -0
  231. package/scripts/command_suggester/loader.py +70 -0
  232. package/scripts/command_suggester/match.py +180 -0
  233. package/scripts/command_suggester/rank.py +120 -0
  234. package/scripts/command_suggester/render.py +86 -0
  235. package/scripts/command_suggester/sanitize.py +113 -0
  236. package/scripts/command_suggester/settings.py +125 -0
  237. package/scripts/command_suggester/types.py +78 -0
  238. package/scripts/hooks/augment-chat-history.sh +56 -0
  239. package/scripts/install-hooks.sh +67 -0
  240. package/scripts/install.py +150 -33
  241. package/scripts/lint_marketplace.py +27 -0
  242. package/scripts/migrate_command_suggestions.py +151 -0
  243. package/scripts/schemas/command.schema.json +41 -0
  244. package/scripts/skill_linter.py +67 -0
  245. package/scripts/sync_agent_settings.py +42 -12
  246. package/templates/consumer-settings/augment-cli-hooks.json +54 -0
  247. package/templates/consumer-settings/claude-settings.json +55 -1
  248. package/.agent-src/templates/scripts/implement_ticket/cli.py +0 -171
  249. package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +0 -134
  250. package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +0 -49
  251. package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +0 -140
  252. /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,95 +7,127 @@ source: package
7
7
 
8
8
  # User Interaction
9
9
 
10
- ## Numbered Options Always
11
-
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.
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.**
14
13
 
15
- ### Format
14
+ ## Iron Law 1 — Single-Source Recommendation
16
15
 
17
16
  ```
18
- > 1. First option brief explanation
19
- > 2. Second option brief explanation
20
- > 3. Third option brief explanation
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
21
  ```
22
22
 
23
- ### Rules
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.
24
27
 
25
- - **Every question with choices** must use numbered options no exceptions.
26
- - **Keep options short** — one line each, with a brief explanation after the dash.
27
- - **Always include a "skip" or "no change" option** when applicable.
28
- - **Always state a recommendation** see iron law below.
29
- - **Use the user's language** for the question and options.
30
- - **Accept both** the number and a natural language answer (e.g., "1" or "the first one").
28
+ **Formatnon-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:**
31
40
 
32
- ### Iron Law ALWAYS recommend
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
33
54
 
34
55
  ```
35
- EVERY numbered-option question MUST state which option the agent recommends and WHY.
36
- "Egal, was bevorzugst Du?" / "no preference" is NEVER an acceptable agent stance.
56
+ EVERY REPLY WITH NUMBERED OPTIONS RUNS THE SELF-CHECK. NO EXCEPTIONS.
57
+ SKIPPING IT IS A RULE VIOLATION, NOT A SLIP.
37
58
  ```
38
59
 
39
- The user is asking the agent because the agent has read the code, the
40
- contracts, the trade-offs. Refusing to take a position dumps that work
41
- back on the user. Take the position; be wrong out loud if needed.
60
+ Before emitting any reply that contains numbered options, scan the
61
+ drafted text:
42
62
 
43
- **Format:**
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.
44
66
 
45
- - Mark the recommended option inline: `1. Do X — short explanation (recommended)`.
46
- - After the option block, state **WHY** in 1–3 sentences: the trade-off
47
- that tips the balance, plus the **caveat** that would flip it.
48
- - If the agent genuinely cannot pick (rare — true 50/50 with missing
49
- data), say what data would break the tie and ask for that instead.
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.
50
70
 
51
- **Example:**
71
+ ## Numbered Options — Always
72
+
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.
76
+
77
+ ### Format
52
78
 
53
79
  ```
54
- > 1. Hybrid contractkeys + query (recommended)
55
- > 2. Key-basedextend the package
56
- > 3. Semanticchange all call sites
80
+ > 1. First optionbrief explanation
81
+ > 2. Second option brief explanation
82
+ > 3. Third option brief explanation
57
83
 
58
- I recommend 1: solves the acute consult-flow without a cross-repo PR,
59
- and the file-fallback stays trivial. Caveat — if hit-rate on the
60
- concat-shim turns out poor in practice, escalate to 2.
84
+ **Recommendation: 2 Second option** <one-sentence reason>. Caveat: <flip-condition>.
61
85
  ```
62
86
 
63
- **What does NOT count as a recommendation:**
87
+ ### Rules
64
88
 
65
- - "Both work" / "either is fine" / "depends on what you prefer"
66
- - Listing pros and cons without picking
67
- - "I'd lean towards X" without a reason
68
- - Hiding behind "you know the project better" (the agent just researched it)
89
+ - **Every question with choices** must use numbered options no exceptions.
90
+ - **Keep options short** one line each, with a brief explanation after the dash.
91
+ - **Always include a "skip" or "no change" option** when applicable.
92
+ - **Always state a recommendation** Iron Law 1 above.
93
+ - **Use the user's language** for the question and options.
94
+ - **Accept both** the number and a natural language answer (e.g., "1" or "the first one").
69
95
 
70
96
  ### Examples
71
97
 
72
- **Binary choice (with recommendation):**
98
+ **Binary choice:**
99
+
73
100
  ```
74
- > 1. Interactive — ask before each comment (recommended)
101
+ > 1. Interactive — ask before each comment
75
102
  > 2. Automatic — handle all independently
76
103
 
77
- I recommend 1: the comments touch security-sensitive code, so a wrong
78
- auto-fix is more expensive than the friction of approving each one.
79
- Switch to 2 if the comments turn out to be pure formatting.
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.
80
107
  ```
81
108
 
82
- **Multiple choice with skip (with recommendation):**
109
+ **Multiple choice with skip:**
110
+
83
111
  ```
84
- > 1. Fix the code (recommended)
112
+ > 1. Fix the code
85
113
  > 2. Fix the test
86
114
  > 3. Skip
87
115
 
88
- I recommend 1: the test is asserting the documented behavior; the
89
- production code drifted from the contract. Pick 2 only if the contract
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
90
118
  itself is wrong.
91
119
  ```
92
120
 
93
- **Confirmation with context (recommendation implicit in framing):**
121
+ **Confirmation with context:**
122
+
94
123
  ```
95
124
  > Found PR #1399 on branch `chore/refactor-agent-setup-2`.
96
125
  >
97
- > 1. Yes, that's the right PR (recommended — branch matches)
126
+ > 1. Yes, that's the right PR
98
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.
99
131
  ```
100
132
 
101
133
  ### When NOT to use numbered options
@@ -73,6 +73,10 @@ class PhaseStats:
73
73
  def total_active(self) -> int: # denominator for %
74
74
  return self.done + self.open_
75
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
+
76
80
  @property
77
81
  def percent(self) -> int:
78
82
  return round(self.done * 100 / self.total_active) if self.total_active else 0
@@ -117,6 +121,10 @@ class RoadmapStats:
117
121
  def total_active(self) -> int:
118
122
  return self.done + self.open_
119
123
 
124
+ @property
125
+ def total_all(self) -> int:
126
+ return self.done + self.open_ + self.deferred + self.cancelled
127
+
120
128
  @property
121
129
  def percent(self) -> int:
122
130
  return round(self.done * 100 / self.total_active) if self.total_active else 0
@@ -213,12 +221,16 @@ def render(roadmaps: list[RoadmapStats]) -> str:
213
221
  lines.append("_No open roadmaps._\n")
214
222
  return "\n".join(lines) + "\n"
215
223
  lines.append("## Open roadmaps\n")
216
- 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 |")
217
229
  lines.append("|---|---|---:|---:|---:|---:|---:|---:|---|")
218
230
  for i, r in enumerate(roadmaps, 1):
219
231
  lines.append(
220
- f"| {i} | [{r.rel}](roadmaps/{r.rel}) | {len(r.phases)} | {r.total_active} | "
221
- 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} | "
222
234
  f"{bar(r.percent)} {r.percent}% |"
223
235
  )
224
236
  lines.append("")
@@ -227,11 +239,11 @@ def render(roadmaps: list[RoadmapStats]) -> str:
227
239
  for r in roadmaps:
228
240
  lines.append(f"### [{r.rel}](roadmaps/{r.rel})\n")
229
241
  lines.append(f"**{r.title}** — {r.done} / {r.total_active} done ({r.percent}%)\n")
230
- lines.append("| # | Phase | State | Done | Open | Deferred | Cancelled | % |")
242
+ lines.append("| # | Phase | State | Open | Done | Deferred | Cancelled | % |")
231
243
  lines.append("|---|---|---|---:|---:|---:|---:|---:|")
232
244
  for p in r.phases:
233
245
  lines.append(
234
- f"| {p.id} | {p.name} | {p.state} | {p.done} | {p.open_} | "
246
+ f"| {p.id} | {p.name} | {p.state} | {p.open_} | {p.done} | "
235
247
  f"{p.deferred} | {p.cancelled} | {p.percent}% |"
236
248
  )
237
249
  lines.append("")