Files
chemenu/docs/language-boundaries.md
T
torben f350999053
CI / verify (push) Failing after 45s
Release / release (push) Successful in 38s
stack: Control-Plane-Sprache universell - Achse ist das Publikum, kein Instanz-Schalter (#103)
Files changed:
- AGENTS.md
- CHANGES.md
- VERSION
- docs/language-boundaries.md
- kb/CONVENTIONS.md
- kb/CONVENTIONS.md.template
- tools/chemenu/commands/dist_cmd.py
2026-09-15 16:58:55 +02:00

7.9 KiB

Language Boundaries

Two languages run through this repo at once. kb/ is written in whatever language the instance chose - German here, and the value lives in kb/CONVENTIONS.md's language:. Everything that tells an agent what to do - AGENTS.md, every CONTRACT.md, everything under instructions/ - is written in English, in every instance, whatever the first value says.

The rule itself is in AGENTS.md § File naming. This page holds the part that is not a rule: why the line runs where it does, why the English half is not a setting, and which argument for it turned out to be wrong.

Contents

The axis is the reader, not the owner

For a long time the two halves could be told apart by asking who owned the file, and the answer came out right every time: the stack owns AGENTS.md and the contracts, which are English; the instance owns its pages and the templates that shape them, which are in the KB language. The ownership boundary is a real and load-bearing thing - ownership-and-templates.md is about what it buys - so it was easy to read the language split as one of its consequences.

It is not. The case that separates them is a page type an instance adds for itself. types/ takes a new type without a code change, so an instance can write one; that file is instance-owned from the first line to the last, ships nowhere, and is nobody's to overwrite. Its authoring guidance is still instruction addressed to an agent, and reads exactly like the guidance in the four types the stack ships. Ownership says "yours"; the audience has not moved at all.

So the question a line answers is not whose file is this but who reads this line, which is the same cut kb/CONTRACT.md already makes inside a single page between prose and identifiers - applied one level up, to the halves of a document. Ownership decides who may change a sentence. The reader decides what language it is in. The two questions were answered together for as long as they happened to agree.

Why the control plane's language is English

Not because English is better for the purpose, and not to be neutral: this instance's operator reads German, and the pages are German for that reason.

  • The control plane is almost entirely about identifiers, and the identifiers are English. base_dir, provenance: sourced, --confirm, exit 42, root: kb. A sentence in another language explaining when to set page_ref_fields is already half English by the time it reaches the verb, and the prose/identifier boundary inside it becomes something a reader has to work out line by line.
  • It quotes a body of material that is English and stays English. The harness documentation it has to agree with, the vendored skill-authoring sources under commonplace/, the tool's own --help. A contract that translates their vocabulary makes its own claims harder to check against them, not easier.
  • One language keeps instances comparable. Two instances running the same stack version hold the same control plane byte for byte, so a question about one is answerable from the other - and anything an instance changes locally shows up as a difference in content rather than in language.

Why it is not a parameter

The natural next move, once kb/CONVENTIONS.md holds language:, is a second value beside it - control_plane_language: - defaulting to English and settable by an instance that would rather read its contracts in its own language. That option is deliberately not taken.

  • The knob's cost is paid by every file; its benefit lands on the few a human reads. Every rule about writing an instruction would have to name which of the two languages it means, every example would need a note saying which one it is in, and every review of an instruction would start by establishing which language it should have been in. The stack has one mechanism for that class of problem - one rule, one place (AGENTS.md invariant 8) - and a second language value forks it everywhere at once.
  • The document the knob is for is read by an agent. An instruction, a contract, a type-spec's guidance half: the reader is a model, and a model reads the English fine. What the operator reads is unaffected by any of this - see the section below.
  • Today's local document is tomorrow's upstream candidate. An instruction an instance wrote for itself is the most likely thing it ever contributes back. Written in the KB language it would have to be translated first, and the translation would have to re-derive the prose/identifier boundary that the original author had in their head and did not write down.
  • Nothing would check it. There is no mechanical test for what language a paragraph is in - a stop-word scan flags the quoted vocabulary the rule deliberately keeps and misses a cleanly translated paragraph. A setting nothing enforces produces drift that is visible only to whoever next opens the file.

What the KB language still decides

Making the control plane English does not make the instance's language an implementation detail. kb/CONVENTIONS.md's language: decides two things, and both are the ones an operator actually experiences:

  • Page text. Every page under kb/, and inside the page type-specs exactly the parts that become page text - each one's ## Template block and its layout: titles.
  • What an agent says. An agent speaks the KB language, whatever the file it just read was written in. An instruction that models a sentence for the operator writes that model in English, like the rest of the control plane, and the agent delivers it in the instance's language.

So an operator who reads no English gets German pages and German answers from an agent reading English instructions. The English is what the machinery is written in, not what it says back.

Where the line runs inside one file

One file shape carries both halves, and it is worth knowing which is which before editing it: a page type-spec (types/entity.md and its three siblings). Its authoring guidance addresses an agent; its ## Template block and layout: titles become the literal headings of pages; its field names and enum values are identifiers and are translated in neither direction. types/type-spec.md § Who owns a type-spec has that split as a table, and ownership-and-templates.md § "Where the file boundary strains" has what it costs to keep two audiences in one file.

What would put this back on the table

A docs/ page goes stale when the reasoning stops holding rather than when the code changes, so it is worth naming what that would look like here. Two things would:

  • A human starts reading the control plane directly and routinely - not an operator checking a rule now and then, which is the case today, but a workflow where people rather than agents are the primary readers of instructions/. The second argument above is the one that fails first, and it is the load-bearing one.
  • The identifiers stop being English. If the tool's own vocabulary were ever localized, the first argument would invert: the prose would then be the only English left in a file that is otherwise not, which is the situation this page argues against.

Neither is close. Both are cheaper to notice here than to rediscover in an argument about a single file.