kb/concepts/ bekommt Areas: layout: fuer concept, Area-Titel aus jedem Type-Spec, Schwellen-Empfehlung im lint (schliesst #59)
CI / verify (push) Successful in 52s
Release / release (push) Successful in 36s

Files changed:
- CHANGES.md
- README.md
- VERSION
- kb/concepts/Ambient Environment Dependency.md
- kb/concepts/Anti-Cramming Heuristic.md
- kb/concepts/Audit Trail.md
- kb/concepts/BM25.md
- kb/concepts/Bulk Operations.md
- kb/concepts/CI Integration.md
- kb/concepts/COLLECTION.md
- kb/concepts/CPPC.md
- kb/concepts/Checkpoint Audit.md
- kb/concepts/Claude Code Auto Mode.md
- kb/concepts/Command Round-Trip Integrity.md
- kb/concepts/Confidence Scoring.md
- kb/concepts/Consolidation Tiers.md
- kb/concepts/Content Quality Control.md
- kb/concepts/Context Isolation.md
- kb/concepts/Contradiction Resolution.md
- kb/concepts/Cross-platform Agent Skills.md
- kb/concepts/Crystallization.md
- kb/concepts/Delete Rather Than Anonymize.md
- kb/concepts/Denylist over Allowlist.md
- kb/concepts/Detect-Repair Asymmetry.md
- kb/concepts/Diff-Reviewable Agent Edits.md
- kb/concepts/Dual Licensing by File Plan.md
- kb/concepts/Entity Extraction.md
- kb/concepts/Episodic Memory.md
- kb/concepts/Event-Driven Automation.md
- kb/concepts/Filter on Ingest.md
- kb/concepts/Forgetting.md
- kb/concepts/Graph Traversal.md
- kb/concepts/Green Suite Blind Spot.md
- kb/concepts/Hooks.md
- kb/concepts/Hybrid Search.md
- kb/concepts/INDEX.md
- kb/concepts/Implementation Spectrum.md
- kb/concepts/Index Scaling.md
- kb/concepts/Issue Label Scheme.md
- kb/concepts/Iteration and Cost Limits.md
- kb/concepts/KB Migration.md
- kb/concepts/KB Stack Versioning.md
- kb/concepts/Knowledge Compounding.md
- kb/concepts/Knowledge Graph.md
- kb/concepts/LLM Wiki Pattern.md
- kb/concepts/Lint Workflow.md
- kb/concepts/MCP-Leseserver.md
- kb/concepts/Mass-Update Gate.md
- kb/concepts/Memory Lifecycle.md
- kb/concepts/Mesh Sync.md
- kb/concepts/Modbus.md
- kb/concepts/Multi-Agent Collaboration.md
- kb/concepts/Naming Convention Conflict.md
- kb/concepts/OKF Compatibility.md
- kb/concepts/Optional Instance Context File.md
- kb/concepts/Personalization Plane.md
- kb/concepts/Privacy and Governance.md
- kb/concepts/Procedural Memory.md
- kb/concepts/Publish-Remote Gate.md
- kb/concepts/Quality Scoring.md
- kb/concepts/Quality and Self-Correction.md
- kb/concepts/RAG.md
- kb/concepts/Reciprocal Rank Fusion.md
- kb/concepts/SSD TRIM.md
- kb/concepts/Scale Ceiling.md
- kb/concepts/Self-Healing.md
- kb/concepts/Semantic Lint Automation.md
- kb/concepts/Semantic Memory.md
- kb/concepts/Session Orientation.md
- kb/concepts/Shared vs Private.md
- kb/concepts/Split Merge Reclassify.md
- kb/concepts/Split Threshold.md
- kb/concepts/Structural Enforcement over Documented Rule.md
- kb/concepts/Stub Threshold.md
- kb/concepts/Supersession.md
- kb/concepts/Three-Layer Architecture.md
- kb/concepts/Token Economics.md
- kb/concepts/Typed Relationships.md
- kb/concepts/User Management.md
- kb/concepts/Vector Search.md
- kb/concepts/Work Coordination.md
- kb/concepts/Workflow Extraction.md
- kb/concepts/Workflow Orchestration.md
- kb/concepts/Working Memory.md
- kb/concepts/Write-Once Frontmatter Fields.md
- kb/concepts/architectures/Consolidation Tiers.md
- kb/concepts/architectures/Context Isolation.md
- kb/concepts/architectures/Cross-platform Agent Skills.md
- kb/concepts/architectures/Episodic Memory.md
- kb/concepts/architectures/Hybrid Search.md
- kb/concepts/architectures/Implementation Spectrum.md
- kb/concepts/architectures/Knowledge Graph.md
- kb/concepts/architectures/LLM Wiki Pattern.md
- kb/concepts/architectures/MCP-Leseserver.md
- kb/concepts/architectures/Memory Lifecycle.md
- kb/concepts/architectures/OKF Compatibility.md
- kb/concepts/architectures/Optional Instance Context File.md
- kb/concepts/architectures/Personalization Plane.md
- kb/concepts/architectures/Procedural Memory.md
- kb/concepts/architectures/RAG.md
- kb/concepts/architectures/Scale Ceiling.md
- kb/concepts/architectures/Semantic Memory.md
- kb/concepts/architectures/Three-Layer Architecture.md
- kb/concepts/architectures/Token Economics.md
- kb/concepts/architectures/Working Memory.md
- kb/concepts/decisions/Delete Rather Than Anonymize.md
- kb/concepts/decisions/Denylist over Allowlist.md
- kb/concepts/decisions/Diff-Reviewable Agent Edits.md
- kb/concepts/decisions/Dual Licensing by File Plan.md
- kb/concepts/decisions/Issue Label Scheme.md
- kb/concepts/decisions/KB Stack Versioning.md
- kb/concepts/decisions/Structural Enforcement over Documented Rule.md
- kb/concepts/patterns/Audit Trail.md
- kb/concepts/patterns/BM25.md
- kb/concepts/patterns/Command Round-Trip Integrity.md
- kb/concepts/patterns/Confidence Scoring.md
- kb/concepts/patterns/Contradiction Resolution.md
- kb/concepts/patterns/Entity Extraction.md
- kb/concepts/patterns/Filter on Ingest.md
- kb/concepts/patterns/Forgetting.md
- kb/concepts/patterns/Graph Traversal.md
- kb/concepts/patterns/Mesh Sync.md
- kb/concepts/patterns/Quality Scoring.md
- kb/concepts/patterns/Reciprocal Rank Fusion.md
- kb/concepts/patterns/Self-Healing.md
- kb/concepts/patterns/Shared vs Private.md
- kb/concepts/patterns/Typed Relationships.md
- kb/concepts/patterns/Vector Search.md
- kb/concepts/patterns/Work Coordination.md
- kb/concepts/problems/Ambient Environment Dependency.md
- kb/concepts/problems/Detect-Repair Asymmetry.md
- kb/concepts/problems/Green Suite Blind Spot.md
- kb/concepts/problems/Naming Convention Conflict.md
- kb/concepts/problems/Write-Once Frontmatter Fields.md
- kb/concepts/protocols/CPPC.md
- kb/concepts/protocols/Modbus.md
- kb/concepts/protocols/SSD TRIM.md
- kb/concepts/workflows/Anti-Cramming Heuristic.md
- kb/concepts/workflows/Bulk Operations.md
- kb/concepts/workflows/CI Integration.md
- kb/concepts/workflows/Checkpoint Audit.md
- kb/concepts/workflows/Claude Code Auto Mode.md
- kb/concepts/workflows/Content Quality Control.md
- kb/concepts/workflows/Crystallization.md
- kb/concepts/workflows/Event-Driven Automation.md
- kb/concepts/workflows/Hooks.md
- kb/concepts/workflows/Index Scaling.md
- kb/concepts/workflows/Iteration and Cost Limits.md
- kb/concepts/workflows/KB Migration.md
- kb/concepts/workflows/Knowledge Compounding.md
- kb/concepts/workflows/Lint Workflow.md
- kb/concepts/workflows/Mass-Update Gate.md
- kb/concepts/workflows/Multi-Agent Collaboration.md
- kb/concepts/workflows/Privacy and Governance.md
- kb/concepts/workflows/Publish-Remote Gate.md
- kb/concepts/workflows/Quality and Self-Correction.md
- kb/concepts/workflows/Semantic Lint Automation.md
- kb/concepts/workflows/Session Orientation.md
- kb/concepts/workflows/Split Merge Reclassify.md
- kb/concepts/workflows/Split Threshold.md
- kb/concepts/workflows/Stub Threshold.md
- kb/concepts/workflows/Supersession.md
- kb/concepts/workflows/User Management.md
- kb/concepts/workflows/Workflow Extraction.md
- kb/concepts/workflows/Workflow Orchestration.md
- kb/index.md
- kb/log.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/catalog.py
- tools/chemenu/commands/index_build.py
- tools/chemenu/lint_core.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_cite_cmd.py
- tools/chemenu/tests/test_git_publish.py
- tools/chemenu/tests/test_index_build.py
- tools/chemenu/tests/test_lint.py
- tools/chemenu/tests/test_new_page.py
- tools/chemenu/tests/test_provenance.py
- tools/chemenu/tests/test_type_resolver.py
- tools/chemenu/tests/test_xref.py
- types/concept.md
- types/type-spec.md
This commit is contained in:
2026-09-08 10:07:46 +02:00
parent 63b4bb82d9
commit 7f74303a00
103 changed files with 703 additions and 180 deletions
@@ -0,0 +1,125 @@
---
type: types/concept.md
concept_type: problem
tags: [tests, ci, tooling, quality]
created: 2026-08-31
modified: 2026-08-31
related:
- exemplifies: Structural Enforcement over Documented Rule
- contrasts: Green Suite Blind Spot
- exemplifies: wikitool
- exemplifies: Gitea Actions
sources: [Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31]
confidence: 0.50
confidence_base: 0.50
provenance: sourced
summary: 'Fehlerklasse, in der ein Test gruen ist, weil die Maschine zufaellig passt statt weil der Code stimmt - abgegrenzt gegen den Green Suite Blind Spot, belegt an vier Faellen unter Gitea-Issue #8'
---
# Ambient Environment Dependency
**Typ:** Problem
## Definition
Eine Ambient Environment Dependency liegt vor, wenn Code stillschweigend Zustand von der
Maschine liest, auf der er läuft - Umgebungsvariablen, globale Konfigurationsdateien, das
Home-Verzeichnis - und ein Testlauf grün wird, *weil die Maschine zufällig passt* statt weil der
Code stimmt. Der grüne Lauf misst dann die Umgebung, nicht das Verhalten.
Das unterscheidet sich vom [[Green Suite Blind Spot]] an genau einer Stelle, und die ist
entscheidend: dort behauptet **kein** Test das richtige Verhalten, hier behauptet ein Test es
sehr wohl und ist grün - aus dem falschen Grund. Der blinde Fleck ist eine Lücke in der
Abdeckung; die Umgebungsabhängigkeit ist ein Fehlbeleg innerhalb der Abdeckung. Beide sind
gegen die Zahl grüner Tests immun, aber nur der zweite überlebt ein "das ist doch getestet".
Die Tücke ist der fehlende Widerstand. Ein Test mit dieser Abhängigkeit verhält sich beim
Schreiben, beim Review und im nächsten hundert Läufen exakt wie ein korrekter Test. Sichtbar
wird sie erst auf einer fremden Maschine - und wenn niemand die Suite je woanders startet, nie.
## Kernpunkte
- **Der Beleg aus diesem Stack (Gitea-Issue #8).** `config.default_author()` ruft
`git config user.name` mit `cwd=config.ROOT` auf. Die Fixture-Wurzel ist kein Repository, also
antwortete die *globale* git-Konfiguration desjenigen, der die Suite startete. Der erste
CI-Lauf, der überhaupt bis `pytest` kam, meldete `2 failed, 628 passed`; auf jeder
Entwicklermaschine war dieselbe Suite monatelang grün gewesen[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31].
- **Sie vermehrt sich schneller, als sie gefunden wird.** Nach der Reparatur der ersten beiden
Fälle führten zwei neue Tests dieselbe Abhängigkeit erneut ein - geschrieben von jemandem, der
das Issue vorher gelesen hatte. Vier Fälle, zwei davon nach der Warnung[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31]. Das ist der Grund,
warum ein Hinweis in einem Dokument hier nicht trägt; siehe
[[Structural Enforcement over Documented Rule]].
- **Die Abwesenheit von Fehlern beweist nichts über den Schutz.** Vor der Härtung war die Suite
unter leerem `HOME` und ohne git-Konfiguration bereits grün (695 Tests): die vier bekannten
Fälle waren einzeln repariert, ein fünfter existierte gerade nicht[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31]. Ein Schutz braucht deshalb
seinen eigenen Nachweis, unabhängig davon, dass nach seinem Einbau alles grün bleibt.
- **Der Nachweis führt über die Gegenprobe, nicht über den grünen Lauf.** In der Sitzung
ausgeführt: dieselbe Funktion antwortet ohne Isolierung `'Torben Nehmer'` und mit Isolierung
`None`[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31]. Erst das zeigt, dass die Isolierung etwas tut.
- **In beide Richtungen prüfen.** Der übliche Gegentest ist die leere Maschine ("übersteht die
Suite, nichts zu haben"). Der zweite ist die *vergiftete* Maschine ("übersteht sie, das Falsche
zu haben"): Variablen absichtlich auf Müll setzen. Eine Isolierung, die nur auf einer ohnehin
sauberen Maschine löscht, besteht den ersten Test und fällt beim zweiten durch.
- **Ein CI-Container ist kein verlässlicher Ersatz für Isolierung.** Das Log von Run 79 zeigt,
dass `actions/checkout@v7` selbst eine globale git-Konfiguration im Container anlegt
(`Copying '/root/.gitconfig' to ...`, `Temporarily overriding HOME=...`), und der
Environment-Schritt schreibt `safe.directory` global dazu[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31]. Die Eigenschaft "Maschine ohne
globale Konfiguration", auf der der ursprüngliche Fund beruhte, hatte der Container
**zufällig**. Ein Guard, der sie voraussetzt, hört still auf zu greifen.
- **Das Gegenmittel setzt an der Ausführung an, nicht am einzelnen Test.** Eine Isolierung, die
vor *jedem* Test greift, macht die Abhängigkeit unschreibbar, statt sie zu melden. Ein Test,
der Identität braucht, muss sie dann explizit herstellen - was er ohnehin tun sollte.
- **Wer isoliert, darf nicht das Verhalten mit-isolieren, das er prüfen will.** Ein pauschal
gesetzter Default (etwa eine Autor-Identität für alle Tests) macht genau den Zweig untestbar,
der nur auf einer Maschine ohne Identität existiert. Die Suite sieht dann grüner aus und belegt
weniger.
- **Die Isolierung selbst braucht Tests.** Sonst kann sie eine Variable verlieren, ohne dass ein
Lauf rot wird - dasselbe Versagen eine Ebene höher.
## Beispiele
- [[wikitool]] - `default_author()` las die globale git-Konfiguration des Aufrufers; vier Tests
hingen nacheinander daran, gefunden erst durch den ersten CI-Lauf, der bis `pytest` kam
- [[Gitea Actions]] - der Job-Container als vermeintlich neutrale Maschine, die es seit
`checkout@v7` nicht mehr ist
- [[Green Suite Blind Spot]] - die verwandte Fehlerklasse, gegen die dieselbe Zahl grüner Tests
ebenfalls nichts aussagt
## Wann zu verwenden
- Wenn ein Test auf einer fremden Maschine fällt, der lokal grün ist - die erste Frage ist nicht
"was ist an der Maschine kaputt", sondern "was hat der Test von ihr gelesen".
- Beim Schreiben eines Tests, der Identität, Pfade, Zeitzone, Locale oder Netzwerkzugang
berührt: was davon kommt aus der Umgebung, und was stellt der Test selbst her.
- Wenn ein grüner Lauf als Beleg für Korrektheit angeführt wird und die Suite bisher nur auf
einer Sorte Maschine lief.
- Bevor eine Suite an eine Stelle wandert, wo sie erstmals woanders läuft - CI, ein zweiter
Entwickler, eine verteilte Instanz.
## Wann NICHT zu verwenden
- Für Tests, die die Umgebung *absichtlich* prüfen und sie dafür selbst aufbauen. Ein Test, der
ein Fixture-Repository anlegt und darin eine lokale Identität setzt, hat keine Abhängigkeit -
er hat ein Fixture.
- Für Werte, die legitim von außen kommen und deren Abwesenheit sauber behandelt wird. Nicht
jeder `os.environ.get` ist ein Defekt; der Defekt ist, wenn ein Testergebnis davon abhängt.
- Als Argument gegen Integrationstests gegen echte Systeme. Die stützen sich bewusst auf eine
Umgebung, und das ist deklariert - nicht still.
## Beziehungen
## Siehe auch
- [[Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31]]
## Fußnoten
[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31]: [[Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31]]
<!-- wikitool:links -->
## Beziehungen
- **exemplifies:** [[Structural Enforcement over Documented Rule]]
- **contrasts:** [[Green Suite Blind Spot]]
- **exemplifies:** [[wikitool]]
- **exemplifies:** [[Gitea Actions]]
<!-- /wikitool:links -->
@@ -0,0 +1,134 @@
---
type: types/concept.md
concept_type: problem
tags: [tooling, lint, provenance, hand-edit, gap]
created: 2026-08-31
modified: 2026-08-31
related:
- exemplifies: wikitool
- rests-on: Lint Workflow
- contrasts: Self-Healing
- see-also: Issue Label Scheme
- contrasts: Write-Once Frontmatter Fields
- contrasts: Command Round-Trip Integrity
sources: [Source - Conversation - Comma Bug Budget Refund and Lint Report Path Session 2026-08-31, Source - Conversation - Issue Triage Labels and TODO Retirement Session 2026-08-31, Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31, Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]
confidence: 0.50
confidence_base: 0.50
provenance: sourced
summary: Werkzeugluecke, in der ein Check einen Defekt zuverlaessig meldet, aber kein Befehl ihn behebt - womit die Handeditierung der einzige verbleibende Ausweg ist
---
# Detect-Repair Asymmetry
**Typ:** Problem
## Definition
Detect-Repair Asymmetry beschreibt den Zustand, in dem ein Werkzeug einen Defekt zuverlässig
**meldet**, aber keinen Befehl anbietet, der ihn **behebt**. Der Agent, dem das Werkzeug den
Befund vorlegt, hat dann genau zwei Auswege: den Defekt stehen lassen oder ihn von Hand
reparieren. In einem Stack, dessen Kernprinzip lautet, dass Mechanisches das Werkzeug erledigt
und niemals die Hand, führt eine solche Lücke die Handeditierung als einzige verbleibende
Option wieder ein - an genau der Stelle, an der die Regeln sie am dringendsten ausschließen
wollen.
Die Asymmetrie ist keine Regelverletzung, sondern ein Konstruktionsfehler in der
Werkzeugoberfläche. Sie fällt erst auf, wenn der gemeldete Defekt zum ersten Mal wirklich
auftritt.
## Kernpunkte
- **Melden und Reparieren sind getrennte Fähigkeiten.** Ein Check zu schreiben ist billig, ein
Reparaturbefehl teuer, weil er den korrekten Zielzustand kennen und atomar herstellen muss.
Deshalb entsteht die Lücke nicht aus Nachlässigkeit, sondern aus dem Kostengefälle zwischen
beiden.
- **Der Befund selbst erzeugt den Druck.** Solange niemand die kaputte Referenz sieht, gibt es
keinen Anlass, sie von Hand zu korrigieren. Sobald `lint` sie in jedem Lauf meldet, ist die
Handeditierung der kürzeste Weg zu einem sauberen Lauf.
- **Fall aus diesem Wiki (2026-08-31):** `lint` und `sources coverage` melden kaputte
`raw_files:`-Referenzen zuverlässig, aber kein `wikitool`-Befehl schreibt `raw_files:` auf
einer bestehenden Seite. `touch` deckt die Felder ab, die die Seite selbst beschreiben,
`xref` die Seiten-Referenz-Arrays; `raw_files:` ist keines von beidem, weil es auf einen Pfad
zeigt und nicht auf einen Seitentitel. `new source --set raw_files=…` schreibt das Feld genau
einmal, bei der Erstellung[^s-conversation-comma-bug-budget-refund-and-lint-report-path-session-2026-08-31].
- **Formal erlaubt ist nicht dasselbe wie beabsichtigt.** Invariante 1 aus `AGENTS.md` zählt
Katalog, `log.md`, `provenance.md`, die Skill-Verzeichnisse, die beiden JSON-Dateien und die
Seiten-Referenz-Arrays auf. `raw_files:` steht in keiner dieser Aufzählungen, die
Handeditierung ist also nicht verboten - sie widerspricht nur dem Kernprinzip, aus dem die
Aufzählung
stammt[^s-conversation-comma-bug-budget-refund-and-lint-report-path-session-2026-08-31].
- **Die Reparatur gehört dorthin, wo der Zwischenzustand nie existiert.** Für den konkreten
Fall wurde `raw rename` vorgeschlagen, das `git mv` und jede referenzierende Source-Seite in
einem Schritt erledigt, statt eines nachgelagerten `sources relink`: nur in der gebündelten
Form gibt es keinen Moment, in dem die Datei weg ist und die Referenz
hängt[^s-conversation-comma-bug-budget-refund-and-lint-report-path-session-2026-08-31].
- **Der Fall wurde am selben Tag geschlossen, und wie er geschlossen wurde, ist die
Verallgemeinerung.** `1.4.0` (Commit `dbe2f73`) gab `touch` ein `--set`/`--add`/`--remove`,
das jedes vom Schema deklarierte Feld erreicht statt nur `raw_files:`. Der Reparaturbefehl
wurde also nicht auf den gemeldeten Befund zugeschnitten, sondern auf die Feldklasse, zu der
er gehört - siehe
[[Write-Once Frontmatter Fields]][^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
- **Die gebündelte Form blieb trotzdem offen.** `raw rename`, das `git mv` und jede
referenzierende Source-Seite in einem Schritt erledigt, wurde als Issue #16 abgespalten. Der
Zwischenzustand „Datei weg, Referenz hängt" existiert seit `1.4.0` also kürzer - zwei Befehle
statt einer Handeditierung -, aber er existiert noch[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
- **Zweiter Fall, andere Herkunft (2026-08-31):** auf einer Source-Seite stand ein `related:`,
das `types/source.md` nicht deklariert. `lint` meldete den Schema-Fehler zuverlässig, aber
`xref remove` räumte nur deklarierte Felder und erreichte ihn nicht. Die Asymmetrie entstand
hier nicht aus einer fehlenden Fähigkeit, sondern daraus, dass ein Schwesterbefehl einen
Zustand schreiben konnte, den der Gegenbefehl nicht kannte - geschlossen mit `1.6.0`
(Gitea-Issue #18). Die Klasse dieser Kombination ist
[[Command Round-Trip Integrity]][^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31]
- **Verwandt, aber nicht dasselbe wie [[Self-Healing]]:** Self-Healing beschreibt, dass ein
Lauf gefundene Mängel automatisch behebt. Detect-Repair Asymmetry beschreibt den Fall davor -
dass es den Befehl, den ein Self-Healing-Lauf aufrufen müsste, überhaupt nicht gibt.
## Beispiele
- [[wikitool]] - `lint` und `sources coverage` meldeten kaputte `raw_files:`-Referenzen, ohne
dass ein Befehl sie korrigierte (Gitea-Issue #14, geschlossen mit `1.4.0`); die gebündelte
Reparatur `raw rename` ist als Issue #16 offen
- [[Lint Workflow]] - der Lauf, der den Befund erzeugt und damit den Druck, ihn von Hand
wegzuräumen
- [[wikitool]] - `lint` meldete das undeklarierte `related:` auf einer Source-Seite, das kein
Befehl entfernen konnte (Gitea-Issue #18, geschlossen mit `1.6.0`)
## Wann zu verwenden
- Beim Entwurf eines neuen Checks: prüfen, ob es für jeden Befund, den er erzeugen kann, einen
Befehl gibt, der ihn behebt. Wenn nicht, ist der Check ohne den zugehörigen Reparaturbefehl
unvollständig ausgeliefert.
- Bei der Bewertung einer wiederkehrenden Handeditierung: die Frage ist nicht, warum der Agent
sie vorgenommen hat, sondern welcher Befehl fehlte.
## Wann NICHT zu verwenden
- Für Befunde, die ein Urteil verlangen und deshalb gar keinen deterministischen Zielzustand
haben - ein Widerspruch zwischen zwei Seiten oder eine veraltete Aussage sind semantische
Befunde, kein fehlender Befehl.
- Als Begründung, einen Check wegzulassen, bis die Reparatur fertig ist. Ein gemeldeter Defekt
ohne Reparatur ist immer noch besser als ein unbemerkter.
## Beziehungen
## Siehe auch
- [[Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31]]
- [[Source - Conversation - Issue Triage Labels and TODO Retirement Session 2026-08-31]]
- [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
## Fußnoten
[^s-conversation-comma-bug-budget-refund-and-lint-report-path-session-2026-08-31]: [[Source - Conversation - Comma Bug Budget Refund and Lint Report Path Session 2026-08-31]]
[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31]: [[Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31]]
[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31]: [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
<!-- wikitool:links -->
## Beziehungen
- **exemplifies:** [[wikitool]]
- **rests-on:** [[Lint Workflow]]
- **contrasts:** [[Self-Healing]]
- **see-also:** [[Issue Label Scheme]]
- **contrasts:** [[Write-Once Frontmatter Fields]]
- **contrasts:** [[Command Round-Trip Integrity]]
<!-- /wikitool:links -->
@@ -0,0 +1,140 @@
---
type: types/concept.md
concept_type: problem
tags: [tests, regression, tooling, quality]
created: 2026-08-31
modified: 2026-08-31
related:
- see-also: Command Round-Trip Integrity
- exemplifies: wikitool
- see-also: Denylist over Allowlist
- see-also: Ambient Environment Dependency
- rests-on: Lint Workflow
sources: [Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31, Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31]
confidence: 0.70
confidence_base: 0.70
provenance: sourced
summary: Defekt, der eine vollstaendig gruene Testsuite ueberlebt, weil nie ein Test das richtige Verhalten behauptet hat - belegt an drei prio/1-2-Defekten (Round-Trip, Zitat-Notation-als-Code, Zitat-Limit)
---
# Green Suite Blind Spot
**Typ:** Problem
## Definition
Ein Green Suite Blind Spot ist ein Defekt, der eine vollständig grüne Testsuite überlebt, weil
nie ein Test das *richtige* Verhalten behauptet hat. Die Suite ist nicht falsch und sie ist
nicht kaputt - sie prüft nur, wovon sie weiß. Ein nie formuliertes Verhalten kann nicht
fehlschlagen, also meldet ein grüner Lauf für diesen Bereich nichts, und die Grünfärbung wird
als Aussage über den gesamten Code gelesen statt über den abgedeckten Ausschnitt.
Die Lücke wächst dort am schnellsten, wo zwei Komponenten sich erst in der Kombination
widersprechen: jede für sich ist getestet, das Zusammenspiel hat nie jemand aufgeschrieben.
## Kernpunkte
- **Der Beleg aus diesem Stack (2026-08-31):** zwei `prio/1`-Datenintegritätsdefekte lagen unter
einer vollständig grünen Suite. 678 Tests waren grün, bevor die Zitat-Tests zu Gitea-Issue #17
geschrieben wurden; 67 Gate-Tests waren grün vor der Zählungsänderung desselben Tages. In
keinem der beiden Fälle hatte je ein Test das falsche Verhalten festgehalten - genau deshalb
hat es überlebt[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Die Zahl der grünen Tests sagt nichts über den ungetesteten Bereich.** Sie misst, wie viel
bekanntes Verhalten abgesichert ist. Ein Defekt in unbekanntem Verhalten ist von einer
grünen 678er-Suite genauso wenig ausgeschlossen wie von einer grünen 60er-Suite[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Das ist etwas anderes als eine falsche Zusicherung.** Ein Test, der das falsche Verhalten
festschreibt, wird beim Fix rot und zwingt zur Entscheidung. Der blinde Fleck erzeugt gar
keinen Widerstand: der Fix ändert Verhalten, das nie jemand behauptet hat, und die Suite
bleibt grün - vorher wie nachher[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Gegenmittel 1 - den neuen Test rot beweisen, bevor man ihm glaubt.** Bei der Reparatur von
Issue #17 wurde nicht behauptet, der neue Test hätte den Defekt gefangen: die alte
Implementierung wurde rekonstruiert und gegen ihn laufen gelassen
(`ALTER Code -> Beziehungen erhalten: False`, `NEUER Code -> Beziehungen erhalten:
True`)[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Gegenmittel 2 - den Umfang messen statt schätzen.** Der Scan über den Korpus ergab 8 Seiten
mit 74 Zeilen in der gefährdeten Position und hielt damit einen laufenden Ingest an, der
`cite add` auf genau diese Seiten aufgerufen hätte. Eine Schätzung hätte diese Entscheidung
nicht getragen[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Gegenmittel 3 - einen Bericht aus zweiter Hand nachstellen, nicht übernehmen.** Die
Meldungen eines Subagenten wurden am Code nachvollzogen, bevor etwas geändert wurde, und die
Prüfung erweiterte den Umfang zweimal: um `rename` und den `cite sync`-Verlustpfad beim
ersten Defekt, und um die Feststellung, dass `xref remove` das undeklarierte Feld gar nicht
erreichen konnte, beim zweiten[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Ein dritter Beleg: `lint` maß Zeilenbreite statt Zitat-Anzahl, und niemand hatte je über die
eigene Zitat-Syntax geschrieben.** Gitea-Issue #20 stellte selbst fest: "auch dieser Fall war
von keinem Test abgedeckt, weil bisher niemand eine Seite über die Zitat-Notation geschrieben
hatte." Das Zitat-Limit (Issue #22) zählte parallel `>`-Zeilen statt Zitate - ein Defekt, den
eine einzige Testseite mit einem umbrochenen Zitat sofort zeigt, aber den niemand geschrieben
hatte, bis eine reale Seite genau das tat. Beide behoben in
`1.7.2`.
Gegenmittel 1 griff erneut: acht neue Tests wurden gegen eine auf No-op zurückgesetzte
Implementierung scharf geprüft und liefen rot, bevor der Fix als bewiesen
galt.
- **Eine Ablehnung, die auf ein anderes Kommando verweist, ist selbst ein blinder Fleck.** Die
Denylist aus `1.4.0` war richtig, ihr Verweisziel nicht: sie behauptete ungeprüft, `xref add`
und `xref remove` deckten die Seiten-Referenz-Felder ab, was für eine Source-Seite falsch war.
Die Regel dazu steht bei [[Denylist over Allowlist]][^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Der Befund stützt die Prämisse von Gitea-Issue #8** - dass eine grüne Suite kein Beleg für
Vollständigkeit ist und ein Bereich seinen eigenen Nachweis braucht[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
- **Issue #8 wurde am 2026-08-31 mit `1.7.1` geschlossen, und zwar über eine Isolierung der
Testausführung statt über weitere Einzeltests**[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31]. Der dort behandelte Fall ist aber
eine eigene Klasse und kein blinder Fleck: dort behauptete ein Test das richtige Verhalten und
war grün, weil die Umgebung lieferte, was der Code hätte liefern müssen. Abgrenzung und Beleg
bei [[Ambient Environment Dependency]].
- **Gegenmittel 1 hat sich dort erneut bewährt.** Vor der Härtung war die Suite unter der
gehärteten Umgebung bereits grün (695 Tests), der Schutz also durch keinen roten Lauf belegt.
Erst die Gegenprobe - dieselbe Funktion antwortet ohne Isolierung mit dem globalen git-Namen
des Entwicklers, mit Isolierung `None` - zeigte, dass er greift[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31].
## Beispiele
- [[wikitool]] - Issue #17 (`cite add` löschte Inhalt hinter dem Fußnotenblock) und Issue #18
(Referenz-Arrays einer Source-Seite unerreichbar), beide unter grüner Suite entstanden und
beide durch einen Ingest, nicht durch einen Testlauf, gefunden
- [[Command Round-Trip Integrity]] - die Defektklasse, die besonders anfällig ist, weil jeder
beteiligte Aufruf für sich getestet und für sich korrekt ist
- [[Lint Workflow]] - Issue #20 (`[^cite-id]`/`[[Wikilink]]` in Backticks oder einem Fence zählte
als echte Referenz) und Issue #22 (Zitat-Limit zählte `>`-Zeilen statt Zitate), beide gefunden
bei einer Seite, die tatsächlich über die eigene Notation schrieb, nicht durch einen Testlauf
## Wann zu verwenden
- Wenn eine grüne Suite als Argument für die Korrektheit einer Änderung angeführt wird: die
Frage ist nicht, wie viele Tests grün sind, sondern welcher Test rot geworden wäre.
- Beim Schreiben eines Regressionstests: erst gegen den alten Code laufen lassen. Ein Test, der
nie rot war, belegt nichts.
- Wenn ein Defekt im Betrieb auffällt statt im Testlauf: die Frage nach dem fehlenden Test
gehört zur Ursachenanalyse, nicht zur Nacharbeit.
## Wann NICHT zu verwenden
- Als Argument gegen Testabdeckung. Der Befund entwertet keinen einzigen der 678 grünen Tests;
er bestreitet nur, dass ihre Zahl eine Aussage über das trifft, was niemand aufgeschrieben
hat.
- Für Defekte, die ein Test sehr wohl abgedeckt hätte und die durch einen übersprungenen oder
nicht ausgeführten Lauf durchgerutscht sind. Das ist ein Prozessfehler, kein blinder Fleck.
## Verwandte Concepts
- [[Structural Enforcement over Documented Rule]]
## Beziehungen
## Siehe auch
- [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
- [[Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31]]
## Fußnoten
[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31]: [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
[^s-conversation-hardening-the-test-suite-against-silent-environment-dependencies-session-2026-08-31]: [[Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31]]
<!-- wikitool:links -->
## Beziehungen
- **see-also:** [[Command Round-Trip Integrity]]
- **exemplifies:** [[wikitool]]
- **see-also:** [[Denylist over Allowlist]]
- **see-also:** [[Ambient Environment Dependency]]
- **rests-on:** [[Lint Workflow]]
<!-- /wikitool:links -->
@@ -0,0 +1,66 @@
---
type: types/concept.md
concept_type: problem
tags: [bug, drifts, kebab-case, human-readable]
created: 2026-08-03
modified: 2026-08-29
related:
- operates-on: AGENTS.md
sources: [Source - LLM Improvements Codex Analysis]
confidence: 0.80
confidence_base: 0.80
provenance: sourced
summary: Widerspruch zwischen README.md (kebab-case) und AGENTS.md (lesbar mit Leerzeichen), der zu Drift bei der Validierung führt
---
# Naming Convention Conflict
**Typ:** problem
## Definition
Naming Convention Conflict ist ein spezifischer Drift/Bug, bei dem README.md und AGENTS.md unterschiedliche Benennungskonventionen für Wiki-Dateien angeben. README.md erfordert kebab-case (z. B. `hybrid-search.md`), während AGENTS.md benutzerfreundliche Titel mit Leerzeichen erfordert (z. B. `Hybrid Search.md`). Diese Inkonsistenz verursacht Validierungsdrift und macht es unmöglich, beide Anforderungen gleichzeitig zu erfüllen.
## Kernpunkte
- **README.md-Anforderung:** kebab-case-Dateinamen (z. B. `my-page.md`)
- **AGENTS.md-Anforderung:** Benutzerfreundliche Titel mit Leerzeichen (z. B. `My Page.md`)
- **Auswirkung:** Verursacht Validierungsinkonsistenzen und verwirrt sowohl Menschen als auch automatisierte Tools
- **Entdeckung:** Während der Codex-Analyse von Repo-Drift identifiziert
## Beispiele
- Konflikt: Sollte `CI/CD Architecture.md` sein wie `CI/CD Architecture.md` (AGENTS.md) oder `ci-cd-architecture.md` (README.md)?
- Ergebnis: Einige Seiten folgen einer Konvention, andere folgen der anderen und erzeugen Inkonsistenz
## Lösungsoptionen
1. **Einen Standard auswählen:** Für kebab-case oder Namen mit Leerzeichen entscheiden und alle Dokumentation aktualisieren
2. **Beide unterstützen:** Die Tooling so gestalten, dass beide Konventionen akzeptiert werden (komplex, nicht empfohlen)
3. **Migrationspfad:** Eine Zielkonvention wählen und alle vorhandenen Seiten migrieren
## Status
- **Identifiziert:** 2026-08-03 (Codex-Analyse)
- **Schweregrad:** Mittel - verursacht Drift, aber Wiki funktioniert immer noch
- **Geplant:** Sollte vor dem Sonnet-Analyse-Vergleich gelöst werden
## Verwandte Concepts
- README.md (gibt kebab-case an)
- [[Source - LLM Improvements Codex Analysis]][^s-llm-improvements-codex-analysis]
## Beziehungen
## Siehe auch
- [[Source - LLM Improvements Codex Analysis]]
## Fußnoten
[^s-llm-improvements-codex-analysis]: [[Source - LLM Improvements Codex Analysis]]
<!-- wikitool:links -->
## Beziehungen
- **operates-on:** [[AGENTS.md]]
<!-- /wikitool:links -->
@@ -0,0 +1,123 @@
---
type: types/concept.md
concept_type: problem
tags: [wikitool, frontmatter, tooling, idempotenz, repair]
created: 2026-08-31
modified: 2026-08-31
related:
- exemplifies: wikitool
- see-also: Denylist over Allowlist
- see-also: Detect-Repair Asymmetry
- see-also: Diff-Reviewable Agent Edits
- see-also: Command Round-Trip Integrity
sources: [Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31, Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]
confidence: 0.70
confidence_base: 0.70
provenance: sourced
summary: Defektklasse, in der ein Feld nur beim Anlegen der Seite schreibbar ist und danach unerreichbar bleibt, weil kein Mutationsbefehl es kennt und new nicht idempotent ist
---
# Write-Once Frontmatter Fields
**Typ:** Problem
## Definition
Ein Write-Once-Feld ist ein Frontmatter-Feld, das der Anlegebefehl schreibt und danach kein
Befehl mehr ändern kann. Es entsteht nicht durch eine Regel, sondern durch eine Lücke: das
Schema deklariert das Feld, das Gerüst füllt es, und die Mutationsbefehle decken es nicht ab.
Der Wert, den der erste Aufruf gesetzt hat, ist damit der endgültige.
Die drei Auswege, die einem Agenten dann bleiben, schließen sich gegenseitig aus. Handeditierung
ist das, was der Stack verhindern soll. Die Seite zu löschen und neu anzulegen zerreißt jede
Referenz, die schon auf sie zeigt - Wikilinks, Fußnoten-Zitate und die Referenz-Arrays
anderer Seiten hängen am Titel. Und der Anlegebefehl selbst ist nicht idempotent, lässt sich
also nicht einfach mit korrigierten Werten wiederholen. Das Fenster für den richtigen Wert ist
genau einen Befehl
breit[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
## Kernpunkte
- **Die Lücke ist eine Kombination, kein einzelner Defekt.** Erst Schema plus fehlender
Mutationsbefehl plus nicht-idempotentes `new` plus Referenzbindung an den Titel machen einen
Tippfehler dauerhaft. Jede dieser Eigenschaften für sich ist harmlos.
- **Sie trifft die Felder, die keiner Seite und keinem Seitentitel gehören.** `touch` deckte
die Felder ab, die die Seite selbst beschreiben (`modified`, `summary`, `provenance`,
`confidence_base`), `xref` die Seiten-Referenz-Arrays. `tags:`, `raw_files:` und `source_url:`
sind
keines von beidem[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
- **Der Beleg, dass es eine Rate ist und kein Unfall:** drei Fehlschläge in drei
aufeinanderfolgenden Ingests desselben Tages, an zwei verschiedenen Feldern, von drei
verschiedenen Agenten. Einer davon war ein nachgestelltes Komma im `--set
tags=`-Wert[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
- **Der Fall, an dem es sichtbar wurde:** [[Diff-Reviewable Agent Edits]] behielt nach einem
solchen Ingest dauerhaft nur `[agent-workflow]`. Der zuständige Agent prüfte alle drei
Auswege und verwarf jeden mit dem richtigen Grund - genau das Verhalten, das die Regeln
verlangen, und genau der Punkt, an dem sie ohne Werkzeug in eine Sackgasse
führen[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
- **Geschlossen in Stack `1.4.0` (Commit `dbe2f73`) durch `touch --set/--add/--remove`:**
schreibbar ist, was das Schema des Seitentyps deklariert, abzüglich einer kurzen Sperrliste
(siehe [[Denylist over Allowlist]]). `--add` und `--remove` arbeiten auf einzelnen Elementen
eines Listenfelds, `--remove` gelingt auch bei einem nicht vorhandenen Element und meldet
das - idempotent, weil ein Reparaturbefehl, der sich beim zweiten Lauf verweigert, nicht
skriptbar ist, aber nie still, weil ein stiller No-op wie eine gelungene Entfernung
aussieht[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
- **Die Klasse kehrte am selben Tag an einer anderen Feldgruppe wieder.** `new source --set
entities=…` schrieb die Referenz-Arrays einer Source-Seite genau einmal; `xref link-source`
fasste sie nicht an, `xref add` lehnte sie ab, und `touch` sperrt sie über seine Denylist.
Damit war eine Source-Seite nach dem Anlegen in ihren eigenen `entities:`/`concepts:`
unerreichbar - dieselbe Lücke wie bei `tags:`, nur an den Feldern, die eine andere
Zuständigkeit haben. Geschlossen mit `1.6.0` (Commit `ce03749`, Gitea-Issue #18), indem
`xref link-source` beide Richtungen schreibt[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31]
- **Abgrenzung zu [[Detect-Repair Asymmetry]]:** Dort meldet ein Check einen Defekt, für den es
keinen Reparaturbefehl gibt. Hier gibt es nicht einmal zwingend einen Befund - ein falsches
`tags:` fällt keinem Check auf. Der `raw_files:`-Fall gehört zu beiden: er wird gemeldet
*und* war nicht reparierbar.
- **Der Existenzcheck bleibt am Feld, nicht am Schema.** Ein per `touch` geschriebenes
`raw_files:` wird gegen das Dateisystem geprüft wie beim Anlegen. Das ist I/O und keine
Datenform, also kann kein Schema es
ausdrücken[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
## Beispiele
- [[wikitool]] - `tags:` und `raw_files:` waren bis `1.4.0` nur beim Anlegen schreibbar
(Gitea-Issue #14, geschlossen)
- [[Diff-Reviewable Agent Edits]] - die Seite, die stundenlang unreparierbar war und den Fall
belegt
## Wann zu verwenden
- Beim Ergänzen eines Schema-Felds: prüfen, welcher Befehl es nach dem Anlegen noch ändert.
Gibt es keinen, ist das Feld write-once ausgeliefert.
- Bei der Bewertung eines nicht-idempotenten Anlegebefehls: die Frage ist nicht, wie oft er
falsch aufgerufen wird, sondern was ein einziger falscher Aufruf dauerhaft festschreibt.
## Wann NICHT zu verwenden
- Für Felder, die absichtlich unveränderlich sind, weil ihre Änderung eine andere Operation
ist: `type:` ändert Schema und Verzeichnis der Seite und gehört in den Seiten-Lebenszyklus,
`confidence:` ist abgeleitet und nicht autorisiert. Eine gesperrte Zuständigkeit ist keine
Lücke.
- Für generierte Dateien. Dass `kb/index.md` nicht von Hand geschrieben wird, ist Invariante 1
und kein Defekt.
## Beziehungen
## Siehe auch
- [[Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31]]
- [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
## Fußnoten
[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31]: [[Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31]]
[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31]: [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
<!-- wikitool:links -->
## Beziehungen
- **exemplifies:** [[wikitool]]
- **see-also:** [[Denylist over Allowlist]]
- **see-also:** [[Detect-Repair Asymmetry]]
- **see-also:** [[Diff-Reviewable Agent Edits]]
- **see-also:** [[Command Round-Trip Integrity]]
<!-- /wikitool:links -->