@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
@@ -0,0 +1,161 @@
1
+ ---
2
+ name: work
3
+ skills: [refine-prompt, command-routing]
4
+ description: Drive a free-form prompt end-to-end through refine → score → plan → implement → test → verify → report — Option-A loop over the `work_engine` Python engine, confidence-band gated, no auto-git.
5
+ disable-model-invocation: true
6
+ suggestion:
7
+ eligible: true
8
+ trigger_description: "build this, implement this, drive this end-to-end"
9
+ trigger_context: "free-form prompt without a ticket key"
10
+ ---
11
+
12
+ # work
13
+
14
+ ## Instructions
15
+
16
+ ### 1. Resolve the prompt
17
+
18
+ `/work` accepts the user's request as a free-form prompt. Resolve the
19
+ input in this order:
20
+
21
+ 1. **Inline argument** — `/work <prompt>` (everything after the verb is
22
+ the prompt; quoting is not required).
23
+ 2. **Pasted block** — markdown block under the command in the same turn.
24
+ 3. **No input** — ask once, with numbered options:
25
+
26
+ ```
27
+ > 1. I'll type the prompt now — paste it on the next line
28
+ > 2. Load from a file — give me a path
29
+ > 3. Abort — never mind
30
+ ```
31
+
32
+ On `1`, wait for the user. On `2`, ask for the path and read it. On
33
+ `3`, stop.
34
+
35
+ Strip leading/trailing whitespace at the boundary, but preserve casing
36
+ and internal spacing — the scorer reads the original text when grading
37
+ goal clarity.
38
+
39
+ ### 2. Prepare the state file
40
+
41
+ The engine persists everything in `.work-state.json` (same envelope as
42
+ `/implement-ticket`, different `input.kind`). Two cases, in this order:
43
+
44
+ - **Resume** — `.work-state.json` exists with `input.kind="prompt"`. Do
45
+ not pass `--prompt-file` or `--persona`; mid-flight switches are
46
+ refused by the engine.
47
+ - **Fresh run** — no state file. Write the resolved prompt to
48
+ `prompt.txt` (raw text, single file, UTF-8) and pass it via
49
+ `--prompt-file prompt.txt`. Honour `roles.active_role` from
50
+ `.agent-settings.yml` via `--persona`.
51
+
52
+ If a `.work-state.json` exists but carries a ticket envelope
53
+ (`input.kind="ticket"`), that's an `/implement-ticket` flow in
54
+ progress. Stop and ask:
55
+
56
+ ```
57
+ > A ticket-flow state file is already in `.work-state.json`. Pick one:
58
+ > 1. Resume the ticket flow — re-run /implement-ticket
59
+ > 2. Discard it — delete the state file and start /work fresh
60
+ > 3. Abort
61
+ ```
62
+
63
+ ### 3. Drive the Option-A dispatch loop
64
+
65
+ Run the engine with the state file on every iteration:
66
+
67
+ ```bash
68
+ ./agent-config work \
69
+ --state-file .work-state.json \
70
+ [--prompt-file prompt.txt --persona <name>] # first call only
71
+ ```
72
+
73
+ The dispatcher wires `PYTHONPATH` and routes to the engine module
74
+ internally. `./agent-config` is the only supported entry point in
75
+ consumer repos — do not call the engine module directly.
76
+
77
+ Branch on the exit code:
78
+
79
+ | Exit | Meaning | Action |
80
+ |---|---|---|
81
+ | `0` | SUCCESS — final report on stdout | Go to step 5 |
82
+ | `1` | BLOCKED — halt surface on stdout, state persisted | Inspect `questions[0]` |
83
+ | `2` | Config/IO error | Surface the stderr message to the user, stop |
84
+
85
+ On exit `1`, look at the first line after `[halt] outcome=… step=…`:
86
+
87
+ - **Starts with `@agent-directive: refine-prompt`** — invoke the
88
+ [`refine-prompt`](../skills/refine-prompt/SKILL.md) skill against
89
+ `state.input.data.raw`, write the resulting `reconstructed_ac` and
90
+ `assumptions` arrays back onto `state.input.data`, then re-run.
91
+ - **Starts with `@agent-directive:` (other verbs)** — see §4.
92
+ - **Starts with `>`** — user question per
93
+ [`user-interaction`](../rules/user-interaction.md). Emit verbatim,
94
+ wait for the user, write their answer back onto `state.input.data`
95
+ (or the matching slice), then re-run. Never guess.
96
+
97
+ ### 4. Confidence-band semantics
98
+
99
+ The engine's `refine` step scores the reconstructed envelope and routes
100
+ on the resulting band. Never attempt to flip the band yourself — the
101
+ engine owns the verdict.
102
+
103
+ | Band | Outcome | What the agent does |
104
+ |---|---|---|
105
+ | `high` | SUCCESS | Engine proceeds silently; the breakdown lands on `state.input.data.confidence` and is included in the delivery report |
106
+ | `medium` | PARTIAL halt | Engine emits the assumptions report; surface verbatim, wait for the user. On confirm, write `state.input.data.confidence_confirmed=true` and re-run. On refine, replace `state.input.data.raw` with the new prompt, clear `reconstructed_ac` + `assumptions`, and re-run |
107
+ | `low` | BLOCKED halt | Engine emits exactly one clarifying question on the weakest dimension (per [`ask-when-uncertain`](../rules/ask-when-uncertain.md) Iron Law). Surface verbatim, wait for the user, append their answer to `state.input.data.raw`, clear `reconstructed_ac` + `assumptions`, and re-run |
108
+
109
+ Once the gate releases, the rest of the loop is identical to
110
+ `/implement-ticket`: `create-plan`, `apply-plan`, `run-tests`,
111
+ `review-changes` directives flow through the same dispatch table.
112
+
113
+ ### 5. Final report + close-prompt
114
+
115
+ On exit `0`, the engine prints the delivery report. Surface it
116
+ unchanged, then append:
117
+
118
+ ```
119
+ > 1. /commit — stage + commit per the delivery report
120
+ > 2. /create-pr — open a pull request from this branch
121
+ > 3. Keep working — I'll hold the state file for the next /work
122
+ > 4. Discard — delete .work-state.json
123
+ ```
124
+
125
+ Per [`scope-control`](../rules/scope-control.md), git operations are
126
+ permission-gated. Never run `/commit` or `/create-pr` without the user
127
+ choosing them.
128
+
129
+ ### Rules
130
+
131
+ - Honour [`scope-control`](../rules/scope-control.md),
132
+ [`minimal-safe-diff`](../rules/minimal-safe-diff.md), and
133
+ [`verify-before-complete`](../rules/verify-before-complete.md) inside
134
+ every directive.
135
+ - Never bypass the engine. Don't skip steps, don't rewrite outcomes,
136
+ don't flip `confidence_confirmed` without the user's explicit OK.
137
+ - The low-band halt emits **one** question. If you find yourself
138
+ surfacing two, you reformatted the engine output — stop and surface
139
+ it verbatim.
140
+ - Persona is session-global. Read it from `.agent-settings.yml` on the
141
+ fresh run; never accept a `--persona` flag from the user mid-flight.
142
+ - When `telemetry.artifact_engagement.enabled: true` in
143
+ `.agent-settings.yml`, emit one `./agent-config telemetry:record` per
144
+ boundary (per phase-step or per task — see `granularity`) with the
145
+ consulted+applied artefact ids. Full contract in
146
+ [`artifact-engagement-recording`](../rules/artifact-engagement-recording.md).
147
+ Default-off; absent setting is a silent no-op.
148
+
149
+ ## Examples
150
+
151
+ ```
152
+ /work fix the failing login test under tests/feature/auth
153
+ /work # asks for the prompt
154
+ /work add a CSV export endpoint to the audit-log controller
155
+ ```
156
+
157
+ ## See also
158
+
159
+ - [`refine-prompt`](../skills/refine-prompt/SKILL.md) — fills `reconstructed_ac` + `assumptions` on the rebound from the first-pass halt
160
+ - [`implement-ticket`](implement-ticket.md) — sibling command for ticket-shaped input; same engine, different envelope
161
+ - [`commit`](commit.md), [`create-pr`](create-pr.md) — post-delivery commands the user runs explicitly
@@ -16,9 +16,8 @@ matching the existing pattern established by `review-routing-data-format`.
16
16
  ## File locations
17
17
 
18
18
  Each schema lives under `agents/memory/<type>/<hash>.yml` (content-addressed,
19
- merge-safe see [`road-to-memory-merge-safety.md`](../../../agents/roadmaps/road-to-memory-merge-safety.md))
20
- **or** in a single `agents/memory/<type>.yml` file for projects that prefer
21
- one file per type.
19
+ merge-safe) **or** in a single `agents/memory/<type>.yml` file for projects
20
+ that prefer one file per type.
22
21
 
23
22
  | Type | Single-file path | Sharded path |
24
23
  |---|---|---|
@@ -111,7 +110,4 @@ active — the report is informational, not a gate.
111
110
 
112
111
  ## See also
113
112
 
114
- - [`road-to-engineering-memory.md`](../../../agents/roadmaps/road-to-engineering-memory.md) — roadmap this guideline implements
115
- - [`road-to-memory-merge-safety.md`](../../../agents/roadmaps/road-to-memory-merge-safety.md) — why content-addressed files
116
113
  - [`review-routing-data-format.md`](review-routing-data-format.md) — sibling format for ownership + bug patterns
117
- - [`road-to-role-modes.md`](../../../agents/roadmaps/road-to-role-modes.md) — role modes that consume these files
@@ -198,4 +198,3 @@ the next explicit settings edit.
198
198
 
199
199
  - [`agent-settings.md`](../../templates/agent-settings.md) — dev-layer schema
200
200
  - [`agent-project-settings.example.yml`](../../templates/agents/agent-project-settings.example.yml) — team-layer template
201
- - [`road-to-project-memory.md`](../../../agents/roadmaps/road-to-project-memory.md) — roadmap this guideline implements
@@ -9,11 +9,6 @@ package adapter (when present). The status helper
9
9
  `scripts/memory_status.py` decides which path to take and caches the
10
10
  result for the session.
11
11
 
12
- Referenced by
13
- [`road-to-agent-memory-integration.md`](../../../agents/roadmaps/road-to-agent-memory-integration.md)
14
- Phase 0. The retrieval contract itself lives in
15
- [`agent-memory/road-to-retrieval-contract.md`](../../../agents/roadmaps/agent-memory/road-to-retrieval-contract.md).
16
-
17
12
  ## The contract
18
13
 
19
14
  ```python
@@ -117,5 +112,3 @@ Other types remain accessible on demand via
117
112
  — the on-disk schema
118
113
  - [`../../rules/context-hygiene.md`](../../rules/context-hygiene.md)
119
114
  — token budget that `max_entries_per_task` protects
120
- - [`../../../agents/roadmaps/road-to-memory-merge-safety.md`](../../../agents/roadmaps/road-to-memory-merge-safety.md)
121
- — why intake is append-only JSONL with `merge=union`
@@ -117,9 +117,8 @@ do not pretend verification happened.
117
117
  ## Structured mode markers
118
118
 
119
119
  Every contract output MUST begin with a one-line HTML comment so
120
- session captures, log scrapers, and the measurement hook in
121
- [`road-to-role-modes.md`](../../../agents/roadmaps/road-to-role-modes.md#phase-4--measurement-hook-closes-q2-of-master-frame)
122
- can count contract-conformant outputs per mode:
120
+ session captures, log scrapers, and the measurement hook can count
121
+ contract-conformant outputs per mode:
123
122
 
124
123
  ```
125
124
  <!-- role-mode: developer | contract: goal,plan,changes,tests,open-questions -->
@@ -206,6 +205,5 @@ finding. See the Q4 rule in `road-to-personas.md`.
206
205
 
207
206
  ## See also
208
207
 
209
- - [`road-to-role-modes.md`](../../../agents/roadmaps/road-to-role-modes.md) — roadmap this guideline implements
210
208
  - [`output-patterns.md`](output-patterns.md) — generic output conventions modes inherit
211
209
  - [`agent-interaction-and-decision-quality.md`](agent-interaction-and-decision-quality.md) — how modes interact with the numbered-options protocol
@@ -129,7 +129,6 @@ unreviewed upstream changes is not.
129
129
 
130
130
  ## See also
131
131
 
132
- - [`road-to-curated-self-improvement.md`](../../../agents/roadmaps/road-to-curated-self-improvement.md) — roadmap this guideline implements
133
132
  - [`proposal.example.md`](../../templates/agents/proposal.example.md) — the template every proposal derives from
134
133
  - [`artifact-drafting-protocol`](../../rules/artifact-drafting-protocol.md) — Understand → Research → Draft sequence used inside Stage 3
135
134
  - [`preservation-guard`](../../rules/preservation-guard.md) — invoked by the gate to check replacement proposals
@@ -15,6 +15,25 @@ Select the implementation based on context (config, user input, enum value).
15
15
  - Notification channels (Email, SMS, Push)
16
16
  - Import parsers (JSON, XML, CSV)
17
17
 
18
+ ## Sniff test — when an enum/string discriminator wants to become a Strategy
19
+
20
+ Run these three questions **before** writing a second `match`/`switch` arm,
21
+ a second `if/elseif` branch, or a second hardcoded class per provider/type.
22
+ Two "yes" answers → extract Strategy + Registry. Three "yes" → it is
23
+ already overdue.
24
+
25
+ 1. **Same-shape branches?** Do two or more branches/classes implement the
26
+ *same operation* on the *same data*, differing only in provider-specific
27
+ details (URL, field mapping, credentials, response parsing)?
28
+ 2. **Closed-list edits?** Adding a new case requires editing an enum, a
29
+ `match` block, an allowlist constant, *and* a service class — i.e. the
30
+ change is mechanical but spans ≥3 files?
31
+ 3. **Discriminator leakage?** Does the discriminator (`Type::FOO`,
32
+ `'stripe'`, an `is_csv()` check) appear in ≥3 places that should not
33
+ have to know about `FOO` specifically?
34
+
35
+ If yes → see *Refactoring recipe* below.
36
+
18
37
  ## Example
19
38
 
20
39
  ```php
@@ -62,8 +81,167 @@ enum DiscountType: string
62
81
  }
63
82
  ```
64
83
 
84
+ ## Refactoring recipe — from discriminator to Strategy
85
+
86
+ Two anti-patterns appear in real codebases and both refactor into the same
87
+ Strategy + Registry shape. Each step is a separate commit so reviewers can
88
+ follow the safety chain.
89
+
90
+ ### Sub-pattern A — *hardcoded single provider per class*
91
+
92
+ Each provider gets its own `FooImportService`, `FooJob`, `FooCommand`,
93
+ and every method body repeats `Provider::FOO->value` or
94
+ `Provider::FOO->getId()`. Adding a new provider means copy-pasting an
95
+ entire class tree.
96
+
97
+ ```php
98
+ // Before — one class per provider, discriminator hardcoded.
99
+ final class StripeImportService
100
+ {
101
+ public function id(): int { return Provider::STRIPE->getId(); }
102
+ public function name(): string { return Provider::STRIPE->value; }
103
+ public function import(): void { /* Stripe-specific logic */ }
104
+ }
105
+
106
+ final class PaypalImportService
107
+ {
108
+ public function id(): int { return Provider::PAYPAL->getId(); }
109
+ public function name(): string { return Provider::PAYPAL->value; }
110
+ public function import(): void { /* PayPal-specific logic */ }
111
+ }
112
+ ```
113
+
114
+ ```php
115
+ // After — one interface, N strategies, one registry.
116
+ interface ImportStrategy
117
+ {
118
+ public function provider(): Provider;
119
+ public function import(): void;
120
+ }
121
+
122
+ final class StripeImport implements ImportStrategy
123
+ {
124
+ public function provider(): Provider { return Provider::STRIPE; }
125
+ public function import(): void { /* Stripe-specific logic */ }
126
+ }
127
+ // ...PaypalImport implements ImportStrategy similarly.
128
+ ```
129
+
130
+ Recipe (one commit per step):
131
+
132
+ 1. Extract the interface (`ImportStrategy`) and move one provider class
133
+ to implement it. Existing call sites keep using the old class.
134
+ 2. Repeat for the remaining providers — still no callers changed.
135
+ 3. Introduce the Registry (next section). Migrate call sites one by one
136
+ from `new StripeImportService()` to `$registry->for(Provider::STRIPE)`.
137
+ 4. Delete the old per-provider classes.
138
+
139
+ ### Sub-pattern B — *allowlist constant on a single coordinator*
140
+
141
+ A central service holds an allowlist of supported discriminator values.
142
+ Every new provider edits the constant *and* a method that branches on it.
143
+
144
+ ```php
145
+ // Before — closed-list edit per new provider.
146
+ final class EquipmentImportService
147
+ {
148
+ private const FULL_SYNC_PROVIDERS = [
149
+ Provider::STRIPE,
150
+ Provider::PAYPAL,
151
+ Provider::INVOICE,
152
+ ];
153
+
154
+ public function supportsFullSync(Provider $p): bool
155
+ {
156
+ return in_array($p, self::FULL_SYNC_PROVIDERS, true);
157
+ }
158
+ }
159
+ ```
160
+
161
+ The fix is a **capability flag on the strategy interface** — the strategy
162
+ declares its own capabilities, and the coordinator asks the strategy
163
+ instead of consulting an allowlist.
164
+
165
+ ```php
166
+ interface ImportStrategy
167
+ {
168
+ public function provider(): Provider;
169
+ public function import(): void;
170
+ public function supportsFullSync(): bool; // capability flag
171
+ }
172
+ ```
173
+
174
+ A new provider now adds itself by implementing the interface — no central
175
+ list to edit, no in_array call to maintain. The coordinator becomes:
176
+
177
+ ```php
178
+ $strategy = $registry->for($provider);
179
+ if ($strategy->supportsFullSync()) {
180
+ $strategy->fullSync();
181
+ }
182
+ ```
183
+
184
+ ## Registry companion
185
+
186
+ A Registry resolves the discriminator → strategy lookup that previously
187
+ lived in the `match` block. It owns the only place the enum is mapped to
188
+ classes; everything downstream sees only the interface.
189
+
190
+ ```php
191
+ final class ImportStrategyRegistry
192
+ {
193
+ /** @var array<string, ImportStrategy> */
194
+ private array $byProvider;
195
+
196
+ /** @param iterable<ImportStrategy> $strategies */
197
+ public function __construct(iterable $strategies)
198
+ {
199
+ foreach ($strategies as $strategy) {
200
+ $this->byProvider[$strategy->provider()->value] = $strategy;
201
+ }
202
+ }
203
+
204
+ public function for(Provider $provider): ImportStrategy
205
+ {
206
+ return $this->byProvider[$provider->value]
207
+ ?? throw new InvalidArgumentException(
208
+ "No import strategy registered for {$provider->value}"
209
+ );
210
+ }
211
+ }
212
+ ```
213
+
214
+ Wire-up in Laravel — tag the strategies, inject the tag into the registry:
215
+
216
+ ```php
217
+ // In a ServiceProvider::register()
218
+ $this->app->tag([
219
+ StripeImport::class,
220
+ PaypalImport::class,
221
+ InvoiceImport::class,
222
+ ], 'import.strategies');
223
+
224
+ $this->app->bind(
225
+ ImportStrategyRegistry::class,
226
+ fn ($app) => new ImportStrategyRegistry($app->tagged('import.strategies')),
227
+ );
228
+ ```
229
+
230
+ A new provider now adds itself by:
231
+
232
+ 1. Implementing `ImportStrategy`.
233
+ 2. Adding one line to the `tag()` call.
234
+
235
+ No `match` block grows. No allowlist edits. No coordinator method changes.
236
+
65
237
  ## When NOT to Use
66
238
 
67
- ❌ Only two cases with trivial logic — a simple `match` or ternary is enough
68
- The "strategies" share no common interface or behavior
239
+ ❌ Only two cases with **trivial logic** — a simple `match` or ternary is
240
+ enough. *"Trivial"* means the two arms each fit on one line and share
241
+ no structural shape. Two arms that each call a method on a service
242
+ are not trivial — see the sniff test.
243
+ ❌ The "strategies" share no common interface or behavior — if the
244
+ operations differ, you do not have a Strategy candidate.
245
+ ❌ The discriminator is set once at boot and never re-evaluated — a
246
+ single binding in the container is simpler than a Registry.
69
247
 
@@ -99,6 +99,5 @@ cast (usually Core-6 for review skills, empty for others).
99
99
 
100
100
  ## Related
101
101
 
102
- - [`../../agents/roadmaps/archive/road-to-personas.md`](../../agents/roadmaps/archive/road-to-personas.md) — roadmap + rationale (shipped 2026-04-22)
103
102
  - [`../guidelines/agent-infra/role-contracts.md`](../guidelines/agent-infra/role-contracts.md) — workflow modes personas compose with
104
103
  - [`../rules/artifact-drafting-protocol.md`](../rules/artifact-drafting-protocol.md) — mandatory per new persona
@@ -39,8 +39,13 @@ If the user skips Q1 or Q5, stop and surface the ambiguity — don't guess.
39
39
 
40
40
  ## Phase B — Research
41
41
 
42
- Scan `.agent-src.uncompressed/` for overlap. Report the top 3-5
43
- most-similar artifacts and ask (numbered options):
42
+ Run the **search protocol** from
43
+ [`learning-to-rule-or-skill` § 4](../skills/learning-to-rule-or-skill/SKILL.md#4-check-for-overlap--search-protocol-mandatory)
44
+ — `ls` all four surfaces (`skills/`, `rules/`, `guidelines/`, `commands/`),
45
+ grep with **solution-words AND problem-words**, scan sub-directory
46
+ taxonomies, then **open and skim** the 3 nearest matches. A negative grep
47
+ alone is not proof of no overlap. Report the top 3-5 most-similar
48
+ artifacts and ask (numbered options):
44
49
 
45
50
  - Extend an existing one?
46
51
  - Create a new one — gap is real?
@@ -0,0 +1,133 @@
1
+ ---
2
+ type: "auto"
3
+ alwaysApply: false
4
+ description: "After completing a /implement-ticket or /work phase-step (refine, memory, analyze, plan, implement, test, verify, report) or full task — emit one telemetry:record call with consulted+applied artefact ids when telemetry.artifact_engagement.enabled is true"
5
+ source: package
6
+ ---
7
+
8
+ <!-- cloud_safe: noop -->
9
+
10
+ # Artifact Engagement Recording
11
+
12
+ Records which **skills, rules, commands, guidelines, personas** the agent
13
+ actually consulted and applied during a `/implement-ticket` or `/work` run.
14
+ Default-off; opt-in via `.agent-settings.yml`. Zero overhead when disabled.
15
+
16
+ The schema, CLI, and storage layer are owned by
17
+ [`scripts/telemetry/`](../../../scripts/telemetry/) and the
18
+ `./agent-config telemetry:record` / `telemetry:status` commands shipped
19
+ in Phase 1+2 of the
20
+ [`road-to-artifact-engagement-telemetry`](../../../agents/roadmaps/road-to-artifact-engagement-telemetry.md)
21
+ roadmap. This rule says **when** to call the CLI, not how the file is
22
+ structured.
23
+
24
+ ## Activation gate — read settings ONCE per task, then cache
25
+
26
+ Before the first `/implement-ticket` or `/work` step runs, read
27
+ `telemetry.artifact_engagement.enabled` from `.agent-settings.yml`. Cache
28
+ the value (and `granularity`) for the whole task.
29
+
30
+ - `enabled: false` or section missing → rule is a **no-op**. Do not import
31
+ the script, do not open the log, do not mention recording. Skip the rest
32
+ of this rule.
33
+ - `enabled: true` → continue with the cadence below.
34
+
35
+ Use `./agent-config telemetry:status --format json` if the value is
36
+ not already in working memory; the call is read-only and never touches
37
+ the log file.
38
+
39
+ ## Cadence — depends on `granularity`
40
+
41
+ | `granularity` | When to emit | Coalescing |
42
+ |---|---|---|
43
+ | `task` *(default)* | Once, when the eight-step flow ends (success, blocked, partial — any terminal state) | All consulted/applied artefacts from refine through report merged into a single event |
44
+ | `phase-step` | At the close of each phase-step (refine, memory, analyze, plan, implement, test, verify, report) | One event per step; per-step consulted/applied lists only |
45
+
46
+ Within a single boundary, **dedupe** consulted and applied lists. A skill
47
+ consulted three times in the same boundary records once.
48
+
49
+ ## What counts as consulted vs applied
50
+
51
+ - **`consulted`** — the agent **read** the artefact this boundary: opened
52
+ its `SKILL.md`, scanned its rule body, viewed its frontmatter,
53
+ referenced its guideline, checked its persona contract, dispatched its
54
+ command. Reading does not imply behaviour change.
55
+ - **`applied`** — the artefact **influenced the output** this boundary:
56
+ its instructions changed how the agent answered, what code it wrote,
57
+ what tools it ran, or what halt surface it produced. Applied is a
58
+ strict subset of consulted.
59
+
60
+ When in doubt → record as `consulted` only. Over-recording `applied`
61
+ inflates the engagement signal and defeats the purpose.
62
+
63
+ ## What to record — id-only, no payload
64
+
65
+ ```bash
66
+ ./agent-config telemetry:record \
67
+ --task-id "$TASK_ID" \
68
+ --boundary task \
69
+ --consulted skills:php-coder \
70
+ --consulted skills:eloquent \
71
+ --consulted rules:scope-control \
72
+ --applied skills:php-coder \
73
+ --applied rules:scope-control
74
+ ```
75
+
76
+ - `--task-id` — the ticket key (`PROJ-123`) for `/implement-ticket`, or a
77
+ short opaque slug derived from the prompt for `/work`. **Never** a
78
+ branch name, a file path, or a free-text title.
79
+ - `--boundary` — `task` or `phase-step`, matching the cadence above.
80
+ - `--consulted <kind>:<id>` — repeat per artefact. `<kind>` is one of
81
+ `skills`, `rules`, `commands`, `guidelines`, `personas`.
82
+ - `--applied <kind>:<id>` — repeat per artefact actually applied.
83
+ - Exit `0` always when disabled (silent). Exit `1` on schema validation
84
+ failure (rule must NOT swallow this — surface to the user). Exit `2`
85
+ on IO failure.
86
+
87
+ ## Privacy contract — what NEVER goes into a record
88
+
89
+ The CLI rejects most violations on the input boundary, but the agent must
90
+ not even attempt these:
91
+
92
+ - ❌ File paths (`src/Foo.php`, `tests/...`) — id fields are
93
+ artefact identifiers only.
94
+ - ❌ Source code, prompt text, ticket body, AC text.
95
+ - ❌ Branch names, commit shas, PR numbers, URLs.
96
+ - ❌ Secrets, env vars, credentials, customer data.
97
+ - ❌ Free-text strings longer than 200 chars (CLI enforces; agent must
98
+ not generate).
99
+
100
+ When in doubt → **don't record**. A missing event is cheap; a leaked
101
+ prompt is not.
102
+
103
+ ## Failure modes — DO NOT block the user's task
104
+
105
+ - Schema rejection (CLI exit `1`) → log the message internally, continue
106
+ the user's task. Do **not** halt the dispatch loop.
107
+ - IO failure (CLI exit `2`) → same. The telemetry is **observation**, not
108
+ a delivery requirement.
109
+ - Settings malformed → already handled by the CLI: it falls back to
110
+ disabled and exits `0`. Agent treats it as "disabled this task".
111
+
112
+ The only error the agent surfaces is when the user explicitly asked for
113
+ recording (`telemetry:status` confirms enabled) but no event reached the
114
+ log — that is a real bug, not a swallowed error.
115
+
116
+ ## What this rule does NOT do
117
+
118
+ - Run when `enabled: false` (cost floor is zero — see
119
+ [`tests/telemetry/test_cost_floor.py`](../../../tests/telemetry/test_cost_floor.py)).
120
+ - Track the agent's tool calls, file reads, or token spend — that is
121
+ out of scope, see the roadmap's "out-of-scope" section.
122
+ - Decide retirement. Phase 4's aggregator + report renderer are the only
123
+ consumers that may interpret the JSONL.
124
+ - Run on cloud surfaces (Claude.ai Web, Skills API). The
125
+ `cloud_safe: noop` marker keeps it inert there.
126
+
127
+ ## See also
128
+
129
+ - [`road-to-artifact-engagement-telemetry`](../../../agents/roadmaps/road-to-artifact-engagement-telemetry.md) — phase contract
130
+ - [`docs/contracts/artifact-engagement-flow.md`](../../docs/contracts/artifact-engagement-flow.md) — recording contract details
131
+ - [`/implement-ticket`](../commands/implement-ticket.md) and [`/work`](../commands/work.md) — boundary points where this rule fires
132
+ - [`scripts/telemetry/`](../../../scripts/telemetry/) — engine source
133
+ - [`agent-settings`](../templates/agent-settings.md) — `telemetry.artifact_engagement.*` reference
@@ -10,6 +10,20 @@ source: package
10
10
  **When in doubt, ask the user.** Do not guess, assume, or improvise.
11
11
  Asking one question too many is always better than a wrong assumption.
12
12
 
13
+ ## Iron Law — one question per turn, ALWAYS
14
+
15
+ ```
16
+ ONE QUESTION PER TURN. NO EXCEPTIONS.
17
+ ASK. WAIT FOR THE ANSWER. THEN ASK THE NEXT.
18
+ ```
19
+
20
+ This is absolute. Not a default, not a guideline, not "usually".
21
+ Every turn that contains a question contains **exactly one** question.
22
+ Even if the questions look trivial. Even if they look independent.
23
+ Even if they would fit on one screen. Even if batching "feels more
24
+ efficient". Full self-check, ordering, and handoff rules under
25
+ [How to ask](#how-to-ask).
26
+
13
27
  ## When to ask
14
28
 
15
29
  - Requirement is ambiguous or could be interpreted multiple ways
@@ -42,22 +56,13 @@ makes the answer unambiguous, proceed — but state the assumption explicitly.
42
56
 
43
57
  Be specific. Present numbered options (per `user-interaction`). Keep it short.
44
58
 
45
- ### The Iron Law one question per turn, ALWAYS
46
-
47
- ```
48
- ONE QUESTION PER TURN. NO EXCEPTIONS.
49
- ASK. WAIT FOR THE ANSWER. THEN ASK THE NEXT.
50
- ```
51
-
52
- This is absolute. Not a default, not a guideline, not "usually". Every
53
- turn that contains a question contains **exactly one** question. Even
54
- if the questions look trivial. Even if they look independent. Even if
55
- they would fit on one screen. Even if batching "feels more efficient".
59
+ The Iron Law (one question per turn) is at the top of this file.
60
+ This section adds the rationale, self-check, and ordering.
56
61
 
57
62
  The user must never have to track sub-numbers, scroll through stacked
58
63
  option blocks, or split their reply across multiple questions. One
59
- question, numbered options (per `user-interaction`), one short answer,
60
- next turn.
64
+ question, numbered options (per `user-interaction`), one short
65
+ answer, next turn.
61
66
 
62
67
  Rationale — why even "trivial" batches fail:
63
68