Die kb_dir-Fixture repointet config.ROOT nicht - ein Test schreibt dadurch ins echte Repo #44

Closed
opened 2026-09-03 04:21:25 +00:00 by torben · 3 comments
Owner

Erledigt in 4.1.1 (23307c3). Der Befund unten ist die Diagnose, die stehen bleibt; die Entscheidungen sind getroffen und umgesetzt. Ein Prozess-Nachtrag ging als 4.1.2 (41f5dfe) hinterher — siehe „Nachtrag" am Ende.

Der Befund

tools/chemenu/tests/conftest.py hatte zwei Fixtures, die eine Baumwurzel aufbauen, und nur eine von beiden richtete config.ROOT mit aus:

Fixture config.ROOT (vor 4.1.1) Folge
raw_dir monkeypatch.setattr(config, "ROOT", tmp_path) isoliert
kb_dir jeder Zugriff über config.ROOT traf das echte Repo

kb_dir baute seinen Baum unter tmp_path / "kb" auf und gab ihn zurück. Das reicht für jeden Test, der den Pfad als Argument weiterreicht (run_lint(kb_dir)). Es reicht nicht, sobald der Code unter Test eine Datei über config.ROOT oder config.KB_DIR auflöst statt über das übergebene Verzeichnis — und das tat er an mehreren Stellen.

Wie es aufgefallen ist

Beim Bau der Migrations-Gate-Tests für 4.1.0. Ein Test rief kb_state.write_kb_state(...), das über kb_state_file() -> config.ROOT / ".wikitool-kb.json" auflöst. Ergebnis:

 M .wikitool-kb.json

Der Applied-Ledger des echten Repos war überschrieben — applied: [] statt der beiden Einträge für 3.0.0-authoring-conventions und 4.0.0-link-taxonomy. Zurückgeholt mit git checkout --, die Tests auf eine lokale rooted_kb-Fixture umgestellt.

Das war eine unversionierte, git-verfolgte Datei, also war der Schaden reversibel und sofort sichtbar. Bei einer gitignorierten Datei — oder in einem Baum mit uncommitteten Änderungen — wäre er es nicht gewesen.

Der zweite, stillere Fall

Derselbe Mechanismus machte Prüfungen wirkungslos, statt Dateien zu überschreiben. lint_core._collection_of() löste eine Seite gegen config.KB_DIR auf, nicht gegen das an run_lint() übergebene Verzeichnis:

page.path.relative_to(config.KB_DIR).parts[0]

Für eine Seite unter tmp_path/kb/ wirft das ValueError, die Funktion gab None zurück, und die Label-Autorisierungsprüfung übersprang die Kante stillschweigend. Das hieß: unauthorised_labels war in der Suite faktisch nicht getestet — jeder Test, der es hätte auslösen können, bekam eine leere Liste zurück und behauptete nichts.

Das war die gefährlichere Hälfte. Ein überschriebenes .wikitool-kb.json sieht man in git status. Eine Prüfung, die unter Test nie feuert, sieht man gar nicht, und ihr grüner Testlauf liest sich wie eine Zusicherung.

Warum das nicht die Autouse-Fixture erledigt

hermetic_environment neutralisiert die UmgebungHOME, XDG_CONFIG_HOME, die Git-Konfiguration, CHEMENU_ROOT. config.ROOT fällt bei fehlendem CHEMENU_ROOT auf _PACKAGE_ROOT zurück, also auf den Checkout, aus dem die Tests laufen. Das ist für die meisten Tests richtig — sie brauchen die ausgelieferten types/ — und genau deshalb greift die Isolation hier nicht von selbst.

configs Modul-__getattr__ löst die abgeleiteten Pfade bei jedem Zugriff auf, monkeypatch.setattr(config, "ROOT", tmp_path) zieht KB_DIR also mit. Der Mechanismus war vorhanden; kb_dir benutzte ihn nur nicht.

Entschieden und umgesetzt

  1. kb_dir repointet selbst (Variante 1, nicht die getrennte rooted_kb-Fixture). Genau das, was raw_dir schon tat: config.ROOT auf das eigene tmp_path, plus use_shipped_type_specs(). Der befürchtete Umfang wurde gemessen statt geschätzt — kein einziger Test kippte (863 vorher). Variante 2 wurde verworfen, weil sie die Falle stehen lässt und die Auswahl zwischen zwei fast identischen Fixturen Wissen wäre, das nirgends steht. rooted_kb ist ersatzlos entfallen.

  2. _collection_of() löst gegen den übergebenen Baum auf, und authorised_labels() bekommt denselben Baum gereicht statt auf config.KB_DIR zurückzufallen. Das ist der eigentliche Fix: eine Funktion, die ein Verzeichnis entgegennimmt, löst dagegen auf — keine Fixture kann diese Form von außen reparieren.

  3. Regressionstest: test_unauthorised_label_is_judged_in_a_tree_that_is_not_the_configured_kb lintet einen Baum, von dem ROOT bewusst wegzeigt. Gegen den alten Code schlägt er fehl (verifiziert), gegen den neuen nicht. Ein Test unter der reparierten Fixture allein hätte nichts bewiesen — dort ist kb_dir == config.KB_DIR, und der Defekt bliebe unsichtbar.

  4. Wächter: ja, zweistufig.

    Guard Default Kosten
    repository_tree_guard (session) an zwei git status --porcelain pro Lauf
    per_test_tree_guard aus, CHEMENU_TREE_GUARD=each ein git status pro Test

    Der Session-Wächter vergleicht vorher gegen nachher statt einen sauberen Baum zu verlangen, sagt also nichts über unveröffentlichte Arbeit des Entwicklers. Er benennt den Verursacher nicht — dafür ist CHEMENU_TREE_GUARD=each da. Ohne git oder außerhalb eines Repositorys sind beide still. Beide gegen eine absichtlich schreibende Probe verifiziert.

    Bewusst nicht abgedeckt: die stillere Hälfte. Eine Prüfung, die unter Test nichts tut, schreibt keine Datei — kein Wächter dieser Bauart sieht das. Dagegen hilft nur ein Test, der das Finding tatsächlich auslöst. Diese Grenze steht in testing-conventions.md, damit sie nicht als abgedeckt missverstanden wird.

Checkliste

  • Entscheidung 1 vs. 2 getroffen und umgesetzt; Suite-Lauf auf gekippte Tests geprüft — keine
  • _collection_of() gegen den übergebenen Baum aufgelöst
  • Test geschrieben, der unauthorised_labels tatsächlich auslöst
  • instructions/dev/testing-conventions.md ergänzt (Abschnitt „Which tree a test writes into", ein Checklisten-Schritt, drei Fixture-Tests in test_hermetic_env.py)
  • Version-Bump --patch → 4.1.1

Verifiziert

867 Tests grün, auch im gehärteten env -i-Lauf; docs verify und instructions verify OK; der Regressionstest gegen den alten Code als fehlschlagend nachgewiesen; beide Wächter gegen eine schreibende Probe getestet.

Nachtrag: der Prozessfehler beim Schließen (4.1.2)

Dieser Issue wurde zunächst mit einem Abschlusskommentar geschlossen, während der Body weiter als offene Arbeit dastand — „Zu entscheiden" über eine längst getroffene Entscheidung, ungehakte Checkliste. Das ist genau der Fehler, den instructions/dev/issue-tracking.md Schritt 2 verhindern soll.

Daraus wurde die Regel geschärft statt nur der Fall repariert (4.1.2, 41f5dfe):

  • Schritt 2: Der Body ist das Plan-File dieses Stacks — fortlaufend aktuell, nicht am Ende nachgezogen. Maßstab ist der Abbruch: eine Session kann jederzeit enden, und der Body ist zu jedem Zeitpunkt die vollständige Übergabe an die nächste.
  • Schritt 7: Abschluss ist die letzte dieser Aktualisierungen, kein Sonderakt. Body auf Endstand, dann schließen, dann Changelog-Kommentar.
  • Schritt 3: Ein Kommentar pro Session-Umfang, nicht pro Edit — sonst erzeugt die fortlaufende Pflege Lärm.
  • Neuer Abschnitt „What no tool checks": wikitool kennt den Tracker nicht und soll ihn nicht kennenlernen (es wird an Instanzen ausgeliefert, die kein Board haben; instructions/dev/ wird von dist export gepruned). Es gibt also keine mechanische Prüfung für einen Body, der offen klingt, obwohl er es nicht ist — das fängt nur eine Session ab, die dieser Datei folgt.
  • stack-dev/SKILL.md sagt es beim Aufgreifen mit.

Vorgeschichte

Gefunden am 2026-09-03 beim Bau der Migrations-Gate-Tests für 4.1.0 (#40). Geschlossen am 2026-09-03 mit 4.1.1; Prozess-Nachtrag als 4.1.2.

**Erledigt in 4.1.1** (`23307c3`). Der Befund unten ist die Diagnose, die stehen bleibt; die Entscheidungen sind getroffen und umgesetzt. Ein Prozess-Nachtrag ging als 4.1.2 (`41f5dfe`) hinterher — siehe „Nachtrag" am Ende. ## Der Befund `tools/chemenu/tests/conftest.py` hatte zwei Fixtures, die eine Baumwurzel aufbauen, und nur eine von beiden richtete `config.ROOT` mit aus: | Fixture | `config.ROOT` (vor 4.1.1) | Folge | |---|---|---| | `raw_dir` | `monkeypatch.setattr(config, "ROOT", tmp_path)` | isoliert | | `kb_dir` | — | **jeder Zugriff über `config.ROOT` traf das echte Repo** | `kb_dir` baute seinen Baum unter `tmp_path / "kb"` auf und gab ihn zurück. Das reicht für jeden Test, der den Pfad als Argument weiterreicht (`run_lint(kb_dir)`). Es reicht nicht, sobald der Code unter Test eine Datei über `config.ROOT` oder `config.KB_DIR` auflöst statt über das übergebene Verzeichnis — und das tat er an mehreren Stellen. ## Wie es aufgefallen ist Beim Bau der Migrations-Gate-Tests für 4.1.0. Ein Test rief `kb_state.write_kb_state(...)`, das über `kb_state_file() -> config.ROOT / ".wikitool-kb.json"` auflöst. Ergebnis: ``` M .wikitool-kb.json ``` Der Applied-Ledger des echten Repos war überschrieben — `applied: []` statt der beiden Einträge für `3.0.0-authoring-conventions` und `4.0.0-link-taxonomy`. Zurückgeholt mit `git checkout --`, die Tests auf eine lokale `rooted_kb`-Fixture umgestellt. Das war eine unversionierte, git-verfolgte Datei, also war der Schaden reversibel und sofort sichtbar. Bei einer gitignorierten Datei — oder in einem Baum mit uncommitteten Änderungen — wäre er es nicht gewesen. ## Der zweite, stillere Fall Derselbe Mechanismus machte Prüfungen wirkungslos, statt Dateien zu überschreiben. `lint_core._collection_of()` löste eine Seite gegen `config.KB_DIR` auf, nicht gegen das an `run_lint()` übergebene Verzeichnis: ```python page.path.relative_to(config.KB_DIR).parts[0] ``` Für eine Seite unter `tmp_path/kb/` wirft das `ValueError`, die Funktion gab `None` zurück, und die Label-Autorisierungsprüfung übersprang die Kante stillschweigend. Das hieß: **`unauthorised_labels` war in der Suite faktisch nicht getestet** — jeder Test, der es hätte auslösen können, bekam eine leere Liste zurück und behauptete nichts. Das war die gefährlichere Hälfte. Ein überschriebenes `.wikitool-kb.json` sieht man in `git status`. Eine Prüfung, die unter Test nie feuert, sieht man gar nicht, und ihr grüner Testlauf liest sich wie eine Zusicherung. ## Warum das nicht die Autouse-Fixture erledigt `hermetic_environment` neutralisiert die *Umgebung* — `HOME`, `XDG_CONFIG_HOME`, die Git-Konfiguration, `CHEMENU_ROOT`. `config.ROOT` fällt bei fehlendem `CHEMENU_ROOT` auf `_PACKAGE_ROOT` zurück, also auf den Checkout, aus dem die Tests laufen. Das ist für die meisten Tests richtig — sie brauchen die ausgelieferten `types/` — und genau deshalb greift die Isolation hier nicht von selbst. `config`s Modul-`__getattr__` löst die abgeleiteten Pfade bei jedem Zugriff auf, `monkeypatch.setattr(config, "ROOT", tmp_path)` zieht `KB_DIR` also mit. Der Mechanismus war vorhanden; `kb_dir` benutzte ihn nur nicht. ## Entschieden und umgesetzt 1. **`kb_dir` repointet selbst** (Variante 1, nicht die getrennte `rooted_kb`-Fixture). Genau das, was `raw_dir` schon tat: `config.ROOT` auf das eigene `tmp_path`, plus `use_shipped_type_specs()`. Der befürchtete Umfang wurde gemessen statt geschätzt — **kein einziger Test kippte** (863 vorher). Variante 2 wurde verworfen, weil sie die Falle stehen lässt und die Auswahl zwischen zwei fast identischen Fixturen Wissen wäre, das nirgends steht. `rooted_kb` ist ersatzlos entfallen. 2. **`_collection_of()` löst gegen den übergebenen Baum auf**, und `authorised_labels()` bekommt denselben Baum gereicht statt auf `config.KB_DIR` zurückzufallen. Das ist der eigentliche Fix: eine Funktion, die ein Verzeichnis entgegennimmt, löst dagegen auf — keine Fixture kann diese Form von außen reparieren. 3. **Regressionstest:** `test_unauthorised_label_is_judged_in_a_tree_that_is_not_the_configured_kb` lintet einen Baum, von dem `ROOT` bewusst wegzeigt. Gegen den alten Code schlägt er fehl (verifiziert), gegen den neuen nicht. Ein Test unter der reparierten Fixture allein hätte nichts bewiesen — dort ist `kb_dir == config.KB_DIR`, und der Defekt bliebe unsichtbar. 4. **Wächter: ja, zweistufig.** | Guard | Default | Kosten | |---|---|---| | `repository_tree_guard` (session) | an | zwei `git status --porcelain` pro Lauf | | `per_test_tree_guard` | aus, `CHEMENU_TREE_GUARD=each` | ein `git status` pro Test | Der Session-Wächter vergleicht vorher gegen nachher statt einen sauberen Baum zu verlangen, sagt also nichts über unveröffentlichte Arbeit des Entwicklers. Er benennt den Verursacher nicht — dafür ist `CHEMENU_TREE_GUARD=each` da. Ohne git oder außerhalb eines Repositorys sind beide still. Beide gegen eine absichtlich schreibende Probe verifiziert. **Bewusst nicht abgedeckt:** die stillere Hälfte. Eine Prüfung, die unter Test nichts tut, schreibt keine Datei — kein Wächter dieser Bauart sieht das. Dagegen hilft nur ein Test, der das Finding tatsächlich auslöst. Diese Grenze steht in `testing-conventions.md`, damit sie nicht als abgedeckt missverstanden wird. ## Checkliste - [x] Entscheidung 1 vs. 2 getroffen und umgesetzt; Suite-Lauf auf gekippte Tests geprüft — keine - [x] `_collection_of()` gegen den übergebenen Baum aufgelöst - [x] Test geschrieben, der `unauthorised_labels` tatsächlich auslöst - [x] `instructions/dev/testing-conventions.md` ergänzt (Abschnitt „Which tree a test writes into", ein Checklisten-Schritt, drei Fixture-Tests in `test_hermetic_env.py`) - [x] Version-Bump `--patch` → 4.1.1 ## Verifiziert 867 Tests grün, auch im gehärteten `env -i`-Lauf; `docs verify` und `instructions verify` OK; der Regressionstest gegen den alten Code als fehlschlagend nachgewiesen; beide Wächter gegen eine schreibende Probe getestet. ## Nachtrag: der Prozessfehler beim Schließen (4.1.2) Dieser Issue wurde zunächst mit einem Abschlusskommentar geschlossen, während der Body weiter als offene Arbeit dastand — „Zu entscheiden" über eine längst getroffene Entscheidung, ungehakte Checkliste. Das ist genau der Fehler, den `instructions/dev/issue-tracking.md` Schritt 2 verhindern soll. Daraus wurde die Regel geschärft statt nur der Fall repariert (4.1.2, `41f5dfe`): - **Schritt 2:** Der Body ist das Plan-File dieses Stacks — fortlaufend aktuell, nicht am Ende nachgezogen. Maßstab ist der Abbruch: eine Session kann jederzeit enden, und der Body ist zu jedem Zeitpunkt die vollständige Übergabe an die nächste. - **Schritt 7:** Abschluss ist die letzte dieser Aktualisierungen, kein Sonderakt. Body auf Endstand, dann schließen, dann Changelog-Kommentar. - **Schritt 3:** Ein Kommentar pro Session-Umfang, nicht pro Edit — sonst erzeugt die fortlaufende Pflege Lärm. - **Neuer Abschnitt „What no tool checks":** `wikitool` kennt den Tracker nicht und soll ihn nicht kennenlernen (es wird an Instanzen ausgeliefert, die kein Board haben; `instructions/dev/` wird von `dist export` gepruned). Es gibt also keine mechanische Prüfung für einen Body, der offen klingt, obwohl er es nicht ist — das fängt nur eine Session ab, die dieser Datei folgt. - `stack-dev/SKILL.md` sagt es beim Aufgreifen mit. ## Vorgeschichte Gefunden am 2026-09-03 beim Bau der Migrations-Gate-Tests für 4.1.0 (#40). Geschlossen am 2026-09-03 mit 4.1.1; Prozess-Nachtrag als 4.1.2.
torben added the prio/plannedsize/Marea/processkind/defect labels 2026-09-03 04:21:25 +00:00
Author
Owner

Umgesetzt in 4.1.1 (23307c3)

Entscheidung 1, nicht 2. kb_dir repointet jetzt selbst — config.ROOT auf das eigene tmp_path, plus use_shipped_type_specs(), also genau das, was raw_dir schon tat. Der befürchtete Umfang war messbar statt geschätzt: kein einziger Test kippte (863 vorher, alle grün nachher). Die lokale rooted_kb-Umgehung aus 4.1.0 ist damit ersatzlos entfallen; die Auswahl zwischen zwei fast identischen Fixturen war Wissen, das nirgends stand.

Punkt 3 ist der eigentliche Fix. _collection_of() löst gegen das an run_lint() übergebene Verzeichnis auf, und authorised_labels() bekommt denselben Baum gereicht statt auf config.KB_DIR zurückzufallen. Regressionstest: test_unauthorised_label_is_judged_in_a_tree_that_is_not_the_configured_kb lintet einen Baum, von dem ROOT bewusst wegzeigt — gegen den alten Code schlägt er fehl (verifiziert), gegen den neuen nicht. Das ist der Beleg, den die Checkliste verlangt hat: hätte die Fixture allein gefixt, wäre kb_dir == config.KB_DIR und der Defekt weiterhin unsichtbar.

Punkt 4, Wächter: ja, zweistufig.

Guard Default Kosten
repository_tree_guard (session) an zwei git status --porcelain pro Lauf
per_test_tree_guard aus, CHEMENU_TREE_GUARD=each ein git status pro Test

Der Session-Wächter vergleicht vorher gegen nachher statt einen sauberen Baum zu verlangen, sagt also nichts über unveröffentlichte Arbeit. Er benennt den Verursacher nicht — dafür ist CHEMENU_TREE_GUARD=each da. Ohne git oder außerhalb eines Repositorys sind beide still. Beide gegen eine absichtlich schreibende Probe verifiziert.

Was der Wächter nicht abfängt: die stillere Hälfte. Eine Prüfung, die unter Test nichts tut, schreibt keine Datei. Dagegen hilft nur ein Test, der das Finding tatsächlich auslöst — steht so auch in den Conventions.

Dokumentiert in instructions/dev/testing-conventions.md, neuer Abschnitt „Which tree a test writes into" plus ein Schritt in der Checkliste: eine neue Fixture, die einen Baum baut, repointet ROOT. Dazu drei Tests in test_hermetic_env.py, die für beide Korpus-Fixturen festhalten, dass sie es tun.

Version: --patch (4.1.1) — Punkt 3 ist ein Fix ohne Interface-Änderung, der Rest ist Test und Doku.

  • Entscheidung 1 vs. 2 getroffen und umgesetzt; Suite-Lauf geprüft, nichts gekippt
  • _collection_of() gegen den übergebenen Baum
  • Test, der unauthorised_labels tatsächlich auslöst
  • testing-conventions.md ergänzt
  • --patch-Bump

Verifiziert: 867 Tests grün, auch im gehärteten env -i-Lauf; docs verify und instructions verify OK.

## Umgesetzt in 4.1.1 (`23307c3`) **Entscheidung 1, nicht 2.** `kb_dir` repointet jetzt selbst — `config.ROOT` auf das eigene `tmp_path`, plus `use_shipped_type_specs()`, also genau das, was `raw_dir` schon tat. Der befürchtete Umfang war messbar statt geschätzt: **kein einziger Test kippte** (863 vorher, alle grün nachher). Die lokale `rooted_kb`-Umgehung aus 4.1.0 ist damit ersatzlos entfallen; die Auswahl zwischen zwei fast identischen Fixturen war Wissen, das nirgends stand. **Punkt 3 ist der eigentliche Fix.** `_collection_of()` löst gegen das an `run_lint()` übergebene Verzeichnis auf, und `authorised_labels()` bekommt denselben Baum gereicht statt auf `config.KB_DIR` zurückzufallen. Regressionstest: `test_unauthorised_label_is_judged_in_a_tree_that_is_not_the_configured_kb` lintet einen Baum, von dem `ROOT` bewusst wegzeigt — gegen den alten Code schlägt er fehl (verifiziert), gegen den neuen nicht. Das ist der Beleg, den die Checkliste verlangt hat: hätte die Fixture allein gefixt, wäre `kb_dir == config.KB_DIR` und der Defekt weiterhin unsichtbar. **Punkt 4, Wächter: ja, zweistufig.** | Guard | Default | Kosten | |---|---|---| | `repository_tree_guard` (session) | an | zwei `git status --porcelain` pro Lauf | | `per_test_tree_guard` | aus, `CHEMENU_TREE_GUARD=each` | ein `git status` pro Test | Der Session-Wächter vergleicht vorher gegen nachher statt einen sauberen Baum zu verlangen, sagt also nichts über unveröffentlichte Arbeit. Er benennt den Verursacher nicht — dafür ist `CHEMENU_TREE_GUARD=each` da. Ohne git oder außerhalb eines Repositorys sind beide still. Beide gegen eine absichtlich schreibende Probe verifiziert. Was der Wächter **nicht** abfängt: die stillere Hälfte. Eine Prüfung, die unter Test nichts tut, schreibt keine Datei. Dagegen hilft nur ein Test, der das Finding tatsächlich auslöst — steht so auch in den Conventions. **Dokumentiert** in `instructions/dev/testing-conventions.md`, neuer Abschnitt „Which tree a test writes into" plus ein Schritt in der Checkliste: eine neue Fixture, die einen Baum baut, repointet `ROOT`. Dazu drei Tests in `test_hermetic_env.py`, die für beide Korpus-Fixturen festhalten, dass sie es tun. **Version:** `--patch` (4.1.1) — Punkt 3 ist ein Fix ohne Interface-Änderung, der Rest ist Test und Doku. - [x] Entscheidung 1 vs. 2 getroffen und umgesetzt; Suite-Lauf geprüft, nichts gekippt - [x] `_collection_of()` gegen den übergebenen Baum - [x] Test, der `unauthorised_labels` tatsächlich auslöst - [x] `testing-conventions.md` ergänzt - [x] `--patch`-Bump Verifiziert: 867 Tests grün, auch im gehärteten `env -i`-Lauf; `docs verify` und `instructions verify` OK.
Author
Owner

Changelog: Body auf den Endstand gezogen — er stand nach dem Schließen noch als offene Arbeit da (Abschnitt „Zu entscheiden", ungehakte Checkliste), obwohl entschieden und umgesetzt. „Zu entscheiden" → „Entschieden und umgesetzt" mit der jeweiligen Begründung, Checkliste abgehakt, Abschnitt „Verifiziert" ergänzt, Diagnose ins Präteritum. Der vorige Kommentar bleibt als Umsetzungsbericht stehen; inhaltlich neu ist nichts.

**Changelog:** Body auf den Endstand gezogen — er stand nach dem Schließen noch als offene Arbeit da (Abschnitt „Zu entscheiden", ungehakte Checkliste), obwohl entschieden und umgesetzt. „Zu entscheiden" → „Entschieden und umgesetzt" mit der jeweiligen Begründung, Checkliste abgehakt, Abschnitt „Verifiziert" ergänzt, Diagnose ins Präteritum. Der vorige Kommentar bleibt als Umsetzungsbericht stehen; inhaltlich neu ist nichts.
Author
Owner

Changelog: Abschnitt „Nachtrag: der Prozessfehler beim Schließen (4.1.2)" ergänzt — der falsch geschlossene Body dieses Issues war der Anlass, issue-tracking.md Schritt 2/3/7 zu schärfen (Body = Plan-File, fortlaufend aktuell; Abschluss ist die letzte Aktualisierung; ein Kommentar pro Session-Umfang) und den Abschnitt „What no tool checks" aufzunehmen. Kopfzeile verweist darauf. Sonst unverändert.

**Changelog:** Abschnitt „Nachtrag: der Prozessfehler beim Schließen (4.1.2)" ergänzt — der falsch geschlossene Body dieses Issues war der Anlass, `issue-tracking.md` Schritt 2/3/7 zu schärfen (Body = Plan-File, fortlaufend aktuell; Abschluss ist die letzte Aktualisierung; ein Kommentar pro Session-Umfang) und den Abschnitt „What no tool checks" aufzunehmen. Kopfzeile verweist darauf. Sonst unverändert.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#44