@event4u/agent-config 1.13.0 → 1.15.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 (291) hide show
  1. package/.agent-src/commands/agent-handoff.md +4 -1
  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 +7 -3
  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 +6 -1
  11. package/.agent-src/commands/chat-history-resume.md +7 -2
  12. package/.agent-src/commands/chat-history.md +7 -2
  13. package/.agent-src/commands/check-current-md.md +137 -0
  14. package/.agent-src/commands/commit-in-chunks.md +118 -0
  15. package/.agent-src/commands/commit.md +4 -0
  16. package/.agent-src/commands/compress.md +37 -2
  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 +5 -2
  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 +33 -0
  50. package/.agent-src/commands/optimize-agents.md +4 -0
  51. package/.agent-src/commands/optimize-augmentignore.md +12 -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 +12 -7
  64. package/.agent-src/commands/review-changes.md +39 -8
  65. package/.agent-src/commands/review-routing.md +4 -0
  66. package/.agent-src/commands/roadmap-create.md +18 -0
  67. package/.agent-src/commands/roadmap-execute.md +14 -1
  68. package/.agent-src/commands/rule-compliance-audit.md +4 -0
  69. package/.agent-src/commands/set-cost-profile.md +11 -0
  70. package/.agent-src/commands/sync-agent-settings.md +12 -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 +6 -3
  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 +64 -37
  89. package/.agent-src/rules/autonomous-execution.md +158 -0
  90. package/.agent-src/rules/chat-history-cadence.md +109 -0
  91. package/.agent-src/rules/chat-history-ownership.md +123 -0
  92. package/.agent-src/rules/chat-history-visibility.md +96 -0
  93. package/.agent-src/rules/cli-output-handling.md +27 -4
  94. package/.agent-src/rules/command-suggestion.md +134 -0
  95. package/.agent-src/rules/commit-policy.md +109 -0
  96. package/.agent-src/rules/direct-answers.md +114 -0
  97. package/.agent-src/rules/docs-sync.md +36 -0
  98. package/.agent-src/rules/downstream-changes.md +10 -9
  99. package/.agent-src/rules/improve-before-implement.md +9 -6
  100. package/.agent-src/rules/language-and-tone.md +85 -6
  101. package/.agent-src/rules/non-destructive-by-default.md +117 -0
  102. package/.agent-src/rules/package-ci-checks.md +4 -0
  103. package/.agent-src/rules/preservation-guard.md +20 -0
  104. package/.agent-src/rules/roadmap-progress-sync.md +159 -27
  105. package/.agent-src/rules/role-mode-adherence.md +1 -1
  106. package/.agent-src/rules/scope-control.md +42 -1
  107. package/.agent-src/rules/size-enforcement.md +2 -3
  108. package/.agent-src/rules/skill-quality.md +3 -8
  109. package/.agent-src/rules/ui-audit-before-build.md +106 -0
  110. package/.agent-src/rules/user-interaction.md +107 -51
  111. package/.agent-src/scripts/update_roadmap_progress.py +73 -9
  112. package/.agent-src/skills/blade-ui/SKILL.md +47 -3
  113. package/.agent-src/skills/command-routing/SKILL.md +32 -0
  114. package/.agent-src/skills/command-writing/SKILL.md +52 -2
  115. package/.agent-src/skills/description-assist/SKILL.md +21 -0
  116. package/.agent-src/skills/estimate-ticket/SKILL.md +0 -1
  117. package/.agent-src/skills/existing-ui-audit/SKILL.md +202 -0
  118. package/.agent-src/skills/fe-design/SKILL.md +78 -61
  119. package/.agent-src/skills/file-editor/SKILL.md +9 -0
  120. package/.agent-src/skills/finishing-a-development-branch/SKILL.md +4 -0
  121. package/.agent-src/skills/flux/SKILL.md +31 -4
  122. package/.agent-src/skills/guideline-writing/SKILL.md +24 -2
  123. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +51 -9
  124. package/.agent-src/skills/livewire/SKILL.md +49 -4
  125. package/.agent-src/skills/md-language-check/SKILL.md +103 -0
  126. package/.agent-src/skills/php-coder/SKILL.md +24 -0
  127. package/.agent-src/skills/react-shadcn-ui/SKILL.md +121 -0
  128. package/.agent-src/skills/refine-prompt/SKILL.md +220 -0
  129. package/.agent-src/skills/refine-ticket/SKILL.md +32 -28
  130. package/.agent-src/skills/roadmap-management/SKILL.md +24 -11
  131. package/.agent-src/skills/rule-writing/SKILL.md +23 -1
  132. package/.agent-src/skills/skill-writing/SKILL.md +3 -5
  133. package/.agent-src/skills/upstream-contribute/SKILL.md +3 -3
  134. package/.agent-src/skills/using-git-worktrees/SKILL.md +3 -1
  135. package/.agent-src/templates/AGENTS.md +24 -6
  136. package/.agent-src/templates/agent-settings.md +149 -0
  137. package/.agent-src/templates/roadmaps.md +11 -4
  138. package/.agent-src/templates/scripts/implement_ticket/__init__.py +63 -26
  139. package/.agent-src/templates/scripts/implement_ticket/__main__.py +8 -2
  140. package/.agent-src/templates/scripts/memory_lookup.py +1 -1
  141. package/.agent-src/templates/scripts/telemetry/__init__.py +42 -0
  142. package/.agent-src/templates/scripts/telemetry/aggregator.py +154 -0
  143. package/.agent-src/templates/scripts/telemetry/boundary.py +171 -0
  144. package/.agent-src/templates/scripts/telemetry/engagement.py +238 -0
  145. package/.agent-src/templates/scripts/telemetry/report_renderer.py +170 -0
  146. package/.agent-src/templates/scripts/telemetry/settings.py +112 -0
  147. package/.agent-src/templates/scripts/telemetry_record.py +166 -0
  148. package/.agent-src/templates/scripts/telemetry_report.py +161 -0
  149. package/.agent-src/templates/scripts/telemetry_status.py +142 -0
  150. package/.agent-src/templates/scripts/work_engine/__init__.py +58 -0
  151. package/.agent-src/templates/scripts/work_engine/__main__.py +9 -0
  152. package/.agent-src/templates/scripts/work_engine/cli.py +195 -0
  153. package/.agent-src/templates/scripts/work_engine/cli_args.py +116 -0
  154. package/.agent-src/templates/scripts/{implement_ticket → work_engine}/delivery_state.py +10 -3
  155. package/.agent-src/templates/scripts/work_engine/directives/__init__.py +33 -0
  156. package/.agent-src/templates/scripts/work_engine/directives/backend/__init__.py +98 -0
  157. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/analyze.py +1 -1
  158. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/implement.py +3 -3
  159. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/memory.py +2 -2
  160. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/plan.py +2 -2
  161. package/.agent-src/templates/scripts/work_engine/directives/backend/refine.py +396 -0
  162. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/report.py +37 -5
  163. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/test.py +2 -2
  164. package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/verify.py +2 -2
  165. package/.agent-src/templates/scripts/work_engine/directives/mixed/__init__.py +116 -0
  166. package/.agent-src/templates/scripts/work_engine/directives/mixed/contract.py +254 -0
  167. package/.agent-src/templates/scripts/work_engine/directives/mixed/stitch.py +229 -0
  168. package/.agent-src/templates/scripts/work_engine/directives/mixed/ui.py +231 -0
  169. package/.agent-src/templates/scripts/work_engine/directives/ui/__init__.py +113 -0
  170. package/.agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +44 -0
  171. package/.agent-src/templates/scripts/work_engine/directives/ui/apply.py +241 -0
  172. package/.agent-src/templates/scripts/work_engine/directives/ui/audit.py +414 -0
  173. package/.agent-src/templates/scripts/work_engine/directives/ui/design.py +335 -0
  174. package/.agent-src/templates/scripts/work_engine/directives/ui/polish.py +510 -0
  175. package/.agent-src/templates/scripts/work_engine/directives/ui/review.py +468 -0
  176. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/__init__.py +119 -0
  177. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/_skipped.py +37 -0
  178. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/apply.py +165 -0
  179. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/refine.py +66 -0
  180. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/report.py +62 -0
  181. package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/test.py +115 -0
  182. package/.agent-src/templates/scripts/work_engine/dispatcher.py +331 -0
  183. package/.agent-src/templates/scripts/work_engine/emitters.py +43 -0
  184. package/.agent-src/templates/scripts/work_engine/errors.py +19 -0
  185. package/.agent-src/templates/scripts/work_engine/hook_bootstrap.py +76 -0
  186. package/.agent-src/templates/scripts/work_engine/hooks/__init__.py +54 -0
  187. package/.agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +32 -0
  188. package/.agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.py +103 -0
  189. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.py +44 -0
  190. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.py +42 -0
  191. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_heartbeat.py +50 -0
  192. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_turn_check.py +49 -0
  193. package/.agent-src/templates/scripts/work_engine/hooks/builtin/directive_set_guard.py +53 -0
  194. package/.agent-src/templates/scripts/work_engine/hooks/builtin/halt_surface_audit.py +50 -0
  195. package/.agent-src/templates/scripts/work_engine/hooks/builtin/state_shape_validation.py +52 -0
  196. package/.agent-src/templates/scripts/work_engine/hooks/builtin/trace.py +84 -0
  197. package/.agent-src/templates/scripts/work_engine/hooks/context.py +66 -0
  198. package/.agent-src/templates/scripts/work_engine/hooks/events.py +44 -0
  199. package/.agent-src/templates/scripts/work_engine/hooks/exceptions.py +79 -0
  200. package/.agent-src/templates/scripts/work_engine/hooks/registry.py +60 -0
  201. package/.agent-src/templates/scripts/work_engine/hooks/runner.py +73 -0
  202. package/.agent-src/templates/scripts/work_engine/hooks/settings.py +141 -0
  203. package/.agent-src/templates/scripts/work_engine/input_builders.py +163 -0
  204. package/.agent-src/templates/scripts/work_engine/intent/__init__.py +47 -0
  205. package/.agent-src/templates/scripts/work_engine/intent/classify.py +280 -0
  206. package/.agent-src/templates/scripts/work_engine/migration/__init__.py +8 -0
  207. package/.agent-src/templates/scripts/work_engine/migration/v0_to_v1.py +231 -0
  208. package/.agent-src/templates/scripts/{implement_ticket → work_engine}/persona_policy.py +1 -1
  209. package/.agent-src/templates/scripts/work_engine/resolvers/__init__.py +22 -0
  210. package/.agent-src/templates/scripts/work_engine/resolvers/diff.py +106 -0
  211. package/.agent-src/templates/scripts/work_engine/resolvers/file.py +113 -0
  212. package/.agent-src/templates/scripts/work_engine/resolvers/prompt.py +90 -0
  213. package/.agent-src/templates/scripts/work_engine/scoring/__init__.py +14 -0
  214. package/.agent-src/templates/scripts/work_engine/scoring/confidence.py +300 -0
  215. package/.agent-src/templates/scripts/work_engine/stack/__init__.py +31 -0
  216. package/.agent-src/templates/scripts/work_engine/stack/detect.py +187 -0
  217. package/.agent-src/templates/scripts/work_engine/state.py +641 -0
  218. package/.agent-src/templates/scripts/work_engine/state_io.py +202 -0
  219. package/.claude-plugin/marketplace.json +105 -2
  220. package/AGENTS.md +38 -8
  221. package/CHANGELOG.md +609 -0
  222. package/README.md +136 -14
  223. package/config/agent-settings.template.yml +45 -0
  224. package/config/gitignore-block.txt +4 -0
  225. package/docs/MIGRATION.md +122 -0
  226. package/docs/architecture.md +111 -35
  227. package/docs/contracts/STABILITY.md +95 -0
  228. package/docs/contracts/adr-chat-history-split.md +132 -0
  229. package/docs/contracts/adr-command-suggestion.md +146 -0
  230. package/docs/contracts/adr-implement-ticket-runtime.md +122 -0
  231. package/docs/contracts/adr-product-ui-track.md +384 -0
  232. package/docs/contracts/adr-prompt-driven-execution.md +187 -0
  233. package/docs/contracts/agent-memory-contract.md +149 -0
  234. package/docs/contracts/artifact-engagement-flow.md +262 -0
  235. package/docs/contracts/command-clusters.md +126 -0
  236. package/docs/contracts/command-suggestion-flow.md +148 -0
  237. package/docs/contracts/implement-ticket-flow.md +628 -0
  238. package/docs/contracts/linear-ai-rules-inclusion.md +143 -0
  239. package/docs/contracts/linear-ai-three-layers.md +131 -0
  240. package/docs/contracts/rule-interactions.md +107 -0
  241. package/docs/contracts/rule-interactions.yml +142 -0
  242. package/docs/contracts/ui-stack-extension.md +236 -0
  243. package/docs/contracts/ui-track-flow.md +338 -0
  244. package/docs/development.md +1 -1
  245. package/docs/getting-started.md +3 -3
  246. package/docs/installation.md +124 -2
  247. package/docs/migrations/commands-1.15.0.md +112 -0
  248. package/docs/showcase.md +204 -0
  249. package/docs/ui-track-mental-model.md +121 -0
  250. package/package.json +1 -1
  251. package/scripts/agent-config +199 -0
  252. package/scripts/audit_cloud_compatibility.py +288 -0
  253. package/scripts/build_cloud_bundle.py +458 -0
  254. package/scripts/build_linear_digest.py +263 -0
  255. package/scripts/chat_history.py +796 -7
  256. package/scripts/check_compression.py +139 -0
  257. package/scripts/check_iron_law_prominence.py +143 -0
  258. package/scripts/check_md_language.py +159 -0
  259. package/scripts/check_portability.py +38 -0
  260. package/scripts/check_public_links.py +185 -0
  261. package/scripts/check_references.py +1 -0
  262. package/scripts/check_reply_consistency.py +140 -0
  263. package/scripts/command_suggester/__init__.py +51 -0
  264. package/scripts/command_suggester/cooldown.py +132 -0
  265. package/scripts/command_suggester/loader.py +70 -0
  266. package/scripts/command_suggester/match.py +180 -0
  267. package/scripts/command_suggester/rank.py +120 -0
  268. package/scripts/command_suggester/render.py +86 -0
  269. package/scripts/command_suggester/sanitize.py +113 -0
  270. package/scripts/command_suggester/settings.py +125 -0
  271. package/scripts/command_suggester/types.py +78 -0
  272. package/scripts/hooks/augment-chat-history.sh +56 -0
  273. package/scripts/install-hooks.sh +67 -0
  274. package/scripts/install.py +150 -33
  275. package/scripts/lint_marketplace.py +27 -0
  276. package/scripts/lint_no_new_atomic_commands.py +179 -0
  277. package/scripts/lint_rule_interactions.py +149 -0
  278. package/scripts/memory_lookup.py +1 -1
  279. package/scripts/migrate_command_suggestions.py +151 -0
  280. package/scripts/release.py +297 -64
  281. package/scripts/schemas/command.schema.json +41 -0
  282. package/scripts/skill_linter.py +81 -0
  283. package/scripts/sync_agent_settings.py +42 -12
  284. package/scripts/update_counts.py +10 -0
  285. package/templates/consumer-settings/augment-cli-hooks.json +54 -0
  286. package/templates/consumer-settings/claude-settings.json +55 -1
  287. package/.agent-src/rules/chat-history.md +0 -171
  288. package/.agent-src/templates/scripts/implement_ticket/cli.py +0 -171
  289. package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +0 -134
  290. package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +0 -49
  291. package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +0 -140
@@ -7,95 +7,151 @@ source: package
7
7
 
8
8
  # User Interaction
9
9
 
10
- ## Numbered Options Always
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
+ POSITION-AGNOSTIC. END-OF-TURN MENUS COUNT. NEXT-STEP LISTS COUNT. NO EXCEPTIONS.
22
+ ```
23
+
24
+ The agent has read the code, the contracts, the trade-offs. Refusing
25
+ to take a position dumps that work back on the user. Take the
26
+ position; be wrong out loud if needed. "Egal, was bevorzugst Du?" /
27
+ "no preference" is NEVER acceptable.
28
+
29
+ **Position-agnostic — closes the most common slip:** End-of-turn
30
+ "Wie weiter?" / "What next?" / "How to proceed?" / "How should we
31
+ continue?" blocks with numbered options are **numbered-options
32
+ blocks**. Same Iron Law applies — exactly one `Empfehlung: N` /
33
+ `Recommendation: N` line, every time. There is no "these are just
34
+ follow-up suggestions" exception, no "the user knows better here"
35
+ exception, no "I genuinely don't have a preference" exception. If
36
+ the agent prints `1. … 2. … 3. …` anywhere in the reply, the
37
+ recommendation line is mandatory.
38
+
39
+ **Format — non-negotiable:**
40
+
41
+ - Options block stays NEUTRAL — no `(recommended)`, no `(rec)`, no `←`, no bold, no checkmark.
42
+ - Directly after the options block, ONE line, bolded, in the user's language:
43
+ - English: `**Recommendation: N — <option-name>** — <why>. Caveat: <flip-condition>.`
44
+ - German: `**Empfehlung: N — <option-name>** — <warum>. Caveat: <flip-bedingung>.`
45
+ - Other numbers MAY appear later in the prose, but ONLY as caveats
46
+ (`escalate to 3 if …`, `flip to 1 when …`). NEVER as a primary recommendation.
47
+ - If the agent genuinely cannot pick (rare — true 50/50 with missing data),
48
+ say what data would break the tie and ask for that instead.
11
49
 
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.
50
+ **What does NOT count as a recommendation:**
14
51
 
15
- ### Format
52
+ - "Both work" / "either is fine" / "depends on what you prefer"
53
+ - Listing pros and cons without picking a number
54
+ - "I'd lean towards X" without a reason
55
+ - Hiding behind "you know the project better"
56
+ - Inline `(recommended)` tag with no follow-up `Recommendation: N` line
57
+
58
+ **Slip handling — same protocol as [`language-and-tone`](language-and-tone.md#when-the-user-calls-out-a-language-slip).**
59
+ User calls out a missing or wrong recommendation → acknowledge once
60
+ in the user's language, rewrite the reply with a recommendation,
61
+ ship. No "from now on" promises — only the next reply proves
62
+ compliance.
63
+
64
+ ## Iron Law 2 — Pre-Send Self-Check
16
65
 
17
66
  ```
18
- > 1. First option brief explanation
19
- > 2. Second option brief explanation
20
- > 3. Third option — brief explanation
67
+ EVERY REPLY WITH NUMBERED OPTIONS RUNS THE SELF-CHECK. NO EXCEPTIONS.
68
+ SKIPPING IT IS A RULE VIOLATION, NOT A SLIP.
21
69
  ```
22
70
 
23
- ### Rules
71
+ Before emitting any reply that contains numbered options, scan the
72
+ **entire drafted reply** — top to bottom, including end-of-turn
73
+ "Wie weiter?" / "What next?" continuation menus, follow-up
74
+ suggestion blocks, and any list of `1. … 2. … 3. …` regardless of
75
+ its position or framing:
24
76
 
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").
77
+ 1. Count occurrences of `(recommended)` / `(rec)` / `(empfohlen)` inline next to a numbered option MUST be **zero**. Found one → rewrite, drop the tag.
78
+ 2. Count `1\.\s` / `2\.\s` / `3\.\s` patterns inside blockquotes or top-level prose if **any** numbered-option block exists anywhere in the reply, the recommendation line is mandatory.
79
+ 3. Count distinct `Recommendation:\s*N` / `Empfehlung:\s*N` lines (case-insensitive) → MUST be **exactly one per options block**. Zero → add one. Two or more distinct numbers rewrite, pick one.
80
+ 4. The number on the recommendation line MUST exist in the option block it follows.
81
+ 5. If the reply has multiple options blocks (e.g. a clarification block AND an end-of-turn menu), each block gets its own `Recommendation: N` line directly underneath.
31
82
 
32
- ### Iron Law ALWAYS recommend
83
+ Mechanical backstop: `python3 scripts/check_reply_consistency.py --stdin < draft.md`
84
+ (non-zero exit on any rule above). Self-scan is the primary gate; the
85
+ script is the deterministic safety net for ambiguous cases.
33
86
 
34
- ```
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.
37
- ```
87
+ ### Common failure modes — known, named, no excuses
38
88
 
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.
89
+ - **End-of-turn menu skipped.** Reply answers the question fine, then ends with `> 1. Foo > 2. Bar > 3. Stop` and no `Empfehlung:`. Iron Law 1 was violated — these are numbered options, position is irrelevant.
90
+ - **"Genuinely no preference" hedge.** Pick anyway. The agent has more context than the user on the trade-off; refusing to pick dumps the work back. Pick the safest option, name the flip-condition.
91
+ - **"User knows the project better" hedge.** Same failure mode, different costume. The user asked for an opinion by virtue of accepting the options block; deliver it.
92
+ - **Multi-block reply with one recommendation.** Two options blocks but only one `Empfehlung:` line — the second block is unguarded. Rule 5 above closes this.
42
93
 
43
- **Format:**
94
+ ## Numbered Options — Always
44
95
 
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.
96
+ When asking the user a question with predefined choices, **always
97
+ present numbered options**. The user should be able to reply with
98
+ just a number (e.g., `1`) instead of typing a sentence.
50
99
 
51
- **Example:**
100
+ ### Format
52
101
 
53
102
  ```
54
- > 1. Hybrid contractkeys + query (recommended)
55
- > 2. Key-basedextend the package
56
- > 3. Semanticchange all call sites
103
+ > 1. First optionbrief explanation
104
+ > 2. Second option brief explanation
105
+ > 3. Third option brief explanation
57
106
 
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.
107
+ **Recommendation: 2 Second option** <one-sentence reason>. Caveat: <flip-condition>.
61
108
  ```
62
109
 
63
- **What does NOT count as a recommendation:**
110
+ ### Rules
64
111
 
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)
112
+ - **Every question with choices** must use numbered options no exceptions.
113
+ - **Every numbered list with `1. … 2. … 3. …`** is a numbered-options block, regardless of position. End-of-turn "Wie weiter?" / "What next?" / "How to proceed?" menus, mid-reply continuation prompts, and clarification blocks all count.
114
+ - **Keep options short** one line each, with a brief explanation after the dash.
115
+ - **Always include a "skip" or "no change" option** when applicable.
116
+ - **Always state a recommendation** — Iron Law 1 above. Per options block, every time, position-agnostic.
117
+ - **Use the user's language** for the question and options.
118
+ - **Accept both** the number and a natural language answer (e.g., "1" or "the first one").
69
119
 
70
120
  ### Examples
71
121
 
72
- **Binary choice (with recommendation):**
122
+ **Binary choice:**
123
+
73
124
  ```
74
- > 1. Interactive — ask before each comment (recommended)
125
+ > 1. Interactive — ask before each comment
75
126
  > 2. Automatic — handle all independently
76
127
 
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.
128
+ **Recommendation: 1 — Interactive** — the comments touch security-sensitive code,
129
+ so a wrong auto-fix is more expensive than approving each one. Caveat: flip to 2
130
+ if the comments turn out to be pure formatting.
80
131
  ```
81
132
 
82
- **Multiple choice with skip (with recommendation):**
133
+ **Multiple choice with skip:**
134
+
83
135
  ```
84
- > 1. Fix the code (recommended)
136
+ > 1. Fix the code
85
137
  > 2. Fix the test
86
138
  > 3. Skip
87
139
 
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
140
+ **Recommendation: 1 — Fix the code** — the test asserts the documented behaviour;
141
+ the production code drifted from the contract. Caveat: pick 2 only if the contract
90
142
  itself is wrong.
91
143
  ```
92
144
 
93
- **Confirmation with context (recommendation implicit in framing):**
145
+ **Confirmation with context:**
146
+
94
147
  ```
95
148
  > Found PR #1399 on branch `chore/refactor-agent-setup-2`.
96
149
  >
97
- > 1. Yes, that's the right PR (recommended — branch matches)
150
+ > 1. Yes, that's the right PR
98
151
  > 2. No, different PR — I'll provide the URL
152
+
153
+ **Recommendation: 1 — Yes** — the branch name matches the PR title exactly.
154
+ Caveat: flip to 2 if the PR was reopened from a different branch.
99
155
  ```
100
156
 
101
157
  ### When NOT to use numbered options
@@ -16,6 +16,13 @@ Checkbox states:
16
16
  Percentage = done / (done + open). Deferred and cancelled do not count towards
17
17
  "open" (they are explicit decisions).
18
18
 
19
+ Roadmap visibility is binary:
20
+
21
+ - No `status:` frontmatter (or `status: ready`) → executable, listed.
22
+ - `status: draft` → hidden from the dashboard entirely (not counted,
23
+ not listed). Drafts become visible the moment the frontmatter flag
24
+ is removed or flipped to `ready`.
25
+
19
26
  Invocation (from project root):
20
27
  python3 .augment/scripts/update_roadmap_progress.py # rewrite
21
28
  python3 .augment/scripts/update_roadmap_progress.py --check # CI: exit 1 if stale
@@ -56,6 +63,13 @@ EXCLUDE_NAMES = {"template.md", "README.md", "progress.md", "roadmaps-progress.m
56
63
  EXCLUDE_PREFIXES = ("open-questions",)
57
64
  EXCLUDE_DIRS = {"archive", "skipped"}
58
65
 
66
+ # Frontmatter — minimal YAML block at the top of a roadmap. Used to hide
67
+ # drafts (`status: draft`) from the dashboard. Anything else (no
68
+ # frontmatter, `status: ready`, unknown values) counts as a normal
69
+ # executable roadmap.
70
+ FRONTMATTER_RE = re.compile(r"\A---\n(.*?)\n---\s*\n", re.DOTALL)
71
+ DRAFT_VALUES = frozenset({"draft"})
72
+
59
73
 
60
74
  @dataclass
61
75
  class PhaseStats:
@@ -73,6 +87,10 @@ class PhaseStats:
73
87
  def total_active(self) -> int: # denominator for %
74
88
  return self.done + self.open_
75
89
 
90
+ @property
91
+ def total_all(self) -> int: # all checkboxes incl. deferred + cancelled
92
+ return self.done + self.open_ + self.deferred + self.cancelled
93
+
76
94
  @property
77
95
  def percent(self) -> int:
78
96
  return round(self.done * 100 / self.total_active) if self.total_active else 0
@@ -117,11 +135,46 @@ class RoadmapStats:
117
135
  def total_active(self) -> int:
118
136
  return self.done + self.open_
119
137
 
138
+ @property
139
+ def total_all(self) -> int:
140
+ return self.done + self.open_ + self.deferred + self.cancelled
141
+
120
142
  @property
121
143
  def percent(self) -> int:
122
144
  return round(self.done * 100 / self.total_active) if self.total_active else 0
123
145
 
124
146
 
147
+ def parse_frontmatter(text: str) -> dict[str, str]:
148
+ """Parse a leading YAML frontmatter block. String scalars only.
149
+
150
+ Returns an empty dict if no frontmatter is present. Handles quoted and
151
+ unquoted values; ignores blank lines and comments. Nested keys, lists,
152
+ and multiline scalars are out of scope — the dashboard only needs flat
153
+ string flags (`status`, `mode`).
154
+ """
155
+ m = FRONTMATTER_RE.match(text)
156
+ if not m:
157
+ return {}
158
+ fm: dict[str, str] = {}
159
+ for line in m.group(1).splitlines():
160
+ stripped = line.strip()
161
+ if not stripped or stripped.startswith("#") or ":" not in line:
162
+ continue
163
+ key, _, value = line.partition(":")
164
+ fm[key.strip()] = value.strip().strip('"').strip("'")
165
+ return fm
166
+
167
+
168
+ def is_draft(fm: dict[str, str]) -> bool:
169
+ """Return True when frontmatter declares the roadmap as draft.
170
+
171
+ `status: draft` is the single supported way to hide a roadmap from
172
+ the dashboard. Everything else (no frontmatter, `status: ready`,
173
+ unknown values) counts as an executable roadmap.
174
+ """
175
+ return fm.get("status", "").lower() in DRAFT_VALUES
176
+
177
+
125
178
  def is_roadmap_candidate(path: Path) -> bool:
126
179
  if path.name in EXCLUDE_NAMES:
127
180
  return False
@@ -172,10 +225,14 @@ def bar(pct: int, width: int = 10) -> str:
172
225
 
173
226
 
174
227
  def collect(roadmap_root: Path) -> list[RoadmapStats]:
228
+ """Collect executable roadmaps. Drafts are excluded."""
175
229
  results: list[RoadmapStats] = []
176
230
  for path in sorted(roadmap_root.rglob("*.md")):
177
231
  if not path.is_file() or not is_roadmap_candidate(path):
178
232
  continue
233
+ text = path.read_text(encoding="utf-8")
234
+ if is_draft(parse_frontmatter(text)):
235
+ continue
179
236
  stats = parse_roadmap(path, roadmap_root)
180
237
  if stats:
181
238
  results.append(stats)
@@ -197,14 +254,17 @@ def render(roadmaps: list[RoadmapStats]) -> str:
197
254
  overall_pct = round(total_done * 100 / total_active) if total_active else 0
198
255
  lines: list[str] = []
199
256
  lines.append("# Roadmap Progress\n")
257
+ header_meta = (
258
+ f"> {len(roadmaps)} open roadmap"
259
+ f"{'s' if len(roadmaps) != 1 else ''}"
260
+ " · [roadmaps/](roadmaps/) · [archive/](roadmaps/archive/) · "
261
+ "[skipped/](roadmaps/skipped/)\n"
262
+ )
200
263
  lines.append(
201
264
  "> Auto-generated by `.augment/scripts/update_roadmap_progress.py`. "
202
265
  "Do not edit — regenerated on every roadmap-create, -execute, or "
203
266
  "completion change (last-modified timestamp lives in git history).\n>\n"
204
- f"> {len(roadmaps)} open roadmap"
205
- f"{'s' if len(roadmaps) != 1 else ''} · "
206
- "[roadmaps/](roadmaps/) · [archive/](roadmaps/archive/) · "
207
- "[skipped/](roadmaps/skipped/)\n"
267
+ + header_meta
208
268
  )
209
269
  lines.append("## Overall\n")
210
270
  lines.append(f"**{total_done} / {total_active} steps done · {overall_pct}%**\n")
@@ -213,12 +273,16 @@ def render(roadmaps: list[RoadmapStats]) -> str:
213
273
  lines.append("_No open roadmaps._\n")
214
274
  return "\n".join(lines) + "\n"
215
275
  lines.append("## Open roadmaps\n")
216
- lines.append("| # | Roadmap | Phases | Steps | Done | Open | Deferred | Cancelled | Progress |")
276
+ # Steps = ALL checkboxes (done + open + deferred + cancelled) so the row
277
+ # arithmetic adds up: Steps − Done − Deferred − Cancelled = Open. Open
278
+ # comes before Done by design — at-a-glance "what's left to do" first,
279
+ # historical "what's behind us" second.
280
+ lines.append("| # | Roadmap | Phases | Steps | Open | Done | Deferred | Cancelled | Progress |")
217
281
  lines.append("|---|---|---:|---:|---:|---:|---:|---:|---|")
218
282
  for i, r in enumerate(roadmaps, 1):
219
283
  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} | "
284
+ f"| {i} | [{r.rel}](roadmaps/{r.rel}) | {len(r.phases)} | {r.total_all} | "
285
+ f"{r.open_} | {r.done} | {r.deferred} | {r.cancelled} | "
222
286
  f"{bar(r.percent)} {r.percent}% |"
223
287
  )
224
288
  lines.append("")
@@ -227,11 +291,11 @@ def render(roadmaps: list[RoadmapStats]) -> str:
227
291
  for r in roadmaps:
228
292
  lines.append(f"### [{r.rel}](roadmaps/{r.rel})\n")
229
293
  lines.append(f"**{r.title}** — {r.done} / {r.total_active} done ({r.percent}%)\n")
230
- lines.append("| # | Phase | State | Done | Open | Deferred | Cancelled | % |")
294
+ lines.append("| # | Phase | State | Open | Done | Deferred | Cancelled | % |")
231
295
  lines.append("|---|---|---|---:|---:|---:|---:|---:|")
232
296
  for p in r.phases:
233
297
  lines.append(
234
- f"| {p.id} | {p.name} | {p.state} | {p.done} | {p.open_} | "
298
+ f"| {p.id} | {p.name} | {p.state} | {p.open_} | {p.done} | "
235
299
  f"{p.deferred} | {p.cancelled} | {p.percent}% |"
236
300
  )
237
301
  lines.append("")
@@ -1,19 +1,39 @@
1
1
  ---
2
2
  name: blade-ui
3
- description: "Use when creating or editing Blade views, components, partials, layouts, or view logic even when the user says 'add a new page' or 'render this data' without naming Blade."
3
+ description: "Stack-implementation skill for Laravel Blade dispatched by `directives/ui/apply.py` (and `review.py` / `polish.py`) when the project's frontend stack is Blade. Covers views, components, partials, layouts, and view logic."
4
4
  source: package
5
5
  ---
6
6
 
7
7
  # blade-ui
8
8
 
9
+ ## Positioning — dispatched, not standalone
10
+
11
+ `blade-ui` is the **apply-step executor** for the Blade stack. It is
12
+ invoked by [`directives/ui/apply.py`](../../templates/scripts/work_engine/directives/ui/apply.py)
13
+ once the design brief is locked, and revisited by `review.py` /
14
+ `polish.py` during the design-review loop. It does **not** own the
15
+ flow, does **not** drive the audit, and does **not** lock the design.
16
+
17
+ | Concern | Owner |
18
+ |---|---|
19
+ | Audit + token inventory (mandatory pre-step) | [`existing-ui-audit`](../existing-ui-audit/SKILL.md) |
20
+ | Design brief (layout / states / microcopy) | [`directives/ui/design.py`](../../templates/scripts/work_engine/directives/ui/design.py) |
21
+ | Universal design heuristics | [`fe-design`](../fe-design/SKILL.md) |
22
+ | Review + polish loop | [`directives/ui/review.py`](../../templates/scripts/work_engine/directives/ui/review.py) + [`polish.py`](../../templates/scripts/work_engine/directives/ui/polish.py) |
23
+
9
24
  ## When to use
10
25
 
11
- Use when creating or editing Blade views, components, partials, layouts, or forms.
26
+ Cite this skill when:
27
+
28
+ - `state.stack.frontend == "blade"` (or the project is clearly Blade-only without Livewire / Flux) and `directives/ui/apply.py` dispatches to this skill
29
+ - Editing or creating Blade views, components, partials, layouts, or forms
12
30
 
13
31
  Do NOT use when:
32
+
14
33
  - API-only endpoints (use `api-endpoint` skill)
15
- - Livewire components (use `livewire` skill)
34
+ - Livewire components (use `livewire` skill — it composes Blade views internally)
16
35
  - Flux UI components (use `flux` skill)
36
+ - Driving the full UI flow yourself — that is the `directives/ui/` orchestrator
17
37
 
18
38
  ## Procedure: Create Blade view or component
19
39
 
@@ -54,6 +74,30 @@ Do NOT use when:
54
74
  1. Blade view or component file(s) following project conventions
55
75
  2. Component class (if applicable) with typed props
56
76
 
77
+ ### Review pass — a11y findings + preview envelope
78
+
79
+ When this skill is dispatched by `directives/ui/review.py` (test slot)
80
+ or `directives/ui/polish.py` (verify slot) — i.e. a review/polish run,
81
+ not the initial apply — it also emits:
82
+
83
+ - `state.ui_review.a11y` — `{violations: [{rule, selector, severity}, ...],
84
+ severity_floor?, accepted_violations?}`. Use the same `(rule, selector)`
85
+ shape as `state.ui_audit.a11y_baseline` so the engine's de-dup matches
86
+ pre-existing entries on replay. Omit the envelope on apply passes; the
87
+ engine's `_apply_a11y_gate` only fires when a baseline is present.
88
+ - `state.ui_review.preview` — `{render_ok: bool, screenshot_path?,
89
+ dom_dump_path?, error?, skipped?}`. `render_ok: false` with `error`
90
+ populated triggers the `preview_render_failed` halt; `render_ok: true`
91
+ with `screenshot_path` threads the screenshot into the delivery
92
+ report's `artifacts` list. Browser tooling (Playwright/Cypress/…) is
93
+ a consumer-project dependency — this package does not ship one.
94
+
95
+ Polish dispatch: when the dispatcher skips `review` because a previous
96
+ review pass already returned `SUCCESS`, this skill MUST itself
97
+ synthesise the updated `state.ui_review.findings` (including any
98
+ remaining `a11y_violation` entries) so the engine's gate sees the
99
+ current state on the next polish round.
100
+
57
101
  ## Gotcha
58
102
 
59
103
  - `@include` shares parent scope — components don't. Know the difference.
@@ -40,6 +40,38 @@ Only ask the user if inference fails and the command cannot proceed without the
40
40
  | `.augment/commands/` | Shared commands (work across projects) |
41
41
  | `agents/overrides/commands/` | Project-specific overrides (used instead of original) |
42
42
 
43
+ ## Commands that dispatch to a Python engine
44
+
45
+ Most commands are pure markdown procedures — the agent reads the steps
46
+ and executes them. Two commands delegate to the `work_engine` Python
47
+ module via the `./agent-config` dispatcher; both share the same
48
+ Option-A loop (read state → run engine → handle exit code → repeat),
49
+ they only differ in the input envelope they build:
50
+
51
+ | Command | Subcommand | Envelope | Use when |
52
+ |---|---|---|---|
53
+ | `/implement-ticket` | `./agent-config implement-ticket` | `input.kind="ticket"` | User points at a Jira/Linear ticket or supplies a structured ticket payload |
54
+ | `/work` | `./agent-config work` | `input.kind="prompt"` | User supplies a free-form prompt — no ticket id, no acceptance criteria yet |
55
+
56
+ Route prompt-shaped intents (`"add a CSV export endpoint…"`,
57
+ `"fix the failing login test"`, `"refactor the audit-log controller"`)
58
+ to `/work`. Route ticket-shaped intents
59
+ (`"work on PROJ-123"`, `"start on the ticket on this branch"`) to
60
+ `/implement-ticket`. If the user pastes both a ticket id **and** a
61
+ free-form goal, prefer `/implement-ticket` and let it pull the AC from
62
+ the ticket — `/work` is the fallback when no ticket exists.
63
+
64
+ The actual step logic, halt formats, scoring breakdowns, and delivery
65
+ report are emitted by the engine. Do not paraphrase or reorder engine
66
+ output — surface it as-is. The two flows are mutually exclusive at the
67
+ state-file level: one `.work-state.json` carries one envelope at a
68
+ time, and the engine refuses to switch mid-flight.
69
+
70
+ A sibling subcommand `./agent-config migrate-state` upgrades a legacy
71
+ `.implement-ticket-state.json` file to the v1 `.work-state.json`
72
+ schema. The wrapper invokes it automatically when the legacy file is
73
+ detected; agents should not bypass the dispatcher.
74
+
43
75
  ## GitHub API: Replying to PR review comments
44
76
 
45
77
  When commands reply to PR review comments (e.g. `/fix-pr-bot-comments`):
@@ -4,6 +4,8 @@ description: "Use when creating or editing a slash command in .agent-src.uncompr
4
4
  source: package
5
5
  ---
6
6
 
7
+ <!-- cloud_safe: degrade -->
8
+
7
9
  # command-writing
8
10
 
9
11
  ## When to use
@@ -58,9 +60,37 @@ name: {command-name} # must match filename without .md
58
60
  description: "Short human-readable summary of what /{name} does"
59
61
  disable-model-invocation: true
60
62
  skills: [optional-skill-1] # optional — skills this command delegates to
63
+ suggestion: # required (road-to-context-aware-command-suggestion Phase 2)
64
+ eligible: true # default; set false to opt out of auto-surfacing
65
+ trigger_description: "natural-language pattern, comma-separated examples"
66
+ trigger_context: "concrete signal — branch name, file pattern, recent tool output"
61
67
  ---
62
68
  ```
63
69
 
70
+ Or, when opting out:
71
+
72
+ ```yaml
73
+ suggestion:
74
+ eligible: false
75
+ rationale: "one-line reason this command must be invoked deliberately"
76
+ ```
77
+
78
+ Suggestion-block rules (linter-enforced):
79
+
80
+ * `eligible` is **required** and must be `true` or `false`.
81
+ * `eligible: true` → both `trigger_description` and `trigger_context` must be
82
+ non-empty (≥ 10 chars each); the linter rejects empty or overly generic
83
+ patterns. The suggestion layer never auto-executes; the user always picks.
84
+ * `eligible: false` → `rationale` must be non-empty. Use the opt-out for
85
+ intentional-only invocations (settings mutations, destructive actions,
86
+ package-internal tools, niche maintenance).
87
+ * Optional `confidence_floor` (0.0–1.0) and `cooldown` (e.g. `10m`)
88
+ override the global settings per command.
89
+
90
+ Eligibility decisions are tracked in
91
+ [`agents/contexts/command-suggestion-eligibility.md`](../../../agents/contexts/command-suggestion-eligibility.md).
92
+ Add or revise entries there before changing a command's `suggestion` block.
93
+
64
94
  When iterating on the description, delegate to the
65
95
  [`description-assist`](../description-assist/SKILL.md) skill — approval-gated,
66
96
  no silent edits, max two rounds.
@@ -105,8 +135,8 @@ multi-paragraph explanation, extract it into a skill and call it.
105
135
  * Run `bash scripts/compress.sh --sync` → regenerates `.agent-src/commands/{name}.md`.
106
136
  * Run `python3 scripts/compress.py --generate-tools` → creates the Claude symlink at
107
137
  `.claude/skills/{name}/SKILL.md`.
108
- * Run the full CI pipeline locally each script directly must exit 0
109
- except for tolerated warnings.
138
+ * Run the full CI pipeline locally (see `Taskfile.yml` in this repo for
139
+ the script list) — must exit 0 except for tolerated warnings.
110
140
 
111
141
  ## Output format
112
142
 
@@ -133,6 +163,26 @@ multi-paragraph explanation, extract it into a skill and call it.
133
163
  * Do NOT edit `.agent-src/`, `.augment/`, or `.claude/` projections
134
164
  * Do NOT exceed the hard size limit without a waiver
135
165
 
166
+ ## Cloud Behavior
167
+
168
+ On cloud surfaces (Claude.ai Web, Skills API) the package's
169
+ `scripts/skill_linter.py`, `scripts/compress.py`, and the `task`
170
+ runner are not available. This skill still applies — but with
171
+ prose-only validation:
172
+
173
+ * Emit the full command file as a copyable Markdown block. Do not
174
+ attempt to write it to disk.
175
+ * Self-check the frontmatter against the rules below — `name`,
176
+ `description`, `disable-model-invocation: true` MUST all be
177
+ present.
178
+ * Self-check the body shape: numbered steps, explicit safety gates,
179
+ no inline skill-level detail.
180
+ * Tell the user to save the file under
181
+ `.agent-src.uncompressed/commands/{name}.md` and run
182
+ `task sync && task lint-skills` locally before committing.
183
+ * Skip every reference to running the linter, compressor, or
184
+ generators yourself — they only run on the user's machine.
185
+
136
186
  ## Examples
137
187
 
138
188
  Good description (trigger-shaped, outcome-focused):
@@ -4,6 +4,8 @@ description: "Use when polishing a skill/rule/command/guideline frontmatter desc
4
4
  source: package
5
5
  ---
6
6
 
7
+ <!-- cloud_safe: degrade -->
8
+
7
9
  # description-assist
8
10
 
9
11
  ## When to use
@@ -155,6 +157,25 @@ and stop. Do not loop further.
155
157
  * Do NOT run `scripts/skill_trigger_eval.py` from inside this skill — eval
156
158
  execution spends API tokens and is a separate user action
157
159
 
160
+ ## Cloud Behavior
161
+
162
+ On cloud surfaces (Claude.ai Web, Skills API) the package's
163
+ `scripts/audit_skill_descriptions.py`, `scripts/skill_linter.py`,
164
+ and `scripts/skill_trigger_eval.py` are not reachable. The skill
165
+ still applies — with prose-only inspection:
166
+
167
+ * Reason from the description text in the conversation. The agent
168
+ acts as the inspector; no separate audit pass runs.
169
+ * Apply the same checklist used by the local audit: length budget,
170
+ trigger prefix ("Use when …"), domain class, symptom class,
171
+ undertrigger tail.
172
+ * Emit verdict + up to 3 numbered variants. The user picks; the
173
+ agent emits the new frontmatter as a copyable block.
174
+ * Skip every reference to running the audit or trigger-eval scripts.
175
+ Recommend the user run the package's local linter after applying.
176
+ * Never claim a description has been "graded" or "scored" by an
177
+ external pass — there isn't one.
178
+
158
179
  ## Examples
159
180
 
160
181
  Inspection verdict (good — compact):
@@ -182,5 +182,4 @@ copy-paste instructions if missing.
182
182
  - [`refine-ticket`](../refine-ticket/SKILL.md) — sibling; refine first if the ticket is vague
183
183
  - [`jira-ticket`](../../commands/jira-ticket.md) — ticket loader
184
184
  - [`feature-plan`](../../commands/feature-plan.md) — downstream planning
185
- - [`road-to-ticket-refinement.md`](../../../agents/roadmaps/road-to-ticket-refinement.md) — governing roadmap
186
185
  - [`artifact-drafting-protocol`](../../rules/artifact-drafting-protocol.md) — drafting protocol