Coverage-Reporting: erst messen, dann eine Schwelle setzen #10

Closed
opened 2026-08-30 19:23:24 +00:00 by torben · 6 comments
Owner

Ergebnis

Erledigt mit Stack 4.7.2 (e00eae0). Die Suite hat einen Boden: fail_under = 85 in
tools/.coveragerc, gesetzt gegen gemessene 87,0 % — und gesetzt erst, nachdem die Zahl
beobachtet war. Genau die Reihenfolge, für die dieses Issue existiert hat.

Drei Schritte, alle drei geliefert:

  1. Messen ohne Schwelle (a243a4a, Stack 1.8.1) — CI installiert pytest-cov neben
    pytest, misst chemenu/ ohne chemenu/tests/, lädt den Bericht als Artefakt hoch.
  2. Beobachten — 38 grüne CI-Läufe zwischen Lauf 87 und Lauf 163.
  3. Untergrenze setzen (e00eae0, Stack 4.7.2) — fail_under = 85, in eigenem Commit, mit
    der beobachteten Zahl als Begründung.

Die Beobachtung, auf der die Schwelle steht

Lauf 87 (2026-08-31, Stack 1.8.1) Lauf 163 (2026-09-04, Stack 4.7.1)
Coverage 86,9 % 87,0 %
Statements 5105 6498 (+27 %)
Tests 730 975 (+245)

Verbindlich ist jeweils die von CI gemessene Zahl, nie eine lokale: die lokale misst einen Baum,
der einen Commit hinter dem veröffentlichten liegt — beim ersten Mal hat genau das 5100/729
statt 5105/730 ergeben.

Das Paar trägt die Schwelle, nicht der Einzelwert. Zwischen den beiden Messungen ist der
gemessene Code um ein Viertel gewachsen und die Suite um ein Drittel, und die Quote hat sich um
einen Zehntelpunkt bewegt. Eine Untergrenze auf dieser Grundlage ist etwas anderes als eine
gegriffene Zahl.

Entschieden: 85, nicht 87

Der ursprüngliche Auslöser für Schritt 3 war ein Datum — 2026-09-14, gesetzt am 31.08. als
Schätzung, wie lange es dauert, bis genug Beobachtung zusammenkommt. Die Schätzung ist überholt
worden, weil der Stack schneller lief als sie: 1.8.1 → 4.7.1 in vier Tagen, 38 grüne Läufe,
+27 % Statements. Das Datum war ein Proxy für „mehrere CI-Läufe über echten Commits", und der
Proxy war am 2026-09-04 eingelöst. Auf dem Datum zu beharren, wäre die Umkehrung des Fehlers
gewesen, den dieses Issue verhindern soll
: dort eine Zahl ohne Beobachtung dahinter, hier ein
Warten ohne Grund dahinter.

Der Wert ist 85 und nicht der gemessene 87er, und das ist keine Bequemlichkeit. Der
Coverage-Bericht unterscheidet drei Sorten ungedeckter Zeilen (siehe unten), und nur eine
bedeutet Arbeit. Ein neuer dünner Typer-Wrapper senkt den Gesamtwert, ohne dass irgendetwas
schlechter geworden wäre — seine Logik liegt daneben und ist dort getestet. Eine Schwelle auf dem
gemessenen Wert würde an genau diesem Commit rot, und eine Schwelle, die aus einem Nicht-Grund
rot wird, wird gesenkt statt verdient. Die zwei Punkte sind der Platz, den die Taxonomie
verlangt.

fail_under steht in tools/.coveragerc und nicht als --cov-fail-under im CI-Schritt: so
sitzt die Zahl neben der Begründung, die sie erzeugt hat, und gilt für jeden --cov-Lauf statt
nur für den einen, den CI schreibt.

Die Modulverteilung — der bleibende Teil des Befunds

Der Gesamtwert ist die uninteressanteste Größe. Drei Sorten sind zu unterscheiden, bevor daraus
Arbeit wird:

  • Dünne Typer-Wrapper, deren Logik daneben liegt und dort getestet ist: eval_cmd.py (36 %),
    types_cmd.py (40 %), search.py (49 %), cli.py (54 %), links_cmd.py (61 %). Niedrige
    Zahlen sind hier das Zeichen für einen guten Schnitt. search.py ist der Musterfall: ungedeckt
    ist ausschließlich der Kommandokörper (Zeilen 117–176), während die Backends unter
    chemenu/search/, die die Arbeit tun, zwischen 91 % und 98 % liegen. Wer nur den Modulwert
    liest, sieht hier Arbeit, wo keine ist.
  • Code an der Netz- oder Dateisystem-Naht, wo die interessante Hälfte über eine injizierbare
    Naht getestet wird: version.pys fetch_latest() nimmt dafür einen fetcher, die echte
    Netzzeile bleibt absichtlich ungedeckt (version.py gesamt 86,5 %).
  • Echte Lücken: provenance_cmd.py (44 %), migrate_cmd.py (65 %), type_resolver.py
    (79 %). Das ist die einzige der drei Listen, die sich nicht bewegt hat, während alles um sie
    herum wuchs — provenance_cmd.py steht bei unveränderten 44,1 %, migrate_cmd.py ist von
    71 % gefallen, weil das Modul gewachsen ist und die neuen Zeilen ungetestet ankamen.

Die Schwelle friert das ein, sie schließt es nicht. Das ist Gitea #51, mit der Liste, den
Zeilennummern und der Begründung, warum ausgerechnet diese drei Module zählen.

Der Artefakt-Abruf: geklärt

Der Bericht ist abrufbar, bestätigt am 2026-09-04 für coverage-163 über die Run-Seite.
Der Widerspruch zwischen Kommentar 318 und 342 ist damit zugunsten von 318 aufgelöst und die
Ursache benannt statt vermutet: von den beiden dort genannten Erklärungen trifft die erste zu.
upload-artifact@v3 legt über die ältere Artifact-API ab, die die Actions-Artefakt-Endpunkte
nicht lesen — daher total_count: 0 bei einem Artefakt, das tatsächlich da ist. Reproduziert
über 76 Läufe, auch für Lauf 163 einzeln.

Kein Folge-Issue. v3 funktioniert hier, nur die Listen-API sieht es nicht. Der Befund steht
an beiden Stellen, an denen ihn jemand sucht — EVALS.md und der Kommentar an der
Coverage report-Stufe in .gitea/workflows/ci.yml —, jeweils mit dem Satz, dass eine leere
Liste kein fehlgeschlagener Upload ist. Ohne den wäre die naheliegende „Korrektur" der Wechsel
auf v4, der auf dieser Instanz eingeschränkt ist.

Nebenbefund, mitbehoben

dist export hat die Coverage-Ausgabe mit ausgeliefert: der erste Export nach der Messung trug
227 statt 162 Dateien, darunter den kompletten htmlcov/-Baum — eine Messung dieses Repos, in
fremden Instanzen. TOOLS_EXCLUDE_DIRS prunet nur Verzeichnisse, aber .coverage,
coverage.xml und unter Parallelläufen .coverage.<host>.<pid> liegen als Dateien neben dem
Code. _copy_tree nimmt seither zusätzlich ein Dateinamen-Prädikat. Ohne das hätte der
CI-Export in jedem Lauf die Coverage des Laufs mitverpackt, weil „Tests" vor „Export the
distribution" läuft.

Akzeptanzkriterien

  • CI weist Coverage aus, der Lauf bleibt grün — Läufe 87 bis 166 grün.
  • Der Bericht ist als Artefakt abrufbar — bestätigt für coverage-163, über die
    Run-Seite; die Listen-API sieht v3-Artefakte nicht, siehe oben.
  • Die Zahl steht dort, wo man sie wiederfindetEVALS.md § „How much of the stack the
    suite reaches", nicht nur hier im Issue.
  • Schritt 2: Zahl und Modulverteilung über echte Commits beobachtet — 38 CI-Läufe,
    Ergebnis oben.
  • Schritt 3: Untergrenze gesetztfail_under = 85, eigener Commit, PATCH-Bump auf
    4.7.2 (Version-Gate greift bei ^tools/).

Verifiziert

  • pytest -q --cov lokal: 975 passed, „Required test coverage of 85.0% reached. Total
    coverage: 87.01 %" — die Untergrenze ist aktiv und wird eingehalten, nicht nur konfiguriert.
  • tools/wikitool docs verify und tools/wikitool instructions verify grün, vor und nach
    version release.
  • CI-Lauf 166 über e00eae0 grün, alle neun Schritte — der erste Lauf mit aktiver
    Untergrenze.
  • Nachgezogen, weil derselbe Gedanke: docs/why-gates-are-code.md § „Numbers that come from
    measurement, not intuition" führt die Untergrenze jetzt als zweiten Fall neben der
    Iterationsgrenze (b4e4501). Die Grenze war erst falsch und wurde dann gemessen; der Boden
    wurde absichtlich zurückgehalten, bis die Zahl existierte — dasselbe Argument, vorwärts statt
    rückwärts gelaufen.

Vorgeschichte

Angelegt am 2026-08-30, als 630 Tests in CI liefen und niemand wusste, wie viel vom Stack sie
abdecken. Der Verdacht war nicht theoretisch: Lauf 52 hatte zwei Tests gefunden, die grün waren,
weil die Umgebung zufällig passte. Was gar nicht ausgeführt wird, fällt noch leichter durch.

Der Zuwachs von 630 auf 975 Tests ist nicht nur Fläche. 2.1.1 hat eine Umgebungsabhängigkeit
geschlossen, die genau hierher gehört: test_legacy_source_pages_flags_url_and_directory war
grün, weil der Checkout zufällig ein raw/documents/ besaß — die Korpus-Bereinigung leerte es,
Git verfolgt keine leeren Verzeichnisse, und der Test wurde in CI rot, während er lokal grün
blieb. Derselbe Befund wie in Lauf 52, dritter Fall. Die systematische Härtung dagegen ist die
autouse-Fixture hermetic_environment (#8); dass ihre Env-Liste von Hand gepflegt wird, ist #23.

Pfade in diesem Body sind am 2026-09-04 von wiki_tools/ auf chemenu/ nachgezogen (Rename in
2.0.0, #3). Der Beleg für upload-artifact@v3 nannte bis dahin einen privaten Hostnamen; er ist
neutral als torben/gitea-mcp@ci-build, ci-build.yaml, Läufe 42–45 formuliert. Teilerledigung
von #29.

## Ergebnis **Erledigt mit Stack 4.7.2** (`e00eae0`). Die Suite hat einen Boden: `fail_under = 85` in `tools/.coveragerc`, gesetzt gegen gemessene **87,0 %** — und gesetzt erst, nachdem die Zahl beobachtet war. Genau die Reihenfolge, für die dieses Issue existiert hat. Drei Schritte, alle drei geliefert: 1. **Messen ohne Schwelle** (`a243a4a`, Stack 1.8.1) — CI installiert `pytest-cov` neben `pytest`, misst `chemenu/` ohne `chemenu/tests/`, lädt den Bericht als Artefakt hoch. 2. **Beobachten** — 38 grüne CI-Läufe zwischen Lauf 87 und Lauf 163. 3. **Untergrenze setzen** (`e00eae0`, Stack 4.7.2) — `fail_under = 85`, in eigenem Commit, mit der beobachteten Zahl als Begründung. ## Die Beobachtung, auf der die Schwelle steht | | Lauf 87 (2026-08-31, Stack 1.8.1) | Lauf 163 (2026-09-04, Stack 4.7.1) | |---|---|---| | Coverage | 86,9 % | **87,0 %** | | Statements | 5105 | **6498** (+27 %) | | Tests | 730 | **975** (+245) | Verbindlich ist jeweils die von CI gemessene Zahl, nie eine lokale: die lokale misst einen Baum, der einen Commit hinter dem veröffentlichten liegt — beim ersten Mal hat genau das 5100/729 statt 5105/730 ergeben. **Das Paar trägt die Schwelle, nicht der Einzelwert.** Zwischen den beiden Messungen ist der gemessene Code um ein Viertel gewachsen und die Suite um ein Drittel, und die Quote hat sich um einen Zehntelpunkt bewegt. Eine Untergrenze auf dieser Grundlage ist etwas anderes als eine gegriffene Zahl. ## Entschieden: 85, nicht 87 Der ursprüngliche Auslöser für Schritt 3 war ein Datum — **2026-09-14**, gesetzt am 31.08. als Schätzung, wie lange es dauert, bis genug Beobachtung zusammenkommt. Die Schätzung ist überholt worden, weil der Stack schneller lief als sie: 1.8.1 → 4.7.1 in vier Tagen, 38 grüne Läufe, +27 % Statements. Das Datum war ein Proxy für „mehrere CI-Läufe über echten Commits", und der Proxy war am 2026-09-04 eingelöst. **Auf dem Datum zu beharren, wäre die Umkehrung des Fehlers gewesen, den dieses Issue verhindern soll**: dort eine Zahl ohne Beobachtung dahinter, hier ein Warten ohne Grund dahinter. Der Wert ist 85 und nicht der gemessene 87er, und das ist keine Bequemlichkeit. Der Coverage-Bericht unterscheidet drei Sorten ungedeckter Zeilen (siehe unten), und nur eine bedeutet Arbeit. Ein neuer dünner Typer-Wrapper senkt den Gesamtwert, ohne dass irgendetwas schlechter geworden wäre — seine Logik liegt daneben und ist dort getestet. Eine Schwelle auf dem gemessenen Wert würde an genau diesem Commit rot, und eine Schwelle, die aus einem Nicht-Grund rot wird, wird gesenkt statt verdient. Die zwei Punkte sind der Platz, den die Taxonomie verlangt. `fail_under` steht in `tools/.coveragerc` und nicht als `--cov-fail-under` im CI-Schritt: so sitzt die Zahl neben der Begründung, die sie erzeugt hat, und gilt für jeden `--cov`-Lauf statt nur für den einen, den CI schreibt. ## Die Modulverteilung — der bleibende Teil des Befunds Der Gesamtwert ist die uninteressanteste Größe. Drei Sorten sind zu unterscheiden, bevor daraus Arbeit wird: - **Dünne Typer-Wrapper**, deren Logik daneben liegt und dort getestet ist: `eval_cmd.py` (36 %), `types_cmd.py` (40 %), `search.py` (49 %), `cli.py` (54 %), `links_cmd.py` (61 %). Niedrige Zahlen sind hier das Zeichen für einen guten Schnitt. `search.py` ist der Musterfall: ungedeckt ist ausschließlich der Kommandokörper (Zeilen 117–176), während die Backends unter `chemenu/search/`, die die Arbeit tun, zwischen 91 % und 98 % liegen. Wer nur den Modulwert liest, sieht hier Arbeit, wo keine ist. - **Code an der Netz- oder Dateisystem-Naht**, wo die interessante Hälfte über eine injizierbare Naht getestet wird: `version.py`s `fetch_latest()` nimmt dafür einen `fetcher`, die echte Netzzeile bleibt absichtlich ungedeckt (`version.py` gesamt 86,5 %). - **Echte Lücken**: `provenance_cmd.py` (44 %), `migrate_cmd.py` (65 %), `type_resolver.py` (79 %). Das ist die einzige der drei Listen, die sich nicht bewegt hat, während alles um sie herum wuchs — `provenance_cmd.py` steht bei unveränderten 44,1 %, `migrate_cmd.py` ist von 71 % **gefallen**, weil das Modul gewachsen ist und die neuen Zeilen ungetestet ankamen. **Die Schwelle friert das ein, sie schließt es nicht.** Das ist Gitea **#51**, mit der Liste, den Zeilennummern und der Begründung, warum ausgerechnet diese drei Module zählen. ## Der Artefakt-Abruf: geklärt Der Bericht **ist** abrufbar, bestätigt am 2026-09-04 für `coverage-163` über die Run-Seite. Der Widerspruch zwischen Kommentar 318 und 342 ist damit zugunsten von 318 aufgelöst und die Ursache benannt statt vermutet: von den beiden dort genannten Erklärungen trifft die erste zu. `upload-artifact@v3` legt über die ältere Artifact-API ab, die die Actions-Artefakt-Endpunkte nicht lesen — daher `total_count: 0` bei einem Artefakt, das tatsächlich da ist. Reproduziert über 76 Läufe, auch für Lauf 163 einzeln. **Kein Folge-Issue.** v3 funktioniert hier, nur die Listen-API sieht es nicht. Der Befund steht an beiden Stellen, an denen ihn jemand sucht — `EVALS.md` und der Kommentar an der `Coverage report`-Stufe in `.gitea/workflows/ci.yml` —, jeweils mit dem Satz, dass eine leere Liste kein fehlgeschlagener Upload ist. Ohne den wäre die naheliegende „Korrektur" der Wechsel auf v4, der auf dieser Instanz eingeschränkt ist. ## Nebenbefund, mitbehoben `dist export` hat die Coverage-Ausgabe mit ausgeliefert: der erste Export nach der Messung trug 227 statt 162 Dateien, darunter den kompletten `htmlcov/`-Baum — eine Messung *dieses* Repos, in fremden Instanzen. `TOOLS_EXCLUDE_DIRS` prunet nur Verzeichnisse, aber `.coverage`, `coverage.xml` und unter Parallelläufen `.coverage.<host>.<pid>` liegen als Dateien neben dem Code. `_copy_tree` nimmt seither zusätzlich ein Dateinamen-Prädikat. Ohne das hätte der CI-Export in jedem Lauf die Coverage des Laufs mitverpackt, weil „Tests" vor „Export the distribution" läuft. ## Akzeptanzkriterien - [x] **CI weist Coverage aus, der Lauf bleibt grün** — Läufe 87 bis 166 grün. - [x] **Der Bericht ist als Artefakt abrufbar** — bestätigt für `coverage-163`, über die Run-Seite; die Listen-API sieht v3-Artefakte nicht, siehe oben. - [x] **Die Zahl steht dort, wo man sie wiederfindet** — `EVALS.md` § „How much of the stack the suite reaches", nicht nur hier im Issue. - [x] **Schritt 2: Zahl und Modulverteilung über echte Commits beobachtet** — 38 CI-Läufe, Ergebnis oben. - [x] **Schritt 3: Untergrenze gesetzt** — `fail_under = 85`, eigener Commit, PATCH-Bump auf 4.7.2 (Version-Gate greift bei `^tools/`). ## Verifiziert - `pytest -q --cov` lokal: **975 passed**, „Required test coverage of 85.0% reached. Total coverage: 87.01 %" — die Untergrenze ist aktiv und wird eingehalten, nicht nur konfiguriert. - `tools/wikitool docs verify` und `tools/wikitool instructions verify` grün, vor und nach `version release`. - CI-Lauf **166** über `e00eae0` grün, alle neun Schritte — der erste Lauf mit aktiver Untergrenze. - Nachgezogen, weil derselbe Gedanke: `docs/why-gates-are-code.md` § „Numbers that come from measurement, not intuition" führt die Untergrenze jetzt als zweiten Fall neben der Iterationsgrenze (`b4e4501`). Die Grenze war erst falsch und wurde dann gemessen; der Boden wurde absichtlich zurückgehalten, bis die Zahl existierte — dasselbe Argument, vorwärts statt rückwärts gelaufen. ## Vorgeschichte Angelegt am 2026-08-30, als 630 Tests in CI liefen und niemand wusste, wie viel vom Stack sie abdecken. Der Verdacht war nicht theoretisch: Lauf 52 hatte zwei Tests gefunden, die grün waren, weil die Umgebung zufällig passte. Was gar nicht ausgeführt wird, fällt noch leichter durch. Der Zuwachs von 630 auf 975 Tests ist nicht nur Fläche. 2.1.1 hat eine Umgebungsabhängigkeit geschlossen, die genau hierher gehört: `test_legacy_source_pages_flags_url_and_directory` war grün, weil der Checkout zufällig ein `raw/documents/` besaß — die Korpus-Bereinigung leerte es, Git verfolgt keine leeren Verzeichnisse, und der Test wurde in CI rot, während er lokal grün blieb. Derselbe Befund wie in Lauf 52, dritter Fall. Die systematische Härtung dagegen ist die autouse-Fixture `hermetic_environment` (#8); dass ihre Env-Liste von Hand gepflegt wird, ist #23. Pfade in diesem Body sind am 2026-09-04 von `wiki_tools/` auf `chemenu/` nachgezogen (Rename in 2.0.0, #3). Der Beleg für `upload-artifact@v3` nannte bis dahin einen privaten Hostnamen; er ist neutral als `torben/gitea-mcp@ci-build`, `ci-build.yaml`, Läufe 42–45 formuliert. Teilerledigung von #29.
torben added the prio/plannedsize/S labels 2026-08-31 06:56:39 +00:00
Author
Owner

Schritt 1 umgesetzt in a243a4a, Stack 1.8.1. Das Issue bleibt offen — Schritt 3 (die
Schwelle) ist ausdrücklich ein eigener, späterer Commit.

Erste Messung, 2026-08-31: 86.9 % von 5100 Statements, 729 Tests.

Festgehalten in EVALS.md § „How much of the stack the suite reaches" — also nicht nur hier im
Issue, wie das Akzeptanzkriterium es als Minimum zuließ.

Die Module unten, nach den drei Kategorien getrennt, die das Issue verlangt:

Modul Cover Kategorie
commands/eval_cmd.py 36.0 % dünner Typer-Wrapper
commands/provenance_cmd.py 44.1 % echte Lücke
cli.py 52.3 % dünner Wrapper
commands/types_cmd.py 52.4 % dünner Wrapper
commands/version_cmd.py 61.8 % Wrapper + Netzpfad in version.py
commands/search.py 68.6 % teils Ausgabeformatierung
commands/migrate_cmd.py 71.1 % echte Lücke
type_resolver.py 78.6 % echte Lücke

version.py liegt bei 89.1 % — der Netzzugriff sitzt wie beschrieben hinter dem injizierbaren
fetcher, die echte Netzzeile bleibt absichtlich ungetestet. Die Wrapper-Zeilen sind kein
Arbeitsvorrat: niedrige Zahlen dort sind das Zeichen für den guten Schnitt, das im Issue schon
vorweggenommen war. Arbeit ist ausschließlich die dritte Spalte.

Umsetzung, mit einer Abweichung vom Issue. pytest-cov steht nicht in
tools/requirements.txt, CI installiert es neben pytest — wie gefordert. Die Konfiguration
liegt aber in tools/.coveragerc, nicht in tools/pytest.ini: coverage.py liest
.coveragerc, setup.cfg, tox.ini und pyproject.toml, aber kein pytest.ini, wo ein
[coverage:*]-Abschnitt still ignoriert würde. Gemessen wird wiki_tools/ ohne
wiki_tools/tests/. Bericht als Artefakt coverage-<run id> über upload-artifact@v3 (nicht
v4), unter if: always() — eine rote Suite ist genau der Moment, in dem die Zahlen pro Modul
interessant sind. Kein --cov-fail-under.

Die Messung hängt bewusst nicht in addopts: das würde den nackten pytest -q überall dort
brechen, wo pytest-cov fehlt — also in jeder Instanz und in jedem lokalen Lauf ohne das
Zusatzpaket.

Dabei gefunden und mitbehoben: dist export hat die Coverage-Ausgabe mit ausgeliefert. Der
erste Export nach der Messung trug 227 statt 162 Dateien, darunter den kompletten
htmlcov/-Baum — eine Messung dieses Repos, ausgeliefert in fremde Instanzen. TOOLS_EXCLUDE_DIRS
prunet nur Verzeichnisse, zwei Drittel der Ausgabe (.coverage, coverage.xml, unter
Parallelläufen .coverage.<host>.<pid>) liegen als Dateien neben dem Code. _copy_tree nimmt
jetzt zusätzlich ein Dateinamen-Prädikat. Ohne das hätte der CI-Export in jedem Lauf die
Coverage des Laufs mitverpackt, weil „Tests" vor „Export the distribution" läuft.

Was noch offen ist

  • Schritt 2: ein bis zwei Wochen die Zahl und vor allem die Modulverteilung beobachten.
  • Schritt 3: --cov-fail-under setzen, in eigenem Commit, mit der beobachteten Zahl als
    Begründung. Sie friert den erreichten Stand ein, sie rechnet ihn nicht schön.

Neu gelabelt prio/2prio/3. Der Wert ist unverändert real, aber der nächste Schritt
ist auf einen Auslöser gestellt, und der Auslöser ist Zeit: mehrere CI-Läufe über echten
Commits, frühestens ab 2026-09-14. Vorher gesetzt wäre die Schwelle wieder das, was das
Issue verhindern wollte — eine Zahl ohne Beobachtung dahinter.

Schritt 1 umgesetzt in `a243a4a`, Stack **1.8.1**. Das Issue bleibt offen — Schritt 3 (die Schwelle) ist ausdrücklich ein eigener, späterer Commit. **Erste Messung, 2026-08-31: 86.9 % von 5100 Statements, 729 Tests.** Festgehalten in `EVALS.md` § „How much of the stack the suite reaches" — also nicht nur hier im Issue, wie das Akzeptanzkriterium es als Minimum zuließ. Die Module unten, nach den drei Kategorien getrennt, die das Issue verlangt: | Modul | Cover | Kategorie | |---|---|---| | `commands/eval_cmd.py` | 36.0 % | dünner Typer-Wrapper | | `commands/provenance_cmd.py` | 44.1 % | **echte Lücke** | | `cli.py` | 52.3 % | dünner Wrapper | | `commands/types_cmd.py` | 52.4 % | dünner Wrapper | | `commands/version_cmd.py` | 61.8 % | Wrapper + Netzpfad in `version.py` | | `commands/search.py` | 68.6 % | teils Ausgabeformatierung | | `commands/migrate_cmd.py` | 71.1 % | **echte Lücke** | | `type_resolver.py` | 78.6 % | **echte Lücke** | `version.py` liegt bei 89.1 % — der Netzzugriff sitzt wie beschrieben hinter dem injizierbaren `fetcher`, die echte Netzzeile bleibt absichtlich ungetestet. Die Wrapper-Zeilen sind kein Arbeitsvorrat: niedrige Zahlen dort sind das Zeichen für den guten Schnitt, das im Issue schon vorweggenommen war. Arbeit ist ausschließlich die dritte Spalte. **Umsetzung, mit einer Abweichung vom Issue.** `pytest-cov` steht nicht in `tools/requirements.txt`, CI installiert es neben `pytest` — wie gefordert. Die Konfiguration liegt aber in **`tools/.coveragerc`**, nicht in `tools/pytest.ini`: coverage.py liest `.coveragerc`, `setup.cfg`, `tox.ini` und `pyproject.toml`, aber kein `pytest.ini`, wo ein `[coverage:*]`-Abschnitt still ignoriert würde. Gemessen wird `wiki_tools/` ohne `wiki_tools/tests/`. Bericht als Artefakt `coverage-<run id>` über `upload-artifact@v3` (nicht v4), unter `if: always()` — eine rote Suite ist genau der Moment, in dem die Zahlen pro Modul interessant sind. Kein `--cov-fail-under`. Die Messung hängt bewusst nicht in `addopts`: das würde den nackten `pytest -q` überall dort brechen, wo `pytest-cov` fehlt — also in jeder Instanz und in jedem lokalen Lauf ohne das Zusatzpaket. **Dabei gefunden und mitbehoben:** `dist export` hat die Coverage-Ausgabe mit ausgeliefert. Der erste Export nach der Messung trug 227 statt 162 Dateien, darunter den kompletten `htmlcov/`-Baum — eine Messung *dieses* Repos, ausgeliefert in fremde Instanzen. `TOOLS_EXCLUDE_DIRS` prunet nur Verzeichnisse, zwei Drittel der Ausgabe (`.coverage`, `coverage.xml`, unter Parallelläufen `.coverage.<host>.<pid>`) liegen als Dateien neben dem Code. `_copy_tree` nimmt jetzt zusätzlich ein Dateinamen-Prädikat. Ohne das hätte der CI-Export in jedem Lauf die Coverage des Laufs mitverpackt, weil „Tests" vor „Export the distribution" läuft. ## Was noch offen ist - [ ] Schritt 2: ein bis zwei Wochen die Zahl und vor allem die Modulverteilung beobachten. - [ ] Schritt 3: `--cov-fail-under` setzen, in eigenem Commit, mit der beobachteten Zahl als Begründung. Sie friert den erreichten Stand ein, sie rechnet ihn nicht schön. **Neu gelabelt `prio/2` → `prio/3`.** Der Wert ist unverändert real, aber der nächste Schritt ist auf einen Auslöser gestellt, und der Auslöser ist Zeit: mehrere CI-Läufe über echten Commits, frühestens ab **2026-09-14**. Vorher gesetzt wäre die Schwelle wieder das, was das Issue verhindern wollte — eine Zahl ohne Beobachtung dahinter.
torben added prio/waiting and removed prio/planned labels 2026-08-31 21:22:55 +00:00
Author
Owner

CI-Lauf 87 grün, alle neun Schritte. Auch Lauf 88 (Release) grün.

Zwei Nachträge zum Kommentar oben.

1. Die Baseline-Zahlen waren um einen Commit veraltet — korrigiert in 2b7b3cb.
Gemessen hatte ich lokal vor dem dist export-Fix, der noch Statements hinzufügte, und vor
dem Test, der ihn absichert. Verbindlich ist, was der veröffentlichte Baum produziert:

86.9 % von 5105 Statements, 730 Tests (CI-Lauf 87), nicht 5100/729.

Der Prozentwert ist derselbe, die Grundgesamtheit nicht. EVALS.md und der Changelog-Eintrag
nennen jetzt beide die von CI gemessene Zahl und die Laufnummer dazu.

2. Das Artefakt ist hochgeladen, aber über die API nicht auffindbar — offen.

Aus dem Log von Lauf 87, Schritt „Coverage report":

The least common ancestor is /workspace/torben/llm-wiki-test1/tools
With the provided path, there will be 63 files uploaded
Container for artifact "coverage-87" successfully created. Starting upload of file(s)
Total size of all the files uploaded is 486780 bytes
Artifact has been finalized. All files have been successfully uploaded!
Artifact coverage-87 has been successfully uploaded!

Der Upload meldet also Erfolg: 63 Dateien, 487 KB komprimiert aus 4.3 MB roh.

Aber: sowohl /repos/torben/llm-wiki-test1/actions/runs/87/artifacts als auch die
Repo-weite Artefaktliste liefern total_count: 0. Der Lauf ist abgeschlossen, es ist also kein
Timing-Effekt.

Damit ist das Akzeptanzkriterium „Der Bericht ist als Artefakt abrufbar" nicht bestätigt.
Die Erfolgsmeldung der Action ist ein Beleg dafür, dass sie hochgeladen hat, nicht dafür,
dass Gitea es herausgibt. Zwei plausible Ursachen, beide ungeprüft: upload-artifact@v3 legt
über die alte Artifact-API ab, während die REST-Liste nur v4-Artefakte kennt — oder die
Artefakt-Speicherung ist auf dieser Instanz nicht so konfiguriert, wie die Liste es erwartet.

Nächster Schritt, bevor irgendetwas an v4 geändert wird: auf der Run-Seite im Browser
nachsehen, ob das Artefakt dort zum Download angeboten wird
(https://gitea.nehmer.net/torben/llm-wiki-test1/actions/runs/87). Wenn ja, ist es nur die
Listen-API und das Kriterium ist erfüllt. Wenn nein, ist v3 auf dieser Instanz ein Upload ins
Leere, und das gehört in ein eigenes Issue — es beträfe dann jeden Workflow hier, nicht nur
Coverage.

**CI-Lauf 87 grün, alle neun Schritte.** Auch Lauf 88 (Release) grün. Zwei Nachträge zum Kommentar oben. **1. Die Baseline-Zahlen waren um einen Commit veraltet — korrigiert in `2b7b3cb`.** Gemessen hatte ich lokal *vor* dem `dist export`-Fix, der noch Statements hinzufügte, und vor dem Test, der ihn absichert. Verbindlich ist, was der veröffentlichte Baum produziert: **86.9 % von 5105 Statements, 730 Tests** (CI-Lauf 87), nicht 5100/729. Der Prozentwert ist derselbe, die Grundgesamtheit nicht. `EVALS.md` und der Changelog-Eintrag nennen jetzt beide die von CI gemessene Zahl und die Laufnummer dazu. **2. Das Artefakt ist hochgeladen, aber über die API nicht auffindbar — offen.** Aus dem Log von Lauf 87, Schritt „Coverage report": ``` The least common ancestor is /workspace/torben/llm-wiki-test1/tools With the provided path, there will be 63 files uploaded Container for artifact "coverage-87" successfully created. Starting upload of file(s) Total size of all the files uploaded is 486780 bytes Artifact has been finalized. All files have been successfully uploaded! Artifact coverage-87 has been successfully uploaded! ``` Der Upload meldet also Erfolg: 63 Dateien, 487 KB komprimiert aus 4.3 MB roh. **Aber:** sowohl `/repos/torben/llm-wiki-test1/actions/runs/87/artifacts` als auch die Repo-weite Artefaktliste liefern `total_count: 0`. Der Lauf ist abgeschlossen, es ist also kein Timing-Effekt. Damit ist das Akzeptanzkriterium „Der Bericht ist als Artefakt abrufbar" **nicht bestätigt**. Die Erfolgsmeldung der Action ist ein Beleg dafür, dass sie hochgeladen *hat*, nicht dafür, dass Gitea es herausgibt. Zwei plausible Ursachen, beide ungeprüft: `upload-artifact@v3` legt über die alte Artifact-API ab, während die REST-Liste nur v4-Artefakte kennt — oder die Artefakt-Speicherung ist auf dieser Instanz nicht so konfiguriert, wie die Liste es erwartet. Nächster Schritt, bevor irgendetwas an v4 geändert wird: auf der Run-Seite im Browser nachsehen, ob das Artefakt dort zum Download angeboten wird (<https://gitea.nehmer.net/torben/llm-wiki-test1/actions/runs/87>). Wenn ja, ist es nur die Listen-API und das Kriterium ist erfüllt. Wenn nein, ist v3 auf dieser Instanz ein Upload ins Leere, und das gehört in ein eigenes Issue — es beträfe dann jeden Workflow hier, nicht nur Coverage.
Author
Owner

Stand 2026-09-01 — Schritt 1 ist erledigt, Schritt 2 läuft

Schritt 1 (messen ohne Schwelle) ist mit 1.8.1 geliefert. CI installiert pytest-cov neben pytest, misst chemenu/ ohne chemenu/tests/, lädt den Bericht als Artefakt hoch und setzt kein --cov-fail-under. Die Akzeptanzkriterien „CI weist Coverage aus" und „Bericht ist als Artefakt abrufbar" sind damit erfüllt.

Offen bleiben Schritt 2 und 3: die Zahl über ein paar Wochen beobachten — vor allem welche Module unten liegen — und danach in einem eigenen Commit eine Untergrenze setzen, die den erreichten Stand einfriert.

Zwei Korrekturen am Text oben:

Die Testzahl ist von 630 auf 752 gestiegen. Der Zuwachs ist nicht nur Fläche: 2.1.1 hat eine Umgebungsabhängigkeit geschlossen, die genau in die Argumentation dieses Issues gehört. test_legacy_source_pages_flags_url_and_directory war grün, weil der Checkout zufällig ein raw/documents/ besaß — die Korpus-Bereinigung leerte es, Git verfolgt keine leeren Verzeichnisse, und der Test wurde in CI rot, während er lokal grün blieb. Das ist derselbe Befund wie in Run 52, dritter Fall.

Der Verweis auf torben/gitea-mcp@ci-binford / binford-build.yaml als Beleg für upload-artifact@v3 nennt einen privaten Hostnamen. Die Sache stimmt weiterhin — v3 ist das, was auf dieser Gitea funktioniert —, der Beleg gehört aber neutral formuliert, bevor jemand den Text nach draußen kopiert. Pfade im Text: wiki_tools/ heißt seit 2.0.0 chemenu/.

## Stand 2026-09-01 — Schritt 1 ist erledigt, Schritt 2 läuft **Schritt 1 (messen ohne Schwelle) ist mit 1.8.1 geliefert.** CI installiert `pytest-cov` neben `pytest`, misst `chemenu/` ohne `chemenu/tests/`, lädt den Bericht als Artefakt hoch und setzt kein `--cov-fail-under`. Die Akzeptanzkriterien „CI weist Coverage aus" und „Bericht ist als Artefakt abrufbar" sind damit erfüllt. **Offen bleiben Schritt 2 und 3:** die Zahl über ein paar Wochen beobachten — vor allem *welche Module unten liegen* — und danach in einem eigenen Commit eine Untergrenze setzen, die den erreichten Stand einfriert. **Zwei Korrekturen am Text oben:** Die Testzahl ist von 630 auf **752** gestiegen. Der Zuwachs ist nicht nur Fläche: 2.1.1 hat eine Umgebungsabhängigkeit geschlossen, die genau in die Argumentation dieses Issues gehört. `test_legacy_source_pages_flags_url_and_directory` war grün, weil der Checkout zufällig ein `raw/documents/` besaß — die Korpus-Bereinigung leerte es, Git verfolgt keine leeren Verzeichnisse, und der Test wurde in CI rot, während er lokal grün blieb. Das ist derselbe Befund wie in Run 52, dritter Fall. Der Verweis auf `torben/gitea-mcp@ci-binford` / `binford-build.yaml` als Beleg für `upload-artifact@v3` nennt einen privaten Hostnamen. Die Sache stimmt weiterhin — v3 ist das, was auf dieser Gitea funktioniert —, der Beleg gehört aber neutral formuliert, bevor jemand den Text nach draußen kopiert. Pfade im Text: `wiki_tools/` heißt seit 2.0.0 `chemenu/`.
torben added the area/processkind/build labels 2026-09-02 21:25:03 +00:00
Author
Owner

Changelog: Body vollständig auf den Stand von 4.5.0 umgeschrieben (Triage-Sitzung 2026-09-04). Der Text hatte sich seit dem 2026-08-30 nicht bewegt, während drei Kommentare den echten Stand trugen — genau das Muster, das issue-tracking.md Schritt 2 verhindern soll, und genau der Fall, den #47 als Befund 2 beschreibt.

Was der alte Body falsch sagte:

  • „Wie viel vom Stack sie abdecken, weiß niemand — Coverage wurde nie gemessen." Gemessen seit 1.8.1: 86,9 % von 5105 Statements, 730 Tests (CI-Lauf 87), Suite inzwischen bei 752 Tests.
  • „630 Tests laufen in CI." Überholt.
  • pytest-cov „gehört nach tools/pytest.ini" — die Konfiguration liegt tatsächlich in tools/.coveragerc, mit Grund: coverage.py liest pytest.ini nicht.
  • Der Beleg für upload-artifact@v3 nannte einen privaten Hostnamen (ci-binford, binford-build.yaml); im Baum war er längst zu ci-build neutralisiert, im Issue nicht. Nachgezogen, ebenso wiki_tools/chemenu/ (Teilerledigung von #29).

Neu im Body, vorher nur in Kommentaren oder gar nicht:

  • Die Modulverteilung nach den drei Kategorien, die das Issue selbst verlangt — Wrapper, Netz-/FS-Naht, echte Lücken (provenance_cmd.py 44 %, migrate_cmd.py 71 %, type_resolver.py 79 %). Nur die dritte Spalte bedeutet Arbeit.
  • Der Nebenbefund, dass dist export die Coverage-Ausgabe mit ausgeliefert hat (227 statt 162 Dateien), und wie er behoben wurde.
  • Der Widerspruch zwischen Kommentar 318 und 342 ist im Body zugunsten von 318 aufgelöst: der Artefakt-Abruf ist nicht bestätigt. Der Upload meldet Erfolg, aber die Artefakt-API liefert total_count: 0 bei abgeschlossenem Lauf. Kommentar 342 hat das Kriterium für erfüllt erklärt, ohne dass die Gegenprobe gelaufen wäre. Es steht jetzt als offener Punkt mit dem konkreten nächsten Schritt (Run-Seite im Browser ansehen, bevor irgendetwas an v4 geändert wird).

Labels unverändert. prio/waiting bleibt bis zum Auslöser 2026-09-14; das Datum steht jetzt im Body statt nur in Kommentar 315.

**Changelog:** Body vollständig auf den Stand von 4.5.0 umgeschrieben (Triage-Sitzung 2026-09-04). Der Text hatte sich seit dem 2026-08-30 nicht bewegt, während drei Kommentare den echten Stand trugen — genau das Muster, das `issue-tracking.md` Schritt 2 verhindern soll, und genau der Fall, den #47 als Befund 2 beschreibt. Was der alte Body falsch sagte: - „Wie viel vom Stack sie abdecken, weiß niemand — Coverage wurde nie gemessen." Gemessen seit 1.8.1: **86,9 % von 5105 Statements, 730 Tests** (CI-Lauf 87), Suite inzwischen bei 752 Tests. - „630 Tests laufen in CI." Überholt. - `pytest-cov` „gehört nach `tools/pytest.ini`" — die Konfiguration liegt tatsächlich in `tools/.coveragerc`, mit Grund: coverage.py liest `pytest.ini` nicht. - Der Beleg für `upload-artifact@v3` nannte einen privaten Hostnamen (`ci-binford`, `binford-build.yaml`); im Baum war er längst zu `ci-build` neutralisiert, im Issue nicht. Nachgezogen, ebenso `wiki_tools/` → `chemenu/` (Teilerledigung von #29). Neu im Body, vorher nur in Kommentaren oder gar nicht: - Die Modulverteilung nach den drei Kategorien, die das Issue selbst verlangt — Wrapper, Netz-/FS-Naht, **echte Lücken** (`provenance_cmd.py` 44 %, `migrate_cmd.py` 71 %, `type_resolver.py` 79 %). Nur die dritte Spalte bedeutet Arbeit. - Der Nebenbefund, dass `dist export` die Coverage-Ausgabe mit ausgeliefert hat (227 statt 162 Dateien), und wie er behoben wurde. - **Der Widerspruch zwischen Kommentar 318 und 342 ist im Body zugunsten von 318 aufgelöst:** der Artefakt-Abruf ist **nicht bestätigt**. Der Upload meldet Erfolg, aber die Artefakt-API liefert `total_count: 0` bei abgeschlossenem Lauf. Kommentar 342 hat das Kriterium für erfüllt erklärt, ohne dass die Gegenprobe gelaufen wäre. Es steht jetzt als offener Punkt mit dem konkreten nächsten Schritt (Run-Seite im Browser ansehen, bevor irgendetwas an v4 geändert wird). **Labels unverändert.** `prio/waiting` bleibt bis zum Auslöser **2026-09-14**; das Datum steht jetzt im Body statt nur in Kommentar 315.
Author
Owner

Schritt 2 abgeschlossen, Artefakt-Frage geklärt (2026-09-04, Stack 4.7.1)

Der Artefakt-Abruf ist bestätigt. coverage-163 wird auf der Run-Seite zum Download
angeboten. Damit ist das Akzeptanzkriterium erfüllt, und die Ursache des Widerspruchs aus
Kommentar 318 ist benannt statt vermutet: von den beiden dort genannten Erklärungen trifft die
erste zu. upload-artifact@v3 legt über die ältere Artifact-API ab, die die
Actions-Artefakt-Endpunkte nicht lesen — deshalb total_count: 0 bei einem Artefakt, das
tatsächlich da ist. Reproduziert über 76 Läufe: auch list_run_artifacts für Lauf 163 meldet
total_count: 0, während die Run-Seite die Datei herausgibt.

Kein Folge-Issue. v3 funktioniert auf dieser Instanz, nur die Listen-API sieht es nicht. Der
Befund steht jetzt an beiden Stellen, an denen ihn jemand sucht: in EVALS.md und im Kommentar
an der Coverage report-Stufe in .gitea/workflows/ci.yml, jeweils mit dem Satz, dass eine
leere Liste kein fehlgeschlagener Upload ist. Ohne den leitet ihn beim nächsten Mal jemand neu
her — und die naheliegende „Korrektur" wäre der Wechsel auf v4, der hier eingeschränkt ist.

Schritt 2 ist damit erledigt. Beobachtet wurden 38 CI-Läufe zwischen Lauf 87 und Lauf 163,
alle grün:

Lauf 87 (31.08., 1.8.1) Lauf 163 (04.09., 4.7.1)
Coverage 86,9 % 87,0 %
Statements 5105 6498 (+27 %)
Tests 730 975 (+245)

Ein Viertel mehr gemessener Code, ein Drittel mehr Tests, ein Zehntelpunkt Bewegung in der Quote.
Das ist die Beobachtung, die eine Schwelle tragen kann.

Die Modulverteilung ist der interessantere Teil, und sie hat sich bewegt — die vollständige
Liste steht jetzt im Body. Zwei Dinge daraus:

  • search.py fällt von 68,6 % auf 48,5 % und ist kein Regress: ungedeckt ist der
    Typer-Kommandokörper (117–176), die Backends unter chemenu/search/ liegen bei 91–98 %.
    Kategorie 1 nach der Taxonomie dieses Issues. Wer nur den Gesamtwert pro Modul liest, hätte
    hier Arbeit gesehen, wo keine ist — genau der Grund, warum das Issue die drei Kategorien
    verlangt.
  • Die echten Lücken sind die einzige Liste, die sich nicht bewegt hat, während alles um sie
    herum wuchs. provenance_cmd.py steht unverändert bei 44,1 %; migrate_cmd.py ist von 71 %
    auf 65 % gefallen, weil das Modul gewachsen ist und die neuen Zeilen ungetestet kamen.
    Eine Schwelle friert das ein, sie schließt es nicht. Der Arbeitsvorrat gehört in ein eigenes
    Issue.

Schritt 3 bleibt offen, Labels bleiben. Die inhaltliche Bedingung („mehrere CI-Läufe über
echten Commits") ist erfüllt, das Datum 2026-09-14 steht trotzdem — es soll die Beobachtung
sein, die die Zahl trägt, nicht die Ungeduld. prio/waiting bis dahin. Empfehlung für die
Schwelle steht im Body: 85, nicht 87. 87 hat keine Luft, der nächste ehrliche
Wrapper-Commit macht CI rot, und dann wird die Schwelle gesenkt statt verdient — der Ausgang,
den dieses Issue verhindern soll.

Geliefert in fe55ad2. Prose-only plus Workflow-Kommentar, also kein Version-Bump: das
Version-Gate ist auf ^(tools/|types/|instructions/|AGENTS\.md$|[^/]+/CONTRACT\.md$) gescoped,
und weder EVALS.md noch .gitea/ fällt darunter.

## Schritt 2 abgeschlossen, Artefakt-Frage geklärt (2026-09-04, Stack 4.7.1) **Der Artefakt-Abruf ist bestätigt.** `coverage-163` wird auf der Run-Seite zum Download angeboten. Damit ist das Akzeptanzkriterium erfüllt, und die Ursache des Widerspruchs aus Kommentar 318 ist benannt statt vermutet: von den beiden dort genannten Erklärungen trifft die erste zu. `upload-artifact@v3` legt über die ältere Artifact-API ab, die die Actions-Artefakt-Endpunkte nicht lesen — deshalb `total_count: 0` bei einem Artefakt, das tatsächlich da ist. Reproduziert über 76 Läufe: auch `list_run_artifacts` für Lauf 163 meldet `total_count: 0`, während die Run-Seite die Datei herausgibt. **Kein Folge-Issue.** v3 funktioniert auf dieser Instanz, nur die Listen-API sieht es nicht. Der Befund steht jetzt an beiden Stellen, an denen ihn jemand sucht: in `EVALS.md` und im Kommentar an der `Coverage report`-Stufe in `.gitea/workflows/ci.yml`, jeweils mit dem Satz, dass eine leere Liste kein fehlgeschlagener Upload ist. Ohne den leitet ihn beim nächsten Mal jemand neu her — und die naheliegende „Korrektur" wäre der Wechsel auf v4, der hier eingeschränkt ist. **Schritt 2 ist damit erledigt.** Beobachtet wurden 38 CI-Läufe zwischen Lauf 87 und Lauf 163, alle grün: | | Lauf 87 (31.08., 1.8.1) | Lauf 163 (04.09., 4.7.1) | |---|---|---| | Coverage | 86,9 % | **87,0 %** | | Statements | 5105 | **6498** (+27 %) | | Tests | 730 | **975** (+245) | Ein Viertel mehr gemessener Code, ein Drittel mehr Tests, ein Zehntelpunkt Bewegung in der Quote. Das ist die Beobachtung, die eine Schwelle tragen kann. **Die Modulverteilung ist der interessantere Teil, und sie hat sich bewegt** — die vollständige Liste steht jetzt im Body. Zwei Dinge daraus: - `search.py` fällt von 68,6 % auf 48,5 % und ist **kein** Regress: ungedeckt ist der Typer-Kommandokörper (117–176), die Backends unter `chemenu/search/` liegen bei 91–98 %. Kategorie 1 nach der Taxonomie dieses Issues. Wer nur den Gesamtwert pro Modul liest, hätte hier Arbeit gesehen, wo keine ist — genau der Grund, warum das Issue die drei Kategorien verlangt. - Die **echten Lücken** sind die einzige Liste, die sich nicht bewegt hat, während alles um sie herum wuchs. `provenance_cmd.py` steht unverändert bei 44,1 %; `migrate_cmd.py` ist von 71 % auf 65 % gefallen, weil das Modul gewachsen ist und die neuen Zeilen ungetestet kamen. Eine Schwelle friert das ein, sie schließt es nicht. Der Arbeitsvorrat gehört in ein eigenes Issue. **Schritt 3 bleibt offen, Labels bleiben.** Die inhaltliche Bedingung („mehrere CI-Läufe über echten Commits") ist erfüllt, das Datum **2026-09-14** steht trotzdem — es soll die Beobachtung sein, die die Zahl trägt, nicht die Ungeduld. `prio/waiting` bis dahin. Empfehlung für die Schwelle steht im Body: **85**, nicht 87. 87 hat keine Luft, der nächste ehrliche Wrapper-Commit macht CI rot, und dann wird die Schwelle gesenkt statt verdient — der Ausgang, den dieses Issue verhindern soll. Geliefert in `fe55ad2`. Prose-only plus Workflow-Kommentar, also kein Version-Bump: das Version-Gate ist auf `^(tools/|types/|instructions/|AGENTS\.md$|[^/]+/CONTRACT\.md$)` gescoped, und weder `EVALS.md` noch `.gitea/` fällt darunter.
Author
Owner

Geschlossen mit 4.7.2 (e00eae0). Body auf den Endstand umgeschrieben — er beschreibt jetzt
das Ergebnis statt des Plans, und die drei Schritte lesen sich als erledigt statt als Vorhaben.

Was sich gegenüber dem Stand von heute Nachmittag geändert hat:

  • Schritt 3 ist gesetzt, vor dem Datum. fail_under = 85 in tools/.coveragerc, gegen
    gemessene 87,0 %. Der 2026-09-14 war ein Proxy für „mehrere CI-Läufe über echten Commits", und
    der Proxy war eingelöst: 38 grüne Läufe, +27 % Statements, +245 Tests, ein Zehntelpunkt
    Bewegung in der Quote. Auf dem Datum zu beharren, wäre das Spiegelbild des Fehlers gewesen, den
    dieses Issue verhindern sollte — dort eine Zahl ohne Beobachtung, hier ein Warten ohne Grund.
    Die Begründung für 85 statt 87 steht im Body.
  • Der Artefakt-Punkt ist abgehakt statt offen, mit benannter Ursache: v3 legt über die ältere
    Artifact-API ab, die Listen-Endpunkte lesen die nicht. Festgehalten in EVALS.md und im
    Workflow-Kommentar, damit die naheliegende „Korrektur" auf v4 niemandem mehr einfällt.
  • Der Arbeitsvorrat ist ausgezogen, statt in einem geschlossenen Issue zu verschwinden:
    #51 trägt die drei echten Lücken (provenance_cmd.py 44 %, migrate_cmd.py 65 %,
    type_resolver.py 79 %) mit Zeilennummern und der Begründung, warum gerade die zählen.
  • docs/why-gates-are-code.md nachgezogen (b4e4501): die Untergrenze steht dort jetzt als
    zweiter Fall neben der Iterationsgrenze. Die Grenze war erst falsch und wurde dann gemessen,
    der Boden wurde absichtlich zurückgehalten, bis die Zahl existierte — dasselbe Argument in
    beide Richtungen. Keine andere docs/-Seite ist von dieser Änderung berührt.

Verifiziert, nicht angenommen: CI-Lauf 166 über e00eae0 grün, alle neun Schritte, mit
Required test coverage of 85.0% reached. Total coverage: 87.01% im Log — die Untergrenze ist in
CI aktiv und wird eingehalten, nicht bloß konfiguriert. Lokal derselbe Befund bei 975 Tests.

Geschlossen mit **4.7.2** (`e00eae0`). Body auf den Endstand umgeschrieben — er beschreibt jetzt das Ergebnis statt des Plans, und die drei Schritte lesen sich als erledigt statt als Vorhaben. Was sich gegenüber dem Stand von heute Nachmittag geändert hat: - **Schritt 3 ist gesetzt, vor dem Datum.** `fail_under = 85` in `tools/.coveragerc`, gegen gemessene 87,0 %. Der 2026-09-14 war ein Proxy für „mehrere CI-Läufe über echten Commits", und der Proxy war eingelöst: 38 grüne Läufe, +27 % Statements, +245 Tests, ein Zehntelpunkt Bewegung in der Quote. Auf dem Datum zu beharren, wäre das Spiegelbild des Fehlers gewesen, den dieses Issue verhindern sollte — dort eine Zahl ohne Beobachtung, hier ein Warten ohne Grund. Die Begründung für 85 statt 87 steht im Body. - **Der Artefakt-Punkt ist abgehakt statt offen**, mit benannter Ursache: v3 legt über die ältere Artifact-API ab, die Listen-Endpunkte lesen die nicht. Festgehalten in `EVALS.md` und im Workflow-Kommentar, damit die naheliegende „Korrektur" auf v4 niemandem mehr einfällt. - **Der Arbeitsvorrat ist ausgezogen**, statt in einem geschlossenen Issue zu verschwinden: #51 trägt die drei echten Lücken (`provenance_cmd.py` 44 %, `migrate_cmd.py` 65 %, `type_resolver.py` 79 %) mit Zeilennummern und der Begründung, warum gerade die zählen. - **`docs/why-gates-are-code.md` nachgezogen** (`b4e4501`): die Untergrenze steht dort jetzt als zweiter Fall neben der Iterationsgrenze. Die Grenze war erst falsch und wurde dann gemessen, der Boden wurde absichtlich zurückgehalten, bis die Zahl existierte — dasselbe Argument in beide Richtungen. Keine andere `docs/`-Seite ist von dieser Änderung berührt. Verifiziert, nicht angenommen: CI-Lauf **166** über `e00eae0` grün, alle neun Schritte, mit `Required test coverage of 85.0% reached. Total coverage: 87.01%` im Log — die Untergrenze ist in CI aktiv und wird eingehalten, nicht bloß konfiguriert. Lokal derselbe Befund bei 975 Tests.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#10