@deftai/directive-content 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/.agents/skills/deft/SKILL.md +6 -0
  2. package/.agents/skills/deft-directive-article-review/SKILL.md +11 -0
  3. package/.agents/skills/deft-directive-build/SKILL.md +10 -0
  4. package/.agents/skills/deft-directive-cost/SKILL.md +12 -0
  5. package/.agents/skills/deft-directive-debug/SKILL.md +13 -0
  6. package/.agents/skills/deft-directive-gh-arch/SKILL.md +11 -0
  7. package/.agents/skills/deft-directive-gh-slice/SKILL.md +10 -0
  8. package/.agents/skills/deft-directive-glossary/SKILL.md +10 -0
  9. package/.agents/skills/deft-directive-interview/SKILL.md +9 -0
  10. package/.agents/skills/deft-directive-pre-pr/SKILL.md +9 -0
  11. package/.agents/skills/deft-directive-refinement/SKILL.md +10 -0
  12. package/.agents/skills/deft-directive-release/SKILL.md +12 -0
  13. package/.agents/skills/deft-directive-review-cycle/SKILL.md +10 -0
  14. package/.agents/skills/deft-directive-setup/SKILL.md +10 -0
  15. package/.agents/skills/deft-directive-swarm/SKILL.md +10 -0
  16. package/.agents/skills/deft-directive-sync/SKILL.md +9 -0
  17. package/.agents/skills/deft-directive-triage/SKILL.md +9 -0
  18. package/.agents/skills/deft-directive-write-skill/SKILL.md +9 -0
  19. package/LICENSE.md +22 -0
  20. package/QUICK-START.md +167 -0
  21. package/UPGRADING.md +517 -0
  22. package/coding/build-output.md +28 -0
  23. package/coding/coding.md +235 -0
  24. package/coding/debugging.md +110 -0
  25. package/coding/holzmann.md +96 -0
  26. package/coding/hygiene.md +127 -0
  27. package/coding/security.md +158 -0
  28. package/coding/testing.md +162 -0
  29. package/coding/toolchain.md +44 -0
  30. package/commands.md +300 -0
  31. package/context/context.md +57 -0
  32. package/context/deterministic-split.md +67 -0
  33. package/context/examples.md +26 -0
  34. package/context/fractal-summaries.md +69 -0
  35. package/context/long-horizon.md +46 -0
  36. package/context/spec-deltas.md +177 -0
  37. package/context/tool-design.md +34 -0
  38. package/context/working-memory.md +62 -0
  39. package/contracts/boundary-maps.md +65 -0
  40. package/contracts/deterministic-questions.md +59 -0
  41. package/contracts/hierarchy.md +77 -0
  42. package/conventions/content-manifest.json +399 -0
  43. package/conventions/machine-generated-banner.md +130 -0
  44. package/conventions/references.md +120 -0
  45. package/conventions/rule-ownership.json +382 -0
  46. package/conventions/task-caching.md +43 -0
  47. package/conventions/vbrief-filenames.md +70 -0
  48. package/deployments/README.md +37 -0
  49. package/deployments/agentuity/README.md +138 -0
  50. package/deployments/agentuity/via-cli.md +380 -0
  51. package/deployments/agentuity/via-cloud.md +425 -0
  52. package/deployments/agentuity/via-github-actions.md +664 -0
  53. package/deployments/agentuity/via-gravity-network.md +606 -0
  54. package/deployments/agentuity/via-vpc.md +607 -0
  55. package/deployments/aws/README.md +38 -0
  56. package/deployments/aws/via-app-runner.md +612 -0
  57. package/deployments/aws/via-ecs-fargate.md +561 -0
  58. package/deployments/aws/via-elastic-beanstalk.md +628 -0
  59. package/deployments/aws/via-lambda.md +649 -0
  60. package/deployments/azure/README.md +37 -0
  61. package/deployments/azure/via-aks.md +390 -0
  62. package/deployments/azure/via-app-service.md +564 -0
  63. package/deployments/azure/via-container-apps.md +599 -0
  64. package/deployments/azure/via-functions.md +552 -0
  65. package/deployments/cloud-gov/README.md +63 -0
  66. package/deployments/cloud-gov/agents/compliance-docs.md +154 -0
  67. package/deployments/cloud-gov/agents.md +39 -0
  68. package/deployments/cloud-gov/cicd.md +64 -0
  69. package/deployments/cloud-gov/deployment.md +150 -0
  70. package/deployments/cloud-gov/logging.md +43 -0
  71. package/deployments/cloud-gov/manifest.md +121 -0
  72. package/deployments/cloud-gov/overview.md +58 -0
  73. package/deployments/cloud-gov/security.md +46 -0
  74. package/deployments/cloud-gov/services.md +72 -0
  75. package/deployments/cloud-gov/upstream/README.md +18 -0
  76. package/deployments/cloudflare/README.md +33 -0
  77. package/deployments/cloudflare/via-dashboard.md +83 -0
  78. package/deployments/cloudflare/via-git.md +90 -0
  79. package/deployments/cloudflare/via-github-actions.md +185 -0
  80. package/deployments/cloudflare/via-terraform.md +157 -0
  81. package/deployments/cloudflare/via-wrangler.md +165 -0
  82. package/deployments/fly-io/README.md +37 -0
  83. package/deployments/fly-io/via-dockerfile.md +648 -0
  84. package/deployments/fly-io/via-flyctl.md +653 -0
  85. package/deployments/fly-io/via-github-actions.md +695 -0
  86. package/deployments/fly-io/via-multi-region.md +598 -0
  87. package/deployments/google/README.md +34 -0
  88. package/deployments/google/via-app-engine.md +42 -0
  89. package/deployments/google/via-cloud-functions.md +23 -0
  90. package/deployments/google/via-cloud-run.md +330 -0
  91. package/deployments/google/via-gke.md +23 -0
  92. package/deployments/netlify/README.md +99 -0
  93. package/deployments/netlify/via-cli.md +17 -0
  94. package/deployments/netlify/via-functions.md +19 -0
  95. package/deployments/netlify/via-git.md +25 -0
  96. package/deployments/vercel/README.md +90 -0
  97. package/deployments/vercel/via-api.md +16 -0
  98. package/deployments/vercel/via-cli.md +17 -0
  99. package/deployments/vercel/via-git.md +24 -0
  100. package/docs/BROWNFIELD.md +179 -0
  101. package/docs/getting-started.md +137 -0
  102. package/docs/good-agents-md.md +137 -0
  103. package/events/README.md +89 -0
  104. package/events/event-record.schema.json +26 -0
  105. package/events/registry.json +166 -0
  106. package/events/registry.schema.json +71 -0
  107. package/glossary.md +145 -0
  108. package/incidents/README.md +81 -0
  109. package/incidents/_template.md +38 -0
  110. package/interfaces/cli.md +104 -0
  111. package/interfaces/rest.md +212 -0
  112. package/interfaces/tui.md +242 -0
  113. package/interfaces/web.md +123 -0
  114. package/languages/6502-DASM.md +132 -0
  115. package/languages/c.md +235 -0
  116. package/languages/commands.md +23 -0
  117. package/languages/cpp.md +132 -0
  118. package/languages/csharp.md +259 -0
  119. package/languages/dart.md +183 -0
  120. package/languages/delphi.md +218 -0
  121. package/languages/elixir.md +208 -0
  122. package/languages/go.md +78 -0
  123. package/languages/java.md +278 -0
  124. package/languages/javascript.md +163 -0
  125. package/languages/julia.md +175 -0
  126. package/languages/kotlin.md +193 -0
  127. package/languages/markdown.md +168 -0
  128. package/languages/mermaid.md +146 -0
  129. package/languages/officejs.md +392 -0
  130. package/languages/python.md +209 -0
  131. package/languages/r.md +163 -0
  132. package/languages/rust.md +216 -0
  133. package/languages/sql.md +216 -0
  134. package/languages/swift.md +153 -0
  135. package/languages/typescript.md +132 -0
  136. package/languages/vba.md +279 -0
  137. package/languages/vhdl.md +180 -0
  138. package/languages/visual-basic.md +151 -0
  139. package/languages/zig.md +196 -0
  140. package/meta/SOUL.md +27 -0
  141. package/meta/code-field.md +44 -0
  142. package/meta/morals.md +40 -0
  143. package/meta/philosophy.md +39 -0
  144. package/meta/project.md +49 -0
  145. package/meta/ralph.md +223 -0
  146. package/meta/security.md +80 -0
  147. package/meta/versioning.md +326 -0
  148. package/package.json +22 -0
  149. package/packs/lessons/lessons-pack-0.1.json +553 -0
  150. package/packs/patterns/patterns-pack-0.1.json +57 -0
  151. package/packs/rules/rules-pack-0.1.json +4767 -0
  152. package/packs/skills/skills-pack-0.1.json +262 -0
  153. package/packs/strategies/strategies-pack-0.1.json +167 -0
  154. package/packs/swarm-spec/swarm-spec-pack-0.1.json +17 -0
  155. package/patterns/executor-layer-credentials.md +227 -0
  156. package/patterns/llm-app.md +156 -0
  157. package/patterns/multi-agent.md +278 -0
  158. package/patterns/prompt-assembly-layer-ordering.md +154 -0
  159. package/patterns/role-as-overlay.md +179 -0
  160. package/platforms/2600.md +137 -0
  161. package/platforms/unity.md +329 -0
  162. package/references/composer-skill-porting.md +152 -0
  163. package/references/cost-models.md +163 -0
  164. package/references/ip-risk.md +246 -0
  165. package/references/plain-english-ux.md +275 -0
  166. package/resilience/context-pruning.md +67 -0
  167. package/resilience/continue-here.md +62 -0
  168. package/scm/changelog.md +276 -0
  169. package/scm/git.md +139 -0
  170. package/scm/github.md +265 -0
  171. package/secrets/.gitkeep +0 -0
  172. package/skills/deft-build/SKILL.md +20 -0
  173. package/skills/deft-directive-article-review/SKILL.md +156 -0
  174. package/skills/deft-directive-build/SKILL.md +302 -0
  175. package/skills/deft-directive-cost/SKILL.md +201 -0
  176. package/skills/deft-directive-debug/SKILL.md +140 -0
  177. package/skills/deft-directive-decompose/SKILL.md +96 -0
  178. package/skills/deft-directive-gh-arch/SKILL.md +160 -0
  179. package/skills/deft-directive-gh-slice/SKILL.md +199 -0
  180. package/skills/deft-directive-glossary/SKILL.md +118 -0
  181. package/skills/deft-directive-interview/SKILL.md +528 -0
  182. package/skills/deft-directive-pre-pr/SKILL.md +131 -0
  183. package/skills/deft-directive-probe/SKILL.md +127 -0
  184. package/skills/deft-directive-refinement/SKILL.md +403 -0
  185. package/skills/deft-directive-release/SKILL.md +266 -0
  186. package/skills/deft-directive-review-cycle/SKILL.md +401 -0
  187. package/skills/deft-directive-setup/SKILL.md +717 -0
  188. package/skills/deft-directive-swarm/SKILL.md +989 -0
  189. package/skills/deft-directive-sync/SKILL.md +288 -0
  190. package/skills/deft-directive-triage/SKILL.md +137 -0
  191. package/skills/deft-directive-write-skill/SKILL.md +169 -0
  192. package/skills/deft-interview/SKILL.md +16 -0
  193. package/skills/deft-pre-pr/SKILL.md +16 -0
  194. package/skills/deft-review-cycle/SKILL.md +16 -0
  195. package/skills/deft-roadmap-refresh/SKILL.md +16 -0
  196. package/skills/deft-setup/SKILL.md +20 -0
  197. package/skills/deft-swarm/SKILL.md +16 -0
  198. package/skills/deft-sync/SKILL.md +16 -0
  199. package/strategies/README.md +83 -0
  200. package/strategies/artifact-guards.md +85 -0
  201. package/strategies/bdd.md +115 -0
  202. package/strategies/brownfield.md +7 -0
  203. package/strategies/discuss.md +129 -0
  204. package/strategies/emit-hints.md +69 -0
  205. package/strategies/enterprise.md +193 -0
  206. package/strategies/interview.md +551 -0
  207. package/strategies/map.md +179 -0
  208. package/strategies/probe.md +151 -0
  209. package/strategies/rapid.md +155 -0
  210. package/strategies/research.md +155 -0
  211. package/strategies/roadmap.md +9 -0
  212. package/strategies/speckit.md +437 -0
  213. package/strategies/v0-20-contract.md +134 -0
  214. package/strategies/yolo.md +169 -0
  215. package/swarm/swarm.md +300 -0
  216. package/templates/COST-ESTIMATE.md +114 -0
  217. package/templates/PULL_REQUEST_TEMPLATE.md +35 -0
  218. package/templates/agent-prompt-preamble.md +409 -0
  219. package/templates/agents-entry.md +211 -0
  220. package/templates/agents-entry.placeholders.md +75 -0
  221. package/templates/embed.go +20 -0
  222. package/templates/embed_test.go +36 -0
  223. package/templates/make-spec-example.md +9 -0
  224. package/templates/make-spec.md +246 -0
  225. package/templates/project.md.template +52 -0
  226. package/templates/specification.md +1 -0
  227. package/templates/swarm-greptile-poller-prompt.md +556 -0
  228. package/templates/user.md.template +31 -0
  229. package/tools/RWLDL.md +80 -0
  230. package/tools/greptile.md +141 -0
  231. package/tools/installer.md +23 -0
  232. package/tools/taskfile-migration.md +32 -0
  233. package/tools/taskfile.md +185 -0
  234. package/tools/telemetry.md +285 -0
  235. package/vbrief/schemas/cache-meta.schema.json +137 -0
  236. package/vbrief/schemas/candidates.schema.json +130 -0
  237. package/vbrief/schemas/codebase-map.schema.json +213 -0
  238. package/vbrief/schemas/lessons-pack.schema.json +134 -0
  239. package/vbrief/schemas/patterns-pack.schema.json +84 -0
  240. package/vbrief/schemas/rules-pack.schema.json +105 -0
  241. package/vbrief/schemas/skills-pack.schema.json +94 -0
  242. package/vbrief/schemas/slices.schema.json +87 -0
  243. package/vbrief/schemas/strategies-pack.schema.json +89 -0
  244. package/vbrief/schemas/swarm-spec-pack.schema.json +84 -0
  245. package/vbrief/schemas/vbrief-core.schema.json +1022 -0
  246. package/vbrief/vbrief.md +684 -0
  247. package/verification/integration.md +76 -0
  248. package/verification/plan-checking.md +85 -0
  249. package/verification/uat.md +60 -0
  250. package/verification/verification.md +117 -0
@@ -0,0 +1,208 @@
1
+ # Elixir Standards
2
+
3
+ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
4
+
5
+ **⚠️ See also**: [main.md](../../main.md) | [PROJECT.md](../../PROJECT.md)
6
+
7
+ **Stack**: Elixir 1.16+ / OTP 26+; Build: Mix; Testing: ExUnit; Lint: Credo; Format: `mix format`; Docs: ExDoc; Types: Dialyxir
8
+
9
+ ## Standards
10
+
11
+ ### Documentation
12
+ - ! `@doc` and `@moduledoc` on all public modules and functions
13
+ - ! `@spec` typespecs on all public functions
14
+ - ! Include `## Examples` with `iex>` doctest blocks for public API
15
+ - ~ Use `@doc false` to explicitly hide internal public functions
16
+ - ~ Cross-reference with `{:link, module}` or backtick syntax
17
+
18
+ ### Testing
19
+ See [testing.md](../coding/testing.md).
20
+
21
+ - ! Use ExUnit (`test`, `describe`, `assert`, `refute`)
22
+ - ! Place tests in `test/` mirroring `lib/` structure; files: `*_test.exs`
23
+ - ! Test happy paths, error cases, and edge cases
24
+ - ~ Use doctests (`doctest Module`) for example-based testing
25
+ - ~ Use `Mox` for mocking via behaviours (not concrete implementations)
26
+ - ~ Use property-based testing via `StreamData`
27
+
28
+ ### Coverage
29
+ - ! ≥80% coverage (measured via `mix test --cover` or excoveralls)
30
+ - ! Count lib/**
31
+ - ! Exclude generated code, migrations, Phoenix boilerplate
32
+
33
+ ### Style
34
+ - ! Run `mix format` on all code (project `.formatter.exs` checked in)
35
+ - ! Use Credo for static analysis (`mix credo --strict`)
36
+ - ! 2-space indentation
37
+ - ! Line length ≤98 characters (Elixir formatter default)
38
+ - ! Follow [Elixir Style Guide](https://github.com/christopheradams/elixir_style_guide)
39
+
40
+ ### Naming Conventions
41
+ - ! `snake_case` for functions, variables, atoms, and file names
42
+ - ! `PascalCase` (CamelCase) for module names: `MyApp.UserService`
43
+ - ! `snake_case` for module file paths matching module name: `my_app/user_service.ex`
44
+ - ! Predicate functions end with `?`: `valid?`, `empty?`, `admin?`
45
+ - ! Dangerous/raising functions end with `!`: `fetch!`, `decode!`
46
+ - ! `SCREAMING_SNAKE_CASE` for module attributes used as constants (convention, not enforced)
47
+ - ⊗ Atoms with spaces or special characters unless protocol requires it
48
+
49
+ ### Pattern Matching
50
+ - ! Use pattern matching for control flow (function heads, `case`, `with`)
51
+ - ! Prefer multi-clause functions over `if`/`cond` for type/shape dispatch
52
+ - ! Use `with` for chaining fallible operations with clear pattern matching
53
+ - ! Destructure in function arguments when possible
54
+ - ⊗ Nested `case` statements >2 levels deep — refactor into functions
55
+ - ≉ `if`/`else` when pattern matching is clearer
56
+
57
+ ### Data & Immutability
58
+ - ! All data is immutable — embrace transformation pipelines
59
+ - ! Use structs (`%MyStruct{}`) for domain entities with enforced keys
60
+ - ! Use `@enforce_keys` for required struct fields
61
+ - ! Use maps for unstructured/dynamic data; keyword lists for options
62
+ - ~ Use Ecto embedded schemas for validated data structures
63
+ - ⊗ Atoms from user input (`String.to_atom/1`) — atom table is not garbage collected
64
+
65
+ ### Pipe Operator
66
+ - ! Use `|>` for data transformation chains (≥2 steps)
67
+ - ! First argument flows through the pipe; design functions pipe-friendly
68
+ - ! One transformation per line in pipe chains
69
+ - ≉ Pipe chains >10 steps — extract named intermediate functions
70
+ - ≉ Pipes with anonymous functions — extract to named functions
71
+
72
+ ### OTP & Concurrency
73
+ - ! Use OTP behaviours: `GenServer`, `Supervisor`, `Agent`, `Task`
74
+ - ! Supervision trees for all long-running processes
75
+ - ! Use `Task.async` / `Task.await` for concurrent one-off work
76
+ - ! Trap exits explicitly when needed; document why
77
+ - ! Design processes for "let it crash" — supervisors restart
78
+ - ⊗ Spawning bare processes without supervision in production
79
+ - ⊗ Shared mutable state outside of OTP processes
80
+ - ~ Use `Registry` for dynamic process naming
81
+ - ~ Use `GenStage` / `Broadway` for back-pressure and data pipelines
82
+
83
+ ### Error Handling
84
+ - ! Use `{:ok, value}` / `{:error, reason}` tuples for expected failures
85
+ - ! Use `!` function variants that raise for unexpected/unrecoverable errors
86
+ - ! Use `with` for composing multiple `{:ok, _}` / `{:error, _}` chains
87
+ - ! Let processes crash on unexpected errors; supervisors handle recovery
88
+ - ⊗ Catching broad exceptions (`rescue Exception`) in normal flow
89
+ - ⊗ Returning bare `:error` without a reason
90
+
91
+ ### Behaviours & Protocols
92
+ - ! Define `@callback` specs in behaviour modules
93
+ - ! Use behaviours for dependency injection / mocking boundaries
94
+ - ! Use protocols for polymorphic dispatch on data types
95
+ - ~ Use `defimpl` in the data type's module or in the protocol module (be consistent)
96
+
97
+ ### Dependencies
98
+ - ! Manage via Mix (`mix.exs` deps); specify version constraints
99
+ - ! Use `mix.lock` committed for applications
100
+ - ! Minimize dependencies; prefer standard library and OTP
101
+ - ~ Run `mix hex.audit` for security advisories
102
+ - ~ Use `mix deps.audit` for outdated dependencies
103
+
104
+ ### Phoenix (Web)
105
+ - ~ Follow Phoenix conventions: contexts for business logic, schemas for data
106
+ - ! Validate all inputs via Ecto changesets
107
+ - ! Use parameterized queries (Ecto handles this by default)
108
+ - ~ Use LiveView for real-time UI; channels for custom WebSocket protocols
109
+ - ⊗ Business logic in controllers — delegate to context modules
110
+
111
+ ### Security
112
+ - ⊗ Hardcode secrets or credentials in source
113
+ - ! Use `Application.get_env` or `System.get_env` for secrets (runtime config)
114
+ - ! Validate all external inputs
115
+ - ⊗ `String.to_atom/1` on user input (denial-of-service vector)
116
+ - ~ Use `Plug.CSRFProtection` for web applications
117
+
118
+ ### Telemetry
119
+ - ! Use `:telemetry` for instrumentation (Erlang standard)
120
+ - ~ Use `telemetry_metrics` + `telemetry_poller` for metrics collection
121
+ - ~ Use `Logger` with structured metadata
122
+ - ? OpenTelemetry via `opentelemetry_api` + `opentelemetry_exporter`
123
+
124
+ ## Commands
125
+
126
+ See [commands.md](./commands.md).
127
+
128
+ ## Patterns
129
+
130
+ ### Pattern Matching & Pipelines
131
+ ```elixir
132
+ defmodule MyApp.Parser do
133
+ @spec parse_value(String.t(), atom()) :: {:ok, term()} | {:error, atom()}
134
+ def parse_value(raw, :integer) do
135
+ case Integer.parse(raw) do
136
+ {val, ""} -> {:ok, val}
137
+ _ -> {:error, :invalid_integer}
138
+ end
139
+ end
140
+ def parse_value("true", :boolean), do: {:ok, true}
141
+ def parse_value("false", :boolean), do: {:ok, false}
142
+ def parse_value(_, :boolean), do: {:error, :invalid_boolean}
143
+ def parse_value(raw, :string) when is_binary(raw), do: {:ok, raw}
144
+ def parse_value(_, _), do: {:error, :unsupported_type}
145
+ end
146
+
147
+ # with pipeline for composed operations
148
+ def create_user(params) do
149
+ with {:ok, v} <- validate_params(params),
150
+ {:ok, user} <- Repo.insert(User.changeset(%User{}, v)),
151
+ {:ok, _} <- Mailer.send_welcome(user) do
152
+ {:ok, user}
153
+ end
154
+ end
155
+ ```
156
+
157
+ ### GenServer
158
+ ```elixir
159
+ defmodule MyApp.Counter do
160
+ use GenServer
161
+ def start_link(opts \\ []), do: GenServer.start_link(__MODULE__, Keyword.get(opts, :initial, 0), name: __MODULE__)
162
+ def increment, do: GenServer.call(__MODULE__, :increment)
163
+ def value, do: GenServer.call(__MODULE__, :value)
164
+ @impl true
165
+ def init(initial), do: {:ok, initial}
166
+ @impl true
167
+ def handle_call(:increment, _from, n), do: {:reply, n + 1, n + 1}
168
+ def handle_call(:value, _from, n), do: {:reply, n, n}
169
+ end
170
+ ```
171
+
172
+ ### Testing (ExUnit)
173
+ ```elixir
174
+ defmodule MyApp.ParserTest do
175
+ use ExUnit.Case, async: true
176
+ doctest MyApp.Parser
177
+
178
+ describe "parse_value/2" do
179
+ test "parses integer" do assert {:ok, 42} = MyApp.Parser.parse_value("42", :integer) end
180
+ test "rejects invalid" do assert {:error, _} = MyApp.Parser.parse_value("abc", :integer) end
181
+ test "parses booleans" do
182
+ assert {:ok, true} = MyApp.Parser.parse_value("true", :boolean)
183
+ assert {:error, _} = MyApp.Parser.parse_value("yes", :boolean)
184
+ end
185
+ end
186
+ end
187
+ ```
188
+
189
+ ## Anti-Patterns
190
+
191
+ Items marked ⊗ in Standards above are not repeated here.
192
+
193
+ - ≉ **`if`/`else` over pattern matching**: Use multi-clause functions or `case`
194
+ - ≉ **Nested `case` >2 deep**: Refactor into named functions
195
+ - ≉ **Anonymous functions in pipes**: Extract to named functions
196
+ - ≉ **Long `with` chains (>5 clauses)**: Break into smaller functions
197
+
198
+ ## Compliance Checklist
199
+
200
+ - ! `@doc`, `@moduledoc`, `@spec` on all public API
201
+ - ! See [testing.md](../coding/testing.md) for testing requirements
202
+ - ! ExUnit + doctests; ≥80% coverage
203
+ - ! `mix format` + Credo (strict) + Dialyxir enforced
204
+ - ! Pattern matching and pipes for control flow; OTP for concurrency
205
+ - ! `{:ok, _}` / `{:error, reason}` tuples; `!` variants for raising
206
+ - ! Supervision trees for all production processes
207
+ - ⊗ Bare `spawn`, `String.to_atom/1` on input, broad `rescue`, logic in controllers
208
+ - ! Run `task check` before commit
@@ -0,0 +1,78 @@
1
+ # Go Standards
2
+
3
+ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
4
+
5
+ **⚠️ See also**: [main.md](../../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
6
+
7
+ ## Standards
8
+
9
+ ### Documentation
10
+ - ! Follow [go.dev/doc/comment](https://go.dev/doc/comment)
11
+ - ! All exported symbols have doc comments (complete sentences)
12
+
13
+ ### Testing
14
+ See [testing.md](../coding/testing.md).
15
+
16
+ - ! Use Testify (assert/require)
17
+ - Files: `*_test.go`, functions: `TestFuncName(t *testing.T)`
18
+
19
+ ### Coverage
20
+ - ! ≥85% coverage
21
+ - ! Count internal/\* + pkg/\*
22
+ - ! Exclude entry points, utilities, generated code
23
+
24
+ ### Telemetry
25
+ - See [telemetry.md](../tools/telemetry.md)
26
+ - ~ Structured logging (zerolog) for production
27
+ - ~ Sentry.io for error tracking
28
+ - ? OpenTelemetry for distributed tracing
29
+
30
+ ## Commands
31
+
32
+ See [commands.md](./commands.md).
33
+
34
+ ## 🔧 Patterns
35
+
36
+ **Table-Driven Tests**:
37
+
38
+ ```go
39
+ tests := []struct{name string; input, want Type; wantErr bool}{
40
+ {"case1", input1, want1, false},
41
+ {"error", input2, want2, true},
42
+ }
43
+ for _, tt := range tests {
44
+ t.Run(tt.name, func(t *testing.T) {
45
+ got, err := Fn(tt.input)
46
+ if tt.wantErr { assert.Error(t, err); return }
47
+ assert.NoError(t, err)
48
+ assert.Equal(t, tt.want, got)
49
+ })
50
+ }
51
+ ```
52
+
53
+ **HTTP**: `w := httptest.NewRecorder(); req, _ := http.NewRequest("GET", "/path", nil); handler.ServeHTTP(w, req); assert.Equal(t, http.StatusOK, w.Code)`
54
+
55
+ **Interface**: Define consumer-side, mock with function fields
56
+
57
+ ## Hygiene
58
+
59
+ **Types:**
60
+ - ⊗ `any` (empty interface) where a concrete type or typed interface is knowable; use generics or explicit interfaces
61
+
62
+ **Error handling:**
63
+ - ⊗ Ignore errors with `_` — every error MUST be checked or explicitly propagated with a reason
64
+ - ⊗ Empty `recover` blocks that swallow panics silently
65
+
66
+ **Dead code:**
67
+ - ~ Run `staticcheck` (detects unused code, unreachable branches) and `deadcode` (golang.org/x/tools/cmd/deadcode) before releases
68
+ - ⊗ Unexported functions that are never called anywhere in the package
69
+
70
+ **Circular dependencies:**
71
+ - The Go compiler rejects import cycles — treat them as build failures, not warnings
72
+ - ! Resolve by extracting shared types to a lower-level package; do not re-order imports
73
+
74
+ ## Compliance Checklist
75
+
76
+ - ! Follow go.dev/doc/comment for all exported symbols
77
+ - ! See [testing.md](../coding/testing.md) for testing requirements
78
+ - ! Run `task check` before commit
@@ -0,0 +1,278 @@
1
+ # Java Standards
2
+
3
+ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
4
+
5
+ **⚠️ See also**: [main.md](../../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
6
+
7
+ **Stack**: Java 21+ (LTS), Maven/Gradle; Web: Spring Boot 3+; Testing: JUnit 5 + Mockito + AssertJ; Analysis: Checkstyle, SpotBugs, Error Prone
8
+
9
+ ## Standards
10
+
11
+ ### Documentation
12
+ - ! Javadoc on all public classes, interfaces, methods, and constants
13
+ - ! Document `@param`, `@return`, `@throws` for public/protected methods
14
+ - ~ Use `@since` tags when adding public API to existing libraries
15
+ - ~ Use `{@code}` and `{@link}` for inline references
16
+
17
+ ### Testing
18
+ See [testing.md](../coding/testing.md).
19
+
20
+ - ! Use JUnit 5 (`@Test`, `@ParameterizedTest`, `@Nested`)
21
+ - ! Use Mockito for mocking; AssertJ for fluent assertions
22
+ - ≉ Use JUnit 4 for new code (maintain existing suites only)
23
+ - Files: `*Test.java` or `*Tests.java` in `src/test/java`
24
+
25
+ ### Coverage
26
+ - ! ≥85% coverage
27
+ - ! Count src/main/\*
28
+ - ! Exclude entry points, generated code, framework config
29
+
30
+ ### Style
31
+ - ! Follow [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)
32
+ - ! Use Checkstyle (project `checkstyle.xml` required)
33
+ - ! Use SpotBugs or Error Prone for static analysis
34
+ - ! Column limit: 100 characters
35
+ - ! 2 or 4 space indentation (pick one, enforce via formatter)
36
+
37
+ ### Naming Conventions
38
+ - ! `PascalCase` for classes, interfaces, enums, records, annotations
39
+ - ! `camelCase` for methods, fields, local variables, parameters
40
+ - ! `UPPER_SNAKE_CASE` for `static final` constants
41
+ - ! Package names all lowercase: `com.example.myapp.service`
42
+ - ! Test classes named `{ClassName}Test`: `UserServiceTest`
43
+ - ~ Interfaces without `I` prefix; use nouns/adjectives: `Repository`, `Serializable`
44
+ - ⊗ Hungarian notation or type prefixes
45
+
46
+ ### Modern Language Features (Java 21+)
47
+ - ! Use `record` for immutable data carriers (DTOs, value objects)
48
+ - ! Use `sealed` classes/interfaces for restricted type hierarchies
49
+ - ! Use pattern matching in `switch` and `instanceof`
50
+ - ! Use text blocks (`"""`) for multi-line strings (SQL, JSON, etc.)
51
+ - ~ Use `var` for local variables when type is obvious from context
52
+ - ~ Use virtual threads (`Executors.newVirtualThreadPerTaskExecutor()`) for I/O-bound concurrency
53
+ - ≉ Use `var` when it obscures the type or reduces readability
54
+
55
+ ### Types & Null Safety
56
+ - ! Use `Optional<T>` for return types that may be absent; ⊗ return `null` from public methods
57
+ - ! Use `@Nullable`/`@NonNull` annotations (JSpecify or JSR 305) on API boundaries
58
+ - ⊗ Use raw generic types (`List` instead of `List<String>`)
59
+ - ⊗ Use `Object` where a specific type or generic is appropriate
60
+ - ~ Prefer immutable collections (`List.of()`, `Map.of()`, `Set.of()`, `Collections.unmodifiable*`)
61
+ - ~ Use `enum` for fixed sets of constants; ⊗ string/int constants for enumerable values
62
+
63
+ ### Records & Sealed Types
64
+ - ! Use `record` instead of manual POJO/DTO boilerplate
65
+ - ! Use `sealed` for closed hierarchies (event types, result types, AST nodes)
66
+ - ~ Use compact constructors in records for validation
67
+ - ⊗ Add mutable state to records (they are immutable by design)
68
+
69
+ ### Resource Management
70
+ - ! Use try-with-resources for all `AutoCloseable` resources
71
+ - ⊗ Manually call `.close()` in a `finally` block (use try-with-resources instead)
72
+ - ! Close streams, connections, readers/writers on all code paths
73
+ - ~ Use `Cleaner` or `PhantomReference` for native resource cleanup (not `finalize()`)
74
+ - ⊗ Override `finalize()` — deprecated and removed in Java 18+
75
+
76
+ ### Error Handling
77
+ - ! Use checked exceptions for recoverable errors; unchecked for programming bugs
78
+ - ! Catch the most specific exception type, not `Exception` or `Throwable`
79
+ - ! Include context in exception messages (what failed, relevant IDs/values)
80
+ - ⊗ Swallow exceptions (empty catch blocks)
81
+ - ⊗ Use exceptions for flow control
82
+ - ~ Create domain-specific exception hierarchies extending `RuntimeException`
83
+ - ~ Use `Optional` instead of throwing for "not found" scenarios in query methods
84
+ - ~ Log exceptions at the boundary where they are handled, not where they are caught and rethrown
85
+
86
+ ### Collections & Streams
87
+ - ! Prefer `List.of()`, `Map.of()`, `Set.of()` for immutable collections
88
+ - ! Use Streams for transformation pipelines; ⊗ for simple iterations with side effects
89
+ - ~ Prefer `Stream.toList()` (Java 16+) over `Collectors.toList()` for unmodifiable results
90
+ - ≉ Modify collections during iteration; use `Iterator.remove()` or build a new collection
91
+ - ⊗ Use `Vector`, `Hashtable`, `Stack` — use `ArrayList`, `HashMap`, `ArrayDeque` instead
92
+
93
+ ### Concurrency
94
+ - ! Use virtual threads (Java 21+) for I/O-bound workloads
95
+ - ! Use `ReentrantLock` over `synchronized` when using virtual threads (avoids carrier thread pinning)
96
+ - ! Use `ExecutorService` with try-with-resources; ⊗ create raw `Thread` instances
97
+ - ~ Use `CompletableFuture` for async composition when virtual threads are not appropriate
98
+ - ~ Use `ConcurrentHashMap`, `CopyOnWriteArrayList` for concurrent data structures
99
+ - ⊗ Use `Thread.stop()`, `Thread.suspend()`, `Thread.resume()` — all deprecated/removed
100
+ - ≉ Use `ThreadLocal` heavily with virtual threads (high memory overhead at scale)
101
+
102
+ ### Dependency Injection
103
+ - ! Use constructor injection; ⊗ field injection (untestable, hides dependencies)
104
+ - ! Keep constructors focused — inject interfaces, not implementations
105
+ - ~ Use `@Qualifier` or custom annotations to disambiguate beans
106
+ - ≉ Use `@Autowired` on fields; prefer `final` fields with constructor injection
107
+
108
+ ### Database
109
+ - ! Use parameterized queries / prepared statements; ⊗ string concatenation for SQL
110
+ - ! Use connection pooling (HikariCP)
111
+ - ~ Use Spring Data JPA or jOOQ; ≉ raw JDBC for application code
112
+ - ~ Wrap multi-step operations in explicit `@Transactional` boundaries
113
+ - ⊗ Use `Statement` with user-supplied input (SQL injection risk)
114
+
115
+ ### Telemetry
116
+ - See [telemetry.md](../tools/telemetry.md)
117
+ - ~ Structured logging (SLF4J + Logback/Log4j2) for production
118
+ - ~ Sentry.io for error tracking
119
+ - ~ Micrometer for metrics
120
+ - ? OpenTelemetry Java for distributed tracing
121
+
122
+ ### Safety
123
+ - ⊗ Hardcode secrets, keys, or credentials in source
124
+ - ! Validate all external input (user, file, network)
125
+ - ! Use `SecurityManager`-independent security practices (removed in Java 24)
126
+ - ~ Keep dependencies up to date; scan with OWASP Dependency-Check or Snyk
127
+
128
+ ## Commands
129
+
130
+ See [commands.md](./commands.md).
131
+
132
+ ## Patterns
133
+
134
+ ### Testing (JUnit 5 + AssertJ + Mockito)
135
+ ```java
136
+ class CalculatorTest {
137
+ private Calculator sut;
138
+ @BeforeEach void setUp() { sut = new Calculator(); }
139
+
140
+ @Test void addPositiveNumbers() { assertThat(sut.add(2, 3)).isEqualTo(5); }
141
+
142
+ @ParameterizedTest @CsvSource({"0,1,1", "-1,1,0", "100,200,300"})
143
+ void addParameterized(int a, int b, int expected) {
144
+ assertThat(sut.add(a, b)).isEqualTo(expected);
145
+ }
146
+
147
+ @Nested class WhenDividingByZero {
148
+ @Test void throwsArithmeticException() {
149
+ assertThatThrownBy(() -> sut.divide(10, 0))
150
+ .isInstanceOf(ArithmeticException.class);
151
+ }
152
+ }
153
+ }
154
+
155
+ @ExtendWith(MockitoExtension.class)
156
+ class UserServiceTest {
157
+ @Mock UserRepository userRepository;
158
+ @InjectMocks UserService userService;
159
+
160
+ @Test void findById_existingUser_returnsUser() {
161
+ var expected = new User(1L, "alice");
162
+ when(userRepository.findById(1L)).thenReturn(Optional.of(expected));
163
+ assertThat(userService.findById(1L)).isPresent().contains(expected);
164
+ verify(userRepository).findById(1L);
165
+ }
166
+ }
167
+ ```
168
+
169
+ ### Records, Sealed Types & Pattern Matching
170
+ ```java
171
+ public record UserDto(long id, String name, String email) {
172
+ public UserDto {
173
+ if (name == null || name.isBlank()) throw new IllegalArgumentException("name required");
174
+ }
175
+ }
176
+
177
+ public sealed interface Result<T> permits Success, Failure {
178
+ record Success<T>(T value) implements Result<T> {}
179
+ record Failure<T>(String error, Exception cause) implements Result<T> {}
180
+ }
181
+
182
+ String describe(Result<?> r) { return switch (r) {
183
+ case Result.Success<?> s -> "OK: " + s.value();
184
+ case Result.Failure<?> f -> "Error: " + f.error();
185
+ }; }
186
+
187
+ // instanceof pattern matching
188
+ if (shape instanceof Circle c) return Math.PI * c.radius() * c.radius();
189
+
190
+ // switch pattern matching (Java 21+)
191
+ return switch (obj) {
192
+ case Integer i when i < 0 -> "Negative: " + i;
193
+ case Integer i -> "Integer: " + i;
194
+ case String s -> "String: " + s.toUpperCase();
195
+ case null -> "null";
196
+ default -> "Unknown: " + obj;
197
+ };
198
+ ```
199
+
200
+ ### Virtual Threads & Resources
201
+ ```java
202
+ try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
203
+ var futures = urls.stream().map(url -> executor.submit(() -> fetchUrl(url))).toList();
204
+ for (var f : futures) process(f.get());
205
+ }
206
+
207
+ // ReentrantLock (not synchronized) with virtual threads
208
+ private final ReentrantLock lock = new ReentrantLock();
209
+ void safeUpdate() { lock.lock(); try { /* critical */ } finally { lock.unlock(); } }
210
+
211
+ // try-with-resources
212
+ try (var conn = ds.getConnection();
213
+ var stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?")) {
214
+ stmt.setLong(1, userId);
215
+ try (var rs = stmt.executeQuery()) { if (rs.next()) return Optional.of(mapUser(rs)); }
216
+ }
217
+ return Optional.empty();
218
+ ```
219
+
220
+ ## Build Configuration
221
+
222
+ **Key requirements** (Maven or Gradle):
223
+ - ! Java 21+ toolchain, UTF-8 encoding
224
+ - ! Test deps: `junit-jupiter`, `assertj-core`, `mockito-junit-jupiter`
225
+ - ! JaCoCo with `minimum = 0.85` line coverage
226
+ - ! SpotBugs plugin for static analysis
227
+
228
+ **Gradle** (`build.gradle.kts`):
229
+ ```kotlin
230
+ plugins { java; jacoco; id("com.github.spotbugs") version "6.0.0" }
231
+ java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }
232
+ dependencies {
233
+ testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
234
+ testImplementation("org.assertj:assertj-core:3.26.0")
235
+ testImplementation("org.mockito:mockito-junit-jupiter:5.14.0")
236
+ }
237
+ tasks.test { useJUnitPlatform() }
238
+ tasks.jacocoTestCoverageVerification {
239
+ violationRules { rule { limit { minimum = "0.85".toBigDecimal() } } }
240
+ }
241
+ ```
242
+
243
+ ## Anti-Patterns
244
+
245
+ Items marked ⊗ in Standards above are not repeated here.
246
+
247
+ - ≉ **Checked exceptions for everything**: Reserve for truly recoverable conditions
248
+ - ≉ **God classes**: Keep <500 lines; extract service/strategy/helper
249
+ - ≉ **`Collectors.toList()`**: Prefer `Stream.toList()` (Java 16+)
250
+
251
+ ## Hygiene
252
+
253
+ **Types:**
254
+ - ⊗ Raw types (`List`, `Map`, `Optional`) without type parameters — always parameterize
255
+ - ⊗ `Object` as parameter or return type where a concrete type or bounded wildcard is knowable
256
+ - ⊗ `@SuppressWarnings("unchecked")` without an inline comment proving the cast is safe
257
+
258
+ **Error handling:**
259
+ - ⊗ Empty `catch (Exception e) {}` — handle, log with context, or re-throw as a typed exception
260
+ - ⊗ `e.printStackTrace()` as the sole handler — use structured logging and propagate or wrap
261
+ - ⊗ Returning `null` from public methods to signal failure — use `Optional<T>` or throw
262
+
263
+ **Dead code:**
264
+ - ~ SpotBugs (in build config) detects `DLS_DEAD_LOCAL_STORE` and unreachable code
265
+ - ~ PMD rules `UnusedPrivateMethod` and `UnusedPrivateField` catch dead private symbols
266
+ - ~ Run `gradle dependencies --configuration runtimeClasspath` to audit unused dependencies
267
+
268
+ ## Compliance Checklist
269
+
270
+ - ! Javadoc on all public APIs
271
+ - ! See [testing.md](../coding/testing.md) for testing requirements
272
+ - ! Use JUnit 5 + AssertJ + Mockito
273
+ - ! Use records for data carriers; sealed types for closed hierarchies
274
+ - ! Use virtual threads for I/O-bound concurrency (Java 21+)
275
+ - ! Try-with-resources for all `AutoCloseable`; ⊗ manual `.close()`
276
+ - ⊗ Return `null` from public methods; raw types; field injection
277
+ - ⊗ `synchronized` with virtual threads
278
+ - ! Run `task check` before commit