@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,33 @@
1
+ ---
2
+ name: remediate
3
+ description: |
4
+ Reads the open failures of the state store (`afm failures promotable`) and proposes the durable artifact: a procedure when the fix is mechanical, a learning when it is conceptual. A failure enters by external signal, never by self-judgment.
5
+ Activates: `afm remediate`, "this failed again, fix it for real", "create a runbook for this", "record this lesson for the next agent sessions".
6
+ ---
7
+
8
+
9
+ # AFM — Remediate (CRITIC loop)
10
+
11
+ ## When NOT to activate
12
+
13
+ This is a disambiguation for a skill that already activated. It is not an activation trigger. That is why it lives in the body and not in the resident listing.
14
+
15
+ Use `afm.md § 5.1` for an in-task retry at the moment of the error. Use `afm gotcha` for an SDK surprise with no failure of its own. Do not invent a failure. Only act on a recorded failure that `afm failures promotable` lists, or on an explicit user correction.
16
+
17
+ ## Pre-check
18
+
19
+ 1. **Does `<consumer>/docs/.afm-version` exist?** If not, stop. Suggest `afm init` for a greenfield project or `afm refactor` for a brownfield project.
20
+ 2. **Is there an open failure?** Run `afm failures promotable`. With `no failure is promotable` and no explicit user correction, report "nothing to remediate" and stop. An empty diagnosis is a valid result.
21
+ 3. **Does `afm preflight` exit 0?** A non-zero exit says why (docs not bootstrapped, content unresolved, pin mismatch). Report it to the user. Do not fall back silently.
22
+
23
+ ## Procedure
24
+
25
+ The op includes the promotion gate (#5): 1 user correction OR at least 2 mechanical occurrences promote a failure. A transient failure does not promote. It also includes classification through the rubric `rubrics/failure-classification.md` (`afm path rubrics/failure-classification.md`). For each delta, propose the artifact (procedure or learning) and cite the source `sig=` (hard rule 19). Ask the artifact question with `afm ask remediate --scope <sig>`, materialize the result, close the signature with `afm failures close --sig <sig> --as remediated`, and report it (#6).
26
+
27
+ ## Invariant principles
28
+
29
+ Most relevant here: #3 (CRITIC corollary — recognition by tool, not self-judgment). See also #5 (do not promote a failure without recurrence or an oracle) and #6 (propose only, the human approves).
30
+
31
+ ## Continuous doctrine
32
+
33
+ Passive mode (`afm reconcile`) is always on. It reads `afm failures promotable` at the end of the turn and can propose remediation with no explicit command. The `afm evolve` cycle uses the failure events as evidence for `afm reflect`, toward a final remediation. This skill is the active record of the loop.
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: restructure
3
+ description: |
4
+ Checks the context architecture of the local docs. It looks at staleness against the code, findability across layers, and the hot versus on-demand partition. It relocates content that already exists and writes no new content.
5
+ Activates: `afm restructure`, "the doc is stale versus the code", "this should load only on demand", "the guidance exists but I cannot find it in the doc".
6
+ ---
7
+
8
+
9
+ # AFM — Restructure (context architecture health)
10
+
11
+ > **Carve-out (does not overlap existing ops):** `afm diagnose` A1 finds a **dead reference** (the path does not exist). `restructure` staleness finds a path that **exists but changed** while the doc did not. `afm reconcile` adds **missing** information. `restructure` relocates information that **exists but sits in the wrong place**. `afm reflect` targets **clarity**. `restructure` targets **location and freshness**. `afm evolve` is the **orchestrator** that composes this skill when `afm diagnose` flags staleness or bloat.
12
+ >
13
+ > **Maturity (honest YAGNI):** the actionable core today is **staleness** (from git) plus **findability**. **Temperature tiering** (always-hot vs on-demand) is an **opt-in** ADR proposal, only for a doc that has actually outgrown its size. Small docs do not need it.
14
+
15
+ ## When NOT to activate
16
+
17
+ This is a disambiguation guide for a skill that has already activated. It does not gate activation, so it stays in the body, not in the resident listing.
18
+
19
+ A path that does not exist belongs to `afm diagnose` (A1). Staleness means the path exists but changed. Information never documented belongs to passive mode (`afm reconcile`) → `afm gotcha` or `afm rule`. An ambiguous doc belongs to `afm reflect`. Merging gotchas belongs to `afm generalize`. The full cycle belongs to `afm evolve`.
20
+
21
+ ## Pre-check
22
+
23
+ 1. **Does `<consumer>/docs/.afm-version` exist?** If not, stop. Suggest `afm init` (greenfield) or `afm refactor` (brownfield) first.
24
+ 2. **Does `afm preflight` exit 0?** A non-zero exit says why (docs not bootstrapped, content unresolved, pin mismatch). Report it to the user. Do not fall back silently.
25
+ 3. **Is git available?** The staleness scan needs the git history. Without git, `afm doctor` marks this axis "not covered: no git". Never omit it.
26
+
27
+ ## Procedure
28
+
29
+ Use these five steps.
30
+
31
+ 1. **Staleness scan.** `afm doctor --json` runs it (findings with axis `staleness` and `dead-gotcha`); read them. The git trigger fires in two cases. First case: a path cited in the doc has a later last commit than the doc. Second case: the doc has been stale for more than N commits. A hit is a candidate, not a verdict. The scan never rewrites the doc on its own.
32
+ 2. **Findability.** Relocate or cross-reference information that exists but sits buried or in the wrong doc. Cite both locations. Route information that is genuinely missing to passive mode (`afm reconcile`).
33
+ 3. **Temperature partition.** Propose a hot/on-demand loading strategy as an opt-in ADR. Do this only when a doc has outgrown its size. Preserve 100% of the content.
34
+ 4. **Its own gate.** This gate is load-bearing and earned, one `afm ask restructure --scope <item-slug>` per finding. It follows the **shared-proposal discipline** in `evolve.md` (`afm path ops/evolve.md`), instead of a duplicate copy of that discipline. `afm evolve` suppresses this gate when it runs.
35
+ 5. **Record.** Write the result to `docs/evolution/NNN-<date>.md`. Suggest `afm promote` if the finding generalizes.
36
+
37
+ ## Invariant principles
38
+
39
+ Most relevant here:
40
+
41
+ - #2: get git evidence before you propose a change.
42
+ - #3: staleness needs an executable git trigger.
43
+ - #4/#5: missing product content becomes `[TBD]` or goes to passive mode (`afm reconcile`). Never invent it.
44
+ - #6/#8: self-check the work, then pass an earned gate.
45
+
46
+ **No new principle here.** `restructure` is a composed materialization. The doctrine lives in the op file.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: rule
3
+ description: |
4
+ Adds a hard rule to `<consumer>/docs/afm.md § 3`. A mechanical trigger is mandatory and must return 0 or 1, such as `grep`, `wc -l`, `git diff` or `tsc`. A code review or a PR template is not a trigger. Without a trigger the entry becomes a principle in § 1.3.
5
+ Activates: `afm rule`, "new hard rule", "this should be a rule".
6
+ ---
7
+
8
+ # AFM — Rule
9
+
10
+ The CLI owns the number, the rule file, the index line and the runner skeleton, and refuses a rule with no
11
+ honest trigger form. This skill keeps only the judgment.
12
+
13
+ ## When NOT to activate
14
+
15
+ This is a disambiguation for a skill that already activated. Use `afm adr` for a one-off architectural
16
+ decision. Use `afm gotcha` for a counterintuitive surprise. Use `afm generalize` to merge rules or gotchas
17
+ that already exist.
18
+
19
+ ## Pre-check
20
+
21
+ `afm preflight`. Exit 3 means there is no instance: stop and suggest `afm init` or `afm refactor` first.
22
+
23
+ ## Procedure (judgment only)
24
+
25
+ 1. Confirm the mechanical trigger as free text, and push back hard: no trigger means a principle in § 1.3.
26
+ Run the anti-Goodhart test: can a diff pass the trigger while it breaks the rule's intent? If yes, rewrite
27
+ or downgrade it.
28
+ 2. Measure the repo for any constant and propose the value with the measurement. An unanswered constant is
29
+ `[TBD]`. Check for an existing versioned script and cite it.
30
+ 3. Choose the surface: `afm ask rule`. Run `afm rule new <slug> --trigger '<command>' --surface <surface>` and
31
+ report the paths (#6). For `pre-commit` or `ci`, follow "Install the gate" in the op: `afm gate --baseline`
32
+ before the gate goes on.
33
+ 4. In a refactored project only, ask where the rule enters: `afm ask rule-scope` (universal § 3 or
34
+ forward-only § 3.1). The scope decision reflects intent, so it stays fixed once made.
35
+
36
+ ## Invariant principles
37
+
38
+ Most relevant here: #3 (a hard rule needs
39
+ a mechanical trigger, or it is a principle instead) and #6 (autonomy-first: materialize the change and
40
+ report it).
41
+
42
+ Passive mode (`afm reconcile`) is always on and can propose `afm rule` when it detects the signal "the user
43
+ corrected an approach with a reusable rule".
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: specify
3
+ description: |
4
+ Opens a feature folder at `docs/features/NNN-slug/spec.md`, linked to a user story. A mechanical heuristic decides first, because a feature folder for a trivial change is overhead.
5
+ Activates: `afm specify <slug>`, "open a feature", "start a new feature", "create a feature folder".
6
+ ---
7
+
8
+ # AFM — Specify
9
+
10
+ ## When NOT to activate
11
+
12
+ A trivial change (no feature folder needed) goes straight to the `afm.md § 2` loop. A full end-to-end delivery is `afm deliver`, which composes this op.
13
+
14
+ ## Pre-check
15
+
16
+ Run `afm preflight`. Exit 3 means no `docs/.afm-version`: stop and suggest `afm init` or `afm refactor`. Exit 4 or 5: report the line it printed.
17
+
18
+ ## Procedure
19
+
20
+ The number comes from `afm next-id feature`, never by hand. What is left to you is judgment: compute the trigger heuristic from the scan (ask the `heuristic` question only when borderline), find the linked US in `docs/ust.md` before asking (`afm ask specify`), create the spec with `afm new feature-spec <slug>` (the generator writes the frontmatter the template names) and fill its body, update the `Spec:` line of the US, and report the open `[NEEDS CLARIFICATION:]` items. Autonomy-first: write and report, review through `git diff`.
21
+
22
+ ## Invariant principles
23
+
24
+ Most relevant here: #2 (discover-first: compute the heuristic and the US from the scan), #5 (never invent a success criterion) and #6 (autonomy-first).
25
+
26
+ ## Continuous doctrine
27
+
28
+ Passive mode (`afm reconcile`) is always on. This skill covers only the opening of the feature.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: tasks
3
+ description: |
4
+ Generates the `tasks:` list of `tasks.md` in TDD order with `afm task add`. Every task references a user story or a requirement. It hard-blocks on an open `[NEEDS CLARIFICATION:]` in the plan.
5
+ Activates: `afm tasks [<feature>]`, "generate the tasks", "break the feature into tasks".
6
+ ---
7
+
8
+ # AFM — Tasks
9
+
10
+ ## When NOT to activate
11
+
12
+ There is no `plan.md` yet: run `afm plan` first. An end-to-end delivery is `afm deliver`, which composes this op.
13
+
14
+ ## Pre-check
15
+
16
+ Run `afm preflight` (exit 3: stop and suggest `afm init` or `afm refactor`). Run `afm feature status <NNN> --json`: a non-empty `blockers` is an open `[NEEDS CLARIFICATION:]` in the plan. That is a hard refusal with no override, not a question.
17
+
18
+ ## Principles
19
+
20
+ Most relevant here: #5 (every task traces to a US or RF) and rule 1 (TDD: no green task without the red task it closes).
21
+
22
+ ## Continuous doctrine
23
+
24
+ Passive mode (`afm reconcile`) is always on. This skill covers only the task list.
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: update
3
+ description: |
4
+ Syncs `<consumer>/docs/` with the current plugin version. It materializes the consumer-facing deltas between the pinned version and the shipped version, then moves the pin. It reads the plugin and never edits it.
5
+ Activates: `afm update`, "bump the methodology version", "sync docs with the new plugin", "my `.afm-version` is behind".
6
+ ---
7
+
8
+ # AFM — Update (sync instance-plugin)
9
+
10
+ The CLI runs the codemod registry, proves each op and moves the pin. This skill keeps the judgment.
11
+
12
+ > **Carve-out (does not overlap existing ops):** `afm init` and `afm refactor` **create** the instance
13
+ > (bootstrap). `update` brings an **existing** instance forward, the path that `afm refactor` refuses.
14
+ > `afm diagnose` only **detects** drift on axis A3 (read-only). `update` **resolves** it. `afm promote`
15
+ > **records** a finding meant for the plugin. `update` reads the plugin and materializes it into the
16
+ > instance, and neither touches the shipped content: an absolute boundary (#7). `afm evolve` is the
17
+ > **cycle** that composes `update` on axis A3.
18
+
19
+ ## When NOT to activate
20
+
21
+ This is a disambiguation for a skill that already activated. Use `afm init` or `afm refactor` if no instance
22
+ is bootstrapped yet. Skip `update` if the pinned version already equals the shipped version (no drift). Use
23
+ `afm promote` to carry a learning from the instance TO the plugin (the opposite direction). Use
24
+ `afm diagnose` to only CHECK for drift. Use `afm evolve` for the full cycle.
25
+
26
+ ## Pre-check
27
+
28
+ `afm update --dry-run` does it: exit 3 means no instance (suggest `afm init` or `afm refactor`), exit 4 means
29
+ the shipped content does not resolve (report it, do not fall back silently), and "already up to date" ends
30
+ the run. A pin **ahead** of the binary is an anomaly: report it, never roll it back.
31
+
32
+ ## Procedure (judgment only)
33
+
34
+ 1. Read the dry run as one package and show it as evidence. Ask `afm ask update`. Under `afm evolve` this gate
35
+ is suppressed.
36
+ 2. Run `afm update`. It moves the pin only at the end, and keeps it where it was when a codemod fails.
37
+ 3. Exit 6 means agent tasks are pending: do each one inside its scope (`afm lint --fix <path>` fixes the
38
+ frontmatter findings), then run `afm update` again. `afm update --accept <path>` closes a sync on a file
39
+ you merged by hand. An opt-in delta is reported and never applied. Exit 5 (a major crossing) is
40
+ `afm migrate`.
41
+ 4. **Language migration** (when the instance is not English): read `prd.md` § 11.1 FIRST and derive the
42
+ excluded scope from it, and only then read a file. `[TBD]` there stops the step and asks
43
+ `afm ask update-strings`. It never picks a language. The artifacts question is
44
+ `afm ask update-artifacts`. On migrate, run the rewrite as one orchestrated batch through
45
+ {{host:workflow}}, with a light model per agent ({{host:light-model}}) for the rewrite and the loss
46
+ check. Escalate only a flagged file to a capable model. The session model keeps the excluded scope and
47
+ the final gate.
48
+ 5. Post-conditions: `afm index --check` returns 0 and the plugin boundary stays clean. Report in chat what
49
+ migrated and what stayed pending. Under `afm evolve`, feed it to `docs/evolution/`.
50
+
51
+ ## Invariant principles
52
+
53
+ Most relevant here: #2 (discover-first): the proof of
54
+ need is the grep that shows what is missing. Follow #4/#5: materialize only what the plugin already provides
55
+ ready-made, and never invent missing product content. Follow #6 (autonomy-first with a gate). Bright line
56
+ #7 applies: only **read** the plugin, and write only to the instance.
57
+
58
+ **No new principle here.** `update` is composed materialization. The doctrine lives in the op file.
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: verify
3
+ description: |
4
+ Stamps a human verification on one doc under `docs/`. It writes the OKF `verified` field and is the only writer of that field. Use it when a person states they reviewed a document.
5
+ Activates: `afm verify <path>`, "I reviewed this rule", "mark this gotcha as verified", "sign off on this ADR".
6
+ ---
7
+
8
+ # AFM — Verify (stamp a human review)
9
+
10
+ ## When not to activate
11
+
12
+ Never on ordinary work, and never on your own output. This skill records that a PERSON read a document. An
13
+ agent stamping its own writing produces a lie the trust tier cannot detect.
14
+
15
+ ## Pre-check
16
+
17
+ 1. `afm preflight`. Exit 3 means there is no instance: stop.
18
+ 2. **Did a person state they reviewed the file?** If not, stop and ask: `afm ask verify`. Inference is not
19
+ review.
20
+ 3. The file must carry a frontmatter block, or there is no contract to stamp.
21
+
22
+ ## Procedure (judgment only)
23
+
24
+ Run `afm verify <path under docs/>` (add `--as <id>` when no git user name is set). The command refuses an
25
+ agent actor. Report the tier that resulted and what it means.
26
+
27
+ ## Invariant principles
28
+
29
+ Most relevant here: #5 is load-bearing.
@@ -0,0 +1,51 @@
1
+ ---
2
+ type: template
3
+ description: 'Template rendered during materialization: ADR-NNNN — {{short title on the decision, not on the problem}}.'
4
+ load: cold
5
+ renders_to: 'docs/adr/*.md'
6
+ frontmatter_for_output: |
7
+ type: adr
8
+ description: '<one sentence: the decision and why it matters>'
9
+ load: warm
10
+ status: proposed # proposed | accepted | superseded | deprecated. Set from step 2's
11
+ # `afm ask adr` answer; `afm adr --supersedes` sets superseded.
12
+ date: YYYY-MM-DD # The day the decision was written down.
13
+ decided_by: '<who>' # `[TBD]` when nobody said.
14
+ supersedes: ADR-NNNN # ONLY when this decision replaces an earlier one. Omit otherwise.
15
+ superseded_by: ADR-NNNN # ONLY when status is superseded by a later decision. Omit otherwise.
16
+ relates_to: [ADR-NNNN] # ONLY when it depends on or refines other ADRs. Omit otherwise.
17
+ trigger_path: '{{glob}}' # ONLY when this decision constrains one path or family of paths.
18
+ # Most decisions bind none: omit the key rather than guess one.
19
+ ---
20
+
21
+ # ADR-NNNN — {{short title on the decision, not on the problem}}
22
+
23
+ ## Context
24
+
25
+ {{What was happening, what problem appeared, which constraints (time, scope, security, cost) limit the decision. 3-5 sentences. Cite the concrete symptom that forced the decision. Do not invent a retroactive motivation.}}
26
+
27
+ ## Decision
28
+
29
+ {{What was decided, in one header sentence.}}
30
+
31
+ {{Operational details. What changes in the code, in which file, with which contract. Use a concrete, absolute path and a snippet when useful.}}
32
+
33
+ ## Alternatives considered
34
+
35
+ - **{{alternative A}}** — why it was NOT chosen (cost / risk / simplicity).
36
+ - **{{alternative B}}** — why it was NOT chosen.
37
+
38
+ <!-- guidance -->
39
+ (List 1-3 alternatives. If you considered none, write "Direct decision — no alternatives evaluated because {{reason}}".)
40
+ <!-- /guidance -->
41
+
42
+ ## Consequence
43
+
44
+ {{What becomes easy now. What becomes hard now. Accepted technical debt. A gotcha other developers will hit (link to `gotchas.md` if it applies).}}
45
+
46
+ ## References
47
+
48
+ - Commit: `{{sha}}`
49
+ - Related US/RF: US-NNN / RF-NN
50
+ - Canonical doc: `/docs/{{file}}.md` §X
51
+ - External issue / PR: {{link}}
@@ -0,0 +1,132 @@
1
+ ---
2
+ type: template
3
+ description: 'Template rendered during materialization: Evolution cycle {{NNNN}} — {{data YYYY-MM-DD}}.'
4
+ load: cold
5
+ renders_to: 'docs/evolution/YYYY-MM-DD-NNN.md'
6
+ frontmatter_for_output: |
7
+ type: evolution-report
8
+ description: '<one sentence: what this cycle found and changed>'
9
+ load: cold
10
+ mechanism: evolve | reflect | restructure | generalize # WHICH mechanism wrote this report
11
+ date: 'YYYY-MM-DD'
12
+ cycle_trigger: '<explicit invocation or the symptom stated by the user: cite it>'
13
+ new_signal: '<which Class A delta or symptom released the cooldown>'
14
+ resolves: [] # optional: fingerprints (from `afm sessions signals`) of the friction this cycle fixed
15
+ ---
16
+
17
+ # Evolution cycle {{NNN}} — {{date YYYY-MM-DD}}
18
+
19
+ <!-- guidance -->
20
+ > **File name: `YYYY-MM-DD-NNN.md`, date first.** The cadence counter picks the last report by
21
+ > sorting these names, and an ordinal-first name sorts by ordinal before date — a low ordinal on
22
+ > a recent date rewinds the window in silence. `NNN` is now only a same-day tiebreak.
23
+ >
24
+ > **`resolves:` (frontmatter, optional)** lists the signal fingerprints this cycle fixed. `afm sessions signals`
25
+ > marks a signal with one of them `resolved` when it happened before this report's date, and `regressed` when
26
+ > it happens again after it (the fix did not hold).
27
+ >
28
+ > **`mechanism:` (frontmatter) is mandatory and it is not decoration.** `reflect`, `evolve` and `restructure`
29
+ > all write into this one directory, and each one's cadence window is "since MY last report".
30
+ > Without the field the windows collapse into one, and the cheap mechanism starves the expensive
31
+ > one: measured on 2026-08-30, five reports, all five `reflect`, and `evolve` had never run.
32
+
33
+ > This is a report of one `afm evolve` cycle (auto-evolution of **this project's local documentation** — the materialized instance of the methodology in `docs/`, never the plugin). It is the **auditable lineage** and the **memory of past attempts** for future cycles. It is not the evolved artifact itself (the edits live in the touched local docs). It is the record of the diagnosis and the gate decisions.
34
+ <!-- /guidance -->
35
+
36
+ ---
37
+
38
+ ## Vital signs
39
+
40
+ | Signal | Before | After (measured in dry-run / post-apply) |
41
+ | --- | --- | --- |
42
+ | Dead refs (A1) | {{n}} | {{n}} |
43
+ | `[TBD]`/`[NEEDS CLARIFICATION:]` markers above threshold (A2) | {{n}} | {{n}} |
44
+ | Version drift (A3) | {{instance X vs plugin Y / ok}} | {{...}} |
45
+ | Broken ADR chain (A4) | {{n}} | {{n}} |
46
+ | Non-parseable § 3 triggers (A5) | {{n}} | {{n}} |
47
+ | Inflation — core docs above threshold (A6) | {{which / ok}} | {{...}} |
48
+
49
+ ---
50
+
51
+ ## Findings (φ signature)
52
+
53
+ <!-- guidance -->
54
+ > Each finding is `(symptom, behavior causal status, mechanism)` plus evidence (`command` + `file:line`) and severity. Non-addressable findings go in the observations section, with no proposal.
55
+ <!-- /guidance -->
56
+
57
+ | ID | Symptom (evidence) | Causal status | Mechanism | Severity | Addressable? |
58
+ | --- | --- | --- | --- | --- | --- |
59
+ | D01 | {{what the command flagged + file:line}} | {{does this imply a methodology behavior?}} | {{miswritten trigger / obsolete rule / orphan doc / agent non-conformance}} | {{CRITICAL/HIGH/MEDIUM/LOW}} | {{yes / no → observation}} |
60
+
61
+ ### Observations (non-addressable findings — no proposal)
62
+
63
+ - {{example: "user did not answer the `[TBD]` items in §X for >180 days — human behavior, not a doc problem. No edit fixes this"}}.
64
+
65
+ ---
66
+
67
+ ## Evolution package
68
+
69
+ ### Bucket (a) — auto-applicable (restorative, non-semantic)
70
+
71
+ <!-- guidance -->
72
+ > Only fixes that **restore what the doc already states**, proven by git or the file system. Never touch a `*Verification:*` command in § 3, or a path the hooks parse.
73
+ <!-- /guidance -->
74
+
75
+ | ID | Surface | Edit | Mechanical proof | Gate decision |
76
+ | --- | --- | --- | --- | --- |
77
+ | A01 | {{file}} | {{corrected path ref / corrected ADR link}} | {{git log --follow / ADR-NNNN exists}} | {{approved / refused}} |
78
+
79
+ ### Bucket (b) — load-bearing (earned gate questions)
80
+
81
+ <!-- guidance -->
82
+ > A 4-field audit record per item. Downgrading or removing a hard rule, and any deletion, need item-by-item approval. This is unavoidable, even without a "go" — evolve has no "go".
83
+ <!-- /guidance -->
84
+
85
+ | ID | Targeted pattern | Edited surface | Expected effect | Regression risk / what to preserve | What breaks if this is wrong | Flip-flop? | Decision |
86
+ | --- | --- | --- | --- | --- | --- | --- | --- |
87
+ | B01 | {{finding D0N}} | {{file:section}} | {{...}} | {{passing behaviors to preserve}} | {{load-bearing consequence}} | {{⚠ cycle NNNN / —}} | {{approved / refused}} |
88
+
89
+ ### Bucket (c) — cosmetic/deferrable
90
+
91
+ - {{note — becomes `[TBD]` or waits for reconcile. Not edited in this cycle}}.
92
+
93
+ ### Overflow staged (above the cap of 8 items/cycle)
94
+
95
+ - {{items that did not fit — carried to the next cycle}}.
96
+
97
+ ---
98
+
99
+ ## ADRs created in this cycle
100
+
101
+ <!-- guidance -->
102
+ > Itemized in the gate (Phase 3). Not materialized after the gate without approval.
103
+ <!-- /guidance -->
104
+
105
+ - {{ADR-NNNN — title — status proposed/approved}}.
106
+
107
+ ---
108
+
109
+ ## Attempt memory (anti-oscillation)
110
+
111
+ <!-- guidance -->
112
+ > Future cycles read this. Re-proposing a refused or reverted item needs **new evidence**. Touching a surface with an opposite history carries a flip-flop flag.
113
+ <!-- /guidance -->
114
+
115
+ ### Refused in this cycle
116
+ - {{ID — proposal — reason the user refused it}}.
117
+
118
+ ### Approved-then-reverted (by mechanical post-condition)
119
+ - {{ID — edit — why it was reverted (hook format broke / plugin got dirty) — flagged dependent items}}.
120
+
121
+ ---
122
+
123
+ ## Mechanical post-conditions
124
+
125
+ - [ ] `afm doctor --json`, `afm index --check` and `afm detect --for <file>` over the touched docs kept the format the hooks parse.
126
+ - [ ] The content root (`afm path`) is clean: `git -C <content-root> status --porcelain` is empty, or, with no git there, no file under it is newer than T0 (no edit leaked into the bundled content).
127
+
128
+ ---
129
+
130
+ ## Suggested promotion
131
+
132
+ - {{finding that generalizes to any instance → suggest `afm promote` (its own gate, evolve only suggests it). Or "none"}}.
@@ -0,0 +1,84 @@
1
+ ---
2
+ type: template
3
+ description: 'Template rendered during materialization: Feature {{NNN}} — Plan.'
4
+ load: cold
5
+ renders_to: 'docs/features/*/plan.md'
6
+ frontmatter_for_output: |
7
+ type: feature-plan
8
+ description: '<one sentence: the approach this plan commits to>'
9
+ load: cold
10
+ status: planned # draft | clarified | planned | in_progress | done | cancelled — the folder's
11
+ # ONE lifecycle value; `planned` once this plan exists, in step with spec.md
12
+ for_paths: # § 2's affected components, as globs — this is where the list
13
+ - '{{glob}}' # spec.md seeded empty gets its first real entries
14
+ us: US-{{NNN}} # carried from spec.md. Omit when spec.md omits it.
15
+ rf: RF-{{NN}} # carried from spec.md. Omit when spec.md omits it.
16
+ ---
17
+
18
+ # Feature {{NNN}} — Plan
19
+
20
+ ## 1. Approach in 3 sentences
21
+
22
+ {{What to build, in which layer, linked to which component-types from `ach.md` § 3.}}
23
+
24
+ ## 2. Affected components
25
+
26
+ | Component-type | File / module | New or edit | Why |
27
+ | --- | --- | --- | --- |
28
+ | {{Procedure-like}} | `{{src-path}}/server/routers/{{x}}.ts` | edit | adds endpoint Y |
29
+ | {{Domain-like}} | `{{src-path}}/domain/{{x}}.ts` | new | business rule Z |
30
+
31
+ ## 3. Data model (delta)
32
+
33
+ {{Mini ASCII ER diagram if there is a new entity. For new fields only, list field + type + reason. If nothing changes, write "no delta".}}
34
+
35
+ ## 4. Architectural decisions
36
+
37
+ {{Each decision that would deserve an ADR goes here FIRST. If it becomes load-bearing later, materialize an ADR (see `ops/adr.md`). Bullet list:}}
38
+
39
+ - **Decision:** {{X}}. **Rejected alternative:** {{Y}}. **Why:** {{concrete reason — cost, risk, simplicity}}.
40
+
41
+ ## 5. Contracts (external boundaries)
42
+
43
+ {{For each new boundary — request/response shape, error codes, status. Keep it inline. Promote to `./contracts/` only when there are more than 3 boundaries OR the schema comes from tooling.}}
44
+
45
+ ### Boundary {{name}}
46
+
47
+ ```ts
48
+ // input
49
+ { field: type }
50
+
51
+ // output (success)
52
+ { field: type }
53
+
54
+ // errors (codes)
55
+ "NOT_FOUND" | "INVALID_INPUT" | "..."
56
+ ```
57
+
58
+ ## 6. Complexity tracking
59
+
60
+ {{Log each complexity that exceeds the "obviously simple" baseline, with a justification. An empty table is a valid answer — it means the baseline stayed simple.}}
61
+
62
+ | Accepted complexity | Rejected simple alternative | Why it was not simple |
63
+ | --- | --- | --- |
64
+ | {{ex: in-memory cache + TTL}} | {{no cache}} | {{p95 would be 800ms vs 80ms}} |
65
+
66
+ ## 7. Validation against invariants
67
+
68
+ - [ ] Does not violate the hard rules in `afm.md` § 3 (list the ones that apply, by number, e.g. "rule 11 — structural change confirmed with the user at {{turn}}").
69
+ - [ ] Follows the universal principles in `PRINCIPLES.md`.
70
+ - [ ] `[NEEDS CLARIFICATION:]` is at zero OR listed in § 9 with a resolution plan.
71
+
72
+ ## 8. Risks
73
+
74
+ - {{1-3 risks, each with a concrete mitigation}}.
75
+
76
+ ## 9. Open questions
77
+
78
+ - [NEEDS CLARIFICATION: {{question}}]
79
+
80
+ ---
81
+
82
+ <!-- guidance -->
83
+ *The plan does NOT contain a granular task list (that goes in `tasks.md`). The plan does NOT choose the stack — it reads the stack from `ach.md`. If the relevant `ach.md` layer is `[TBD]`, flag it here and block tasks until it is resolved.*
84
+ <!-- /guidance -->
@@ -0,0 +1,56 @@
1
+ ---
2
+ type: template
3
+ description: 'Template rendered during materialization: Research — Feature {{NNN}} — {{title}}.'
4
+ load: cold
5
+ renders_to: 'docs/features/*/research.md'
6
+ frontmatter_for_output: |
7
+ type: feature-research
8
+ description: '<one sentence: what this research investigates>'
9
+ load: cold
10
+ status: open # open | closed — `closed` once the findings were applied to spec.md or plan.md
11
+ consumed_by: '<the artifact that cites this research; omit until one does>'
12
+ context: '<the marker from spec.md or plan.md this answers, or "free investigation: <topic>">'
13
+ ---
14
+
15
+ # Research — Feature {{NNN}} — {{title}}
16
+
17
+ <!-- guidance -->
18
+ {{For each topic investigated, repeat the block below. Put multiple topics in the same file if they went to the subagent in the same round.}}
19
+ <!-- /guidance -->
20
+
21
+ ## {{topic 1 — concrete question}}
22
+
23
+ **Decision (proposed):** {{X}}
24
+
25
+ **Rationale:**
26
+ - {{bullet 1 with concrete evidence — number, benchmark, documented case}}
27
+ - {{bullet 2}}
28
+ - {{bullet 3}}
29
+
30
+ **Alternatives considered:**
31
+ - **{{alt A}}** — rejected because {{concrete reason — cost, risk, simplicity, compat}}.
32
+ - **{{alt B}}** — rejected because {{reason}}.
33
+
34
+ **Sources:**
35
+ - {{real URL or ref}}
36
+ - {{real URL or ref}}
37
+
38
+ ---
39
+
40
+ ## {{topic 2}}
41
+
42
+ <!-- guidance -->
43
+ (Same as the previous block if more topics exist.)
44
+ <!-- /guidance -->
45
+
46
+ ---
47
+
48
+ <!-- guidance -->
49
+ *Research is input. It is not a decision. To add it to the project, follow these steps.*
50
+
51
+ *1. Edit the feature's `spec.md` or `plan.md`. Cite this research as the source.*
52
+
53
+ *2. If the decision is load-bearing (a change would break something visible), make it an ADR with `afm adr`.*
54
+
55
+ *3. After you add it, set this file's frontmatter `status` from `open` to `closed`.*
56
+ <!-- /guidance -->