Abgeschlossen. Veröffentlicht in 0f0a579 als 10.0.0-beta.9 (minor). CI grün: Run 672 (Push-Workflow, Jobs verify und pwsh) hat die Änderung mechanisch geprüft - Tests, Verify the development tree, Version gate, Distribution als frische Instanz. Run 673 (Release-Workflow) hat die Version aufgelöst und die Publish-Schritte für den Beta-Kandidaten wie vorgesehen übersprungen.
Manuelle Gegenprobe (Operator, 12.10.): Ein kurzer Ingest mit Sonnet in dieser Instanz antwortete im Chat durchgehend Deutsch - das letzte Akzeptanzkriterium ist erfüllt. Nicht getestet: GPT (Luna), mit dem das Problem zuletzt auftrat. Das Kriterium verlangte nur Sonnet; trägt die Regel bei GPT nicht, ist das ein neuer Befund und ein eigenes Issue, kein Rest dieses Issues.
Abweichungen gegenüber der Planung:
Die Verweisliste der Planung hatte kb/CONVENTIONS.md und kb/CONVENTIONS.md.template nicht; beide verweisen jetzt auf beide Abschnitte (Control-Plane-Regel in § File naming, Gesprächsregel in § Conversation language).
doctor nennt im skills-Detail jetzt den ersten Drift-Grund (..., first: <Grund>), damit der Sprachblock als Ursache sichtbar wird; vorher stand dort nur die Anzahl.
Die Frontmatter-Grenze wird zeilenweise per Regex erkannt, nicht über find("---"): ein --- in einem Frontmatter-Wert bricht das Einfügen nicht. CRLF-Quellen behalten ihre Zeilenenden; ein Skill ohne geschlossenes Frontmatter wird unverändert kopiert.
Befund
In einer Instanz mit kb/CONVENTIONS.mdlanguage: de schrieb der Agent die kb/-Seiten korrekt auf Deutsch, sprach im Chat aber Englisch - Zwischenmeldungen zwischen Tool-Calls und die Abschlusszusammenfassung, auch wenn der User ausschließlich Deutsch schrieb. Funktional war der Ingest korrekt, es war ein UX-Defekt. Beobachtet vor allem in kurzen, einfachen Ingest-Läufen und verschärft bei schwächeren Modellen (Sonnet, zuletzt GPT). Einfache Queries sind nicht getestet.
Reales, anonymisiertes Transkript aus einer privaten Instanz (Kommentar vom 19.09.): User-Prompt deutsch („Ingeste “ plus Randbemerkung); alle Agent-Meldungen englisch („The file is promoted to raw/…“, „All edges applied correctly…“, „Published cleanly, no gate triggered…“), Abschluss ## Ingest complete vollständig englisch - während jede neu angelegte Seite korrekt deutsch war. Kein Tool-Output und keine Instruction hat Englisch verlangt.
Ob die Regel zum Zeitpunkt schon galt, ist nicht mehr feststellbar: „An agent speaks the instance's KB language“ steht seit c64479f (#99, 15.09.) in AGENTS.md; welchen Stand die private Instanz am 19.09. hatte, kann der Operator nicht mehr sagen. Der Bau rechtfertigt sich unabhängig davon über die Ursachen 2-4.
Ursachen (Analyse gegen den Tree, 11.10.)
Ort: Die Regel war Punkt 2 der „Two languages“ in AGENTS.md § File naming - ein Abschnitt über Dateien. Die Punkte 1 (Control Plane englisch) und 3 (Menschendoku englisch) gehören dorthin, weil sie die Sprache einer Datei an ihren Leser binden; Punkt 2 regelte dagegen Verhalten im Chat und war dort nicht zu finden. Außerdem war er als Feststellung formuliert („An agent speaks…“), nicht als Anweisung.
Indirektion:AGENTS.md nennt den Wert nicht, er steht in kb/CONVENTIONS.md. wiki-ingest liest die Datei erst, wenn Seitenprosa geschrieben wird (Schritt 5). Bis dahin sind mehrere englische Zwischenmeldungen geschrieben, und das Gespräch bleibt in der Sprache, in der es begonnen hat.
Kontextübermacht: Instructions, Tool-Ausgaben, Fehlermeldungen sind englisch; dagegen steht eine kurze deutsche Usernachricht. Schwächere Modelle folgen der dominanten Kontextsprache.
Claude Code:CLAUDE.md importiert USER.md/SOUL.md bewusst nicht; dass sie gelesen werden, hängt an der Modell-Compliance und fällt in kurzen Sessions plausibel weg.
Entscheidung: A und B zusammen (Operator, 11.10.)
A - die Gesprächsregel als Zweizeiler in einen eigenen Abschnitt von AGENTS.md. Behebt Ursache 1 und den Teil von 2, der sich ohne Wert im Kontext beheben lässt; deckt Sessions ohne Skill ab.
B - den Sprachwert in die veröffentlichten Skills kompilieren (instructions sync). Behebt 2 und 3: Der Wert steht genau dann im Kontext, wenn die Aufgabe beginnt. Das ist die Idee aus dem ursprünglichen Stub („als Platzhalter in die primären Skillfiles schreiben und mit Updates neu schreiben“), ohne Hand-Edit, weil die veröffentlichten Skills ohnehin generiert sind. Gilt für beide Zielverzeichnisse, .claude/skills/ und .agents/skills/ (Operator, 11.10. - das Problem trat zuletzt mit GPT auf).
Keine Wiederholung zwischen A und B: Die Regel steht nur in AGENTS.md, der Wert nur in kb/CONVENTIONS.md; die Skill-Zeile trägt den Wert und einen Verweis auf die Regel, nicht die Regel selbst, und ist generiert. Beides ist nötig: Der Zweizeiler deckt Sessions ohne Skill, die Skill-Zeile bringt den Wert in den Kontext - den AGENTS.md nicht tragen kann, weil es verbatim ausgeliefert wird.
Verworfen: Ausgabe der Sprache in wikitool sync (Tool-Output geht unter, sichtbar nur, wer session-setup befolgt); harness-eigene Spracheinstellungen (je Harness verschieden, nicht Teil des Stacks); alle drei Sprachregeln in einen neuen Abschnitt verschieben (erste Fassung dieses Bodys - Regeln 1 und 3 stehen in § File naming richtig, Operator 11.10.).
Randbedingung aus #99: Die Sprachregeln wurden damals nach AGENTS.md gezogen, weil sie in einer instanzeigenen Datei standen und stackeigene Dateien banden. Der Schnitt hier hält das ein - alle Regeln bleiben in AGENTS.md, nur Regel 2 bekam einen eigenen Abschnitt.
A im Detail (umgesetzt)
Neuer Abschnitt ## Conversation language direkt nach ## Invariants, in den Contents eingetragen, zwei Sätze: Jede Nachricht an den User - Zwischenmeldungen und Abschlussbericht eingeschlossen - in der KB-Sprache (language: im Frontmatter von kb/CONVENTIONS.md, zu Sessionbeginn gelesen); gilt unabhängig von der Sprache von Dateien, Tool-Ausgaben und Quellen; zitierte Befehle, Pfade und Feldnamen bleiben unverändert.
§ File naming: aus „Two languages“ wurde „Two rules for the language of a file“; die Gesprächsregel ist als Regel entfernt, bei Regel 1 steht der Halbsatz zum Mustersatz mit Link; Menschendoku ist jetzt Regel 2; „Nothing checks either mechanically…“ angepasst. Die Begründung steht nur noch in docs/explanation/language-boundaries.md.
Verweise auf die Gesprächsregel zeigen auf § Conversation language: instructions/dev/stack-dev, stack-build und stack-close (SKILL.md), instructions/CONTRACT.md (beide Abschnitte), docs/explanation/language-boundaries.md, kb/CONVENTIONS.md(.template). Unverändert blieben Verweise auf die Dateitabelle oder Regel 1/3.
B im Detail (umgesetzt)
tools/chemenu/commands/instructions_cmd.py: sync kopiert wie bisher, danach fügt render_skill_md in SKILL.md direkt nach der schließenden ----Zeile des Frontmatters genau einen Block ein: > **Conversation language: de** - see AGENTS.md§ Conversation language (value fromkb/CONVENTIONS.mdlanguage:, written by wikitool instructions sync). Der Text steht an einer Stelle (language_block), sync und Drift-Prüfung teilen ihn. Frontmatter und alle anderen Dateien bleiben byte-identisch.
Nur der Tag, kein Sprachname.
Keine Sprache deklariert: kein Block, SKILL.md unverändert; die sync-Meldung nennt die Sprache bzw. „no language declared“.
Drift: drift() vergleicht SKILL.md gegen die gerenderte Erwartung, alle übrigen Dateien byte-genau. Ist nur der Block der Unterschied, nennt die Meldung ihn („language block is for en, conventions say de“, „language block missing, conventions say de“, „language block is for de, conventions declare no language“). instructions verify und doctor nutzen beide drift().
setup-instance.md: Der KB-Sprach-Schritt liegt vor dem instructions sync-Schritt - bestätigt, keine Änderung.
Doku, die mitgezogen wurde
instructions/CONTRACT.md § Publishing und der Abschnitt zu ausgehenden Skill-Verweisen; Modul-Docstring und cli_contract-Records von instructions sync/verify; docs/explanation/language-boundaries.md (neuer Unterabschnitt „Why a rule alone did not hold“); tools/CONTRACT.md und docs/reference/commands/types-instructions-and-docs.md (regeneriert); CHANGES.md (Bump). Im Abschluss geprüft: keine weitere Doku wurde durch die Änderung veraltet.
Akzeptanzkriterien
AGENTS.md hat einen Abschnitt ## Conversation language direkt nach ## Invariants, in den Contents gelistet, mit der Gesprächsregel als Anweisung samt „language: zu Sessionbeginn lesen“ - nicht länger als ein kurzer Absatz.
§ File naming enthält die Gesprächsregel nicht mehr als Regel, nur den Halbsatz zum Mustersatz mit Link; Regeln 1 und 3 (jetzt 1 und 2) stehen unverändert dort; Zählformen und der „Nothing checks…“-Satz stimmen.
Jeder Verweis, der die Gesprächsregel meint, zeigt auf § Conversation language; docs verify und instructions verify sind grün (lokal und in CI-Run 672).
Nach instructions sync in einer Instanz mit language: de enthält jede SKILL.md unter .claude/skills/und.agents/skills/ direkt nach dem Frontmatter genau einen Sprachblock mit de und Verweis auf § Conversation language; Frontmatter und alle übrigen Dateien sind byte-identisch zur Quelle.
Ohne deklarierte Sprache ist jede veröffentlichte Kopie byte-identisch zur Quelle.
Wird language: nach dem sync geändert, melden instructions verify und doctor (skills) Drift für jede Kopie und benennen den Sprachblock als Grund; ein erneuter sync macht beide grün.
Ein zweiter sync ohne Änderung erzeugt byte-identische Kopien (idempotent, kein doppelter Block).
Tests in tools/chemenu/tests/test_instructions_cmd.py (und test_doctor.py für den Drift-Fall) decken die vier vorigen Punkte ab.
Die unter „Doku, die mitgezogen wurde“ genannten Stellen beschreiben die Kopie mit Sprachblock statt „byte for byte“.
Manuelle Gegenprobe nach dem Publish (nicht mechanisch prüfbar - wikitool eval liest nur Tool-Traces, nicht den Chat): ein kurzer Ingest mit Sonnet in dieser Instanz antwortet im Chat durchgehend Deutsch. Erfüllt (Operator, 12.10.). GPT (Luna) ist nicht getestet und war nicht Teil des Kriteriums.
Version
minor (version bump --minor), umgesetzt als 10.0.0-beta.9. Drop-in-Test: vorwärts - das Upgrade (upgrade-instance.md Schritt 8) führt instructions sync ohnehin aus, bis dahin meldet verify Drift mit der dokumentierten Reaktion; das ist bei jedem Release mit geänderten Skills so und keine neue Handarbeit. Rückwärts - die alte Version sieht die Kopien mit Sprachblock als Drift, ihr eigener sync stellt den alten Zustand her. Kein Befehl, kein Flag, keine maschinengelesene Datei ändert ihre Form; kb/ bleibt unberührt. Kein Boundary-Crossing, daher weder --breaking noch eine Migrationsangabe (die Kandidatenzeile 10.0.0 stammt aus früheren Bumps).
## Stand
Abgeschlossen. Veröffentlicht in `0f0a579` als **10.0.0-beta.9** (minor). **CI grün:** Run 672 (Push-Workflow, Jobs `verify` und `pwsh`) hat die Änderung mechanisch geprüft - Tests, Verify the development tree, Version gate, Distribution als frische Instanz. Run 673 (Release-Workflow) hat die Version aufgelöst und die Publish-Schritte für den Beta-Kandidaten wie vorgesehen übersprungen.
**Manuelle Gegenprobe (Operator, 12.10.):** Ein kurzer Ingest mit Sonnet in dieser Instanz antwortete im Chat durchgehend Deutsch - das letzte Akzeptanzkriterium ist erfüllt. **Nicht getestet:** GPT (Luna), mit dem das Problem zuletzt auftrat. Das Kriterium verlangte nur Sonnet; trägt die Regel bei GPT nicht, ist das ein neuer Befund und ein eigenes Issue, kein Rest dieses Issues.
Abweichungen gegenüber der Planung:
- Die Verweisliste der Planung hatte `kb/CONVENTIONS.md` und `kb/CONVENTIONS.md.template` nicht; beide verweisen jetzt auf beide Abschnitte (Control-Plane-Regel in § File naming, Gesprächsregel in § Conversation language).
- `doctor` nennt im `skills`-Detail jetzt den ersten Drift-Grund (`..., first: <Grund>`), damit der Sprachblock als Ursache sichtbar wird; vorher stand dort nur die Anzahl.
- Die Frontmatter-Grenze wird zeilenweise per Regex erkannt, nicht über `find("---")`: ein `---` in einem Frontmatter-Wert bricht das Einfügen nicht. CRLF-Quellen behalten ihre Zeilenenden; ein Skill ohne geschlossenes Frontmatter wird unverändert kopiert.
## Befund
In einer Instanz mit `kb/CONVENTIONS.md` `language: de` schrieb der Agent die `kb/`-Seiten korrekt auf Deutsch, sprach im **Chat** aber Englisch - Zwischenmeldungen zwischen Tool-Calls und die Abschlusszusammenfassung, auch wenn der User ausschließlich Deutsch schrieb. Funktional war der Ingest korrekt, es war ein UX-Defekt. Beobachtet vor allem in kurzen, einfachen Ingest-Läufen und verschärft bei schwächeren Modellen (Sonnet, zuletzt GPT). Einfache Queries sind nicht getestet.
Reales, anonymisiertes Transkript aus einer privaten Instanz (Kommentar vom 19.09.): User-Prompt deutsch („Ingeste <URL>“ plus Randbemerkung); alle Agent-Meldungen englisch („The file is promoted to raw/…“, „All edges applied correctly…“, „Published cleanly, no gate triggered…“), Abschluss `## Ingest complete` vollständig englisch - während jede neu angelegte Seite korrekt deutsch war. Kein Tool-Output und keine Instruction hat Englisch verlangt.
**Ob die Regel zum Zeitpunkt schon galt, ist nicht mehr feststellbar:** „An agent speaks the instance's KB language“ steht seit c64479f (#99, 15.09.) in `AGENTS.md`; welchen Stand die private Instanz am 19.09. hatte, kann der Operator nicht mehr sagen. Der Bau rechtfertigt sich unabhängig davon über die Ursachen 2-4.
## Ursachen (Analyse gegen den Tree, 11.10.)
1. **Ort:** Die Regel war Punkt 2 der „Two languages“ in `AGENTS.md` § File naming - ein Abschnitt über *Dateien*. Die Punkte 1 (Control Plane englisch) und 3 (Menschendoku englisch) gehören dorthin, weil sie die Sprache einer Datei an ihren Leser binden; Punkt 2 regelte dagegen Verhalten im Chat und war dort nicht zu finden. Außerdem war er als Feststellung formuliert („An agent speaks…“), nicht als Anweisung.
2. **Indirektion:** `AGENTS.md` nennt den Wert nicht, er steht in `kb/CONVENTIONS.md`. `wiki-ingest` liest die Datei erst, wenn Seitenprosa geschrieben wird (Schritt 5). Bis dahin sind mehrere englische Zwischenmeldungen geschrieben, und das Gespräch bleibt in der Sprache, in der es begonnen hat.
3. **Kontextübermacht:** Instructions, Tool-Ausgaben, Fehlermeldungen sind englisch; dagegen steht eine kurze deutsche Usernachricht. Schwächere Modelle folgen der dominanten Kontextsprache.
4. **Claude Code:** `CLAUDE.md` importiert `USER.md`/`SOUL.md` bewusst nicht; dass sie gelesen werden, hängt an der Modell-Compliance und fällt in kurzen Sessions plausibel weg.
## Entscheidung: A und B zusammen (Operator, 11.10.)
**A - die Gesprächsregel als Zweizeiler in einen eigenen Abschnitt von `AGENTS.md`.** Behebt Ursache 1 und den Teil von 2, der sich ohne Wert im Kontext beheben lässt; deckt Sessions ohne Skill ab.
**B - den Sprachwert in die veröffentlichten Skills kompilieren (`instructions sync`).** Behebt 2 und 3: Der Wert steht genau dann im Kontext, wenn die Aufgabe beginnt. Das ist die Idee aus dem ursprünglichen Stub („als Platzhalter in die primären Skillfiles schreiben und mit Updates neu schreiben“), ohne Hand-Edit, weil die veröffentlichten Skills ohnehin generiert sind. Gilt für **beide** Zielverzeichnisse, `.claude/skills/` und `.agents/skills/` (Operator, 11.10. - das Problem trat zuletzt mit GPT auf).
**Keine Wiederholung zwischen A und B:** Die Regel steht nur in `AGENTS.md`, der Wert nur in `kb/CONVENTIONS.md`; die Skill-Zeile trägt den Wert und einen Verweis auf die Regel, nicht die Regel selbst, und ist generiert. Beides ist nötig: Der Zweizeiler deckt Sessions ohne Skill, die Skill-Zeile bringt den *Wert* in den Kontext - den `AGENTS.md` nicht tragen kann, weil es verbatim ausgeliefert wird.
Verworfen: Ausgabe der Sprache in `wikitool sync` (Tool-Output geht unter, sichtbar nur, wer `session-setup` befolgt); harness-eigene Spracheinstellungen (je Harness verschieden, nicht Teil des Stacks); alle drei Sprachregeln in einen neuen Abschnitt verschieben (erste Fassung dieses Bodys - Regeln 1 und 3 stehen in § File naming richtig, Operator 11.10.).
Randbedingung aus #99: Die Sprachregeln wurden damals nach `AGENTS.md` gezogen, weil sie in einer instanzeigenen Datei standen und stackeigene Dateien banden. Der Schnitt hier hält das ein - alle Regeln bleiben in `AGENTS.md`, nur Regel 2 bekam einen eigenen Abschnitt.
### A im Detail (umgesetzt)
- Neuer Abschnitt `## Conversation language` direkt nach `## Invariants`, in den Contents eingetragen, zwei Sätze: Jede Nachricht an den User - Zwischenmeldungen und Abschlussbericht eingeschlossen - in der KB-Sprache (`language:` im Frontmatter von `kb/CONVENTIONS.md`, zu Sessionbeginn gelesen); gilt unabhängig von der Sprache von Dateien, Tool-Ausgaben und Quellen; zitierte Befehle, Pfade und Feldnamen bleiben unverändert.
- § File naming: aus „Two languages“ wurde „Two rules for the language of a file“; die Gesprächsregel ist als Regel entfernt, bei Regel 1 steht der Halbsatz zum Mustersatz mit Link; Menschendoku ist jetzt Regel 2; „Nothing checks either mechanically…“ angepasst. Die Begründung steht nur noch in `docs/explanation/language-boundaries.md`.
- Verweise auf die Gesprächsregel zeigen auf § Conversation language: `instructions/dev/stack-dev`, `stack-build` und `stack-close` (`SKILL.md`), `instructions/CONTRACT.md` (beide Abschnitte), `docs/explanation/language-boundaries.md`, `kb/CONVENTIONS.md(.template)`. Unverändert blieben Verweise auf die Dateitabelle oder Regel 1/3.
### B im Detail (umgesetzt)
- `tools/chemenu/commands/instructions_cmd.py`: `sync` kopiert wie bisher, danach fügt `render_skill_md` in `SKILL.md` direkt nach der schließenden `---`-Zeile des Frontmatters genau einen Block ein: `> **Conversation language: `de`** - see `AGENTS.md` § Conversation language (value from `kb/CONVENTIONS.md` `language:`, written by `wikitool instructions sync`).` Der Text steht an einer Stelle (`language_block`), `sync` und Drift-Prüfung teilen ihn. Frontmatter und alle anderen Dateien bleiben byte-identisch.
- Nur der Tag, kein Sprachname.
- Keine Sprache deklariert: kein Block, `SKILL.md` unverändert; die `sync`-Meldung nennt die Sprache bzw. „no language declared“.
- Drift: `drift()` vergleicht `SKILL.md` gegen die gerenderte Erwartung, alle übrigen Dateien byte-genau. Ist nur der Block der Unterschied, nennt die Meldung ihn („language block is for `en`, conventions say `de`“, „language block missing, conventions say `de`“, „language block is for `de`, conventions declare no language“). `instructions verify` und `doctor` nutzen beide `drift()`.
- `setup-instance.md`: Der KB-Sprach-Schritt liegt vor dem `instructions sync`-Schritt - bestätigt, keine Änderung.
### Doku, die mitgezogen wurde
`instructions/CONTRACT.md` § Publishing und der Abschnitt zu ausgehenden Skill-Verweisen; Modul-Docstring und `cli_contract`-Records von `instructions sync`/`verify`; `docs/explanation/language-boundaries.md` (neuer Unterabschnitt „Why a rule alone did not hold“); `tools/CONTRACT.md` und `docs/reference/commands/types-instructions-and-docs.md` (regeneriert); `CHANGES.md` (Bump). Im Abschluss geprüft: keine weitere Doku wurde durch die Änderung veraltet.
## Akzeptanzkriterien
- [x] `AGENTS.md` hat einen Abschnitt `## Conversation language` direkt nach `## Invariants`, in den Contents gelistet, mit der Gesprächsregel als Anweisung samt „`language:` zu Sessionbeginn lesen“ - nicht länger als ein kurzer Absatz.
- [x] § File naming enthält die Gesprächsregel nicht mehr als Regel, nur den Halbsatz zum Mustersatz mit Link; Regeln 1 und 3 (jetzt 1 und 2) stehen unverändert dort; Zählformen und der „Nothing checks…“-Satz stimmen.
- [x] Jeder Verweis, der die Gesprächsregel meint, zeigt auf § Conversation language; `docs verify` und `instructions verify` sind grün (lokal und in CI-Run 672).
- [x] Nach `instructions sync` in einer Instanz mit `language: de` enthält jede `SKILL.md` unter `.claude/skills/` **und** `.agents/skills/` direkt nach dem Frontmatter genau einen Sprachblock mit `de` und Verweis auf § Conversation language; Frontmatter und alle übrigen Dateien sind byte-identisch zur Quelle.
- [x] Ohne deklarierte Sprache ist jede veröffentlichte Kopie byte-identisch zur Quelle.
- [x] Wird `language:` nach dem `sync` geändert, melden `instructions verify` und `doctor` (`skills`) Drift für jede Kopie und benennen den Sprachblock als Grund; ein erneuter `sync` macht beide grün.
- [x] Ein zweiter `sync` ohne Änderung erzeugt byte-identische Kopien (idempotent, kein doppelter Block).
- [x] Tests in `tools/chemenu/tests/test_instructions_cmd.py` (und `test_doctor.py` für den Drift-Fall) decken die vier vorigen Punkte ab.
- [x] Die unter „Doku, die mitgezogen wurde“ genannten Stellen beschreiben die Kopie mit Sprachblock statt „byte for byte“.
- [x] Manuelle Gegenprobe nach dem Publish (nicht mechanisch prüfbar - `wikitool eval` liest nur Tool-Traces, nicht den Chat): ein kurzer Ingest mit Sonnet in dieser Instanz antwortet im Chat durchgehend Deutsch. **Erfüllt (Operator, 12.10.).** GPT (Luna) ist nicht getestet und war nicht Teil des Kriteriums.
## Version
**minor** (`version bump --minor`), umgesetzt als 10.0.0-beta.9. Drop-in-Test: *vorwärts* - das Upgrade (`upgrade-instance.md` Schritt 8) führt `instructions sync` ohnehin aus, bis dahin meldet `verify` Drift mit der dokumentierten Reaktion; das ist bei jedem Release mit geänderten Skills so und keine neue Handarbeit. *Rückwärts* - die alte Version sieht die Kopien mit Sprachblock als Drift, ihr eigener `sync` stellt den alten Zustand her. Kein Befehl, kein Flag, keine maschinengelesene Datei ändert ihre Form; `kb/` bleibt unberührt. Kein Boundary-Crossing, daher weder `--breaking` noch eine Migrationsangabe (die Kandidatenzeile 10.0.0 stammt aus früheren Bumps).
Beispiel-Transkript (real, anonymisiert) an die Issue-Beschreibung angehaengt - zeigt einen kurzen Ingest-Lauf, bei dem der kb-Inhalt korrekt Deutsch war, die Chat-Antworten an den User aber durchgehend Englisch blieben.
Beispiel-Transkript (real, anonymisiert) an die Issue-Beschreibung angehaengt - zeigt einen kurzen Ingest-Lauf, bei dem der kb-Inhalt korrekt Deutsch war, die Chat-Antworten an den User aber durchgehend Englisch blieben.
torben
changed title from Agent spricht englisch mit mir in einer deutschen kb to Agent spricht im Chat Englisch, obwohl die KB-Sprache Deutsch ist - Regel sichtbar machen und Sprachwert in die Skills kompilieren2026-10-11 20:47:46 +00:00
Changelog: Body gegen den Tree ausgearbeitet und neu geschrieben: Ursachenanalyse (Regel steht seit #99 in AGENTS.md § File naming, aber an falscher Stelle, ohne Wert, gegen englische Kontextübermacht), Entscheidung des Operators für A (eigener Abschnitt ## Language in AGENTS.md) plus B (instructions sync kompiliert den Sprachtag in jede veröffentlichte SKILL.md, beide Harness-Verzeichnisse), Akzeptanzkriterien, Version minor. Ob die beobachtete Session schon #99 hatte, ist nicht mehr feststellbar - im Body vermerkt. Labels: status/unconfirmed entfernt (Verhalten durch das Transkript belegt), gesetzt area/kb, kind/build, prio/planned, size/M. Titel präzisiert.
Ursprünglicher Stub, wörtlich:
Vor allem zu sehen in kurzen, einfachen ingest Läufen
Vermutlich liest Sonnet nicht die Regeln vollständig ein, selective disclosure bringt es nicht soweit in einfachen fällen.
Eventuell nur mit Anpassungen direkt in agents.md wirklich zuverlässig
Ist effektiv ein UX Thema, funktional ist alles richtig beim ingest
Nicht für einfache queries getestet
speziell schwächere modelle zeigen das Problem verschärft. Eventuell müssen wir das einfack als Platzhaltr in die primäen skillfiles schreiben und das mit Updates halt neu schreiben. Zuletzt aufgetreren mit GPT
**Changelog:** Body gegen den Tree ausgearbeitet und neu geschrieben: Ursachenanalyse (Regel steht seit #99 in `AGENTS.md` § File naming, aber an falscher Stelle, ohne Wert, gegen englische Kontextübermacht), Entscheidung des Operators für A (eigener Abschnitt `## Language` in `AGENTS.md`) plus B (`instructions sync` kompiliert den Sprachtag in jede veröffentlichte `SKILL.md`, beide Harness-Verzeichnisse), Akzeptanzkriterien, Version minor. Ob die beobachtete Session schon #99 hatte, ist nicht mehr feststellbar - im Body vermerkt. Labels: `status/unconfirmed` entfernt (Verhalten durch das Transkript belegt), gesetzt `area/kb`, `kind/build`, `prio/planned`, `size/M`. Titel präzisiert.
Ursprünglicher Stub, wörtlich:
> Vor allem zu sehen in kurzen, einfachen ingest Läufen
> Vermutlich liest Sonnet nicht die Regeln vollständig ein, selective disclosure bringt es nicht soweit in einfachen fällen.
> Eventuell nur mit Anpassungen direkt in agents.md wirklich zuverlässig
> Ist effektiv ein UX Thema, funktional ist alles richtig beim ingest
> Nicht für einfache queries getestet
> speziell schwächere modelle zeigen das Problem verschärft. Eventuell müssen wir das einfack als Platzhaltr in die primäen skillfiles schreiben und das mit Updates halt neu schreiben. Zuletzt aufgetreren mit GPT
Changelog: A verkleinert (Operator, 11.10.): statt alle drei Sprachregeln in einen neuen Abschnitt ## Language zu verschieben, bekommt nur die Gesprächsregel einen Zweizeiler-Abschnitt ## Conversation language nach den Invarianten; Regeln 1 und 3 bleiben in § File naming, wo sie als Datei-Regeln hingehören. Skill-Block verweist auf den neuen Abschnitt und trägt nur Wert + Verweis. Verweisliste entsprechend auf die Stellen reduziert, die die Gesprächsregel meinen; #99-Randbedingung (Regeln in stackeigener Datei) als eingehalten vermerkt. Akzeptanzkriterien 1-3 angepasst.
**Changelog:** A verkleinert (Operator, 11.10.): statt alle drei Sprachregeln in einen neuen Abschnitt `## Language` zu verschieben, bekommt nur die Gesprächsregel einen Zweizeiler-Abschnitt `## Conversation language` nach den Invarianten; Regeln 1 und 3 bleiben in § File naming, wo sie als Datei-Regeln hingehören. Skill-Block verweist auf den neuen Abschnitt und trägt nur Wert + Verweis. Verweisliste entsprechend auf die Stellen reduziert, die die Gesprächsregel meinen; #99-Randbedingung (Regeln in stackeigener Datei) als eingehalten vermerkt. Akzeptanzkriterien 1-3 angepasst.
Build-Phase abgeschlossen: veröffentlicht in 0f0a579 als 10.0.0-beta.9 (minor), CI-Run 672 grün, Release-Run 673 für den Beta-Kandidaten wie vorgesehen übersprungen.
AGENTS.md: neuer Abschnitt ## Conversation language nach den Invarianten; § File naming trägt nur noch die zwei Dateisprachregeln, Verweise (Skills, instructions/CONTRACT.md, language-boundaries.md, kb/CONVENTIONS.md(.template)) zeigen auf den neuen Abschnitt.
instructions sync schreibt in jede veröffentlichte SKILL.md (.claude/skills/ und .agents/skills/) direkt nach dem Frontmatter eine generierte Zeile mit dem Sprachtag aus kb/CONVENTIONS.md; ohne deklarierte Sprache bleibt die Kopie unverändert. drift(), instructions verify und doctor vergleichen gegen diese Erwartung und nennen den Sprachblock als Grund; doctor zeigt zusätzlich den ersten Drift-Grund.
Tests: 14 neue in test_instructions_cmd.py, 1 in test_doctor.py; Docs (Contract, Referenz, language-boundaries.md) beschreiben „Kopie plus Sprachblock“.
Offen: die manuelle Gegenprobe mit Sonnet (Ingest in dieser Instanz, Chat durchgehend Deutsch) - Aufgabe des Abschlusses.
Build-Phase abgeschlossen: veröffentlicht in `0f0a579` als 10.0.0-beta.9 (minor), CI-Run 672 grün, Release-Run 673 für den Beta-Kandidaten wie vorgesehen übersprungen.
- `AGENTS.md`: neuer Abschnitt `## Conversation language` nach den Invarianten; § File naming trägt nur noch die zwei Dateisprachregeln, Verweise (Skills, `instructions/CONTRACT.md`, `language-boundaries.md`, `kb/CONVENTIONS.md(.template)`) zeigen auf den neuen Abschnitt.
- `instructions sync` schreibt in jede veröffentlichte `SKILL.md` (`.claude/skills/` und `.agents/skills/`) direkt nach dem Frontmatter eine generierte Zeile mit dem Sprachtag aus `kb/CONVENTIONS.md`; ohne deklarierte Sprache bleibt die Kopie unverändert. `drift()`, `instructions verify` und `doctor` vergleichen gegen diese Erwartung und nennen den Sprachblock als Grund; `doctor` zeigt zusätzlich den ersten Drift-Grund.
- Tests: 14 neue in `test_instructions_cmd.py`, 1 in `test_doctor.py`; Docs (Contract, Referenz, `language-boundaries.md`) beschreiben „Kopie plus Sprachblock“.
Offen: die manuelle Gegenprobe mit Sonnet (Ingest in dieser Instanz, Chat durchgehend Deutsch) - Aufgabe des Abschlusses.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Stand
Abgeschlossen. Veröffentlicht in
0f0a579als 10.0.0-beta.9 (minor). CI grün: Run 672 (Push-Workflow, Jobsverifyundpwsh) hat die Änderung mechanisch geprüft - Tests, Verify the development tree, Version gate, Distribution als frische Instanz. Run 673 (Release-Workflow) hat die Version aufgelöst und die Publish-Schritte für den Beta-Kandidaten wie vorgesehen übersprungen.Manuelle Gegenprobe (Operator, 12.10.): Ein kurzer Ingest mit Sonnet in dieser Instanz antwortete im Chat durchgehend Deutsch - das letzte Akzeptanzkriterium ist erfüllt. Nicht getestet: GPT (Luna), mit dem das Problem zuletzt auftrat. Das Kriterium verlangte nur Sonnet; trägt die Regel bei GPT nicht, ist das ein neuer Befund und ein eigenes Issue, kein Rest dieses Issues.
Abweichungen gegenüber der Planung:
kb/CONVENTIONS.mdundkb/CONVENTIONS.md.templatenicht; beide verweisen jetzt auf beide Abschnitte (Control-Plane-Regel in § File naming, Gesprächsregel in § Conversation language).doctornennt imskills-Detail jetzt den ersten Drift-Grund (..., first: <Grund>), damit der Sprachblock als Ursache sichtbar wird; vorher stand dort nur die Anzahl.find("---"): ein---in einem Frontmatter-Wert bricht das Einfügen nicht. CRLF-Quellen behalten ihre Zeilenenden; ein Skill ohne geschlossenes Frontmatter wird unverändert kopiert.Befund
In einer Instanz mit
kb/CONVENTIONS.mdlanguage: deschrieb der Agent diekb/-Seiten korrekt auf Deutsch, sprach im Chat aber Englisch - Zwischenmeldungen zwischen Tool-Calls und die Abschlusszusammenfassung, auch wenn der User ausschließlich Deutsch schrieb. Funktional war der Ingest korrekt, es war ein UX-Defekt. Beobachtet vor allem in kurzen, einfachen Ingest-Läufen und verschärft bei schwächeren Modellen (Sonnet, zuletzt GPT). Einfache Queries sind nicht getestet.Reales, anonymisiertes Transkript aus einer privaten Instanz (Kommentar vom 19.09.): User-Prompt deutsch („Ingeste “ plus Randbemerkung); alle Agent-Meldungen englisch („The file is promoted to raw/…“, „All edges applied correctly…“, „Published cleanly, no gate triggered…“), Abschluss
## Ingest completevollständig englisch - während jede neu angelegte Seite korrekt deutsch war. Kein Tool-Output und keine Instruction hat Englisch verlangt.Ob die Regel zum Zeitpunkt schon galt, ist nicht mehr feststellbar: „An agent speaks the instance's KB language“ steht seit
c64479f(#99, 15.09.) inAGENTS.md; welchen Stand die private Instanz am 19.09. hatte, kann der Operator nicht mehr sagen. Der Bau rechtfertigt sich unabhängig davon über die Ursachen 2-4.Ursachen (Analyse gegen den Tree, 11.10.)
AGENTS.md§ File naming - ein Abschnitt über Dateien. Die Punkte 1 (Control Plane englisch) und 3 (Menschendoku englisch) gehören dorthin, weil sie die Sprache einer Datei an ihren Leser binden; Punkt 2 regelte dagegen Verhalten im Chat und war dort nicht zu finden. Außerdem war er als Feststellung formuliert („An agent speaks…“), nicht als Anweisung.AGENTS.mdnennt den Wert nicht, er steht inkb/CONVENTIONS.md.wiki-ingestliest die Datei erst, wenn Seitenprosa geschrieben wird (Schritt 5). Bis dahin sind mehrere englische Zwischenmeldungen geschrieben, und das Gespräch bleibt in der Sprache, in der es begonnen hat.CLAUDE.mdimportiertUSER.md/SOUL.mdbewusst nicht; dass sie gelesen werden, hängt an der Modell-Compliance und fällt in kurzen Sessions plausibel weg.Entscheidung: A und B zusammen (Operator, 11.10.)
A - die Gesprächsregel als Zweizeiler in einen eigenen Abschnitt von
AGENTS.md. Behebt Ursache 1 und den Teil von 2, der sich ohne Wert im Kontext beheben lässt; deckt Sessions ohne Skill ab.B - den Sprachwert in die veröffentlichten Skills kompilieren (
instructions sync). Behebt 2 und 3: Der Wert steht genau dann im Kontext, wenn die Aufgabe beginnt. Das ist die Idee aus dem ursprünglichen Stub („als Platzhalter in die primären Skillfiles schreiben und mit Updates neu schreiben“), ohne Hand-Edit, weil die veröffentlichten Skills ohnehin generiert sind. Gilt für beide Zielverzeichnisse,.claude/skills/und.agents/skills/(Operator, 11.10. - das Problem trat zuletzt mit GPT auf).Keine Wiederholung zwischen A und B: Die Regel steht nur in
AGENTS.md, der Wert nur inkb/CONVENTIONS.md; die Skill-Zeile trägt den Wert und einen Verweis auf die Regel, nicht die Regel selbst, und ist generiert. Beides ist nötig: Der Zweizeiler deckt Sessions ohne Skill, die Skill-Zeile bringt den Wert in den Kontext - denAGENTS.mdnicht tragen kann, weil es verbatim ausgeliefert wird.Verworfen: Ausgabe der Sprache in
wikitool sync(Tool-Output geht unter, sichtbar nur, wersession-setupbefolgt); harness-eigene Spracheinstellungen (je Harness verschieden, nicht Teil des Stacks); alle drei Sprachregeln in einen neuen Abschnitt verschieben (erste Fassung dieses Bodys - Regeln 1 und 3 stehen in § File naming richtig, Operator 11.10.).Randbedingung aus #99: Die Sprachregeln wurden damals nach
AGENTS.mdgezogen, weil sie in einer instanzeigenen Datei standen und stackeigene Dateien banden. Der Schnitt hier hält das ein - alle Regeln bleiben inAGENTS.md, nur Regel 2 bekam einen eigenen Abschnitt.A im Detail (umgesetzt)
## Conversation languagedirekt nach## Invariants, in den Contents eingetragen, zwei Sätze: Jede Nachricht an den User - Zwischenmeldungen und Abschlussbericht eingeschlossen - in der KB-Sprache (language:im Frontmatter vonkb/CONVENTIONS.md, zu Sessionbeginn gelesen); gilt unabhängig von der Sprache von Dateien, Tool-Ausgaben und Quellen; zitierte Befehle, Pfade und Feldnamen bleiben unverändert.docs/explanation/language-boundaries.md.instructions/dev/stack-dev,stack-buildundstack-close(SKILL.md),instructions/CONTRACT.md(beide Abschnitte),docs/explanation/language-boundaries.md,kb/CONVENTIONS.md(.template). Unverändert blieben Verweise auf die Dateitabelle oder Regel 1/3.B im Detail (umgesetzt)
tools/chemenu/commands/instructions_cmd.py:synckopiert wie bisher, danach fügtrender_skill_mdinSKILL.mddirekt nach der schließenden----Zeile des Frontmatters genau einen Block ein:> **Conversation language:de** - seeAGENTS.md§ Conversation language (value fromkb/CONVENTIONS.mdlanguage:, written bywikitool instructions sync).Der Text steht an einer Stelle (language_block),syncund Drift-Prüfung teilen ihn. Frontmatter und alle anderen Dateien bleiben byte-identisch.SKILL.mdunverändert; diesync-Meldung nennt die Sprache bzw. „no language declared“.drift()vergleichtSKILL.mdgegen die gerenderte Erwartung, alle übrigen Dateien byte-genau. Ist nur der Block der Unterschied, nennt die Meldung ihn („language block is foren, conventions sayde“, „language block missing, conventions sayde“, „language block is forde, conventions declare no language“).instructions verifyunddoctornutzen beidedrift().setup-instance.md: Der KB-Sprach-Schritt liegt vor deminstructions sync-Schritt - bestätigt, keine Änderung.Doku, die mitgezogen wurde
instructions/CONTRACT.md§ Publishing und der Abschnitt zu ausgehenden Skill-Verweisen; Modul-Docstring undcli_contract-Records voninstructions sync/verify;docs/explanation/language-boundaries.md(neuer Unterabschnitt „Why a rule alone did not hold“);tools/CONTRACT.mdunddocs/reference/commands/types-instructions-and-docs.md(regeneriert);CHANGES.md(Bump). Im Abschluss geprüft: keine weitere Doku wurde durch die Änderung veraltet.Akzeptanzkriterien
AGENTS.mdhat einen Abschnitt## Conversation languagedirekt nach## Invariants, in den Contents gelistet, mit der Gesprächsregel als Anweisung samt „language:zu Sessionbeginn lesen“ - nicht länger als ein kurzer Absatz.docs verifyundinstructions verifysind grün (lokal und in CI-Run 672).instructions syncin einer Instanz mitlanguage: deenthält jedeSKILL.mdunter.claude/skills/und.agents/skills/direkt nach dem Frontmatter genau einen Sprachblock mitdeund Verweis auf § Conversation language; Frontmatter und alle übrigen Dateien sind byte-identisch zur Quelle.language:nach demsyncgeändert, meldeninstructions verifyunddoctor(skills) Drift für jede Kopie und benennen den Sprachblock als Grund; ein erneutersyncmacht beide grün.syncohne Änderung erzeugt byte-identische Kopien (idempotent, kein doppelter Block).tools/chemenu/tests/test_instructions_cmd.py(undtest_doctor.pyfür den Drift-Fall) decken die vier vorigen Punkte ab.wikitool evalliest nur Tool-Traces, nicht den Chat): ein kurzer Ingest mit Sonnet in dieser Instanz antwortet im Chat durchgehend Deutsch. Erfüllt (Operator, 12.10.). GPT (Luna) ist nicht getestet und war nicht Teil des Kriteriums.Version
minor (
version bump --minor), umgesetzt als 10.0.0-beta.9. Drop-in-Test: vorwärts - das Upgrade (upgrade-instance.mdSchritt 8) führtinstructions syncohnehin aus, bis dahin meldetverifyDrift mit der dokumentierten Reaktion; das ist bei jedem Release mit geänderten Skills so und keine neue Handarbeit. Rückwärts - die alte Version sieht die Kopien mit Sprachblock als Drift, ihr eigenersyncstellt den alten Zustand her. Kein Befehl, kein Flag, keine maschinengelesene Datei ändert ihre Form;kb/bleibt unberührt. Kein Boundary-Crossing, daher weder--breakingnoch eine Migrationsangabe (die Kandidatenzeile 10.0.0 stammt aus früheren Bumps).Beispiel-Transkript (real, anonymisiert) an die Issue-Beschreibung angehaengt - zeigt einen kurzen Ingest-Lauf, bei dem der kb-Inhalt korrekt Deutsch war, die Chat-Antworten an den User aber durchgehend Englisch blieben.
Agent spricht englisch mit mir in einer deutschen kbto Agent spricht im Chat Englisch, obwohl die KB-Sprache Deutsch ist - Regel sichtbar machen und Sprachwert in die Skills kompilierenChangelog: Body gegen den Tree ausgearbeitet und neu geschrieben: Ursachenanalyse (Regel steht seit #99 in
AGENTS.md§ File naming, aber an falscher Stelle, ohne Wert, gegen englische Kontextübermacht), Entscheidung des Operators für A (eigener Abschnitt## LanguageinAGENTS.md) plus B (instructions synckompiliert den Sprachtag in jede veröffentlichteSKILL.md, beide Harness-Verzeichnisse), Akzeptanzkriterien, Version minor. Ob die beobachtete Session schon #99 hatte, ist nicht mehr feststellbar - im Body vermerkt. Labels:status/unconfirmedentfernt (Verhalten durch das Transkript belegt), gesetztarea/kb,kind/build,prio/planned,size/M. Titel präzisiert.Ursprünglicher Stub, wörtlich:
Changelog: A verkleinert (Operator, 11.10.): statt alle drei Sprachregeln in einen neuen Abschnitt
## Languagezu verschieben, bekommt nur die Gesprächsregel einen Zweizeiler-Abschnitt## Conversation languagenach den Invarianten; Regeln 1 und 3 bleiben in § File naming, wo sie als Datei-Regeln hingehören. Skill-Block verweist auf den neuen Abschnitt und trägt nur Wert + Verweis. Verweisliste entsprechend auf die Stellen reduziert, die die Gesprächsregel meinen; #99-Randbedingung (Regeln in stackeigener Datei) als eingehalten vermerkt. Akzeptanzkriterien 1-3 angepasst.Build-Phase abgeschlossen: veröffentlicht in
0f0a579als 10.0.0-beta.9 (minor), CI-Run 672 grün, Release-Run 673 für den Beta-Kandidaten wie vorgesehen übersprungen.AGENTS.md: neuer Abschnitt## Conversation languagenach den Invarianten; § File naming trägt nur noch die zwei Dateisprachregeln, Verweise (Skills,instructions/CONTRACT.md,language-boundaries.md,kb/CONVENTIONS.md(.template)) zeigen auf den neuen Abschnitt.instructions syncschreibt in jede veröffentlichteSKILL.md(.claude/skills/und.agents/skills/) direkt nach dem Frontmatter eine generierte Zeile mit dem Sprachtag auskb/CONVENTIONS.md; ohne deklarierte Sprache bleibt die Kopie unverändert.drift(),instructions verifyunddoctorvergleichen gegen diese Erwartung und nennen den Sprachblock als Grund;doctorzeigt zusätzlich den ersten Drift-Grund.test_instructions_cmd.py, 1 intest_doctor.py; Docs (Contract, Referenz,language-boundaries.md) beschreiben „Kopie plus Sprachblock“.Offen: die manuelle Gegenprobe mit Sonnet (Ingest in dieser Instanz, Chat durchgehend Deutsch) - Aufgabe des Abschlusses.
Changelog: Abschluss. Letztes Kriterium (manuelle Gegenprobe mit Sonnet) erfüllt, Chat durchgehend Deutsch (Operator, 12.10.); Body auf Endzustand gebracht, alle Kriterien abgehakt. Doku-Staleness-Prüfung: nichts veraltet. GPT (Luna) bleibt ungetestet; bei Negativbefund ein eigenes Issue.