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
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
# 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](../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](../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.
|
||||
|
||||
<!-- wikitool:toc -->
|
||||
## Contents
|
||||
|
||||
- [The axis is the reader, not the owner](#the-axis-is-the-reader-not-the-owner)
|
||||
- [Why the control plane's language is English](#why-the-control-planes-language-is-english)
|
||||
- [Why it is not a parameter](#why-it-is-not-a-parameter)
|
||||
- [What the KB language still decides](#what-the-kb-language-still-decides)
|
||||
- [Where the line runs inside one file](#where-the-line-runs-inside-one-file)
|
||||
- [What would put this back on the table](#what-would-put-this-back-on-the-table)
|
||||
<!-- /wikitool:toc -->
|
||||
|
||||
## 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](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](../kb/CONTRACT.md#language-and-identifiers) 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](../types/type-spec.md#who-owns-a-type-spec) has that
|
||||
split as a table, and [ownership-and-templates.md](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.
|
||||
Reference in New Issue
Block a user