coding.sgit.ai / the house style

The house style

The five languages look different. The instincts underneath them are the same four, and naming those is what turns a set of per-language pages into a house style rather than five unrelated preferences.

Everything on this page was derived by counting, not from documentation. Four of the five languages have no documented rules at all — every convention below was reconstructed from the code and measured. Where a documented rule and the code disagree, both are published with the numbers. The rules, and whether the code obeys them →

1. One idea per file, and the filename says which

In Python the filename is the class name: Schema__Caller__IP.py defines class Schema__Caller__IP and nothing else. 187 of 208 sampled files define exactly one class, and 3,871 of 3,999 filenames carry the __ separator. __init__.py stays empty — 299/302 = 99% of packages — so there is no re-export layer to hide behind.

The same shape appears everywhere else. In JavaScript, one component per directory, and the directory, the three files, the class and the custom element all carry the same name. CSS and HTML are that component's sibling files, same basename. Bash is one Section__* class per boot concern.

A name should let you find the file, and a file should contain one thing.

Everything else follows from wanting that to be true without a search index: the double underscores, the empty __init__.py, the fully-qualified imports, the three-file triplet. It is also the convention with the clearest machine-reader payoff — a model can locate any symbol by constructing a path, with no index and no grep. Why that matters →

2. Banners, and the three characters

Every file opens with a comment block naming what it is and why it exists. One idea, four expressions:

LanguageCharacterFormWritten down?
Python# ═══… × 79, then product — class — purposeYes — rule 7, at 100% compliance
Generated shell# ── Auto-terminate after 1h ──…No
JS shared modules// ── launch-defaults.js — canonical launch constants ──…No
JS componentsJSDoc/** … @module … @version */No

Rule 7 carries a caveat that reads like scar tissue, because it is: the banner is Python files only, because in Markdown # is heading syntax and a banner renders on GitHub as a stack of H1s.

The recommendation this site publishes is to make the shape the rule — a banner names the file, its owner and its purpose in three lines — and let the comment character follow the language. Then fix the JavaScript, where components and shared modules currently disagree with each other. 15 of 50 JS files open with a banner at all.

3. Alignment, and the argument that it is for machines

This is the estate's most visible convention and its least explained.

WhereMeasured
Python schema attribute colons100% aligned46 of 46 files with two or more annotated attributes
Python class attribute valuesAligned
Python trailing commentsAligned
Python from X import Y39% aligned321 of 817
CSS property valuesAligned per block
JS object literal keysAligned

The usual case for alignment is aesthetic, and it is usually a bad trade: it produces noisy diffs when the longest name changes, which is exactly why gofmt and black refuse to do it.

There is a better argument available here. This is a codebase where 61% of commits were written by an agent, and where the stated house position is that someone still needs to understand what is underneath. Aligned columns turn a class body into a table. A reader — human or model — scanning a five-attribute primitive sees two columns rather than five sentences. The same is true of a schema's field list and a CSS block's property list.

That is a claim, and it is falsifiable. Alignment costs diff noise and buys scanability; the estate has decided the trade is worth it, and this site publishes it as a position with the evidence attached rather than as a finding. Nobody has measured the benefit. Q1: is alignment for humans or for machines? →

Two details are worth copying even if you reject the argument. The unit of alignment is the block, not the file — in CSS, two adjacent rules align to different columns, each set by its own longest property, because the thing you read at once is the block. And the one place the discipline is not kept is imports, at 39%, which is also the easiest of all of them to automate.

4. Single source of truth, enforced by structure

The same instinct appears in every language, and each time with a mechanism rather than a convention:

Duplication is prevented by making the second copy impossible to write, not by asking people not to write it.

This site is built the same way, which is the only honest way to publish that sentence: the version lives in one file and is written into every page by a script, the nav and footer are defined once and rewritten across the tree, and every number and every code example on these pages is written in from its source document by a generator, with CI failing the release if one has drifted. How that works here →

5. The prose rules that touch code

Three conventions govern the documents around the code, and they belong on a coding site because they apply to anything an engineer here writes:

The em-dash rule is the clearest documented-rule-versus-practice gap on this site, and it is in the source documents themselves. The rule says every document is em-dash-free. Counted across the eleven markdown documents this site is written from — the same documents that state the rule — there are 248 em-dashes, and not one file has zero:

# grep -o '—' briefs/*.md | wc -l, per file
00__BRIEF.md                     28     05__cross-cutting.md             30
01__python.md                    42     06__the-rules-and-compliance.md  24
02__javascript.md                20     07__site-architecture.md         25
03__html-and-css.md              16     08__gaps-and-open-questions.md   20
04__bash-and-generated-shell.md  15     LICENSE.md                        9
                                        README.md                        19
                              TOTAL 248, in 11 of 11 files

This site follows the practice, not the stated rule, and says so rather than quietly picking one. The alternative — stripping em-dashes from these pages while publishing 248 of them verbatim two clicks away under /documents/ — would be a consistency nobody could see and an inconsistency anybody could. The rule needs retiring or enforcing; it currently does neither, which is the same state rule 9 is in.

It is also the cheapest rule here to enforce, if the answer is to keep it: one grep, one line of CI. That nobody has is the point.

The five languages

217,266 lines · 3,999 files

Python

The deepest, and the only one with a written rule set behind it. Double-underscore naming families, one class per file, Type_Safe instead of static typing, and constrained primitives instead of validation.

50 files · 41 components

JavaScript

Native web components, no framework and no build step. The three-file triplet, the self-locating component, and a versioned CDN path instead of a lockfile. Undocumented anywhere.

37 files · 2-space indent

HTML

Fragments rather than documents, semantic elements, ARIA on every control, and one rule worth its own line: classes are for styling, data-* is for behaviour, and the two never mix.

38 files · tokens only

CSS

The alignment discipline applied to property values, design tokens from a versioned CDN, and the argument that shadow DOM removes the problem BEM exists to solve.

5 .sh files · 15 generators

Bash

The surprise: shell is not written here, it is generated from typed Python. Five shell scripts in 217,266 lines, and fifteen Section__* classes that render the rest.

the thesis

Writing code for agents

Several of these conventions only make sense once you accept that a model is a primary reader and writer of the code. This is the page that explains why the rest looks the way it does.