code-naming · git:20261030.53ce6d5 · 2026-10-30 · sha256 806201710b29849c
code-naming git:20261030.53ce6d5A
Immutable. This exact content never changes and is served at /api/v1/blob/806201710b29849c.
--- name: code-naming description: > Code conventions for names, file layout, docstrings and the source of truth. Use when writing or reviewing code, when a review comment asks what a name means or why a thing exists, when a docstring or comment explains how the code works, when a helper sits outside its owning class, or when a value is parsed out of a string, read from a file, or taken from a built-in default instead of read from where it is stored. --- # Code naming and layout Four rules for code in any repo. Each one puts the meaning where the reader looks first: the name, the file, the first line of the docstring, the stored column. ## No short or cute names, ever - A name is spelled out in full. A two-letter name is wrong; a three-letter name has to be a real word (`datadog_steps_loader` not `dd`, `config` not `cfg`, `query_params` not `q`, `trigger` not `trig`, `job_family_names` not `F`). - A name carries the domain concept, so the reader never opens the body to learn what it holds: a class is named for the thing it models with its vendor or domain in the name (`GitlabCiYaml`, `PipelineDependencyGraph`, `RequestBudget`), never a generic private class (`_Loader`, `_Pool`); a function is a verb plus its object (`parse_yaml`, `run_git_checkout`). - A route, page key or JSON key says what it returns, so a reader of the path alone knows the payload. - A constant says why it exists, with its role in the name (`ERROR_FILE_UNREADABLE_REASON`, `STEP_DURATION_SECONDS`), never a bare value name. - A legend that maps short names to their meanings at the top of a file is the sign that the long names belong in the code; rename instead of explaining. - A review comment that asks what a name means is a rename request. Do the rename in the same pass, across the whole branch, and say so. Grounding: John Ousterhout, *A Philosophy of Software Design*, 2018, ch. 14 "Choosing Names", https://web.stanford.edu/~ouster/cgi-bin/book.php. ## File equals class, helpers as methods - A file holds one class and is named after it (`GitLabRawSource` lives in `gitlab_raw_source.py`). - Every helper function is a method on the file's owning class; only `main()` and its argument parser stay at module level as the driver. Module-level constants and compiled patterns may stay. - Test helpers follow the same rule: they live in the test class, not as loose functions beside it. - A database schema (table and index creation) lives in its own file, not inline in the class that uses it. ## Docstrings: one idea, one line, what not how - A docstring is one line that says what the thing is for. - No docstring or comment describes how the code works. Retry counts, wait sequences, loop order and similar mechanics live in the code; a reader who needs them reads the code. - No `#` inline comments and no multi-line block comments. - The one exception is a class docstring that describes, one idea per line, the structure the class walks or models (the shape of a pipeline graph, the layers of a config file). It says what the structure is, not what the code does with it. ## Source of truth, never string parsing - An identity field (a job kind, a family, a base name) is a stored column derived from the source when the row is written, never recovered later by regex or string splitting over another field. - A layer above the source reads the database, not files; a path that bypasses the store to read a file is a layering bug. Dependencies point one way, toward the layer that owns the data. Grounding: Robert C. Martin, "The Clean Architecture", 2012, the Dependency Rule, https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html. - No built-in host, project or window default in the code (no hardcoded GitLab host, no `DEFAULT_PROJECT`, no `_6h` baked into a name); every such value comes from configuration. Grounding: Adam Wiggins, *The Twelve-Factor App*, 2011, III. Config, https://12factor.net/config. - No silent cap on data: a row limit, sample size or byte ceiling is never baked into a query, slice or server. Where one must exist it is a configured value with its reason beside it, and output labelled "every run" or "all rows" contains every one. Grounding: *The Twelve-Factor App*, III. Config (above); no known prior art for the labelled-output half. - Two views of the same data share one loader and one computation. When two outputs built from the same data disagree, treat the mismatch as a bug until one source is shown to feed both. Grounding: Andrew Hunt and David Thomas, *The Pragmatic Programmer*, 20th anniversary ed., 2019, the DRY principle, https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/. - Runtime data (databases, caches, fetched pages) lives in a per-user directory outside the checkout, so the repo's ignore rules never change to hide it.