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

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 (276) 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 +4256 -0
  6. package/content/PRINCIPLES.md +121 -0
  7. package/content/README-light.md +160 -0
  8. package/content/README.md +152 -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 +265 -0
  27. package/content/core/afm.md +496 -0
  28. package/content/core/gotchas.md +18 -0
  29. package/content/core/prd.md +143 -0
  30. package/content/core/protocol.md +160 -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 +72 -0
  37. package/content/interview/bootstrap.md +415 -0
  38. package/content/interview/promotion.md +117 -0
  39. package/content/interview/refactor.md +381 -0
  40. package/content/interview/triggers.md +109 -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 +129 -0
  60. package/content/ops/clarify.md +86 -0
  61. package/content/ops/deliver.md +211 -0
  62. package/content/ops/diagnose.md +146 -0
  63. package/content/ops/evolve.md +317 -0
  64. package/content/ops/export-template.md +97 -0
  65. package/content/ops/generalize.md +120 -0
  66. package/content/ops/gotcha.md +46 -0
  67. package/content/ops/plan.md +61 -0
  68. package/content/ops/policy.md +63 -0
  69. package/content/ops/promote.md +72 -0
  70. package/content/ops/protocol.md +51 -0
  71. package/content/ops/reconcile.md +44 -0
  72. package/content/ops/reflect.md +180 -0
  73. package/content/ops/remediate.md +146 -0
  74. package/content/ops/restructure.md +145 -0
  75. package/content/ops/rule.md +165 -0
  76. package/content/ops/specify.md +62 -0
  77. package/content/ops/tasks.md +67 -0
  78. package/content/ops/update.md +223 -0
  79. package/content/ops/verify.md +69 -0
  80. package/content/patterns/adapter.md +46 -0
  81. package/content/patterns/facade.md +47 -0
  82. package/content/patterns/factory.md +46 -0
  83. package/content/patterns/null-object.md +55 -0
  84. package/content/patterns/result-vs-exception.md +52 -0
  85. package/content/patterns/strategy.md +45 -0
  86. package/content/patterns/template-method-vs-composition.md +50 -0
  87. package/content/questions/adr.questions.yaml +14 -0
  88. package/content/questions/analyze.questions.yaml +12 -0
  89. package/content/questions/bootstrap-mapping.questions.yaml +14 -0
  90. package/content/questions/bootstrap-rules.questions.yaml +10 -0
  91. package/content/questions/bootstrap-stack.questions.yaml +23 -0
  92. package/content/questions/clarify.questions.yaml +10 -0
  93. package/content/questions/code-style.questions.yaml +12 -0
  94. package/content/questions/confirm.questions.yaml +12 -0
  95. package/content/questions/deliver.questions.yaml +23 -0
  96. package/content/questions/evolve.questions.yaml +15 -0
  97. package/content/questions/export-template-apply.questions.yaml +11 -0
  98. package/content/questions/export-template.questions.yaml +23 -0
  99. package/content/questions/gates.questions.yaml +27 -0
  100. package/content/questions/generalize.questions.yaml +13 -0
  101. package/content/questions/gotcha.questions.yaml +11 -0
  102. package/content/questions/init-template.questions.yaml +10 -0
  103. package/content/questions/init.questions.yaml +28 -0
  104. package/content/questions/plan.questions.yaml +14 -0
  105. package/content/questions/refactor.questions.yaml +23 -0
  106. package/content/questions/reflect.questions.yaml +13 -0
  107. package/content/questions/remediate.questions.yaml +27 -0
  108. package/content/questions/restructure.questions.yaml +15 -0
  109. package/content/questions/rf-mapping.questions.yaml +12 -0
  110. package/content/questions/rule-scope.questions.yaml +12 -0
  111. package/content/questions/rule.questions.yaml +12 -0
  112. package/content/questions/specify.questions.yaml +23 -0
  113. package/content/questions/update-artifacts.questions.yaml +10 -0
  114. package/content/questions/update-strings.questions.yaml +14 -0
  115. package/content/questions/update.questions.yaml +10 -0
  116. package/content/questions/verify.questions.yaml +9 -0
  117. package/content/roles/executor.md +18 -0
  118. package/content/roles/explorer.md +22 -0
  119. package/content/roles/reviewer.md +23 -0
  120. package/content/rubrics/enum-vs-union-vs-branded.md +40 -0
  121. package/content/rubrics/episodic-vs-semantic-boundary.md +37 -0
  122. package/content/rubrics/error-classification.md +98 -0
  123. package/content/rubrics/failure-classification.md +113 -0
  124. package/content/rubrics/negative-filters.md +38 -0
  125. package/content/rubrics/solid-triggers.md +121 -0
  126. package/content/rubrics/template-vs-streaming-precedence.md +34 -0
  127. package/content/rubrics/validation-boundary.md +94 -0
  128. package/content/rubrics/when-to-create-dsl.md +65 -0
  129. package/content/rubrics/when-to-create-lib.md +49 -0
  130. package/content/rubrics/when-to-create-module.md +39 -0
  131. package/content/rubrics/when-to-evolve-methodology.md +62 -0
  132. package/content/skills/adr.md +42 -0
  133. package/content/skills/analyze.md +34 -0
  134. package/content/skills/clarify.md +34 -0
  135. package/content/skills/deliver.md +42 -0
  136. package/content/skills/diagnose.md +50 -0
  137. package/content/skills/evolve.md +67 -0
  138. package/content/skills/export-template.md +40 -0
  139. package/content/skills/generalize.md +47 -0
  140. package/content/skills/gotcha.md +40 -0
  141. package/content/skills/init.md +82 -0
  142. package/content/skills/plan.md +34 -0
  143. package/content/skills/policy.md +31 -0
  144. package/content/skills/promote.md +41 -0
  145. package/content/skills/protocol.md +42 -0
  146. package/content/skills/reconcile.md +49 -0
  147. package/content/skills/refactor.md +84 -0
  148. package/content/skills/reflect.md +53 -0
  149. package/content/skills/remediate.md +39 -0
  150. package/content/skills/restructure.md +52 -0
  151. package/content/skills/rule.md +44 -0
  152. package/content/skills/specify.md +34 -0
  153. package/content/skills/tasks.md +34 -0
  154. package/content/skills/update.md +56 -0
  155. package/content/skills/verify.md +31 -0
  156. package/content/templates/adr.template.md +51 -0
  157. package/content/templates/evolution-report.template.md +129 -0
  158. package/content/templates/feature-plan.template.md +86 -0
  159. package/content/templates/feature-research.template.md +57 -0
  160. package/content/templates/feature-spec.template.md +86 -0
  161. package/content/templates/feature-tasks.induced.template.md +67 -0
  162. package/content/templates/feature-tasks.template.md +60 -0
  163. package/content/templates/focus.template.md +30 -0
  164. package/content/templates/gotcha.template.md +31 -0
  165. package/content/templates/guardrail-runner.template.md +81 -0
  166. package/content/templates/guardrail.template.md +63 -0
  167. package/content/templates/learning.template.md +40 -0
  168. package/content/templates/procedure.template.md +47 -0
  169. package/content/templates/protocols/p1.md +29 -0
  170. package/content/templates/protocols/p2.md +28 -0
  171. package/content/templates/protocols/p3.md +47 -0
  172. package/content/templates/research.template.md +50 -0
  173. package/content/templates/session-handoff.template.md +58 -0
  174. package/content/templates/us.template.md +39 -0
  175. package/content/tools/gate/core-rules/PLUGIN-13-secrets.sh +36 -0
  176. package/content/tools/gate/core-rules/PLUGIN-21-code-language.sh +27 -0
  177. package/content/tools/gate/core-rules/PLUGIN-35-gate-complete.sh +19 -0
  178. package/content/tools/gate/core-rules/PLUGIN-36-absolute-path.sh +38 -0
  179. package/content/tools/gate/core-rules/PLUGIN-37-prose-language.sh +56 -0
  180. package/content/tools/gate/core-rules/PLUGIN-38-parser-marker.sh +82 -0
  181. package/content/tools/gate/core-rules/PLUGIN-39-frontmatter-ops.sh +325 -0
  182. package/content/tools/gate/core-rules/PLUGIN-40-dead-reference.sh +74 -0
  183. package/content/tools/gate/core-rules/README.md +55 -0
  184. package/content/tools/gate/guardrails.sh +740 -0
  185. package/content/tools/gate/lib/ratchet.sh +119 -0
  186. package/content/tools/gate/lib/scope.sh +85 -0
  187. package/content/tools/gate/ratchet.seed.tsv +1 -0
  188. package/content/tools/gate/rules/README.md +50 -0
  189. package/package.json +19 -5
  190. package/plugin/agy/hooks.json +29 -0
  191. package/plugin/agy/mcp_config.json +7 -0
  192. package/plugin/agy/plugin.json +6 -0
  193. package/plugin/agy/skills/afm-adr/SKILL.md +44 -0
  194. package/plugin/agy/skills/afm-analyze/SKILL.md +36 -0
  195. package/plugin/agy/skills/afm-clarify/SKILL.md +36 -0
  196. package/plugin/agy/skills/afm-deliver/SKILL.md +44 -0
  197. package/plugin/agy/skills/afm-diagnose/SKILL.md +50 -0
  198. package/plugin/agy/skills/afm-evolve/SKILL.md +69 -0
  199. package/plugin/agy/skills/afm-export-template/SKILL.md +42 -0
  200. package/plugin/agy/skills/afm-generalize/SKILL.md +49 -0
  201. package/plugin/agy/skills/afm-gotcha/SKILL.md +42 -0
  202. package/plugin/agy/skills/afm-init/SKILL.md +84 -0
  203. package/plugin/agy/skills/afm-plan/SKILL.md +36 -0
  204. package/plugin/agy/skills/afm-policy/SKILL.md +31 -0
  205. package/plugin/agy/skills/afm-promote/SKILL.md +41 -0
  206. package/plugin/agy/skills/afm-protocol/SKILL.md +42 -0
  207. package/plugin/agy/skills/afm-reconcile/SKILL.md +49 -0
  208. package/plugin/agy/skills/afm-refactor/SKILL.md +86 -0
  209. package/plugin/agy/skills/afm-reflect/SKILL.md +55 -0
  210. package/plugin/agy/skills/afm-remediate/SKILL.md +41 -0
  211. package/plugin/agy/skills/afm-restructure/SKILL.md +54 -0
  212. package/plugin/agy/skills/afm-rule/SKILL.md +46 -0
  213. package/plugin/agy/skills/afm-specify/SKILL.md +36 -0
  214. package/plugin/agy/skills/afm-tasks/SKILL.md +34 -0
  215. package/plugin/agy/skills/afm-update/SKILL.md +58 -0
  216. package/plugin/agy/skills/afm-verify/SKILL.md +33 -0
  217. package/plugin/claude-code/.claude-plugin/marketplace.json +15 -0
  218. package/plugin/claude-code/.claude-plugin/plugin.json +9 -0
  219. package/plugin/claude-code/.mcp.json +7 -0
  220. package/plugin/claude-code/agents/afm-executor.md +18 -0
  221. package/plugin/claude-code/agents/afm-explorer.md +20 -0
  222. package/plugin/claude-code/agents/afm-reviewer.md +21 -0
  223. package/plugin/claude-code/hooks/hooks.json +85 -0
  224. package/plugin/claude-code/skills/adr/SKILL.md +44 -0
  225. package/plugin/claude-code/skills/analyze/SKILL.md +36 -0
  226. package/plugin/claude-code/skills/clarify/SKILL.md +36 -0
  227. package/plugin/claude-code/skills/deliver/SKILL.md +44 -0
  228. package/plugin/claude-code/skills/diagnose/SKILL.md +50 -0
  229. package/plugin/claude-code/skills/evolve/SKILL.md +69 -0
  230. package/plugin/claude-code/skills/export-template/SKILL.md +42 -0
  231. package/plugin/claude-code/skills/generalize/SKILL.md +49 -0
  232. package/plugin/claude-code/skills/gotcha/SKILL.md +42 -0
  233. package/plugin/claude-code/skills/init/SKILL.md +84 -0
  234. package/plugin/claude-code/skills/plan/SKILL.md +36 -0
  235. package/plugin/claude-code/skills/policy/SKILL.md +31 -0
  236. package/plugin/claude-code/skills/promote/SKILL.md +41 -0
  237. package/plugin/claude-code/skills/protocol/SKILL.md +42 -0
  238. package/plugin/claude-code/skills/reconcile/SKILL.md +49 -0
  239. package/plugin/claude-code/skills/refactor/SKILL.md +86 -0
  240. package/plugin/claude-code/skills/reflect/SKILL.md +55 -0
  241. package/plugin/claude-code/skills/remediate/SKILL.md +41 -0
  242. package/plugin/claude-code/skills/restructure/SKILL.md +54 -0
  243. package/plugin/claude-code/skills/rule/SKILL.md +46 -0
  244. package/plugin/claude-code/skills/specify/SKILL.md +36 -0
  245. package/plugin/claude-code/skills/tasks/SKILL.md +34 -0
  246. package/plugin/claude-code/skills/update/SKILL.md +58 -0
  247. package/plugin/claude-code/skills/verify/SKILL.md +33 -0
  248. package/plugin/opencode/afm.js +173 -0
  249. package/plugin/opencode/agents/afm-executor.md +31 -0
  250. package/plugin/opencode/agents/afm-explorer.md +47 -0
  251. package/plugin/opencode/agents/afm-reviewer.md +48 -0
  252. package/plugin/opencode/skills/afm-adr/SKILL.md +44 -0
  253. package/plugin/opencode/skills/afm-analyze/SKILL.md +36 -0
  254. package/plugin/opencode/skills/afm-clarify/SKILL.md +36 -0
  255. package/plugin/opencode/skills/afm-deliver/SKILL.md +44 -0
  256. package/plugin/opencode/skills/afm-diagnose/SKILL.md +50 -0
  257. package/plugin/opencode/skills/afm-evolve/SKILL.md +69 -0
  258. package/plugin/opencode/skills/afm-export-template/SKILL.md +42 -0
  259. package/plugin/opencode/skills/afm-generalize/SKILL.md +49 -0
  260. package/plugin/opencode/skills/afm-gotcha/SKILL.md +42 -0
  261. package/plugin/opencode/skills/afm-init/SKILL.md +84 -0
  262. package/plugin/opencode/skills/afm-plan/SKILL.md +36 -0
  263. package/plugin/opencode/skills/afm-policy/SKILL.md +31 -0
  264. package/plugin/opencode/skills/afm-promote/SKILL.md +41 -0
  265. package/plugin/opencode/skills/afm-protocol/SKILL.md +42 -0
  266. package/plugin/opencode/skills/afm-reconcile/SKILL.md +49 -0
  267. package/plugin/opencode/skills/afm-refactor/SKILL.md +86 -0
  268. package/plugin/opencode/skills/afm-reflect/SKILL.md +55 -0
  269. package/plugin/opencode/skills/afm-remediate/SKILL.md +41 -0
  270. package/plugin/opencode/skills/afm-restructure/SKILL.md +54 -0
  271. package/plugin/opencode/skills/afm-rule/SKILL.md +46 -0
  272. package/plugin/opencode/skills/afm-specify/SKILL.md +36 -0
  273. package/plugin/opencode/skills/afm-tasks/SKILL.md +34 -0
  274. package/plugin/opencode/skills/afm-update/SKILL.md +58 -0
  275. package/plugin/opencode/skills/afm-verify/SKILL.md +33 -0
  276. package/README.md +0 -3
@@ -0,0 +1,51 @@
1
+ ---
2
+ type: code-style
3
+ description: 'Proposes a path-bound grep that verifies TRPCError never appears in the domain layer, for a project that keeps domain code under a fixed path.'
4
+ load: cold
5
+ stack: trpc-v11
6
+ concern: error-boundary
7
+ detect: |
8
+ if command -v jq >/dev/null 2>&1; then jq -e '(.dependencies//{})+(.devDependencies//{})+(.peerDependencies//{})|has("@trpc/server")' package.json >/dev/null 2>&1; else grep -q '"@trpc/server"' package.json 2>/dev/null; fi
9
+ ---
10
+
11
+ # Code style — tRPC v11 error-boundary check
12
+
13
+ > The principle behind this — a transport error type must not reach the domain layer — is a
14
+ > genuine tRPC layering fact, kept in `modules/trpc-v11/rules.patch.md` as a §1.3 principle. What
15
+ > is a **proposal** here, not a fact, is the concrete mechanical check below: it is bound to one
16
+ > house layout (`{{src-path}}/server/modules/*/domain/`), and a project that lays out its domain
17
+ > code differently needs a different glob, or none at all.
18
+
19
+ ## The convention
20
+
21
+ Add a hard rule to `docs/afm.md` §3 that mechanically enforces the principle, verified by:
22
+
23
+ ```sh
24
+ grep -rn "TRPCError" {{src-path}}/server/modules/*/domain/
25
+ ```
26
+
27
+ Zero results required. `TRPCError` appearing anywhere under a project's domain path means a
28
+ transport type leaked past the procedure boundary.
29
+
30
+ ## Why this works
31
+
32
+ Review alone misses this reliably — `TRPCError` is a normal, typed import, and nothing about
33
+ using it inside a domain function raises a compiler error or a lint warning on its own; the
34
+ violation is architectural, not syntactic. A path-bound grep turns "domain must not import
35
+ TRPCError" from a principle a reviewer has to remember into a check a hook runs on every commit.
36
+
37
+ ## The trade-off
38
+
39
+ The check is only as good as the glob. A monorepo with more than one domain root, a project mid
40
+ -migration to a new folder layout, or one that does not separate "domain" into its own directory
41
+ at all gets a check that is silently vacuous (matches nothing, so it always passes) rather than
42
+ one that fails loudly. Confirm the glob actually matches existing domain files before trusting a
43
+ green result — an empty match set means either the boundary holds, or the path is wrong.
44
+
45
+ ## If the operator accepts this
46
+
47
+ Materialize the hard rule into `docs/afm.md` §3 with `{{src-path}}` resolved to the project's
48
+ actual domain-layer root (fill the placeholder at bootstrap, the way `docs/afm.md` fills every
49
+ other `{{src-path}}` site). Do not paste the grep with the placeholder left in — a rule with an
50
+ unresolved `{{src-path}}` runs against a literal, nonexistent directory and passes vacuously on
51
+ every project.
@@ -0,0 +1,44 @@
1
+ ---
2
+ type: code-style
3
+ description: 'Proposes exactly one domain function per file, with shared constants and schemas factored to a sibling file.'
4
+ load: cold
5
+ stack: trpc-v11
6
+ concern: file-size
7
+ detect: |
8
+ if command -v jq >/dev/null 2>&1; then jq -e '(.dependencies//{})+(.devDependencies//{})+(.peerDependencies//{})|has("@trpc/server")' package.json >/dev/null 2>&1; else grep -q '"@trpc/server"' package.json 2>/dev/null; fi
9
+ ---
10
+
11
+ # Code style — tRPC v11 domain file granularity
12
+
13
+ > This is a **proposal**, not a fact about tRPC. Materialize it into `docs/ach.md` only if the
14
+ > operator accepts it — item by item, at bootstrap. Nothing here is `(mandatory)`.
15
+
16
+ ## The convention
17
+
18
+ One domain function per file. Shared constants, Zod schemas, or types that more than one domain
19
+ function needs move to `<name>.ts` in the module — never added as a second export in a domain
20
+ file.
21
+
22
+ ## Why this works
23
+
24
+ A domain file's name (`<action>-<module>.ts`) then names exactly one thing, so `git blame` and
25
+ `git log --follow` on that file tell the history of one business rule, not several interleaved
26
+ ones. It also keeps a domain file's diff small and reviewable — a change to one rule cannot
27
+ accidentally touch the body of an unrelated one two exports down.
28
+
29
+ ## The trade-off
30
+
31
+ Two domain functions that are always read and changed together (a `create` and its matching
32
+ `validate`) end up in two files a reviewer has to open side by side anyway, and a module with
33
+ many small, closely related domain functions accumulates many small files, which has its own
34
+ navigation cost. A project that already caps files by line count rather than by function count
35
+ gains nothing extra from this — it addresses a different axis.
36
+
37
+ ## If the operator accepts this
38
+
39
+ Materialize it into `docs/ach.md` under the Domain-like component type. This convention has no
40
+ practical mechanical check of its own — "one function per file" is check-able only by parsing
41
+ exports per file, which the existing naming check (`code-style/trpc-v11/naming.md`) already
42
+ covers as a side effect: if every domain file matches `^export const domain_` for exactly one
43
+ export, a second export in that file (a hand-added constant, say) would itself be a naming-rule
44
+ violation with a different shape. Do not add a redundant hard rule for this alone.
@@ -0,0 +1,60 @@
1
+ ---
2
+ type: code-style
3
+ description: 'Proposes a fixed export/file naming pattern for tRPC procedures and domain functions, plus a fixed location for module subrouters.'
4
+ load: cold
5
+ stack: trpc-v11
6
+ concern: naming
7
+ detect: |
8
+ if command -v jq >/dev/null 2>&1; then jq -e '(.dependencies//{})+(.devDependencies//{})+(.peerDependencies//{})|has("@trpc/server")' package.json >/dev/null 2>&1; else grep -q '"@trpc/server"' package.json 2>/dev/null; fi
9
+ ---
10
+
11
+ # Code style — tRPC v11 naming
12
+
13
+ > This is a **proposal**, not a fact about tRPC. Materialize it into `docs/ach.md` and
14
+ > `docs/afm.md` §3 only if the operator accepts it — item by item, at bootstrap. Nothing here is
15
+ > `(mandatory)`.
16
+
17
+ ## The convention
18
+
19
+ - **Procedure export:** `procedure_<action><Module>` — camelCase, action first, plural module
20
+ after. Example: `procedure_getApps`, `procedure_createRegistries`.
21
+ - **Procedure file:** `<action>-<module>.ts` — kebab-case, same stem as the export.
22
+ - **Domain export:** `domain_<action><Module>` — same shape as the procedure, so the two read as
23
+ a matched pair.
24
+ - **Domain file:** `<action>-<module>.ts` — kebab-case, same pattern as the procedure.
25
+ - **Module subrouter:** lives at `modules/<f>/router.ts`. It imports the module's procedures and
26
+ exports a tRPC subrouter — aggregation plus namespacing, never a business rule.
27
+
28
+ Anti-examples for the procedure prefix:
29
+ - ❌ `procedure_signOut` — missing the module.
30
+ - ❌ `signOutProcedure` — suffix instead of prefix.
31
+ - ❌ `procedure_AuthSignOut` — module before the action.
32
+
33
+ ## Why this works
34
+
35
+ A fixed prefix makes `grep -rn "^export const procedure_"` a complete inventory of every
36
+ tRPC entry point, and the matching `procedure_`/`domain_` pair makes the transport-to-business
37
+ mapping readable by name alone, without opening either file. The `modules/<f>/router.ts` location
38
+ gives every module the same subrouter address, so a new contributor finds the aggregation point
39
+ without asking.
40
+
41
+ ## The trade-off
42
+
43
+ The prefix is redundant with the file's own location (`server/modules/x/procedures/get-apps.ts`
44
+ already says "this is a procedure in module x") and with the tool tip / import statement a caller
45
+ sees. A project that already has a naming scheme — feature-first folders, a different subrouter
46
+ layout, no `modules/` tier at all — gains nothing from importing this one; the value is
47
+ consistency **within** a project that adopts it, not a property of tRPC itself.
48
+
49
+ ## If the operator accepts this
50
+
51
+ - Materialize the naming rule and anti-examples into `docs/ach.md` (Procedure-like /
52
+ Domain-like sections).
53
+ - Add a hard rule to `docs/afm.md` §3, verified by:
54
+ ```sh
55
+ grep -rn "^export const procedure_" {{src-path}}/server/modules/*/procedures/*.ts
56
+ grep -rn "^export const domain_" {{src-path}}/server/modules/*/domain/*.ts
57
+ ```
58
+ Every export returned must match the pattern — an empty result on a project with procedures
59
+ means the convention was not followed, not that the check passed vacuously; confirm at least
60
+ one procedure file exists first.
@@ -0,0 +1,52 @@
1
+ ---
2
+ type: code-style
3
+ description: 'Proposes a neighbor-test layout for tRPC procedures and domains, and a single shared test-context factory.'
4
+ load: cold
5
+ stack: trpc-v11
6
+ concern: test-placement
7
+ detect: |
8
+ if command -v jq >/dev/null 2>&1; then jq -e '(.dependencies//{})+(.devDependencies//{})+(.peerDependencies//{})|has("@trpc/server")' package.json >/dev/null 2>&1; else grep -q '"@trpc/server"' package.json 2>/dev/null; fi
9
+ ---
10
+
11
+ # Code style — tRPC v11 test placement
12
+
13
+ > This is a **proposal**, not a fact about tRPC. Materialize it into `docs/ach.md` and
14
+ > `docs/afm.md` §3 only if the operator accepts it — item by item, at bootstrap. Nothing here is
15
+ > `(mandatory)`.
16
+
17
+ ## The convention
18
+
19
+ - **Neighbor test.** `<action>-<module>.test.ts` lives in the SAME directory as
20
+ `<action>-<module>.ts` — no separate `__tests__/` folder.
21
+ - **One shared context factory.** Every test that needs a `TRPCContext` (procedures) or a
22
+ `DomainContext` (domains) builds it through one helper — for example
23
+ `makeTestCtx(override?)`, returning a fresh, deep-copied ctx — instead of constructing the
24
+ context object by hand in each test file.
25
+
26
+ ## Why this works
27
+
28
+ A neighbor test is found by the same file-explorer sort that finds the source file, and a
29
+ directory listing shows source and test side by side, which makes an untested file visible at a
30
+ glance. A single context factory means a `TRPCContext` field added once is available to every
31
+ test through one function, instead of a hand-rolled object per test file quietly drifting from
32
+ the real shape.
33
+
34
+ ## The trade-off
35
+
36
+ `__tests__/` (or a top-level `test/` mirror) is itself a legitimate, widely used layout — it
37
+ keeps a directory listing free of test files for someone scanning source only, and some test
38
+ runners default to it. A hand-built context per test can also be the right call for a test that
39
+ deliberately exercises a malformed or partial context — forcing every test through one factory
40
+ can hide that case behind an `override` parameter nobody reads closely. Pick the layout that
41
+ matches how the team already scans the codebase; do not adopt this because it is here.
42
+
43
+ ## If the operator accepts this
44
+
45
+ - Materialize the neighbor-test convention into `docs/ach.md` (Procedure-like / Domain-like).
46
+ - If a shared context factory is adopted, name and locate it explicitly in `docs/ach.md`
47
+ (project-specific — do not copy a path from another repo).
48
+ - Add a hard rule to `docs/afm.md` §3, verified by:
49
+ ```sh
50
+ find {{src-path}}/server -name "__tests__" -type d
51
+ ```
52
+ Zero results required.
@@ -0,0 +1,265 @@
1
+ ---
2
+ type: core
3
+ description: 'The architecture guide: the component types and where each one lives.'
4
+ load: warm
5
+ materializes_to: 'docs/ach.md'
6
+ ---
7
+
8
+ # ACH — Architecture Guide
9
+
10
+ > Live architecture guide for {{nome do projeto}}.
11
+ > **Author:** owner of the architecture. Changes go through review before merge.
12
+ >
13
+ > This document answers: "Where do I put this logic?", "How do I structure this new module?", "How much testing does this change need?".
14
+ >
15
+ > **Related docs:** [`/docs/afm.md`](./afm.md) (process + hard rules), [`/docs/gotchas/`](./gotchas/) (counterintuitive surprises), [`/docs/adr/`](./adr/) (versioned decisions).
16
+
17
+ > **In this file:** 1. Macro Architecture · 2. Folder Architecture · 3. Components · 4. Test Strategy · 5. Cross-cutting Principles · 6. Code Conventions
18
+
19
+
20
+ ---
21
+
22
+ ## 1. Macro Architecture
23
+
24
+ ```
25
+ {{Diagrama ASCII das camadas. Fluxo principal. Dataflow de artefatos entre serviços externos.
26
+
27
+ Convenção: setas unidirecionais (→ camada chama camada). Boxes pra serviços externos. Texto curto identificando o tech (ex: "Postgres", "Redis", "S3-compatible").}}
28
+ ```
29
+
30
+ **Canonical entities:**
31
+ - **{{Entidade A}}** — {{descrição em 1 linha}}.
32
+ - **{{Entidade B}}** — {{descrição em 1 linha}}.
33
+
34
+ **Dataflow:**
35
+ - **{{Storage primário}}** — source of truth for {{X}}.
36
+ - **{{Storage secundário}}** — source of truth for {{Y}}.
37
+
38
+ ---
39
+
40
+ ## 2. Folder Architecture
41
+
42
+ ```
43
+ {{árvore de pastas comentada — uma linha por pasta importante explicando o que vive ali}}
44
+ ```
45
+
46
+ ### Import rules
47
+
48
+ ```
49
+ {{layer X}} → can import: {{lista}}
50
+ NEVER imports: {{lista}}
51
+
52
+ {{layer Y}} → can import: {{lista}}
53
+ does NOT import directly, receives via parameter: {{lista}}
54
+ ```
55
+
56
+ **Promotion to `domain/shared/`:** a function/value object in `modules/<X>/domain/` moves to `{{src-path}}/domain/shared/` when used by **3+ modules** (Rule of Three).
57
+
58
+ ---
59
+
60
+ ### Boundary exit
61
+
62
+ A boundary holds from the first need: a primitive needed on the forbidden side moves to the lowest layer both sides may import, never copied and never injected. The Rule of Three decides when a domain value becomes shared; it never decides whether a boundary may be crossed.
63
+
64
+ ## 3. Components
65
+
66
+ ### 3.1 First-class components
67
+
68
+ This section defines the **project vocabulary**. It maps universal component types to concrete tools in the chosen stack. The interview (`afm path interview/bootstrap.md`) fills this in.
69
+
70
+ #### Procedure-like — handler sync request/response
71
+
72
+ - **Universal concept:** handler for a short synchronous operation (< ~5s). Input is validated, auth is checked, and the return is typed for the frontend.
73
+ - **Stack implementation:** {{ex: tRPC procedure / Express route handler / Nest Controller / FastAPI endpoint}}.
74
+ - **Single responsibility:** orchestrate — validate → authorize → call domain/lib → persist → respond.
75
+ - **When to use:** every synchronous UI ↔ server interaction.
76
+ - **When NOT to use:**
77
+ - Heavy logic → delegate to Domain-like.
78
+ - Long-running, retryable, or scheduled work → delegate to Task-like.
79
+ - **Naming convention:** {{ex: `procedure_<action><Module>` + arquivo `<action>-<module>.ts`}}.
80
+ - **Canonical example:** {{path real do projeto}}.
81
+ - **Anti-examples (do not do this):**
82
+ - ❌ {{exemplo de naming errado com porquê}}.
83
+ - ❌ {{exemplo de pasta errada com porquê}}.
84
+
85
+ #### Domain-like — pure business rule function
86
+
87
+ - **Universal concept:** a pure function that applies a business rule. No un-abstracted I/O. No undeclared side effects. Testable without infra.
88
+ - **Stack implementation:** {{ex: função TS exportada com prefixo `domain_` / Use Case do DDD / função Python pura}}.
89
+ - **Canonical contract:** {{ex: `({ ctx, input }: DomainInput<T>) => Result<T, DomainErrorCode>`}}.
90
+ - **ONE domain function per file. No exceptions.** Shared constants and types go into `<nome>.{{ext}}` in the module. Never add them as a second export in the domain file.
91
+ - **When to use:**
92
+ - Logic that survives a transport change (HTTP today, CLI tomorrow).
93
+ - A rule you can test without a real DB.
94
+ - **When NOT to use — Domain is NOT:**
95
+ - ❌ **A data-access helper.** Building a query, mapping to a DTO, or forming a JOIN is infra or procedure work.
96
+ - ❌ **Transport glue.** HTTP headers, webhook parsers — those live in lib or procedure.
97
+ - ❌ **Orchestration between modules.** That is procedure or task responsibility.
98
+ - ❌ **Un-abstracted I/O** (fetch, spawn, direct S3 calls).
99
+ - ❌ **A file with only types or constants.** Move it out of `domain/` into `*.types.{{ext}}`.
100
+ - ❌ **Importing a transport error type** (hard rule 15).
101
+ - **Anti-examples (do not do this):**
102
+ - ❌ {{exemplo `domain_xWhereClause` retornando query parcial}}.
103
+ - ❌ {{exemplo arquivo com 2 `domain_*` exports}}.
104
+
105
+ #### Shared Domain — rule used by 3+ modules
106
+
107
+ - **Universal concept:** value objects, rules, and types shared across multiple modules.
108
+ - **When to use:** on the third confirmed duplicate across modules — promote it (Rule of Three).
109
+ - **When NOT to use:** on the first or second occurrence — keep it in `modules/<X>/domain/`.
110
+
111
+ #### Task-like — retry-safe async unit of work
112
+
113
+ - **Universal concept:** async work that can retry without corrupting state. It reads canonical state from the DB, early-returns on terminal states, updates atomically, and triggers the next task when needed.
114
+ - **Stack implementation:** {{ex: Trigger.dev v4 task / BullMQ Job / Celery task / AWS Step Function}}.
115
+ - **When to use:**
116
+ - Cron or scheduled jobs.
117
+ - Long workflows with retry (build, publish).
118
+ - External integrations with variable latency.
119
+ - **When NOT to use:**
120
+ - It fits in < 5s with no retry → use procedure.
121
+ - It is pure logic with no I/O → use domain.
122
+
123
+ ##### Orchestration pattern: thin parent calls subtasks
124
+
125
+ A multi-stage workflow = a thin parent that coordinates, plus subtasks that do the work. Each subtask has its own retry, its own log, and its own sizing. The parent only calls `triggerAndWait`.
126
+
127
+ #### Lib-like — isolated, publishable package
128
+
129
+ - **Universal concept:** a self-contained package with no dependency on the app runtime (no ORM, no web framework, no orchestrator). It must be safe to `publish`.
130
+ - **Stack implementation:** {{ex: a folder under `{{src-path}}/lib/` with an `index.ts` and zero framework imports}}.
131
+ - **Responsibility:** a self-contained feature.
132
+ - **When to use:** any of these:
133
+ - The same helper already has 3 callers.
134
+ - It wraps a nameable external integration (Stripe, S3, etc.).
135
+ - It holds > ~150 lines of coupled pure logic.
136
+ - **When NOT to use — a Lib is NOT:**
137
+ - ❌ **A lib that imports an ORM type.** Accept a minimal structural shape instead.
138
+ - ❌ **A lib with an implicit singleton** (a module-level variable caching a client). Export a factory instead.
139
+ - ❌ **A lib with a God object** (a class or object with 8+ methods). Use named functions instead.
140
+ - ❌ **A lib that logs on its own.** Receive `log` by DI, or return a `Result`.
141
+ - ❌ **A lib that defines errors with no literal discriminant** (`code: "..." as const`).
142
+ - ❌ **A lib with 1 caller.** YAGNI.
143
+ - ❌ **A lib with a huge options bag** (≥ 6 optional fields).
144
+ - ❌ **A lib that imports from a layer above it.** Layer order follows this project's Import rules in § 2. It is not a hardcoded example.
145
+
146
+ #### Adapter-like — implementation of a typed port
147
+
148
+ - **Universal concept:** a concrete implementation of a port (a typed interface). Examples: a registry adapter (NPM/GitHub/Custom), a storage adapter (S3/R2/MinIO), an email adapter (Resend/SES).
149
+ - **LSP in action:** every implementation of the same port returns the same classified result shape (e.g., `PUBLISHED|CONFLICT|FAILED`). Adapter A cannot return `null` on conflict while adapter B throws an exception.
150
+ - **OCP in action:** adding a new provider means a new file that implements the port, **with no** `switch (provider)` scattered around.
151
+
152
+ ### 3.2 Supporting components (second class)
153
+
154
+ #### Module router — aggregation inside the module namespace
155
+
156
+ {{Implementação no stack — ex: `modules/<f>/router.ts` que junta procedures num subrouter tRPC}}.
157
+
158
+ #### Infra — cross-cutting utilities
159
+
160
+ Singleton clients, rate-limit wrappers, email senders, and test context factories. **Contains no business rules.**
161
+
162
+ #### UI primitives
163
+
164
+ Presentation components. No direct fetch — data comes via {{cliente do stack — ex: tRPC + React Query}}.
165
+
166
+ ---
167
+
168
+ ## 4. Test Strategy
169
+
170
+ ### 4.1 Levels (classic pyramid + strong XP)
171
+
172
+ | Level | What it tests | Where it lives | Target ratio |
173
+ | ----- | ----------- | --------- | -------------- |
174
+ | **Unit** | Pure logic, domain, pure libs | {{paths}} | ~70% |
175
+ | **Integration** | Contracts between layers with real I/O | {{paths}} | ~25% |
176
+ | **E2E** | End-to-end user flow | {{paths}} | ~5% |
177
+
178
+ ### 4.2 Strict TDD + types-as-test
179
+
180
+ ```
181
+ 1. RED — write a test (or a type signature) that fails for the right reason
182
+ 2. GREEN — minimal implementation that passes
183
+ 3. REFACTOR — remove duplication, improve names, type-check + tests
184
+ ```
185
+
186
+ `tsc --noEmit` is part of the red/green loop, just like the tests.
187
+
188
+ ### 4.3 Regression
189
+
190
+ **Bug found → write a reproducing test BEFORE the fix.** No exceptions. Production hotfix: add the test in the same PR.
191
+
192
+ ### 4.4 Types as tests
193
+
194
+ `unknown` or `any` in a helper you own is a missing type test. Fix the inference.
195
+
196
+ ### 4.5 Target coverage by layer
197
+
198
+ {{Tabela: por camada/pasta, qual cobertura mínima e se é policiada por CI ou só guideline.}}
199
+
200
+ **No global threshold in CI** — the metric is easy to game. Confidence comes from the reviewer plus AFM, not from a number.
201
+
202
+ ---
203
+
204
+ ## 5. Cross-cutting Principles
205
+
206
+ - **XP + Pragmatic** — DRY, YAGNI, KISS, Broken Windows, Design by Contract, Rubber Duck. Daily practices in [`/docs/afm.md`](./afm.md).
207
+ - **Task idempotency** — every task is retry-safe. Canonical state lives in the DB. Early return on terminal states is the rule.
208
+ - **{{Storage primário}} = source of truth for {{X}}. {{Storage secundário}} = source of truth for {{Y}}.** Resolve any divergence by always reading from the authoritative source per type.
209
+ - **Types instead of comments.** The name and type carry the *what*. Use a comment only to explain a surprising *why*.
210
+ - **Observability by design.** Every async operation leaves a traceable trail (run id, correlation id, etc.).
211
+ - **Auditable schema — state with a lifecycle gets its own model.**
212
+ - State with a cycle (start → update → end) is NOT a scalar field on the owner.
213
+ - Use a separate model with one row per instance instead.
214
+ - Rule of thumb: if X is recreated, do you want its history?
215
+ - If yes, add a model with an FK to the owner.
216
+ - Lifelong 1:1 external identifiers can stay as a plain field.
217
+
218
+ {{Adicione princípios transversais específicos do projeto.}}
219
+
220
+ ---
221
+
222
+ ## 6. Code Conventions (cheat sheet)
223
+
224
+ ### Decision rubrics
225
+
226
+ Check the rubrics in [`rubrics/`](rubrics/) **before** you choose:
227
+
228
+ - [`when-to-create-lib.md`](rubrics/when-to-create-lib.md) — triggers for creating `{{src-path}}/lib/<x>/`.
229
+ - [`when-to-create-module.md`](rubrics/when-to-create-module.md) — triggers for creating a top-level module.
230
+ - [`when-to-create-dsl.md`](rubrics/when-to-create-dsl.md) — DSL-first: when primitive boilerplate scales (≥3 repeated sequences, wiring dominates, and a grammar exists), suggest a DSL. Rule 11: do not build it yourself.
231
+ - [`enum-vs-union-vs-branded.md`](rubrics/enum-vs-union-vs-branded.md) — which type to use for an enumerable value.
232
+ - [`error-classification.md`](rubrics/error-classification.md) — Domain vs Procedure vs Infra.
233
+ - [`failure-classification.md`](rubrics/failure-classification.md) — a failure recognized by an external signal (CRITIC) → procedure (mechanical) | learning (conceptual) | nothing (transient). Used by the CRITIC loop (`remediate`).
234
+ - [`episodic-vs-semantic-boundary.md`](rubrics/episodic-vs-semantic-boundary.md) — what decays (episodic: session handoffs, `_focus.md`) vs. what is permanent (semantic: rules/decisions/gotchas). Defines what belongs in the diagnose axes.
235
+ - [`negative-filters.md`](rubrics/negative-filters.md) — what NOT to promote to durable docs (a negative tool claim, transient failure, one-off narrative, or status update). The rejection checklist for the `gotcha`/`reconcile`/`remediate` gate. A false constraint is poison (#5).
236
+ - [`solid-triggers.md`](rubrics/solid-triggers.md) — OCP/LSP/ISP/DIP with a concrete trigger.
237
+ - [`validation-boundary.md`](rubrics/validation-boundary.md) — where the Zod parser (or equivalent) fits in.
238
+ - [`when-to-evolve-methodology.md`](rubrics/when-to-evolve-methodology.md) — when to run an `afm evolve` cycle (health of this project's whole local doc set) vs. a one-off fix (`afm gotcha`/`afm rule`/`afm adr` via reconcile).
239
+ - [`template-vs-streaming-precedence.md`](rubrics/template-vs-streaming-precedence.md) — when a frozen template (`export-template`) and streaming learning (`reconcile`) collide: precedence plus tombstone, never additive (AWM non-additivity).
240
+
241
+ ### Naming (fill in during the interview)
242
+
243
+ | Layer | Export pattern | File pattern |
244
+ | ----- | ---- | ---- |
245
+ | Procedure-like | {{ex: `procedure_<action><Module>`}} | {{ex: `<action>-<module>.ts`}} |
246
+ | Domain-like | {{ex: `domain_<action><Module>`}} | {{ex: `<action>-<module>.ts`}} |
247
+ | External lib | {{ex: `<libname>_<action>`}} | {{ex: `<action>.ts`}} |
248
+ | Test file | {{ex: same name + `.test.{{ext}}`}} | {{ex: same directory, no `__tests__/`}} |
249
+
250
+ ### Size and responsibility
251
+
252
+ - ≤ 300 lines per file.
253
+ - One responsibility per file.
254
+ - Shared types → `*.types.{{ext}}` next to the file.
255
+ - Constants → `*.constants.{{ext}}` next to the file.
256
+
257
+ ### Types: explicit at boundaries, inferred elsewhere
258
+
259
+ - **Explicit:** return types of exported functions, public parameters, ctx/input of procedures and domain functions, props of exported components.
260
+ - **Inferred:** local variables, closure return values, `.map` output, chained calls.
261
+ - **Never `any` / `unknown` in a helper you own.**
262
+
263
+ ---
264
+
265
+ *Changes here follow hard rule 11: an architectural change stops and asks. The surface is `afm approve` for a plan, or `afm ask <op>` for a question, whichever the situation calls for.*