@tenkara/afm-linux-arm64 0.0.0-stage → 4.0.0-alpha.11

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 (283) hide show
  1. package/bin/afm +4 -0
  2. package/content/.coupling-baseline.tsv +1 -0
  3. package/content/.pending-commands.txt +2 -0
  4. package/content/CHANGELOG-archive.md +806 -0
  5. package/content/CHANGELOG.md +4330 -0
  6. package/content/PRINCIPLES.md +119 -0
  7. package/content/README-light.md +158 -0
  8. package/content/README.md +150 -0
  9. package/content/code-style/_any/file-size.md +62 -0
  10. package/content/code-style/_any/imports.md +68 -0
  11. package/content/code-style/_any/naming.md +72 -0
  12. package/content/code-style/_any/test-placement.md +57 -0
  13. package/content/code-style/nextjs-app-router/imports.md +50 -0
  14. package/content/code-style/nextjs-app-router/naming.md +50 -0
  15. package/content/code-style/prisma-postgres/error-boundary.md +55 -0
  16. package/content/code-style/prisma-postgres/imports.md +61 -0
  17. package/content/code-style/shadcn-ui/naming.md +48 -0
  18. package/content/code-style/stripe-billing/naming.md +76 -0
  19. package/content/code-style/trigger-dev-v4/imports.md +58 -0
  20. package/content/code-style/trigger-dev-v4/naming.md +49 -0
  21. package/content/code-style/trigger-dev-v4/test-placement.md +61 -0
  22. package/content/code-style/trpc-v11/error-boundary.md +51 -0
  23. package/content/code-style/trpc-v11/file-size.md +44 -0
  24. package/content/code-style/trpc-v11/naming.md +60 -0
  25. package/content/code-style/trpc-v11/test-placement.md +52 -0
  26. package/content/core/ach.md +260 -0
  27. package/content/core/afm.md +514 -0
  28. package/content/core/gotchas.md +18 -0
  29. package/content/core/prd.md +141 -0
  30. package/content/core/protocol.md +158 -0
  31. package/content/core/ust.md +65 -0
  32. package/content/guardrails/README.md +55 -0
  33. package/content/guardrails/dsl-com-ordem-obrigatoria.md +47 -0
  34. package/content/guardrails/exaustividade-de-union.md +48 -0
  35. package/content/guardrails/fronteira-de-import.md +57 -0
  36. package/content/hooks/README.md +70 -0
  37. package/content/interview/bootstrap.md +417 -0
  38. package/content/interview/promotion.md +115 -0
  39. package/content/interview/refactor.md +379 -0
  40. package/content/interview/triggers.md +107 -0
  41. package/content/modules/nextjs-app-router/ach.patch.md +44 -0
  42. package/content/modules/nextjs-app-router/gotchas.seed.md +78 -0
  43. package/content/modules/nextjs-app-router/rules.patch.md +35 -0
  44. package/content/modules/prisma-postgres/ach.patch.md +65 -0
  45. package/content/modules/prisma-postgres/rules.patch.md +28 -0
  46. package/content/modules/shadcn-ui/ach.patch.md +42 -0
  47. package/content/modules/stripe-billing/ach.patch.md +46 -0
  48. package/content/modules/stripe-billing/gotchas.seed.md +73 -0
  49. package/content/modules/stripe-billing/rules.patch.md +30 -0
  50. package/content/modules/trigger-dev-v4/ach.patch.md +64 -0
  51. package/content/modules/trigger-dev-v4/gotchas.seed.md +53 -0
  52. package/content/modules/trigger-dev-v4/rules.patch.md +35 -0
  53. package/content/modules/trpc-v11/ach.patch.md +56 -0
  54. package/content/modules/trpc-v11/rules.patch.md +34 -0
  55. package/content/modules/vireya-ui/ach.patch.md +85 -0
  56. package/content/modules/vireya-ui/gotchas.seed.md +98 -0
  57. package/content/modules/vireya-ui/rules.patch.md +36 -0
  58. package/content/ops/adr.md +54 -0
  59. package/content/ops/analyze.md +130 -0
  60. package/content/ops/clarify.md +86 -0
  61. package/content/ops/deliver.md +209 -0
  62. package/content/ops/diagnose.md +143 -0
  63. package/content/ops/evolve.md +366 -0
  64. package/content/ops/export-template.md +97 -0
  65. package/content/ops/generalize.md +117 -0
  66. package/content/ops/gotcha.md +46 -0
  67. package/content/ops/obligations.md +145 -0
  68. package/content/ops/plan.md +61 -0
  69. package/content/ops/policy.md +61 -0
  70. package/content/ops/promote.md +72 -0
  71. package/content/ops/protocol.md +51 -0
  72. package/content/ops/reconcile.md +44 -0
  73. package/content/ops/reflect.md +182 -0
  74. package/content/ops/remediate.md +143 -0
  75. package/content/ops/restructure.md +142 -0
  76. package/content/ops/rule.md +170 -0
  77. package/content/ops/specify.md +62 -0
  78. package/content/ops/tasks.md +67 -0
  79. package/content/ops/update.md +252 -0
  80. package/content/ops/verify.md +67 -0
  81. package/content/patterns/adapter.md +46 -0
  82. package/content/patterns/facade.md +47 -0
  83. package/content/patterns/factory.md +46 -0
  84. package/content/patterns/null-object.md +55 -0
  85. package/content/patterns/result-vs-exception.md +52 -0
  86. package/content/patterns/strategy.md +45 -0
  87. package/content/patterns/template-method-vs-composition.md +50 -0
  88. package/content/questions/adr.questions.yaml +14 -0
  89. package/content/questions/analyze.questions.yaml +12 -0
  90. package/content/questions/bootstrap-mapping.questions.yaml +14 -0
  91. package/content/questions/bootstrap-rules.questions.yaml +10 -0
  92. package/content/questions/bootstrap-stack.questions.yaml +23 -0
  93. package/content/questions/clarify.questions.yaml +10 -0
  94. package/content/questions/code-style.questions.yaml +12 -0
  95. package/content/questions/confirm.questions.yaml +12 -0
  96. package/content/questions/deliver.questions.yaml +23 -0
  97. package/content/questions/evolve.questions.yaml +15 -0
  98. package/content/questions/export-template-apply.questions.yaml +11 -0
  99. package/content/questions/export-template.questions.yaml +23 -0
  100. package/content/questions/gates.questions.yaml +27 -0
  101. package/content/questions/generalize.questions.yaml +13 -0
  102. package/content/questions/gotcha.questions.yaml +11 -0
  103. package/content/questions/init-template.questions.yaml +10 -0
  104. package/content/questions/init.questions.yaml +41 -0
  105. package/content/questions/obligations.questions.yaml +17 -0
  106. package/content/questions/plan.questions.yaml +14 -0
  107. package/content/questions/refactor.questions.yaml +23 -0
  108. package/content/questions/reflect.questions.yaml +13 -0
  109. package/content/questions/remediate.questions.yaml +27 -0
  110. package/content/questions/restructure.questions.yaml +15 -0
  111. package/content/questions/rf-mapping.questions.yaml +12 -0
  112. package/content/questions/rule-scope.questions.yaml +12 -0
  113. package/content/questions/rule.questions.yaml +12 -0
  114. package/content/questions/specify.questions.yaml +23 -0
  115. package/content/questions/update-artifacts.questions.yaml +10 -0
  116. package/content/questions/update-strings.questions.yaml +14 -0
  117. package/content/questions/update.questions.yaml +10 -0
  118. package/content/questions/verify.questions.yaml +9 -0
  119. package/content/roles/executor.md +18 -0
  120. package/content/roles/explorer.md +22 -0
  121. package/content/roles/reviewer.md +23 -0
  122. package/content/rubrics/enum-vs-union-vs-branded.md +40 -0
  123. package/content/rubrics/episodic-vs-semantic-boundary.md +37 -0
  124. package/content/rubrics/error-classification.md +98 -0
  125. package/content/rubrics/failure-classification.md +111 -0
  126. package/content/rubrics/negative-filters.md +38 -0
  127. package/content/rubrics/solid-triggers.md +119 -0
  128. package/content/rubrics/template-vs-streaming-precedence.md +34 -0
  129. package/content/rubrics/validation-boundary.md +94 -0
  130. package/content/rubrics/when-to-create-dsl.md +65 -0
  131. package/content/rubrics/when-to-create-lib.md +49 -0
  132. package/content/rubrics/when-to-create-module.md +39 -0
  133. package/content/rubrics/when-to-evolve-methodology.md +62 -0
  134. package/content/skills/adr.md +42 -0
  135. package/content/skills/analyze.md +28 -0
  136. package/content/skills/clarify.md +28 -0
  137. package/content/skills/deliver.md +26 -0
  138. package/content/skills/diagnose.md +42 -0
  139. package/content/skills/evolve.md +43 -0
  140. package/content/skills/export-template.md +37 -0
  141. package/content/skills/generalize.md +31 -0
  142. package/content/skills/gotcha.md +40 -0
  143. package/content/skills/init.md +77 -0
  144. package/content/skills/obligations.md +27 -0
  145. package/content/skills/plan.md +28 -0
  146. package/content/skills/policy.md +25 -0
  147. package/content/skills/promote.md +39 -0
  148. package/content/skills/protocol.md +41 -0
  149. package/content/skills/reconcile.md +45 -0
  150. package/content/skills/refactor.md +79 -0
  151. package/content/skills/reflect.md +43 -0
  152. package/content/skills/remediate.md +33 -0
  153. package/content/skills/restructure.md +46 -0
  154. package/content/skills/rule.md +43 -0
  155. package/content/skills/specify.md +28 -0
  156. package/content/skills/tasks.md +24 -0
  157. package/content/skills/update.md +58 -0
  158. package/content/skills/verify.md +29 -0
  159. package/content/templates/adr.template.md +51 -0
  160. package/content/templates/evolution-report.template.md +132 -0
  161. package/content/templates/feature-plan.template.md +84 -0
  162. package/content/templates/feature-research.template.md +56 -0
  163. package/content/templates/feature-spec.template.md +86 -0
  164. package/content/templates/feature-tasks.induced.template.md +91 -0
  165. package/content/templates/feature-tasks.template.md +82 -0
  166. package/content/templates/focus.template.md +30 -0
  167. package/content/templates/gotcha.template.md +31 -0
  168. package/content/templates/guardrail-runner.template.md +97 -0
  169. package/content/templates/guardrail.template.md +63 -0
  170. package/content/templates/learning.template.md +40 -0
  171. package/content/templates/procedure.template.md +47 -0
  172. package/content/templates/protocols/p1.md +29 -0
  173. package/content/templates/protocols/p2.md +28 -0
  174. package/content/templates/protocols/p3.md +47 -0
  175. package/content/templates/research.template.md +50 -0
  176. package/content/templates/session-handoff.template.md +58 -0
  177. package/content/templates/us.template.md +39 -0
  178. package/content/tools/gate/core-rules/PLUGIN-13-secrets.sh +36 -0
  179. package/content/tools/gate/core-rules/PLUGIN-21-code-language.sh +27 -0
  180. package/content/tools/gate/core-rules/PLUGIN-35-gate-complete.sh +19 -0
  181. package/content/tools/gate/core-rules/PLUGIN-36-absolute-path.sh +38 -0
  182. package/content/tools/gate/core-rules/PLUGIN-37-prose-language.sh +56 -0
  183. package/content/tools/gate/core-rules/PLUGIN-38-parser-marker.sh +82 -0
  184. package/content/tools/gate/core-rules/PLUGIN-39-frontmatter-ops.sh +325 -0
  185. package/content/tools/gate/core-rules/PLUGIN-40-dead-reference.sh +74 -0
  186. package/content/tools/gate/core-rules/README.md +55 -0
  187. package/content/tools/gate/guardrails.sh +740 -0
  188. package/content/tools/gate/lib/ratchet.sh +119 -0
  189. package/content/tools/gate/lib/scope.sh +85 -0
  190. package/content/tools/gate/ratchet.seed.tsv +1 -0
  191. package/content/tools/gate/rules/README.md +50 -0
  192. package/package.json +19 -5
  193. package/plugin/agy/hooks.json +29 -0
  194. package/plugin/agy/mcp_config.json +7 -0
  195. package/plugin/agy/plugin.json +6 -0
  196. package/plugin/agy/skills/afm-adr/SKILL.md +48 -0
  197. package/plugin/agy/skills/afm-analyze/SKILL.md +34 -0
  198. package/plugin/agy/skills/afm-clarify/SKILL.md +34 -0
  199. package/plugin/agy/skills/afm-deliver/SKILL.md +30 -0
  200. package/plugin/agy/skills/afm-diagnose/SKILL.md +46 -0
  201. package/plugin/agy/skills/afm-evolve/SKILL.md +49 -0
  202. package/plugin/agy/skills/afm-export-template/SKILL.md +43 -0
  203. package/plugin/agy/skills/afm-generalize/SKILL.md +37 -0
  204. package/plugin/agy/skills/afm-gotcha/SKILL.md +46 -0
  205. package/plugin/agy/skills/afm-init/SKILL.md +81 -0
  206. package/plugin/agy/skills/afm-obligations/SKILL.md +31 -0
  207. package/plugin/agy/skills/afm-plan/SKILL.md +34 -0
  208. package/plugin/agy/skills/afm-policy/SKILL.md +29 -0
  209. package/plugin/agy/skills/afm-promote/SKILL.md +43 -0
  210. package/plugin/agy/skills/afm-protocol/SKILL.md +45 -0
  211. package/plugin/agy/skills/afm-reconcile/SKILL.md +49 -0
  212. package/plugin/agy/skills/afm-refactor/SKILL.md +83 -0
  213. package/plugin/agy/skills/afm-reflect/SKILL.md +49 -0
  214. package/plugin/agy/skills/afm-remediate/SKILL.md +39 -0
  215. package/plugin/agy/skills/afm-restructure/SKILL.md +52 -0
  216. package/plugin/agy/skills/afm-rule/SKILL.md +49 -0
  217. package/plugin/agy/skills/afm-specify/SKILL.md +34 -0
  218. package/plugin/agy/skills/afm-tasks/SKILL.md +28 -0
  219. package/plugin/agy/skills/afm-update/SKILL.md +64 -0
  220. package/plugin/agy/skills/afm-verify/SKILL.md +35 -0
  221. package/plugin/claude-code/.claude-plugin/marketplace.json +15 -0
  222. package/plugin/claude-code/.claude-plugin/plugin.json +9 -0
  223. package/plugin/claude-code/.mcp.json +7 -0
  224. package/plugin/claude-code/agents/afm-executor.md +18 -0
  225. package/plugin/claude-code/agents/afm-explorer.md +20 -0
  226. package/plugin/claude-code/agents/afm-reviewer.md +21 -0
  227. package/plugin/claude-code/hooks/hooks.json +85 -0
  228. package/plugin/claude-code/skills/adr/SKILL.md +48 -0
  229. package/plugin/claude-code/skills/analyze/SKILL.md +34 -0
  230. package/plugin/claude-code/skills/clarify/SKILL.md +34 -0
  231. package/plugin/claude-code/skills/deliver/SKILL.md +30 -0
  232. package/plugin/claude-code/skills/diagnose/SKILL.md +46 -0
  233. package/plugin/claude-code/skills/evolve/SKILL.md +49 -0
  234. package/plugin/claude-code/skills/export-template/SKILL.md +43 -0
  235. package/plugin/claude-code/skills/generalize/SKILL.md +37 -0
  236. package/plugin/claude-code/skills/gotcha/SKILL.md +46 -0
  237. package/plugin/claude-code/skills/init/SKILL.md +81 -0
  238. package/plugin/claude-code/skills/obligations/SKILL.md +31 -0
  239. package/plugin/claude-code/skills/plan/SKILL.md +34 -0
  240. package/plugin/claude-code/skills/policy/SKILL.md +29 -0
  241. package/plugin/claude-code/skills/promote/SKILL.md +43 -0
  242. package/plugin/claude-code/skills/protocol/SKILL.md +45 -0
  243. package/plugin/claude-code/skills/reconcile/SKILL.md +49 -0
  244. package/plugin/claude-code/skills/refactor/SKILL.md +83 -0
  245. package/plugin/claude-code/skills/reflect/SKILL.md +49 -0
  246. package/plugin/claude-code/skills/remediate/SKILL.md +39 -0
  247. package/plugin/claude-code/skills/restructure/SKILL.md +52 -0
  248. package/plugin/claude-code/skills/rule/SKILL.md +49 -0
  249. package/plugin/claude-code/skills/specify/SKILL.md +34 -0
  250. package/plugin/claude-code/skills/tasks/SKILL.md +28 -0
  251. package/plugin/claude-code/skills/update/SKILL.md +64 -0
  252. package/plugin/claude-code/skills/verify/SKILL.md +35 -0
  253. package/plugin/opencode/afm/index.js +245 -0
  254. package/plugin/opencode/afm/tui.js +21 -0
  255. package/plugin/opencode/agents/afm-executor.md +39 -0
  256. package/plugin/opencode/agents/afm-explorer.md +92 -0
  257. package/plugin/opencode/agents/afm-reviewer.md +93 -0
  258. package/plugin/opencode/skills/afm-adr/SKILL.md +48 -0
  259. package/plugin/opencode/skills/afm-analyze/SKILL.md +34 -0
  260. package/plugin/opencode/skills/afm-clarify/SKILL.md +34 -0
  261. package/plugin/opencode/skills/afm-deliver/SKILL.md +30 -0
  262. package/plugin/opencode/skills/afm-diagnose/SKILL.md +46 -0
  263. package/plugin/opencode/skills/afm-evolve/SKILL.md +49 -0
  264. package/plugin/opencode/skills/afm-export-template/SKILL.md +43 -0
  265. package/plugin/opencode/skills/afm-generalize/SKILL.md +37 -0
  266. package/plugin/opencode/skills/afm-gotcha/SKILL.md +46 -0
  267. package/plugin/opencode/skills/afm-init/SKILL.md +81 -0
  268. package/plugin/opencode/skills/afm-obligations/SKILL.md +31 -0
  269. package/plugin/opencode/skills/afm-plan/SKILL.md +34 -0
  270. package/plugin/opencode/skills/afm-policy/SKILL.md +29 -0
  271. package/plugin/opencode/skills/afm-promote/SKILL.md +43 -0
  272. package/plugin/opencode/skills/afm-protocol/SKILL.md +45 -0
  273. package/plugin/opencode/skills/afm-reconcile/SKILL.md +49 -0
  274. package/plugin/opencode/skills/afm-refactor/SKILL.md +83 -0
  275. package/plugin/opencode/skills/afm-reflect/SKILL.md +49 -0
  276. package/plugin/opencode/skills/afm-remediate/SKILL.md +39 -0
  277. package/plugin/opencode/skills/afm-restructure/SKILL.md +52 -0
  278. package/plugin/opencode/skills/afm-rule/SKILL.md +49 -0
  279. package/plugin/opencode/skills/afm-specify/SKILL.md +34 -0
  280. package/plugin/opencode/skills/afm-tasks/SKILL.md +28 -0
  281. package/plugin/opencode/skills/afm-update/SKILL.md +64 -0
  282. package/plugin/opencode/skills/afm-verify/SKILL.md +35 -0
  283. package/README.md +0 -3
@@ -0,0 +1,209 @@
1
+ ---
2
+ type: op
3
+ description: Delivers one feature end to end, from discovery to the last task, with one approval gate.
4
+ load: warm
5
+ writes: ["docs/features/*"]
6
+ composes: ["specify", "plan", "tasks", "clarify", "analyze", "reconcile"]
7
+ ---
8
+ # Sub-flow: autonomous feature delivery (`deliver`)
9
+
10
+ > **Form** — effect: spec/plan/tasks + commits · trigger: `afm deliver`, delivery NL · precondition: `.afm-version` · composed of: — (orchestrator) · **degree of freedom: medium**
11
+
12
+ Triggers: `afm deliver [<feature-desc|slug>]`, or natural language for **delivery**: "build feature X", "implement X end to end", "deliver X", "the tasks already exist, run them", "continue the delivery of feature N".
13
+
14
+ > **`deliver` is a conductor, not an executor.** It owns three things the atomic ops do not have: (1) the discovery loop, (2) the single approval gate, (3) the execute-to-the-end driver. It **reads and follows** the other ops (`afm specify`, `afm plan`, `afm tasks`, `afm clarify`, `afm analyze`, `afm reconcile`) and suppresses only their per-artifact questions. See the **suppression contract** at the end. That table is the DRY guarantee: zero duplicated procedure.
15
+ >
16
+ > It materializes principle #2 (discover-first) and #6 (autonomy-first: approval at checkpoint granularity). See [`../PRINCIPLES.md`](../PRINCIPLES.md).
17
+
18
+ ## Conventions
19
+
20
+ - **The CLI owns the state.** Phase, next task, blockers, ids, task marks, the approval record and the gate are `afm` commands. The files on disk are the only delivery state: nothing is kept in memory across a halt.
21
+ - **Ask = question data.** The fixed decisions of this op are in `questions/deliver.questions.yaml`. Run `afm ask deliver --scope <NNN-slug>` (a harness renders it natively; a terminal prompts; with no terminal pass `--answers <file>`, and an open question exits 2). Record one answer with `afm answer deliver <id> <label> --scope <NNN-slug>`. The scope is the feature folder name (`NNN-slug`), so each feature asks afresh.
22
+ - **Dynamic question.** A question whose text comes from this feature (a product decision found in discovery) cannot live in a file. Put it to the operator through whatever question facility the host offers, in the same shape as a question-file entry: a header of at most 12 characters, 2 to 4 options, the recommended option first with its reason, and the evidence. With no such facility, ask in plain chat. Record the answer in `spec.md § 7`.
23
+ - **Roles.** Dispatch an `explorer` (read-only) for scans of the code. External research goes to nasca, never to a role. Delegation follows the protocol's delegation ceiling. If the host cannot spawn a role, run the work inline.
24
+ - **Capabilities.** Write files with `fs.write`, run commands with `shell.exec`, read pages with `web.read`, and keep the live checklist with `task.track`. `task.track` is a view for the operator, never the state: the state is `tasks.md`.
25
+ - **Reading another file of the content.** Use `afm path <content-relative path>`, for example `afm path ops/plan.md`.
26
+
27
+ ## Pre-check
28
+
29
+ 1. Run `afm preflight`. Exit 0 continues. Exit 3 means the project has no `docs/.afm-version`: stop and suggest `afm init` (greenfield) or `afm refactor` (brownfield). Exit 4 means the content does not resolve and exit 5 means the pin drifted: report the line it printed and stop. Do not fall back silently.
30
+ 2. **Capture `<feature-desc>`** from the trigger: what the operator said after "build feature".
31
+ 3. **Resolve the protocol.** Run `afm protocol`. It prints the posture (`plan auto|assisted`, `exec auto|assisted`) and the parameters (`MAX_DISCOVERY_ROUNDS`, `QUESTION_CAP`, `ROUND_CAP`, `HALT_PER_PHASE`, `RETRY_CAP`, `MAX_PARALLEL_SUBAGENTS`). With "defaults" printed, use the defaults of [`core/protocol.md`](../core/protocol.md) § 2.
32
+ - The field that governs the Phase 2 gate is **`plan`**: `auto` skips it, `assisted` keeps it.
33
+ - **Ephemeral override.** These exact words from the operator force `plan=auto` **for this delivery only**: `go`, `go ahead`, `just do it`, `no need to review`, `don't ask`, and their Portuguese equivalents (`vai`, `pode ir`, `sem perguntar`, `direto`, `não precisa revisar`). They are the operator's own words, not artifact text, so the list stays bilingual. The override does not change the project protocol: a gate override is not a contract change.
34
+ 4. **Pick the feature.** A new feature has no folder yet: its number is `afm next-id feature`. With features present, match the hint to a folder; use the branch name (`feat/NNN-*`) when the hint is empty. If it is still ambiguous, ask in plain chat with the candidate folders (a dynamic list is not a question-file entry), plus "new feature".
35
+
36
+ ## The loop
37
+
38
+ The artifacts on disk are the state. After each step run:
39
+
40
+ ```
41
+ afm feature status <NNN> --json # {phase, status, next_task, blockers}; status is the fm value of spec.md
42
+ ```
43
+
44
+ and jump to the phase it names. `<NNN>` is the folder number (or the full `NNN-slug`). A halt leaves `done: true` on the done tasks and `done: false` on the one that failed, so re-invoking `deliver` resumes exactly there. This also covers an operator who ran `afm specify` or `afm plan` by hand and then said "now deliver it".
45
+
46
+ | `phase` | Meaning | Go to |
47
+ | --- | --- | --- |
48
+ | `discovery` (no folder) | new feature | Phase 0 |
49
+ | `discovery` (with `blockers`) | an open `[NEEDS CLARIFICATION:]` in spec or plan | a micro-round of 0.E, then re-run status. Skip the scan |
50
+ | `spec` | folder with no `spec.md` | Phase 1.B |
51
+ | `plan` | `spec.md`, no `plan.md`, no open marker | Phase 1.C |
52
+ | `tasks` | `plan.md`, no `tasks.md`, no open marker | Phase 1.D |
53
+ | `execute` | the `tasks:` list of `tasks.md` has a task with `done: false`; `next_task` is the first one | Phase 2 (when no valid approval), else Phase 3 |
54
+ | `reconcile` | every task is done | Phase 4 |
55
+
56
+ When `blockers` is non-empty in `execute`, the next task depends on an unconfirmed assumption (see 2.C): halt there.
57
+
58
+ ---
59
+
60
+ ## Phase 0 — Discovery (convergent loop; cap `MAX_DISCOVERY_ROUNDS`, default 2)
61
+
62
+ A loop that converges, never a dump of questions. Discovery fires on a **gap** (principle #2), not as a mandatory sweep. A trivial or already-specified feature passes through almost untouched. It composes two precedents: [`interview/refactor.md`](../interview/refactor.md) Part A (code archaeology, scoped to the feature) and the nasca research flow (external unknowns, cited sources). It is the **only** place `deliver` asks anything before the gate, and it has a cap.
63
+
64
+ For each round `r` in 1..`MAX_DISCOVERY_ROUNDS`:
65
+
66
+ - **0.A0 — Retrieval before generate (compose, do not regenerate).** Before you scan from zero, prove there is no equivalent feature, ADR or gotcha to compose from. This is the `retrieval-before-create` discipline of [`evolve.md § Proposal discipline (shared)`](evolve.md) item 1, applied to the product side. Reuse the feature-name tokens of 0.A.
67
+ ```
68
+ grep -rliE "<kw1>|<kw2>" docs/features/*/spec.md 2>/dev/null
69
+ grep -rliE "<kw1>|<kw2>" docs/adr/ 2>/dev/null
70
+ grep -rniE "fires_when.*(<path-seg>)" docs/gotchas/ 2>/dev/null
71
+ ```
72
+ Hits feed the discovery model, and Phase 1 **cites or extends** ("composes from docs/features/NNN"). An empty result is a valid signal, not a block.
73
+ - **0.A — List the gaps, then scan only those** (read-only, no turn spent). Enumerate what is missing to deliver: current state, components, contracts, rules, library unknowns. No gap means skip to 0.B.
74
+ - Read `docs/{prd,ust,ach,afm,gotchas}.md` for the product context, the linked US (the oracle), the component types (`ach.md § 3.1`) and the rules and gotchas of the touched area. `afm index --for <path>` routes a code path to the docs that cover it.
75
+ - Search the code for the files, modules and entities the feature name implies: what exists against what is net-new. Note which component types are touched and the boundary surface. `afm detect --rubrics` lists the shapes the rubrics fire on.
76
+ - **0.B — Sort the unknowns into three buckets.**
77
+ - **resolved-by-scan**: the scan answered it. Do not ask.
78
+ - **researchable**: a technology or library unknown ("which PDF library", "does SDK X support Y"). It is not a question for the operator. It goes to 0.C.
79
+ - **irreducible**: a product or intent decision nothing on disk can answer (a persona nuance, a business rule, a scope cut, an acceptance threshold the PRD does not fix). Only this bucket becomes a question. If code, docs or search can answer it, the agent answers it.
80
+ - **0.C — Resolve the researchable ones.** Run the nasca research flow (`nasca-research` skill, or `nasca-campaign` for a deep multi-front study) and cite its stored sources. Take at most `MAX_PARALLEL_SUBAGENTS` topics per round (default 4; above the cap, keep the topics that move the decision most). If nasca is not installed, ask the operator instead of searching the web ad hoc. Decisions and their citations stay in memory and go into the spec or plan in the Phase 1 batch.
81
+ - **0.D — Convergence.**
82
+ - Irreducible bucket empty: discovery converged. Go to Phase 1.
83
+ - `r == MAX_DISCOVERY_ROUNDS`: force-exit. Each remaining irreducible item becomes a `[NEEDS CLARIFICATION:]` entry carried into the spec. Do not ask again.
84
+ - Otherwise go to 0.E.
85
+ - **The cap counts per feature lifetime, not per invocation.** The question budget spans discovery, verification and the holistic rounds of #8. A resumed `deliver` does not reset it: record "discovery round N/M on <date>" in `spec.md § 7 Clarifications` and read it back on resume. Without that, a feature that halts three times would ask six rounds.
86
+ - **0.E — ONE batched, recommendation-first round**, only when the irreducible bucket is non-empty and the cap allows it. Use the question form of `afm clarify`, but batch: up to `QUESTION_CAP` (default 4) dynamic questions in the same call. `ROUND_CAP` limits the rounds; with `ROUND_CAP = 0` (P1) nothing is asked and every irreducible item follows the protocol's `UNKNOWN_POLICY`.
87
+ - **0.F — Fold the answers back.** Return to 0.A of round `r+1` with a deeper scan. Example: the operator said "PDF server-side", so scan the existing storage and signing libraries, and maybe run the nasca research flow once more.
88
+
89
+ ---
90
+
91
+ ## Phase 1 — Draft spec, plan and tasks (delegate and suppress)
92
+
93
+ Discovery left an in-memory model: the linked US, the component inventory, the boundary surface, the resolved research (nasca citations) and the unknowns. Phase 1 turns it into **draft artifacts in one batch, with no per-artifact question**. The drafts are written to disk now, because the approval of Phase 2 is a hash of them (`afm approve`). Nothing is executed until the approval is recorded.
94
+
95
+ If 0.A0 found a similar feature, ADR or gotcha, the spec and plan **compose from it**: cite `docs/features/NNN`, reuse its decisions, inherit its task shape. That is a link, not a duplicate.
96
+
97
+ - **1.A — Trigger heuristic, from the scan, no question.** Reuse `afm specify` step 2 and `afm.md § 2.1`: does it hit `>1 day OR >200 lines OR >3 files OR new layer/component OR new external boundary OR >2 unknowns`? **No**: a trivial change. Say "this is small, going straight to the § 2 loop", skip the feature folder and run the `core/afm.md § 2` cycle once. **Yes**: continue.
98
+ - **1.B — `spec.md`.** Follow `afm specify` steps 3 to 9. Suppress its step 2 (computed in 1.A) and its per-artifact diff. Irreducible items from the force-exit become the spec's `[NEEDS CLARIFICATION:]` entries. Answers resolved in 0.E go into `§ 7 Clarifications` (the integration of `afm clarify`).
99
+ - **1.C — `plan.md`.** Follow `afm plan` steps 4 to 10, 12. Read `ach.md` for the stack and never reopen it. Fill § 2, § 4, § 5, § 6 and § 7 (binary validation against `afm.md § 3`). The steps that ask in standalone mode (the components, the decisions, the contracts) are **filled from the discovery model** here. Suppress its step 3 (Phase 0 already tried the markers) and its diff.
100
+ - **1.D — `tasks.md`.** Follow `afm tasks` steps 4 to 7: add every task with `afm task add`, never by hand. The `tasks:` list covers setup, a red task and the green task that closes it per scenario, the boundary, and one reconcile task, last, with `parallel` where it applies and a US or RF on every task. Suppress its step 2 for markers already resolved or deferred as cosmetic; a load-bearing marker adopted under "go" (see 2.C) stays on the task that depends on it. The reconcile task (it sets the `status:` keys to `done`) runs last, because it edits the hashed documents; `afm task done` refuses it while another task is open.
101
+ - **1.E — Verification (`afm analyze`, gating mode).** Run `afm feature lint <NNN>` (`--json` for machines): it does the mechanical passes A, C, D, E and the structure of `tasks.md`, and exits 1 on CRITICAL or HIGH. Add the judgment passes of `afm analyze` (constitution, duplication, severity) on top. **Sort** every finding into the three buckets of the verification corollary (#6 in [`../PRINCIPLES.md`](../PRINCIPLES.md)):
102
+ - **(a) resolvable by evidence**: the fix comes from the scan or the research. Correct the draft and note it in the digest.
103
+ - **(b) load-bearing and not resolvable**: it becomes an **earned question** (evidence, a recommendation, "what breaks if this is wrong") carried to the gate.
104
+ - **(c) cosmetic or deferrable**: `[TBD]` or `[NEEDS CLARIFICATION:]` in the artifact.
105
+ - **Loop** the passes until CRITICAL and HIGH are 0, at most 3 auto-fix rounds. Keep the list `finding -> fix applied`: a finding that reappears after a fix is an oscillation and goes straight to bucket (b). A stuck CRITICAL or HIGH after 3 rounds also goes to (b).
106
+ - 1.E is **mandatory**: #6 is *produce, self-verify, report*. An empty bucket (b) with no CRITICAL makes the gate skippable (2.A).
107
+
108
+ ---
109
+
110
+ ## Phase 2 — Single gate (the verification residue)
111
+
112
+ `deliver` collapses four sequential approvals (spec, plan, tasks, T001) into **one** gate. It carries exactly bucket (b) of 1.E: the load-bearing residue that self-critique did not close. Answering those earned questions IS the approval. The criterion does not depend on the host or its modes; the host only changes how the approval is shown.
113
+
114
+ The approval is a record, not a chat message: `afm approve <NNN>` stores the sha256 of `plan.md`, `spec.md` and `tasks.md` (`done: true` reads as `done: false`, so progress is not an edit). `afm approve --check <NNN>` exits 0 only while those hashes still match. **Any edit to a hashed document after approval invalidates it and sends the delivery back to this gate.**
115
+
116
+ - **2.A — Bucket (b) empty and no CRITICAL.** There is no residue to decide.
117
+ - `plan=auto`: skip the question. Print one line ("Plan: N tasks, M components, K boundaries. Verification is clean, you said go, proceeding.") and record the approval (2.D).
118
+ - `plan=assisted`: the gate is a light approval with no earned questions (2.C).
119
+ - **2.B — Build ONE consolidated proposal.** The approach in three sentences (plan § 1), the component table (§ 2), the boundaries (§ 5), a summary of the tasks (count per kind, total, parallel), the earned questions of bucket (b) each with evidence, a recommendation and "what breaks if this is wrong", and a verification digest ("self-corrected X (a). These N decisions need you (b). Y became `[TBD]` (c). Scanned and researched Z."). **Every quantitative number in the proposal carries its provenance: "(measured | estimated, how)".** An unlabelled estimate reads as a measurement. Evidence: a plan said "~37% fewer tokens" with no label, and the later measurement was -3.3%.
120
+ - **2.C — Present it.**
121
+ - **There are (b) questions**: ask them as dynamic questions, at most `QUESTION_CAP` per call and respecting the `ROUND_CAP` of #8. Answering resolves the residue **and** approves. Fold the answers into spec and plan.
122
+ - **Then the outcome**: `afm ask deliver --scope <NNN-slug>` puts the question `outcome`: `run-to-completion` (recommended), `pause-per-phase` (sets `HALT_PER_PHASE`), `materialize-only`, `adjust-or-cancel`. With no (b) questions it is the only question of the gate.
123
+ - **`plan=auto` with bucket (b) non-empty and no CRITICAL**: the operator said "go". Adopt your own recommendation for each (b) item as the default and log it as a `[NEEDS CLARIFICATION:]` assumption in the spec, so it is documented and not guessed in silence. Every (b) item changes the structural inventory, by the #6 test, so **the tasks that depend on it are born tagged with the marker** and `afm feature status` reports them in `blockers`. The Phase 3 driver halts on the first one and reports the assumption before building on it. Tasks that do not depend on it continue.
124
+ - **A (b) item that is CRITICAL** (it changes the inventory of the whole plan): ask even with "go". Autonomy is not recklessness (rule 11).
125
+ - `materialize-only` ends here with the drafts on disk. `adjust-or-cancel` means no approval: take the change the operator asks for, edit the drafts, re-run 1.E and return to 2.B, or stop.
126
+ - **2.D — Record the approval.** Run `afm approve <NNN>` after the last answer was folded in, so the hash covers the final text. Then go to Phase 3. Re-run `afm approve --check <NNN>` before each task in Phase 3.
127
+
128
+ ---
129
+
130
+ ## Phase 3 — Execute to the end
131
+
132
+ The tasks run in list order, as [`core/afm.md § 2`](../core/afm.md) sets the cycle: a red task, the green task that closes it, an optional refactor, then COMMIT. The loop lives there and is not restated here (rule 34). This driver changes two things: READ is already warm from discovery, and a green task that fails runs the capped reflect-retry of `core/afm.md § 5.1` **before** any halt, grounded in the test or type-checker output.
133
+
134
+ Drive it with the loop of this op. Repeat until `phase` is `reconcile`:
135
+
136
+ 1. `afm feature status <NNN> --json`. `phase` is `execute` and `next_task` is `T`. A non-empty `blockers` halts here (an adopted assumption): report it and stop, resumable.
137
+ 2. `afm approve --check <NNN>`. Non-zero means a hashed document changed: go back to Phase 2.
138
+ 3. Mirror `T` in `task.track` and run the cycle. Run `afm gate --staged` before the commit and fix what it reports; the commit-time hook runs the same gate. Commit with a reference to a US or RF.
139
+ 4. On success run `afm task done <NNN> T`, never an edit of the list. This is the source of truth for resumability. When `T` is the reconcile task, run Phase 4.A first: `afm task done` refuses it while another task is open.
140
+ 5. **A task that is not `parallel` fails**: run the capped reflect-retry, at most `RETRY_CAP` retries (default 2). The same failure twice is an oscillation: stop at once. If it still fails, **HALT**: report which task, what failed, the error, what the retries tried and a suggested fix. Leave the task `done: false`; re-invoking `deliver` resumes from it.
141
+ 6. **A `parallel` task fails**: once the retry is exhausted, continue the sibling parallel tasks, collect the failure and report it at the end of the phase.
142
+ 7. **Phase boundary** with `HALT_PER_PHASE` on: summarize the phase and ask the fixed question `phase-continue` (`afm ask deliver --scope <NNN-slug>`). Otherwise continue silently.
143
+
144
+ > **Scope: `tasks.md` is the ceiling, not the floor.** Autonomy (#6) is permission to execute without asking *inside* the approved scope, not to widen it.
145
+ > - A refactor task applies to the code the task touched, not to code that happened to be nearby. Do not invent an abstraction for a hypothetical requirement and do not add a `try/catch` for a scenario that cannot happen (rule 16 puts validation at the boundary).
146
+ > - Not narrowing matters too. "Done" with half the task finished is the mirror failure. If something is stuck, do the rest, say plainly what is left and why. A declared partial is a result; a silent partial is debt.
147
+ > - If you conclude the task is wrong, or a better path exists, say so in one sentence and continue with the task as approved. Resizing the work is the operator's decision. An architectural divergence already falls under rule 11: stop and ask.
148
+
149
+ **The push boundary.** `deliver` stops at the push boundary and never pushes on its own. `afm.md § 6.1` requires the suite, the type-check and the build before a push: print that reminder and stop.
150
+
151
+ ### Stop table (everything else is autonomous)
152
+
153
+ | Situation | What `deliver` does |
154
+ | --- | --- |
155
+ | Task (parallel or not) passes | `afm task done`, continue |
156
+ | A task that is not `parallel` fails | Capped reflect-retry; if it still fails, **HALT** with the report. The task stays `done: false`. Resumable |
157
+ | Same failure twice (oscillation) | **HALT** at once |
158
+ | A `parallel` task fails | Retry runs out, continue the siblings, report at the end of the phase |
159
+ | `afm approve --check` fails | Back to the Phase 2 gate: a hashed document changed |
160
+ | Phase boundary + `HALT_PER_PHASE` | Pause, summarize, ask `phase-continue` |
161
+ | Architectural surprise (rule 11: new layer, first-class component, cross-module contract, folder refactor) | **STOP and ask**. Applies even with `plan=auto` |
162
+ | `blockers` names an adopted assumption | **HALT** on the first dependent task and report it |
163
+ | Every task done | Phase 4 and a final summary |
164
+ | Ready to push | **Never push on your own.** Print the § 6.1 reminder and stop |
165
+
166
+ **Bright line.** Inside an approved plan `deliver` is autonomous. It stops for the operator at five boundaries: (1) the single gate, unless "go" was said, (2) a failure of a task that is not `parallel` that persists after the capped retry, (3) a rule-11 surprise, (4) the push, (5) a task that depends on an unconfirmed adopted assumption.
167
+
168
+ ---
169
+
170
+ ## Phase 4 — Reconcile
171
+
172
+ - **4.A** The reconcile task runs inside the Phase 3 loop, as the last task: `ach.md § 3` for a new component, an ADR (`afm adr new <slug>`) for an architectural decision, the US status set to done. It also sets the `status:` frontmatter of `spec.md`, `plan.md` and `tasks.md` to `done` (never a body Status line), which makes the approval stale by design: nothing runs after it.
173
+ - **4.B** Hand the closing turn to `afm reconcile` (always-on): a gotcha that bit twice, a rule the operator corrected, a learning that generalizes to the template. It **proposes**; `deliver` does not reimplement it.
174
+ - **4.C — Final output.** The feature path, tasks done over total, the files touched, the commits made, the `[NEEDS CLARIFICATION:]` and `[TBD]` entries that remain, and reconcile's proposals. Add the **§ 6.1 pre-push reminder**: "run the ritual before you push, I did not push on my own".
175
+ - **4.D — Post-delivery self-reflection (composes `afm reflect`).** This step does not decide the cadence. `REFLECT_EVERY` does (`core/protocol.md § 2`), enforced by the session-stop hook. What remains here is the context note: under `plan=auto` the operator reviewed less inline, so a reflection tends to yield more. When the cadence calls for it, run `afm reflect` after 4.C. It keeps its own gate and never self-applies (#6); with no friction observed in the session it reports that and stops. A session that ends before 4.D does not fire it later on its own: re-invoking `deliver` on a feature whose tasks are all done lands in Phase 4 and re-evaluates.
176
+
177
+ ---
178
+
179
+ ## Suppression contract (the DRY guarantee)
180
+
181
+ `deliver` never copies an op's body. **It reads the op and follows it**, with this documented set of suppressions for orchestrated mode.
182
+
183
+ > The only *universal* suppression is each op's per-artifact question and diff: it moves up to the single gate. If you only need to know "does this op ask or show a diff on its own here?", the answer is **no, that becomes the gate**. The few suppressions beyond that are listed per op below. Read the row. Do not re-subtract steps from the whole op.
184
+
185
+ | Op | Steps reused | Suppressed in orchestrated mode | Why it is safe |
186
+ | --- | --- | --- | --- |
187
+ | `afm specify` | 1, 3 to 6, 8, 9 | 2 (heuristic, computed in 1.A), 7 (diff) | the gate replaces the diff, the scan replaces the heuristic question |
188
+ | `afm plan` | 1, 2, 4, 5, 7 to 10, 12 | 3 (marker soft-block, Phase 0 resolved it), 6 (components, filled from the scan), 11 (diff) | discovery filled in what the plan used to ask |
189
+ | `afm tasks` | 1, 3 to 7, 9 | 2 (HARD block, only for a resolved or cosmetic marker; a CRITICAL becomes a gate question, a load-bearing HIGH under "go" blocks the dependent task in Phase 3), 8 (diff) | no load-bearing marker drives the implementation in silence |
190
+ | `afm clarify` | question form (step 4) and § 7 integration (step 5) | one question per turn, batched up to `QUESTION_CAP` (0.E) | #8 allows consolidating independent questions in one call |
191
+ | `afm analyze` | detection passes and the **gating mode** | the chat report (6) and the remediation offer (8) | gating mode sorts into three buckets, self-corrects (a), loops to zero CRITICAL and HIGH; bucket (b) becomes the earned questions of the gate |
192
+ | `afm reconcile` | everything (it proposes, it does not apply) | nothing | runs as designed in Phase 4 |
193
+ | `afm reflect` | everything, **gate kept** | **nothing**: its gate is not suppressed, that is the point | runs only at 4.D, self-gated by evidence |
194
+
195
+ > If a marker is so load-bearing that the tasks would come out incoherent, verification throws it into bucket (b), or CRITICAL. It becomes an earned gate question, and the gate **is not skippable** with an open CRITICAL (the 2.A condition applies even with "go"). The `tasks.md` HARD block turns into a gate question. It does not disappear.
196
+
197
+ ## Anti-patterns
198
+
199
+ - ❌ Asking what the scan or the research can answer (#2). Discovery first, ask only the irreducible part.
200
+ - ❌ Inventing a file or an entity during the scan (#5). 0.A is search and read on the real tree. What cannot be anchored becomes `[TBD]` or `[NEEDS CLARIFICATION:]`.
201
+ - ❌ Duplicating procedure from specify, plan, tasks and the rest. Read the op and follow it. Suppress only through the contract above.
202
+ - ❌ More than `MAX_DISCOVERY_ROUNDS` rounds, or more than `QUESTION_CAP` questions per round. The anti-interrogation cap is hard.
203
+ - ❌ Executing a task before `afm approve` recorded the approval, or past a failing `afm approve --check`.
204
+ - ❌ Editing `spec.md`, `plan.md` or `tasks.md` during Phase 3 to make a task pass, or closing a task by editing the `tasks:` list instead of `afm task done`. An edit invalidates the approval; if the plan is wrong, go back to the gate.
205
+ - ❌ Pushing on your own, or crossing the rule-11 boundary without asking. Both apply even with `plan=auto`.
206
+ - ❌ Continuing after the failure of a task that is not `parallel`. Halt, report, stay resumable. The capped retry **precedes** the halt; what is forbidden is going *past* the cap, or halting flat when the signal is cheap to re-run.
207
+ - ❌ Stealing the intent of a standalone step. "Just generate the tasks" or "just open the spec" belongs to the atomic op, not to `deliver`.
208
+ - ❌ Delivering without self-verification. 1.E is mandatory: *produce, self-verify, report*.
209
+ - ❌ Putting into the gate what verification could self-correct (a) or defer (c). The gate carries only bucket (b), each with an articulable "what breaks if this is wrong" (#8 earned).
@@ -0,0 +1,143 @@
1
+ ---
2
+ type: op
3
+ description: Scans the instance mechanically for weakness and reports what it measured, read only.
4
+ load: warm
5
+ writes: []
6
+ composes: []
7
+ ancestors: the *Weakness Mining* stage of Self-Harness (arXiv 2606.09498).
8
+ ---
9
+ # Sub-flow: mechanical weakness-mining of the methodology (`diagnose`)
10
+
11
+
12
+ > **Form** — effect: **read-only** (evidence bundle) · trigger: `afm diagnose`, composition · precondition: `.afm-version`, git · composed by: `evolve` 1.1 · **degree of freedom: low**
13
+
14
+ Triggers: `afm diagnose`. Also natural language for a **health scan**: "diagnose the methodology" or "scan the docs". Or: "what is broken in the docs?" or "list the instance health signals".
15
+
16
+ > **Target = this project's local docs (`<consumer>/docs/`), never the plugin.** "Health of the methodology" here means health of the **materialized instance** in this repo, not the canonical framework (the bundled content). `diagnose` is read-only. It does not touch anything, not the local docs and not the plugin. See [`evolve.md § The target of evolution`](./evolve.md).
17
+ >
18
+ > **Read-only mechanism, not a conductor.** `diagnose` is the mechanism-skill that runs the **mechanical scan** of the instance's health and returns an **evidence bundle** — no edit proposal, no gate, no mutation. The `evolve` orchestrator composes it (together with `reflect`) to feed the cycle. À la carte, it is a **health report**.
19
+ >
20
+ > WeaknessMining(traces, verifier):
21
+ > 1. ANALYZER := the role that only finds # "you are an ANALYZER, not a solver"
22
+ > — it proposes no edit and picks no fix
23
+ > 2. for each trace, run verifier # verifier := the mechanical checks (git/file-system/command)
24
+ > 3. Symptom := the verifier's output, anchored to file:line
25
+ > 4. PhiSignature := (Symptom, causal-status-of-behavior, mechanism) # the φ signature
26
+ > 5. EvidenceBundle := every PhiSignature, ordered by severity # severity := support
27
+ > 6. return EvidenceBundle # ANALYZER stops here; IMPROVER proposes the fix, elsewhere
28
+ >
29
+ > `diagnose` plays ANALYZER over `docs/` as the trace set. It materializes #2 (discover-first:
30
+ > diagnose with evidence before any proposal) and #3 (mechanize-or-demote: the checks themselves
31
+ > must pass the test they audit). See [`../PRINCIPLES.md`](../PRINCIPLES.md).
32
+
33
+ ---
34
+
35
+ ## What `diagnose` is / is not
36
+
37
+ **Is:** the scan of the **7 axes** of health of the materialized instance (`<consumer>/docs/`). It uses evidence **external to the text** (command + `file:line`), partitioned by severity, and is **read-only**. Role ANALYZER: it produces findings. **Zero edit proposals**.
38
+
39
+ **Is not:**
40
+ - `analyze` (it audits **one feature** — coverage and consistency across spec, plan, and tasks). `diagnose` audits the **whole instance** of `/docs/`.
41
+ - `reflect` (its evidence is **behavioral** — the agent stumbled on a doc). `diagnose` is **static** (file system, git, command). These are the two sides of the Self-Harness φ: `c` (mechanical cause, here) vs `q/m` (behavioral mechanism, in `reflect`).
42
+ - A proposer or editor. `diagnose` does not touch anything. The proposal (role IMPROVER) and the gate belong to `evolve` (or to `reflect`, on the behavioral axis).
43
+ - "The agent feels the doc looks bloated": every finding is mechanized as a 0/1 command. An impression without `command + file:line` is forbidden (#5).
44
+
45
+ > **No cooldown** (unlike `evolve`): `diagnose` is read-only and cheap. Running it again has no mutation cost. The cooldown that refuses a **cycle** without a new signal belongs to the orchestrator (the cycle is costly: gate plus record).
46
+
47
+ ---
48
+
49
+ ## Pre-check
50
+
51
+ 1. **Does `<consumer>/docs/.afm-version` exist?** If not, stop. Suggest `afm init` (greenfield) or `afm refactor` (brownfield).
52
+ 2. **Does `afm preflight` exit 0?** A non-zero exit says why: the docs are not bootstrapped, the bundled content does not resolve, or the pin does not match. Report it to the user. Do not use a silent fallback.
53
+ 3. **Capture the stated symptom** (what the user said after invoking it — "the rules do not fire", "confusion between docs"). This becomes the scan's **directed focus**. If absent, run a uniform scan of all 7 axes.
54
+ 4. **Thresholds are the instance's, and `afm doctor` reads them.** The override is one comment line at the end of `docs/.afm-version`: `<!-- evolve: marker-age-days=120 inflation-lines=500 cooldown-days=14 -->`. With no line, the defaults apply (marker age 90 days, inflation 400 lines). The agent never guesses a threshold: it reads the number `afm doctor` reports.
55
+
56
+ ---
57
+
58
+ ## Phase 0 — Scan (≈ Weakness Mining / Execute)
59
+
60
+ Gap-driven, **not a blind sweep**: it runs `afm doctor --json` (the Class A checks, below) plus reads directed by the pre-check's symptom. If the user said "rules do not fire", it goes deeper into § 3. If the user said "confusion", it cross-checks the core docs against each other (the gap that per-feature `analyze` does not cover).
61
+
62
+ **Golden rule of the scan:** every piece of evidence is **command + output + `file:line`**. `afm doctor` prints each finding that way (`evidence: <command> @ <file>:<line>`), and it exits 0 healthy, 1 with findings, 2 outside an AFM project. *A finding without evidence external to the text is forbidden.* "This doc looks bloated" is not a finding. `wc -l`, `git log`, or a grep for a duplicate block is a finding. (This blocks the self-reference loop: the agent auditing the text based on the text itself.)
63
+
64
+ ### Class A checks (mechanizable — 0/1 command)
65
+
66
+ Run **`afm doctor --json`** once. It is read only. It scans A1 through A6, A5b, staleness and dead gotchas in one pass and returns the evidence bundle as data: `status`, `findings[]` (`axis`, `severity`, `symptom`, `evidence[]` as `command` + `file` + `line`, an optional `rival`) and `notCovered[]`. The session-start digest shows the same signs in two or three lines when something is wrong. Here they run live, with no time budget, and the agent reads each finding to the bottom. **A7 is in-cycle-only** (semantic, paired reading — `afm doctor` does NOT run it). Without `--json`, `afm doctor` prints the same bundle as text.
67
+
68
+ | # | Signal | What `afm doctor` decides (the CLI runs it; read the finding, do not redo the scan) |
69
+ | --- | --- | --- |
70
+ | A1 | **Dead reference** | extracts the paths cited in the normative docs (`afm.md`, `ach.md`, `prd.md`, `ust.md`, `_focus.md`, the ADR index, `rules/`, `gotchas/`, `learnings/`, `guardrails/`, `procedures/`; the same scope as PLUGIN-40, so an ADR body, an immutable record, is out), then checks each one exists (from the repo root, the citing file's directory, or by suffix of a tracked file). Missing = signal. A line that announces a removal is history, not a reference |
71
+ | A2 | **Aged marker** | `git log -S` finds the introduction date of each open `[TBD]`/`[NEEDS CLARIFICATION:]` (a marker inside a code span is the doc talking about the notation, not an open one). Age > threshold (default 90 days) = signal. It measures **age**. It never rewards a zero count |
72
+ | A3 | **Version drift** | the pin in `docs/.afm-version` is behind the shipped version (compared as semver, a prerelease sorts below its release). It never fires when either side is not a version |
73
+ | A4 | **Broken ADR chain** | every `Superseded by ADR-NNNN` (bare, or in the markdown-link form) is checked: does the referenced NNNN exist in `adr/`? Numbers compare as numbers |
74
+ | A5 | **Unparseable trigger (static)** | for each `*Verification:*` command in `afm.md` § 3: does the path or glob it targets exist? Does the command parse and return 0/1? **Static check** — it does NOT execute § 3 (that does not fit a health check and gives an ambiguous exit 0). The real-execution dry run belongs to `evolve` Phase 2 (or `afm gate --audit`). **Severity:** a command that returns **something other than 0/1** (error exit, or a target path that does not exist) = **CRITICAL** (a stillborn guard-rail means zero enforcement), **regardless of an observable violation** — distinct from a trigger that regressed but still runs (HIGH). **Sub-case (HIGH, read by the agent — the CLI cannot see it):** the command rewrites in prose what a versioned repo script already does (a `test/` script, `npm run <x>`, a project hook). Two sources of truth for the same check drift out of sync on their own, and the one the human reads is not the one that runs. Finding: "point the `*Verification:*` field at the script." **Sub-case (CRITICAL, mechanical):** the command ends in `\| head`, `\| wc -l`, or a pipe whose last stage always exits 0. It is **vacuously green**. It passes whether installed or not, and it measures presence instead of activation |
75
+ | A5b | **Missing inalienable rule** | for each rule marked `INALIENABLE` in the shipped `core/afm.md § 3`: does it stand in the instance's `docs/afm.md`, with its marker and no N/A? (An instance from before the `PLUGIN-` namespace that wrote the rule as a plain number is accepted.) **Severity:** missing = **CRITICAL**. This is the only axis that compares the instance against the plugin outside A3, and that is deliberate — A3 measures *version*, this one measures *floor integrity*. Detection, not prevention: the file belongs to the operator |
76
+ | A6 | **Inflation** | the line count of **any `.md` in `docs/`** (not only the 4 core files `afm/ach/prd/ust` — this also catches orphan appendices like `ach-notes.md`) **> 400 lines** (default threshold, override in the instance) **AND/OR** a paragraph repeated verbatim **AND/OR** an orphan doc (no doc references it; `afm index --orphans` lists them too). A high `wc` alone, with none of these extra signals, is **not** a finding (this avoids rewarding or punishing raw size — mechanize-or-demote, #3) |
77
+
78
+ **A7 — Cross-doc normative contradiction.** This axis runs in-cycle, with paired reading. It runs ALWAYS, not only when the user says "confusion". This is the "mental confusion" axis. The method has 2 steps.
79
+
80
+ (1) **Surface candidates mechanically.** Grep for opposing normative assertions in `ach.md § 6` (code conventions), `afm.md § 1.3` (principles), and `afm.md § 3` (rules). Use antonym verbs and terms: `only at the boundary` vs `in the domain`, `always` vs `never`, `before` vs `after`.
81
+
82
+ (2) **Read the matched passages in pairs.** Confirm the real conflict, with `file:line` for both sides.
83
+
84
+ This is the **only legitimate case where paired reading replaces a pure 0/1 check**. It is distinct from "looks bloated" (forbidden). A7 requires citing **both literal conflicting assertions**, not an impression. No literal conflicting pair means no A7 finding.
85
+ >
86
+ > **Before you mark a contradiction — layer test (anti-false-positive):** check whether the two passages operate at **different layers or scopes** (example: "validation at the boundary" can mean input validation at the edge, while "invariant checked in the domain" can mean a business rule — both correct). Mechanical heuristic: **same decision** = both passages use the same normative term in absolute form, with no layer qualifier. **Different layers** = each passage carries a different scope qualifier (input vs. invariant, request vs. persistence). When the layers differ, log the A7 finding as **"layer ambiguity"** (the fix will be to disambiguate, not to pick a side — but that decision belongs to the proposal Phase of `evolve`/`reflect`, not to `diagnose`). Only when both passages provably govern the *same* decision is there a real contradiction.
87
+
88
+ > **Watch for the right field and section (disambiguating `## 3.`):** the **hook-parsed § 3 is EXCLUSIVELY the one in `afm.md`** (the `*Verification:*` field, read by the pre-edit hook and by `afm doctor` from the `## 3.` section of `afm.md`), plus the `trigger_path` frontmatter key in **gotchas**. `## 3.` headers in **other** docs (example: `ach.md ## 3. Mapa componente→onde`) are **prose, NOT hook surface** — a dead reference in them has a different nature (see `hooks/README.md`). `diagnose` only **classifies** the surface. The treatment (auto-applicable vs. gate) is a decision for the `evolve` proposal.
89
+
90
+ > **Where the thresholds live (deterministic override).** The defaults (`A2` marker 90 days, `A6` inflation 400 lines) belong to the op. Override them with one parseable comment line at the end of `docs/.afm-version`: `<!-- evolve: marker-age-days=120 inflation-lines=500 cooldown-days=14 -->` (`afm doctor` reads it; if absent, it uses the defaults).
91
+
92
+ ### Axis coverage is mandatory (anti-miss)
93
+
94
+ An **empty** diagnosis is a valid result (a healthy instance). A **silent partial** diagnosis is not valid. The 7 axes are A1 reference, A2 marker, A3 drift, A4 ADR, A5 trigger, A6 inflation, and **A7 contradiction**. The scan checks all 7 axes, every time: `afm doctor` covers six, and the agent covers A7.
95
+
96
+ An axis that could not be scanned (example: no git, no `adr/`) gets a report entry. `afm doctor` lists it in `notCovered` as **"not covered: <reason>"**, and A7 is yours to report the same way when you skip it. Never omit it. Omitting an axis hides a problem the scan exists to find.
97
+
98
+ ---
99
+
100
+ ## Phase 1 — Diagnosis (≈ Reflect ρ) — role ANALYZER, **forbidden to propose edits**
101
+
102
+ This is a literal role separation (Autogenesis: "You are an ANALYZER, not a solver"). This phase **only** produces findings with evidence. Zero edit proposals — that belongs to `evolve`/`reflect`.
103
+
104
+ 1. **φ signature per finding** = `(symptom, causal-status-of-behavior, mechanism)`:
105
+ - *symptom* — what the command flagged (with `file:line`). For a mechanical axis this is the `symptom` and `evidence` of the `afm doctor` finding, copied, never paraphrased into something the command did not say.
106
+ - *causal-status-of-behavior* — was the methodology's behavior causally implicated? (True to the paper: the middle slot is the **causal status of the behavior**, not "the cause".)
107
+ - *mechanism* — why the methodology produced this. Options: a badly written trigger, an obsolete rule, an orphan doc, or **the agent out of compliance**.
108
+
109
+ **Mandatory competing mechanisms (do not assume the rule itself is the defect).** A finding of `afm doctor` may carry a `rival`; keep it, and add the ones below that apply:
110
+ - For the signal **"rule violated despite being injected"**, always list a rival hypothesis. Say **"the agent is out of compliance"**, not just "the rule is wrong". Otherwise the cycle turns into a self-serving loop. It demotes anything that constrains the agent.
111
+ - For the signal **"rotten / stillborn trigger" (A5)**, list a rival too. Besides "badly written rule", consider **"the target subsystem was legitimately removed"**. If the code was deliberately removed, the right action is different. **Archive the rule with a tombstone** instead (a downstream step). Distinguishing the two needs git evidence of what happened to the target.
112
+
113
+ 2. **Addressability filter** (Self-Harness: exclude beats forcing a patch). A finding needs a plausible editable surface on the whitelist. Example: "this library is hard to use" is an external limit. Such a finding becomes an **observation in the report**, never a proposal candidate. This stops the cycle from "patching every friction point".
114
+
115
+ **Case A2 (aged marker):** an `[TBD]` marker past the threshold is addressable as a **binary posture question** (`is this still deliberate deferral` / `is it time to decide?`). But the marker's **content**, and the user's silence, stay an **observation** (the cycle never invents the answer — #4/#5). `diagnose` only tags the finding as "addressable: posture question". The question itself belongs to the `evolve` gate.
116
+
117
+ 3. **Severity** — self-contained inline matrix:
118
+ - **CRITICAL** — violates a `PRINCIPLES.md` invariant. OR it breaks or stillbirths an enforcement guard-rail. Examples: a `*Verification:*` trigger that does not return 0/1, or a hook that stops injecting.
119
+ - **HIGH** — the functional health of a doc or rule. Examples: version drift, a broken ADR chain, or a dead reference on a surface that matters. Also a trigger that regressed but still runs.
120
+ - **MEDIUM** — guidance/§1.3, terminology drift, addressable inflation.
121
+ - **LOW** — cosmetic, a posture marker, a minor near-duplicate.
122
+
123
+ **Severity is not fix friction.** Severity = the impact of the **symptom** (how bad the problem is). The bucket classification (auto-applicable / gate / defer) is **downstream**, in the `evolve` proposal. It is **orthogonal** to severity (a finding can be HIGH and auto-applicable at the same time). `diagnose` delivers only the severity. It does not pre-decide the bucket.
124
+
125
+ ---
126
+
127
+ ## Output — evidence bundle (read-only)
128
+
129
+ `diagnose` returns an **evidence bundle**, ordered by severity (CRITICAL to LOW). Each finding carries: axis (A1-A7), φ signature, evidence (`command` + `file:line`), severity, and addressability (yes / observation). It also lists the rival mechanisms when they apply. Axes not covered are listed as "not covered: <reason>".
130
+
131
+ - **À la carte:** it prints the bundle in the chat as a **health report** (the `afm doctor` findings plus A7). Nothing is written to disk, and there is no gate. (Useful on its own: "how is the methodology's health here?")
132
+ - **Under `evolve`:** the bundle feeds the orchestrator's proposal Phase (role IMPROVER). That Phase sorts it into buckets and takes it to the gate. `diagnose` does not write `docs/evolution/` — that belongs to the cycle.
133
+
134
+ ---
135
+
136
+ ## Anti-patterns
137
+
138
+ - ❌ **A finding with no evidence external to the text** — "looks bloated" is not a finding. Command + `file:line` is (#5).
139
+ - ❌ **An empty diagnosis treated as a failure** — for a healthy instance, report "100%" and stop. Never fabricate a problem to justify the invocation.
140
+ - ❌ **A silent partial diagnosis** — staying silent on an axis (A1-A7) without saying it was not checked. A7 (contradiction) always runs, not only when the user says "confusion".
141
+ - ❌ **Proposing an edit, demoting a rule, or archiving a doc** — `diagnose` is read-only. That is role IMPROVER, in `evolve`/`reflect`.
142
+ - ❌ **Assuming a violated rule means a wrong rule.** The agent may be out of compliance instead. Always list that as a rival mechanism in the φ.
143
+ - ❌ **Pre-deciding the bucket** — severity is not fix friction. The bucket is decided downstream, in the proposal.