@@ -147,6 +147,68 @@ Types: `feat`, `fix`, `refactor`, `perf`, `test`, `docs`, `style`, `ci`, `build`
147147
148148** Branches:** ` fix/description ` or ` feat/description `
149149
150+ ## Code comments and docs
151+
152+ Default to ** no comment** . Only write one when the * why* is non-obvious — a hidden
153+ invariant, a surprising decision, a workaround. If removing the comment wouldn't
154+ confuse a future reader who can see the code, don't write it.
155+
156+ ** Never restate what the code already says.** Well-named identifiers and types are
157+ the documentation. Comments that paraphrase the next line are noise.
158+
159+ ### Module / file headers
160+ One paragraph max. State what lives here; don't enumerate every item or describe
161+ the flow step-by-step.
162+
163+ ### Struct / enum field docs
164+ Skip the obvious (` pub unstaking: Balance ` , ` pub voters_count: u32 ` ). Document a
165+ field only when its semantics are surprising — e.g. it stacks instead of replacing,
166+ must match an external balance, doubles as an idempotency signal.
167+
168+ ### Error variants
169+ One line each, or none if the name already tells the story. Don't write a
170+ paragraph explaining the policy that produces the error — that belongs at the
171+ check site.
172+
173+ ### Extrinsic docs
174+ Follow the Description / Parameters / Emits structure from the "Extrinsic
175+ documentation" section above, but keep the ** Description to 1–2 lines plus at
176+ most one short paragraph** for genuinely load-bearing context. In particular:
177+
178+ - Do not enumerate ` Error ` variants in the Description — the ` #[pallet::error] `
179+ enum is the source of truth.
180+ - Do not list internal implementation steps ("locks X, then mints Y, then calls
181+ Z"). The code shows that.
182+ - Keep the * why* of any non-obvious constraint (e.g. "refuses while stHDX is in
183+ circulation — outstanding aTokens would be stranded").
184+
185+ ### Trait method docs
186+ One line. If the trait-level doc already explains the contract, leave method
187+ docs out entirely.
188+
189+ ### Inline comments inside function bodies
190+ Reserve for:
191+ - Non-obvious invariants the next line relies on.
192+ - Why a defensive branch exists / why an error is intentionally swallowed.
193+ - Why an unusual construct (` drain_prefix(...).count() ` to actually drain,
194+ ` set_lock ` vs ` extend_lock ` , pre-decrement before an external call) is correct.
195+
196+ Skip:
197+ - Narrating control flow ("// new record: increment voter count" above
198+ ` voters_count += 1 ` ).
199+ - Explaining what a well-named helper does at its call site.
200+ - Restating the assertion in the next ` ensure! ` .
201+
202+ ### What to keep
203+ Comments that warn a future reader about something they would otherwise miss:
204+ - "Must match ` LockableAToken.sol ` 's ` freeBalance ` check"
205+ - "Saturating math — hooks must never block voting"
206+ - "Pool presence ⇔ allocation has run" (load-bearing idempotency signal)
207+ - "stHDX invariants — verify on AAVE config change: (1)…(2)…"
208+
209+ If in doubt, delete the comment and see if the code still reads. If it does,
210+ leave it out.
211+
150212## Versioning
151213
152214- ** SemVer** on all crates — bump ` Cargo.toml ` version on changes
0 commit comments