@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,47 @@
1
+ ---
2
+ type: protocol
3
+ description: 'Template rendered during materialization: P3 — Planned Autonomous Delivery.'
4
+ load: cold
5
+ ---
6
+
7
+ # P3 — Planned Autonomous Delivery
8
+
9
+ > the middle ground — P2 quality with P1 interaction. You plan together. The agent executes alone.
10
+
11
+ | Field | Phase 1 (planning) | Phase 2 (execution) |
12
+ | --- | --- | --- |
13
+ | posture | `assisted` | `auto` |
14
+ | `RETRY_CAP` | 2 | 2 |
15
+ | `ROUND_CAP` | 2 | **0** |
16
+ | `HALT_PER_PHASE` | — | off |
17
+ | `SUPPRESS_SUBGATES` | off | on |
18
+ | `delegation` | read-only | full |
19
+ | `MAX_PARALLEL_SUBAGENTS` | **6** | 4 |
20
+
21
+ **Transition gate — the only gate. The criterion is mechanical.** `plan.md` and `tasks.md` have no **open** `[NEEDS CLARIFICATION:]` marker. `grep` returns 0 or 1. This is not a judgment call about plan quality.
22
+
23
+ The command is:
24
+
25
+ ```sh
26
+ sed 's/`[^`]*`//g' plan.md tasks.md | grep -c '\[NEEDS CLARIFICATION:'
27
+ ```
28
+
29
+ The `sed` step is load-bearing. Without it, the gate is **vacuously red**. A plan that *mentions* the marker inside backticks — describing the gate itself, or citing an example — fails itself. This happened in delivery 001 of this repo, where the only "hit" was the line that documented the gate. A gate that fails because it talks about itself is as useless as a gate that passes without looking. Both teach the operator to ignore it.
30
+
31
+ **Why phase 2 can be autonomous:** every unknown was already decided in phase 1, and every critical point was already resolved. Execution is predictable and known. `ROUND_CAP = 0` in phase 2 makes this concrete. If something **outside the plan** appears, there is no question budget left. That case falls to the `deliver` stop table (rule 11, bright line, failure beyond `RETRY_CAP`), which escalates on external signal, not on confidence.
32
+
33
+ **Cadence (large initiative):** run `reflect` every 3-4 tasks. When you close the deliverable, run a general `reflect`, then `evolve`.
34
+
35
+ ## The native Plan Mode is the mechanism, not the analogy
36
+
37
+ P3 **is** the shape of Claude Code's plan mode: assisted planning. Approval offers *"Yes, and use auto mode"* — a gate that transitions to autonomous execution. From v3.5.0 onward, this is not a comparison. It is the executed path.
38
+
39
+ | Moment | Mechanism |
40
+ | --- | --- |
41
+ | Enter phase 1 | `EnterPlanMode` |
42
+ | Transition gate | the `grep` 0/1 check above, over `plan.md`/`tasks.md` |
43
+ | Exit to phase 2 | `afm approve <feature>` on the consolidated plan — the recorded approval (sha256 of the plan) **is** the gate |
44
+
45
+ **Declared degradation.** If the harness has no native plan approval, P3 **does not stop**. It falls back to the path already described in `ops/deliver.md` Phase 1 (chat summary + one recommendation-first `afm ask deliver`). The transition criterion is the same `grep` check in both paths. The native mode changes the **approval surface**, never the criterion. A gate whose criterion depended on the mode being on would be posture, not mechanism.
46
+
47
+ **What the native mode buys you.** Phase 1 becomes read-only by construction of the harness, not by a promise from the model. `delegation: read-only` in phase 1 stops being cooperative prose and becomes a floor imposed from outside — exactly the "hard vs. soft" distinction in `core/protocol.md § 6`.
@@ -0,0 +1,50 @@
1
+ ---
2
+ type: template
3
+ description: 'Template rendered during materialization: Research — {{topic or area}}.'
4
+ load: cold
5
+ renders_to: 'docs/research/*.md'
6
+ frontmatter_for_output: |
7
+ type: research
8
+ description: '<one sentence: the question this research answers>'
9
+ load: cold
10
+ fires_on: op-call # a human never fires research directly — an op reads it to decide
11
+ fires_when: '<the question it answers, in one line — the sentence the body already states>'
12
+ date: 'YYYY-MM-DD'
13
+ context: 'free context: before bootstrap, during refactor, decide auth library'
14
+ status: draft | reviewed | applied
15
+ consumed_by: ADR-NNNN # ONLY once an ADR or feature used it: omit the key while `status: draft`
16
+ # and add it in the same edit that moves status to `applied`
17
+ # — a consumed dossier is not re-read.
18
+ ---
19
+
20
+ # Research — {{topic or area}}
21
+
22
+ <!-- guidance -->
23
+ {{Repeat the block below for each investigated topic.}}
24
+ <!-- /guidance -->
25
+
26
+ ## {{topic 1 — concrete question}}
27
+
28
+ **Decision (proposed):** {{X}}
29
+
30
+ **Rationale:**
31
+ - {{bullet 1 with concrete evidence}}
32
+ - {{bullet 2}}
33
+ - {{bullet 3}}
34
+
35
+ **Alternatives considered:**
36
+ - **{{alt A}}** — rejected because {{concrete reason}}.
37
+ - **{{alt B}}** — rejected because {{reason}}.
38
+
39
+ **Sources:**
40
+ - {{real URL or reference}}
41
+ - {{real URL or reference}}
42
+
43
+ ---
44
+
45
+ <!-- guidance -->
46
+ *Global research (not tied to a feature) feeds future PRD/ACH decisions or cross-project ADRs. To incorporate it:*
47
+ *1. Cite this research in any project doc that decides based on it (e.g. `prd.md` § 4 RFs, `ach.md` § 1 stack, a specific ADR).*
48
+ *2. If it becomes a load-bearing decision, turn it into an ADR via `afm adr`.*
49
+ *3. After you incorporate it, change this file's frontmatter `status` from `draft` to `applied`.*
50
+ <!-- /guidance -->
@@ -0,0 +1,58 @@
1
+ ---
2
+ type: template
3
+ description: 'Template rendered during materialization: Session {{YYYY-MM-DD-HHMM}} — {{name}}.'
4
+ load: cold
5
+ renders_to: 'the session record in the state store'
6
+ frontmatter_for_output: |
7
+ type: session
8
+ description: 'Session {{YYYY-MM-DD-HHMM}} — {{name}}.'
9
+ load: cold
10
+ tier: dual
11
+ state: open
12
+ name: '{{human label — mechanical default = dominant subtree in files_touched; reflect refines it}}'
13
+ date: '{{YYYY-MM-DD}}'
14
+ claude_session_id: '{{FULL session id — pointer to the harness transcript}}'
15
+ cwd: '{{absolute path of the consumer project}}'
16
+ created_at: '{{ISO-8601 UTC}}'
17
+ reflection: '{{link to docs/evolution/<date>-NNN.md — what reflect found AND fixed in the local docs}}'
18
+ ---
19
+
20
+ # Session {{YYYY-MM-DD-HHMM}} — {{name}}
21
+
22
+ <!-- guidance -->
23
+ > **Two tiers in the same file** (v4/F9). The **handoff** block (`state`, `open_questions`, `next_steps`) is episodic and single-use. `state: open|consumed` governs **only this block**. The `reconcile` op consumes it. The rest is **durable telemetry**. It survives, it is versioned, and a plugin-repo agent reads it to improve AFM from real usage. It stays **outside** the `diagnose` A1–A7 axes. It is not a normative doc.
24
+ >
25
+ > **Two writers.** The `afm-session-end.sh` hook (`Stop`, 0-LLM) writes the skeleton and the mechanical fields for a session with work (non-empty `git diff`). `afm reflect` (§ 5.1) fills in the fields that need judgment: `name`, the two timeline sections, `afm_findings`, and `reflection:`. **A session without a `reflect` run keeps only the skeleton.** This is acceptable, not a defect.
26
+ >
27
+ > **File name ≠ `name:`.** The file is `<date>-<sid6>.md` (stable identity, dedup key, target of links already emitted). `name:` is a label and can be rewritten.
28
+ >
29
+ > ⚠️ **Hard rule 13 covers this directory.** The narrative cites commands. A command with a key inside becomes a versioned secret. Write the narrative with the secret removed.
30
+ <!-- /guidance -->
31
+
32
+ ## files_touched
33
+
34
+ - {{`git diff --name-only HEAD`}}
35
+
36
+ ## summary (events in this session)
37
+
38
+ - {{titles of the `s=<sid>` events for this session in the event ledger (the state store)}}
39
+
40
+ ## what was asked
41
+
42
+ - {{reflect — what the agent UNDERSTOOD from the user's request, including where the reading changed midway. Interpretation, not transcription.}}
43
+
44
+ ## how it was executed
45
+
46
+ - {{reflect — how AFM was used: ops run, rules that fired, where the harness helped and where it got in the way. No other artifact holds this data.}}
47
+
48
+ ## afm_findings
49
+
50
+ - {{reflect/promote — what generalizes to the PLUGIN, in the format of `ops/promote.md` step 4 (title · `target:` · `evidence:` · `origin:` · why). An explicit empty result is valid.}}
51
+
52
+ ## open_questions
53
+
54
+ - {{what stayed open — session state, not the same as a spec `[NEEDS CLARIFICATION:]`}}
55
+
56
+ ## next_steps
57
+
58
+ - {{concrete next step / `T0NN` — points to tasks, does not change spec/plan/tasks}}
@@ -0,0 +1,39 @@
1
+ ---
2
+ type: template
3
+ description: 'Template rendered during materialization: .'
4
+ load: cold
5
+ renders_to: 'docs/ust.md'
6
+ ---
7
+
8
+ ### US-NNN — {{objective title, "[Persona] [verb] [outcome]"}}
9
+
10
+ - **Persona:** {{who, from PRD §3}}.
11
+ - **Pain:** {{1 sentence on the current workaround}}.
12
+ - **Story:** As {{persona}}, I want {{action}} to get {{measurable outcome}}.
13
+
14
+ **Acceptance criteria:**
15
+
16
+ ```gherkin
17
+ Scenario: {{happy path scenario name}}
18
+ Given {{precondition}}
19
+ And {{extra precondition, if any}}
20
+ When {{user action}}
21
+ Then {{expected observable result}}
22
+ And {{verifiable side effect}}
23
+ ```
24
+
25
+ ```gherkin
26
+ Scenario: {{most likely error scenario}}
27
+ Given {{precondition}}
28
+ When {{user action in an invalid state}}
29
+ Then {{expected error, typed classification}}
30
+ And {{no DB side effect}}
31
+ ```
32
+
33
+ **Metadata:**
34
+ - **Priority:** P0 | P1 | P2
35
+ - **Status:** draft | ready | in_progress | done | cancelled
36
+ - **RF:** RF-NN
37
+ - **RNF:** RNF-NN (if applicable)
38
+ - **Success metric:** {{how to measure that the job was done}}
39
+ - **Dependencies:** US-NNN, US-NNN (if any)
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env bash
2
+ # Hard rule 13 — a token or a secret never leaks, the docs/sessions/ narrative included.
3
+ # It is a gate because it is the cheapest error to make (the agent quotes the command it ran,
4
+ # and the command carried the key) and the most expensive to undo: a committed secret is a
5
+ # rotated secret.
6
+ set -u
7
+ MODE="${1:-staged}"
8
+ REPO="${AFM_GATE_REPO:-$PWD}"
9
+ . "${AFM_GATE_LIB:?}/scope.sh"
10
+ RC=0
11
+
12
+ # A secret in the ADDED lines. The awk tracks the current `+++ b/<file>` because "diff:7"
13
+ # locates no leak at all — and locating it fast is the point: a committed secret is a rotated
14
+ # secret, and the rotation starts by knowing which file to open.
15
+ scan() {
16
+ scope_diff "$MODE" | awk -v pat="$1" -v msg="$2" '
17
+ /^\+\+\+ b\// { f = substr($0, 7); next }
18
+ /^\+/ && $0 ~ pat { printf "13\t%s\t%s\n", (f == "" ? "(index)" : f), msg }
19
+ '
20
+ }
21
+
22
+ OUT="$(scan "(token|secret|api[_-]?key|password|bearer)[[:space:]]*[:=][[:space:]]*[\"'"'"'][^\"'"'"']+" "key/value pair with a plaintext secret")
23
+ $(scan "(sk-[A-Za-z0-9]{16,}|ghp_[A-Za-z0-9]{20,}|AIza[A-Za-z0-9_-]{30,}|xox[baprs]-[A-Za-z0-9-]{10,}|eyJ[A-Za-z0-9_-]{20,}[.])" "token in a recognizable format (sk-/ghp_/AIza/xox/JWT)")"
24
+ if printf '%s' "$OUT" | grep -q .; then
25
+ printf '%s\n' "$OUT" | grep -v '^$'
26
+ RC=1
27
+ fi
28
+
29
+ # A versioned .env. `.env.example` is legitimate and stays out.
30
+ while IFS= read -r f; do
31
+ case "$f" in *.env.example|*.env.sample) continue ;; esac
32
+ printf '13\t%s\ta .env file must not be versioned\n' "$f"
33
+ RC=1
34
+ done < <(scope_files "$MODE" | grep -E '(^|/)\.env')
35
+
36
+ exit $RC
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+ # Hard rule 21 (INALIENABLE) — code and tests are written in English.
3
+ # The trigger covers an identifier and a test name with a non-ASCII character. It does NOT
4
+ # cover unaccented Portuguese (an identifier without a diacritic passes) and it does not cover
5
+ # a comment — English prose uses em dashes and curly quotes, so non-ASCII inside a comment is
6
+ # noise, not signal. Since 3.9.0-rc.1 the comment is covered from the other side, by density,
7
+ # in `tools/afm-lang.sh`.
8
+ set -u
9
+ MODE="${1:-staged}"; : "$MODE" # COUNTING rule: the scope is the whole repo (see the gate lib scope.sh)
10
+ REPO="${AFM_GATE_REPO:-$PWD}"
11
+ . "${AFM_GATE_LIB:?}/scope.sh"
12
+
13
+ # `grep -P` is GNU. Without it the runner does NOT decide — and an abstention never becomes a
14
+ # failure, or the first machine without GNU grep turns the gate into a permanent block.
15
+ echo x | grep -qP 'x' 2>/dev/null || exit 2
16
+
17
+ RC=0
18
+ PAT='\b(?:function|class|const|let|var|def|interface|type|enum|describe|it|test)\b\s*\(?\s*["\x27]?[A-Za-z_$][\w$ ]*[^\x00-\x7F]'
19
+ while IFS= read -r f; do
20
+ [ -f "$REPO/$f" ] || continue
21
+ while IFS=: read -r n _; do
22
+ printf '21\t%s:%s\tidentifier or test name with a non-ASCII character\n' "$f" "$n"
23
+ RC=1
24
+ done < <(grep -nP "$PAT" "$REPO/$f" 2>/dev/null)
25
+ done < <(scope_all 'plugins/*/mcp/src/*')
26
+
27
+ exit $RC
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ # Hard rule 35 — a rule with a 0/1 trigger has a versioned runner and sits in the gate.
3
+ # It is the rule that stops the gate from rotting: without it, someone adds a rule with a
4
+ # verification written in prose and the document goes back to promising what nobody runs.
5
+ set -u
6
+ : "${1:-staged}" # the rule is about the STRUCTURE of the gate, not about the diff
7
+ # The aggregator ships BESIDE this runner, in the plugin and in a materialized `docs/tools/gate/`
8
+ # alike, so `$0` resolves it in both. Until 3.20.0 this line read `$REPO/test/guardrails.sh` —
9
+ # one repository's path, hardcoded in a file meant to travel.
10
+ GATE="$(cd "$(dirname "$0")/.." && pwd)/guardrails.sh"
11
+ [ -x "$GATE" ] || { printf 'PLUGIN-35\tdocs/afm.md\tthe aggregator is not beside this runner at %s\n' "$GATE"; exit 2; }
12
+
13
+ OUT="$("$GATE" --repo "${AFM_GATE_REPO:-$PWD}" --audit 2>&1)"; RC=$?
14
+ [ "$RC" = 0 ] && exit 0
15
+
16
+ printf '%s\n' "$OUT" | grep -E '^ FAIL' | sed 's/^ FAIL — //' | while IFS= read -r l; do
17
+ printf 'PLUGIN-35\tdocs/afm.md\t%s\n' "$l"
18
+ done
19
+ exit 1
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+ # Hard rule 36 — a doc under docs/ carries no absolute path.
3
+ # A runbook holding a home directory of one user runs only on the machine of whoever wrote it,
4
+ # and the agent that reads it in a different clone either obeys the wrong path or hallucinates
5
+ # the correction. A relative path is what makes the markdown executable in any checkout.
6
+ #
7
+ # TWO exclusions, both structural and not "convenience":
8
+ #
9
+ # 1. `docs/sessions/` — the `cwd: <path>` line is LOAD-BEARING: afm-session-start.sh matches
10
+ # the pending handoff with `grep -lF "cwd: $PWD"`. Without the absolute path the
11
+ # cross-session handoff stops finding the right session. The directory also grows one entry
12
+ # per session, so a ratchet (which only decreases) would be broken by design.
13
+ #
14
+ # 2. The pattern requires a segment AFTER the user name. Without that, a doc that *describes*
15
+ # the trigger — this one — would accuse itself, and a rule that fails its own documentation
16
+ # is the first one to be turned off.
17
+ set -u
18
+ MODE="${1:-staged}"; : "$MODE" # COUNTING rule: the scope is the whole repo (see the gate lib scope.sh)
19
+ REPO="${AFM_GATE_REPO:-$PWD}"
20
+ . "${AFM_GATE_LIB:?}/scope.sh"
21
+ RC=0
22
+
23
+ while IFS= read -r f; do
24
+ [ -f "$REPO/$f" ] || continue
25
+ while IFS=: read -r n _; do
26
+ printf '36\t%s:%s\tabsolute path in a doc (use a path relative to the repo root)\n' "$f" "$n"
27
+ RC=1
28
+ done < <(grep -nE '(^|[^A-Za-z0-9_])(/home/[A-Za-z0-9._-]+/|/Users/[A-Za-z0-9._-]+/|[A-Z]:\\\\[A-Za-z0-9._-]+)' "$REPO/$f")
29
+ # Three exclusions, and all three are the same reason: a MACHINE-WRITTEN, append-only record
30
+ # whose content is evidence. `docs/sessions/` was excluded from the start. The other two were
31
+ # missed, and `.afm-log-failures/` proved it on 2026-09-03: the CRITIC hook recorded a failing
32
+ # command verbatim — which is the point of the record — and this rule then failed the tree over
33
+ # the absolute path inside that command. Rewriting the record to satisfy the rule would destroy
34
+ # the evidence the record exists to hold, and rules 17/18 forbid rewriting either substrate.
35
+ done < <(scope_all 'docs/*.md' 'docs/**/*.md' \
36
+ | grep -vE '^docs/(sessions|\.afm-log|\.afm-log-failures)/')
37
+
38
+ exit $RC
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env bash
2
+ # Hard rule 37 — the prose of an artifact is English.
3
+ #
4
+ # It complements rule 21, which covers only an IDENTIFIER and a TEST NAME carrying a
5
+ # non-ASCII character. Rule 21 is blind to prose: a `.md` written entirely in Portuguese
6
+ # passes it clean, and that is exactly how this repo reached 2026-08 with 175 Portuguese
7
+ # doc files while the gate reported green.
8
+ #
9
+ # The measurement itself lives in `framework-template/tools/afm-lang.sh` and NOT here.
10
+ # Rule 34: one canonical source. The same threshold has to decide at `PreToolUse`, where
11
+ # the text is still a proposal, and at commit, where it is already a fact — two copies of
12
+ # a measured threshold drift apart in silence, and the commit gate would then contradict
13
+ # the hook that had just approved the write.
14
+ set -u
15
+ MODE="${1:-staged}"; : "$MODE" # COUNTING rule: the scope is the whole repo
16
+ REPO="${AFM_GATE_REPO:-$PWD}"
17
+ . "${AFM_GATE_LIB:?}/scope.sh"
18
+ . "${AFM_GATE_LIB:?}/ratchet.sh"
19
+
20
+ # Resolved through $0, not $REPO (see README "Resolve a sibling tool through $0"): the tool
21
+ # ships beside this directory both in the plugin (framework-template/tools/, two levels up from
22
+ # tools/gate/core-rules/) and in a materialized consumer (docs/tools/, same two levels up from
23
+ # docs/tools/gate/core-rules/). $REPO/plugins/afm/framework-template/tools/afm-lang.sh only
24
+ # exists when this very repository is being dogfooded through ./test/ — in a project bootstrapped
25
+ # by afm init it never exists, so this used to report "missing" against a tool that was right
26
+ # there at docs/tools/afm-lang.sh.
27
+ LANG_TOOL="$(dirname "$0")/../../afm-lang.sh"
28
+ if [ ! -x "$LANG_TOOL" ]; then
29
+ printf 'PLUGIN-37\t%s\tthe language tool is missing or not executable — rule 37 cannot be decided\n' \
30
+ "$LANG_TOOL"
31
+ exit 1
32
+ fi
33
+
34
+ RC=0
35
+ while IFS= read -r f; do
36
+ [ -f "$REPO/$f" ] || continue
37
+ # Exemptions live in the ratchet, never in this file. A `case` arm naming a path is an
38
+ # exclusion that only one repository can have, invisible to any reviewer who does not read
39
+ # the runner. See `ratchet_exempt` in `lib/ratchet.sh`.
40
+ ratchet_exempt PLUGIN-37 "$f" && continue
41
+ # An archived CHANGELOG is a frozen historical record everywhere, not a per-project choice,
42
+ # so it stays in code: it is a SHAPE, not a path.
43
+ case "$f" in */CHANGELOG-archive.md) continue ;; esac
44
+ D="$("$LANG_TOOL" --density "$REPO/$f" 2>/dev/null)" || continue
45
+ # Exit 1 is the accusation; exit 2 is "too short to be a ratio" and has to read as a pass.
46
+ # Collapsing the two reported 83 extra files on the first run of this delegation — every
47
+ # short eval fixture — because `if ! cmd` cannot tell an accusation from an abstention.
48
+ "$LANG_TOOL" --verdict --path "$f" "$REPO/$f" >/dev/null 2>&1; V=$?
49
+ if [ "$V" -eq 1 ]; then
50
+ printf '37\t%s\tPortuguese prose (density %s, %s hits in %s words)\n' \
51
+ "$f" "$(printf '%s' "$D" | cut -f3)" "$(printf '%s' "$D" | cut -f2)" "$(printf '%s' "$D" | cut -f1)"
52
+ RC=1
53
+ fi
54
+ done < <(scope_all '*.md')
55
+
56
+ exit $RC
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env bash
2
+ # Hard rule 38 — a Portuguese literal inside a script or inside a quoted marker.
3
+ #
4
+ # Why it exists: "the data was translated and the parser was not" was the MOST FREQUENT failure
5
+ # of the english-first migration, and NONE of the occurrences was caught by a gate. Three of
6
+ # them killed a mechanism in silence:
7
+ #
8
+ # - afm-health.sh matched the Portuguese "superseded by ADR-" heading while the ADRs said
9
+ # something else, so vital sign A4 (broken ADR chain) found zero, always.
10
+ # - ops/restructure.md read the Portuguese bite and last-bite fields while the template wrote
11
+ # `Bites:`/`last:`, so the dead-gotcha prune never found anything.
12
+ # - guardrails/README.md documented the Portuguese key names while the files used `signal:`
13
+ # and `trigger:`, so a new guardrail would be born invisible.
14
+ #
15
+ # The symptom never varies: the literal stays Portuguese and the target has already changed.
16
+ # Because the repo is english-first (rule 37), the HEURISTIC is cheap and precise — an accented
17
+ # word inside a `.sh`, or inside backticks in a plugin `.md`, is a candidate. It does not prove
18
+ # the drift; it points at where the drift lives. The human triages.
19
+ #
20
+ # It complements rule 37, which looks only at prose DENSITY in `.md` and is therefore blind both
21
+ # to `.sh` and to an isolated literal inside an English doc.
22
+ #
23
+ # Since 2026-08-27 `test/` is NO LONGER exempt. It used to be, by an explicit decision that the
24
+ # gates of this repo speak to the maintainer and are not distributed surface. Translating them
25
+ # found three dead mechanisms this exemption had been hiding for months — rule 34's check (a),
26
+ # the plugin-effect boundary in refs-lint, and the protocol assert in update-rehearsal — each one
27
+ # a parser left on a spelling nothing produces any more. The exemption was protecting exactly the
28
+ # files that most needed this rule.
29
+ set -u
30
+ MODE="${1:-staged}"; : "$MODE" # COUNTING rule: the scope is the whole repo
31
+ REPO="${AFM_GATE_REPO:-$PWD}"
32
+ . "${AFM_GATE_LIB:?}/scope.sh"
33
+ . "${AFM_GATE_LIB:?}/ratchet.sh"
34
+
35
+ # LC_ALL=C: the [À-ÿ] range is INVALID outside a UTF-8 locale and makes grep abort.
36
+ # The prototype of this runner swallowed that error with 2>/dev/null and reported "0 findings"
37
+ # over a corpus with 6 known cases — a gate that swallows its own error is indistinguishable
38
+ # from one that passed, which is exactly the bug hunted here.
39
+ # Hence: an explicit alternation, no range, and the grep NEVER goes to /dev/null.
40
+ export LC_ALL=C
41
+ PT='ã|ç|õ|á|é|í|ó|ú|â|ê|ô|à|Ã|Ç|Õ|Á|É|Í|Ó|Ú|Â|Ê|Ô|À|ambos|planejada|gatilho|Gatilho'
42
+
43
+ RC=0
44
+ report() { printf '38\t%s\t%s\n' "$1" "$2"; RC=1; }
45
+
46
+ # --- 1. shell: any accented word (a comment included: it is instruction) ------
47
+ while IFS= read -r f; do
48
+ [ -f "$REPO/$f" ] || continue
49
+ # Exemptions live in the ratchet, never in this file. A `case` arm naming a path is an
50
+ # exclusion that only one repository can have, invisible to any reviewer who does not read
51
+ # the runner. See `ratchet_exempt` in `lib/ratchet.sh`.
52
+ ratchet_exempt PLUGIN-38 "$f" && continue
53
+ n=$(grep -cE "$PT" "$REPO/$f") || n=0
54
+ [ "$n" -gt 0 ] && report "$f" "${n} line(s) with a Portuguese literal in a script"
55
+ done < <(scope_all '*.sh')
56
+
57
+ # --- 2. plugin markdown: a backticked literal (marker candidate) -------------
58
+ while IFS= read -r f; do
59
+ [ -f "$REPO/$f" ] || continue
60
+ # Exemptions live in the ratchet, never in this file. A `case` arm naming a path is an
61
+ # exclusion that only one repository can have, invisible to any reviewer who does not read
62
+ # the runner. See `ratchet_exempt` in `lib/ratchet.sh`.
63
+ ratchet_exempt PLUGIN-38 "$f" && continue
64
+ # These three are SHAPES that hold in any AFM instance, not paths one project happens to
65
+ # have, so they stay in code: a changelog is a historical record; `core/afm.md` quotes a
66
+ # Portuguese identifier as the example of what rule 21 forbids, and the example has to be
67
+ # wrong to be an example; `ops/deliver.md` lists the override phrases, which are USER SPEECH.
68
+ case "$f" in
69
+ *CHANGELOG.md|*CHANGELOG-archive.md) continue ;;
70
+ */core/afm.md|*/ops/deliver.md|*/ops/update.md) continue ;;
71
+ esac
72
+ # REAL backtick pairing: splitting on the backtick leaves the EVEN fields inside the code
73
+ # span. A naive grep for a backtick, anything, a Portuguese word, anything, a backtick also
74
+ # matches the SPACE BETWEEN two spans — that is how the first version reported a French loan
75
+ # phrase as a Portuguese marker.
76
+ n=$(awk -v pat="$PT" '
77
+ { k=split($0, S, "`"); for (i=2; i<=k; i+=2) if (S[i] ~ pat) c++ }
78
+ END { print c+0 }' "$REPO/$f")
79
+ [ "$n" -gt 0 ] && report "$f" "${n} backticked Portuguese literal(s)"
80
+ done < <(scope_all 'plugins/*/**/*.md' 'plugins/*/*.md')
81
+
82
+ exit $RC