Which language a surface may be AUTHORED in is an axis of its own, distinct from rendering coverage — and the commit message is source-only, held by a gate

Accepted

ontoref
MEASURED 2026-08-10, over the parent, `code` and `outreach` corpora (~400 commits), and

Context

MEASURED 2026-08-10, over the parent, `code` and `outreach` corpora (~400 commits), and shipped the same day as commit 9f0ea12. Nothing here is supposed.

· THE RULE EXISTED, IN THE ONE PLACE THAT BINDS NOBODY. "Code documentation, output docs, summaries of tasks, strings in code ALL in ENGLISH if no other specification is indicated" lived in an agent carrier and nowhere else. A commit message is none of those four things BY NAME, so the rule reached commit messages by INFERENCE — and inference is not a mechanism. It holds for exactly as long as whoever infers keeps inferring.

· THE DRIFT, AND ITS SHAPE. The parent repo switched to Spanish subjects and stayed there:

parent, commits 0- 30: 24/30 Spanish ← most recent 30- 60: 0/30 60- 90: 0/30 90-120: 0/30

Every one of those was authored the way the next would have been: by reading the last fifteen and matching them. A convention transmitted by imitation has no floor — it only has to break once to become the new example, and then the example does the rest. Nothing reported it for weeks because nothing had ever been asked.

· THE CORPUS HANDED OVER A THRESHOLD RATHER THAN A PREFERENCE. Marker counts over the whole message body, after blanking code spans and « » quotations:

0 markers: 232 commits ← English 1 marker : 7 commits ← English, each one a QUOTATION or a MENTION 11-36 : 30 commits ← Spanish

NOTHING LANDS BETWEEN 1 AND 11. `fail_at = 3` is not a tuned cutoff; it is the middle of a hole ten wide. The discriminator is the corpus, not the constant — which is why a future disagreement is obliged to re-run the measurement rather than nudge the number.

· ONE MORE THING THE MEASUREMENT FOUND, AND IT IS NOT COSMETIC. A commit in the parent carries a BAD signature (521d665, 2026-07-17, `%G? = B`) — content altered after signing, not a trust or key problem. Unrelated to language, found by the same sweep, and recorded here only so the next reader does not have to rediscover it: the integrity of the commit surface and the language of the commit surface were audited together, and only one of them was repaired.

Decision

WHICH LANGUAGE A SURFACE MAY BE AUTHORED IN IS A SEPARATE AXIS FROM HOW IT RENDERS, and it is declared in the spine:

reflection/schemas/lexicon.ncl `source_only_type` — surface · authored · markers · warn_at · fail_at · blind · note ontology/lexicon.ncl the `source_only` DECLARATION: commit-message → "en" scripts/check-commit-lang.nu the checker, which READS the declaration .pre-commit-config.yaml the binding, at `stages: [commit-msg]` scripts/agent-git.nu the agent path, covered in every member

IT IS NOT A FIFTH `surface_tag`, AND THE REASON IS MECHANICAL, NOT AESTHETIC. `CoversEverySurfaceAndLanguage` demands every tag × every target language. Adding 'Commit to that enum would have made the build fail until the project declared A SPANISH COMMIT COVERAGE — the exact thing the entry exists to forbid. A rule and its precise inverse cannot share an enum. `coverage` answers "this surface, in THIS TARGET LANGUAGE, is these files", so a rendering policy can be checked. Authorship-language asks the question BEFORE it: may this surface be written in that language at all. A commit message has no Spanish edition whose renderings could be checked; it has an English one or it is a defect.

THE RULE LIVES WHERE IT IS QUERYABLE, AND THE CHECKER IS EMPTY OF POLICY. Markers, thresholds, and what the gate is blind to are declared in `ontology/lexicon.ncl`; `check-commit-lang.nu` holds none of them. The gate is a reader of the surface, never a second copy of it (adr-074).

THE GATE DECLARES WHAT IT CANNOT SEE, IN THE DECLARATION AND NOT IN A COMMENT. Three blind spots are named in `blind`: a message in a third language (the markers are Spanish and nothing here detects Portuguese, French or Italian); fluent Spanish written without any of the 36 function words (possible in a very short subject); and whether the message is TRUE of the diff, which this gate says nothing about.

AND IT HAS A BAND AND AN ESCAPE, BECAUSE A GATE THAT CRIES WOLF IS A GATE PEOPLE SKIP. `warn_at = 1` reports and lets through; `fail_at = 3` refuses. A line reading `[lang:es]` suppresses counting until the next blank line. The seven single-marker English commits are why: an English message may legitimately quote the other language, and correcting a citation is a worse outcome than the finding.

Constraints

  • Hard The commit-message language rule is declared in ontology/lexicon.ncl `source_only`, never only in an agent carrier or inside the checker.
  • Hard 'Commit never enters the `surface_tag` enum. Authorship-language and rendering coverage stay separate axes.
  • Hard The commit-message check runs as a commit-msg stage hook, not merely as a script that exists.
  • Hard The agent writing path invokes the same checker, so agent commits are gated in every member regardless of that member's pre-commit config.
  • Soft The refusal threshold is recorded with the corpus distribution that produced it, so it can be re-derived rather than argued.
  • Hard The declaration names the gate's blind spots, at the surface, not in a comment inside the checker.

Alternatives considered

  • Add 'Commit as a fifth member of `surface_tag`rejected: Mechanically impossible, not merely inelegant. `CoversEverySurfaceAndLanguage` demands every tag × every target language, so the build would have failed until the project declared a SPANISH COMMIT COVERAGE — the precise inverse of the rule being added. A rule and its negation cannot share an enum. This was the first candidate and the reason the separate axis exists.
  • Declare it in ADR-040's `conventions` blockrejected: Wrong mechanism. `conventions` binds guideline CONTENT from a shared origin by symlink, vendoring or local copy, with version drift and a sync verb — built for propagating a Rust style guide across projects. Commit-message language is not content bound from an origin; it is a one-line policy about a surface this project owns. Routing it through convention sync would add an origin, a version and a resolution mode to say 'English'.
  • Leave the rule in the agent carrier and rely on reviewrejected: This is the measured status quo and it is what produced the drift: 24 of the last 30 commits Spanish, nothing able to report it. Review did not catch it either, because a Spanish subject among Spanish subjects reads as correct. The failure mode is not inattention, it is the absence of a floor.
  • Detect the language with a library or model instead of counted function wordsrejected: It would trade a falsifiable threshold for an opaque one. The 36 markers and `fail_at = 3` are derived from this project's own corpus and can be re-derived by anyone; a classifier's verdict on a seven-word subject line cannot be argued with, cannot be re-measured, and adds a dependency to a commit-msg hook that must run in every clone.
  • Gate on the subject line only, rather than the whole message bodyrejected: The body is where the reasoning lives and where the drift was heaviest — several messages had English subjects over Spanish bodies, which the corpus shows as 11-36 markers. Gating the subject alone would have gone green over exactly the commits that motivated this.

Anti-patterns

  • A convention stated where nothing can enforce it — A rule written in an agent instruction file, a README or a CLAUDE.md, with no schema declaring it and no gate reading it. It reaches the surfaces it did not name BY INFERENCE, and holds only while whoever infers keeps inferring. Measured: 24 of 30 consecutive commits violated such a rule with nothing able to report it.
  • Transmitting a convention by reading the last fifteen entries — Authors match the local precedent rather than a declaration, so the convention has no floor — it need break only once to become the new example, and the example then propagates it faithfully. Indistinguishable from compliance while the precedent happens to be right.
  • Declaring an authorship rule as a rendering tag — Adding a source-only surface to the enum that a totality contract quantifies over. The contract then demands renderings in every target language for a surface whose entire point is that it has none — so the build fails until the project declares the inverse of the rule it was adding.
  • A gate constant chosen rather than measured — A cutoff set by intuition and then defended by seniority, because no distribution was recorded beside it. It cannot be challenged except by opinion, and it drifts whenever someone with standing finds it inconvenient. The repair is not a better guess: it is publishing the corpus so the number becomes falsifiable.

Related ADRs

ADR-029 · ADR-040 · ADR-066 · ADR-070 · ADR-071 · ADR-072 · ADR-074 · ADR-083

Was this useful? Rate it
Got something to add? Tell me what you think, what you'd suggest, or whether we should keep exploring this topic.
· reads

We use cookies to help this site function, understand service usage, and support marketing efforts. Cookie Policy for more info.