No description
Find a file
Pandi a287e59ee3 feat(gates): count the widget self-check asserts
node test_widget.js prints its check count; the gate had no regex, so the number never appeared and a shrinking suite would have gone unnoticed.
2026-11-05 10:42:23 +01:00
src feat(gates): count the widget self-check asserts 2026-11-05 10:42:23 +01:00
tests chore: initial commit 2026-10-30 12:45:06 +01:00
.gitignore chore: initial commit 2026-10-30 12:45:06 +01:00
Cargo.lock chore: initial commit 2026-10-30 12:45:06 +01:00
Cargo.toml chore: initial commit 2026-10-30 12:45:06 +01:00
README.md feat(gates): run the tts-kokoro normalizer tests, and stop inventing gate counts 2026-11-05 09:24:13 +01:00

run-gates (Rust)

Rust-Port von ~/coding/scripts/run-gates.py (172 Zeilen). Führt die Test-/Lint-Gates aller Projekte unter ~/coding/projects aus und druckt eine Zeile pro Gate:

repo | gate | ok/FAIL/skip | dauer | testzahl

Die letzte Spalte ist die Testzahl, wie sie aus der Gate-Ausgabe kommt. Bei den Go-Gates (go test ./...) zählt sie Pakete mit ok, nicht Testfunktionen (SuperDaemon hat 201 Testfunktionen, aber 24 Pakete) — für „ist etwas kaputt" reicht das, für „sind Tests verschwunden" nicht.

Exit 1, sobald ein Gate rot ist. Keine Farben, keine Emojis.

Warum

Das Skript läuft am Anfang jedes Agenten-Runs und prüft danach die ganze Matrix — beim Debuggen auch einzeln pro Repo. Der Port startet in 0,7 ms statt 28 ms und hängt nicht am Interpreter. Die Gate-Tabelle, die Statuslogik und beide Ausgabeformate sind unverändert, damit die Aufrufer (Skill daily-coding-routine, Reports) dieselben Zeilen sehen.

Bauen und installieren

cargo build --release
install -m 755 target/release/run-gates ~/bin/run-gates

Benutzen

run-gates                        # alle Gates, Tabelle
run-gates --repo OakSeerr        # nur ein Repo
run-gates --slow                 # inkl. DarkOaktyl test-integration (~7,5 min)
run-gates --json --repo sml      # maschinenlesbar ({"gates": [...], "summary": {...}, "exit": N})
run-gates --timeout 60           # Timeout pro Gate (default 300 s)
run-gates --selfcheck            # prueft die parse_count-Logik gegen sieben Beispiele

Pfade sind hartkodiert wie im Original (/home/pandi/coding/projects, /usr/bin/python3 als PY für die pytest-Gates, ~/local/go/bin als PATH-Präfix für die Go-Gates).

Neue Projekte müssen in GATES in src/main.rs eingetragen werden (Rust: cargo test --offline --quiet, Python: /usr/bin/python3 -m pytest -q bzw. -m unittest <modul>, expect als gemessene Untergrenze, danach cargo test gate_table und den Testnamen gate_table_has_N_entries mitziehen) — sonst tauchen sie in keiner Gate-Runde auf.

Nie zwei Runden gleichzeitig starten: zwei next build kollidieren, ein gekillter Build hinterlässt ein halbes .next und das folgende tsc fällt mit TS6053 aus. Das gilt für beide Implementierungen (kein Portfehler, aber beim Paritäts-Vergleich aufgefallen).

Abweichungen

  1. --selfcheck-Erwartungswerte korrigiert. Zwei der sieben Assertions im Original sind arithmetisch falsch und liessen --selfcheck schon am ersten Assert scheitern (Exit 1): 24 + 153 ergibt 177, nicht 178; "Tests 76 passed (76)" ergibt 76, nicht 79. Die Zaehllogik ist unverändert portiert, nur diese beiden Zielwerte stehen jetzt auf dem, was sie tatsächlich liefert. Alles andere (Regexe, Tabelle, Statuslogik, Ausgabe) ist 1:1.
  2. round(dur, 1) nutzt Rusts round() (halb weg von null) statt Pythons banker's rounding. Betrifft nur exakte x.x5-Grenzen der Dauer im JSON, nicht Status/Zähler/Ausgabe der Tabelle.
  3. Detail-Tail: Python str.splitlines() trennt zusätzlich an \r, \x0b, \x0c, \x1c–\x1e, \x85, U+2028/9; Rust lines() nur an \n (und \r\n). Die „letzten 15 nicht-leeren Zeilen" sind für normale Tool-Ausgaben identisch.
  4. --selfcheck im Fehlerfall: Meldung auf stderr + Exit 1 statt Python-Traceback mit AssertionError. Im Erfolgsfall identisch (selfcheck ok, Exit 0).
  5. --help: Text ist nachgebaut; argparse bricht die usage:-Zeile zusätzlich nach Terminalbreite um, Rust nicht.
  6. Abhängigkeiten: regex (bereits in nc-sortier-check-rs und ollama-cloud-rs im Einsatz) und serde_json mit preserve_order (gleiche Key-Reihenfolge wie Pythons json.dumps). Beides liegt im lokalen Cargo-Cache, Build läuft mit --offline.

Keine Verhaltensabweichung bei: Gate-Tabelle (alle Einträge, inkl. erwarteter Testzahlen, Regexe, --slow-Flag, 900-s-Timeout für test-integration, GO_PATH), --repo-Filter, Exitcodes (0/1, 2 bei unbekanntem Repo), Spaltenbreiten 26/17/4, >6.1fs-Dauer, Summary-Zeile, --- Details (rote Gates) --- mit den letzten 15 nicht-leeren Zeilen, JSON-Struktur.

Tests

cargo test
  • tests::selfcheck_holds — die sieben --selfcheck-Assertions
  • tests::parse_count_matches_original_strings — parse_count gegen die Original-Strings (Gruppen-Summe vs. Trefferzahl, None ohne Regex/Match)
  • tests::gate_table_has_45_entries — Tabellengröße (die Zahl steht im Testnamen und in assert_eq!; wer ein Gate ergänzt, zieht beides mit — cargo test gate_table)
  • tests/parity::json_matches_python_for_sml — Rust-Binary vs. /usr/bin/python3 coding/scripts/run-gates.py, beide --json --repo sml, JSON-Feldvergleich ohne dur, gleicher Exitcode
  • tests/parity::unknown_repo_exits_two — --repo gibt-es-nicht → Exit 2 + Meldung

Der Paritätstest überspringt sich selbst, wenn python3 oder das Original fehlt.

Gemessen (2026-10-30)

Lauf Rust Python
--repo sml (Skip-Gate, 20 Iterationen) 0,7 ms 27,9 ms
--repo ipad-notizen-app (5 pytest-Tests) 0,42–0,48 s 0,45 s

Der Repo-Lauf wird von pytest dominiert; der Unterschied ist reiner Start-Overhead.

Real-Lauf --repo OakSeerr --json (16 s): JSON ohne dur identisch zum Original. Der Lauf am 30.10. meldete cargo-test mit erwartet 193, gefunden 195 (Sollwert war veraltet); der Sollwert steht jetzt auf 195 (cargo test | grep '^test result' summiert 195 passed). Die volle Runde nach dem Farbkontrast-Spec (39 neue Frontend-Tests) und den OakSeerr-Advisory-Fixes: 26 ok, 0 FAIL, 2 skip und frontend-test mit erwartet 134 — Matrix grün (Exit 0).

Real-Lauf ~/bin/run-gates (2026-11-05, ohne --slow): 42 ok, 0 FAIL, 2 skip, Exit 0, 68 s — 44 Gates laufen, test-integration fehlt ohne --slow (45 Einträge in der Tabelle). Neu in dieser Runde: tts-kokoro (unittest, 35 Normalizer-Tests).

ollama-usage-monitor hat ein eigenes Gate, braucht aber ein Projekt-venv (die Pakete fastapi/httpx fehlen im System-Python, python3 -m pytest bricht mit drei Collection-Errors ab). Einmalig im Projekt:

uv venv --python 3.11 .venv
uv pip install -r requirements.txt pytest

Das Gate ruft dann .venv/bin/python -m pytest -q (27 Tests). Fehlt das venv, steht das Gate rot da — das ist gewollt, ein stiller Skip wäre hier eine Lücke.