Anti-fingerprint
A separate chapter, because it is a separate problem.
Code written by a language model without a standard is recognisable at a glance — not by its mistakes, but by its pull toward the middle of the distribution. The model picks the most probable name (handleData, processItems, utils.ts), the most probable comment (a restatement of the next line), the most probable defence (try/catch around a pure function). The result is code with no author.
Exactly the same happens to a person who writes "the way it is done" and has never asked why it is done that way.
The rules of the standard remove this as a side effect: a closed verb lexicon physically contains no handle, tagged comments leave no room for restatement, file roles leave no room for utils.ts. On top of that, these are banned:
| Tic | Why |
|---|---|
| Emoji in code, logs, commits | A log is read by grep |
// Step 1:, // Step 2: | A restatement of control flow |
| JSDoc repeating the signature | The types are already written and checked by the compiler |
const result = await x(); return result | A variable that lives one line |
?. where the type cannot be null | Guarding against the impossible masks real bugs |
try/catch around a pure function | A pure function does not fail |
// ============ | Structure comes from splitting files |
Enhanced, Advanced, V2 in names | Judgement instead of description |
What GRAIN deliberately leaves alone
A standard that reaches into everything stops being an engineering document.
| Not our business | Why |
|---|---|
| Indentation, quotes, semicolons, line length | The formatter's job. Arguing about it is not worth a minute |
| Choice of libraries and frameworks | Depends on the task and changes more often than the standard |
| Layered architecture, DDD, hexagons | GRAIN fixes dependency direction and file roles; which school to build on top is the team's call |
| Commit style and branching | A different document, a different discipline |
| Test coverage as a percentage | A metric that is easy to lie with |
How to argue with the standard
A rule that gets in the way is a reason to change it, not to quietly work around it.
- Bring the code where the rule makes things worse. Code, not a description.
- Propose the edit to the
grain.synxvocabulary and to the document — as one change, because they only move together. - Until the edit lands, use
// grain:allow <rule> — <reason>. The reason is mandatory: it is the argument.
A standard with no amendment procedure turns into a stone tablet, and stone tablets get bypassed in silence.