Automatischer Push: 6 Datei(en) geändert

- .vault-tools/plan-kopie/LIESMICH.md
- .vault-tools/plan-kopie/rot_nachweis.py
- .vault-tools/trading-plattform-pruefung/LIESMICH.md
- .vault-tools/trading-plattform-pruefung/browser_r.py
- .vault-tools/trading-plattform-pruefung/start_probe_w.py
- .vault-tools/trading-plattform-pruefung/start_probe_zugang.py

Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Pascal MichelandClaude Opus 5 committed 2026-09-23 04:00:01 +02:00
1 parent 593acdd122
commit d7ffc9a5b5
6 files changed
+233 -5

No files matched your search

+5 -1
View File
@@ -21,16 +21,20 @@ Die Regel dazu steht in [[AI/Regelwerk/codeworkflow|codeworkflow.md]] („Die Ko
5. **Nach jeder Welle:** `welle_vergleich.py --projekt <projekt> --mat <kopie> [--prosa <rel> …] -- <taskdateien der Welle>`. Prüft, ob genau die Zieldateien geändert sind und ob jede byte-gleich mit der Kopie ist. Es zeigt je Datei nur die erste Abweichung — danach `diff` auf die ganze Datei. Eigene Plankorrekturen im Baum meldet es zu Recht als „außerhalb der Zieldateien".
6. **Escape-Folgen setzen:** `plan_escape.py <datei> <zeile> <codepunkt-hex> …` ersetzt echte Zeichen in einer Zeile durch ihre Escape-Folge, ohne dass eine Schreibschicht mitredet.
7. **Rot-Nachweis je Task (seit 2026-09-18):** `rot_nachweis.py <basis-kopie> <planordner> <arbeitsordner> <spec.json> [--fixturen <ordner>] [--node-modules <pfad>]`. `plan_materialisiere.py` wendet eine Taskdatei immer ganz an; „erst der Test, dann die Umsetzung" lässt sich damit nicht beobachten. Das Skript stellt den Zustand dazwischen auf Wegwerfkopien her — Basis plus Voraussetzungstasks plus der Task, danach die produktiven Zieldateien zurück auf den Stand vor dem Task — und fährt die Testdateien des Tasks (pytest in WSL, vitest unter Windows über eine Junction, die es vor dem Löschen löst). Es meldet je Task `ROT` mit der ersten Fehlerzeile oder `GRUEN`; ein Test, der ohne Umsetzung grün ist, misst sie nicht. Die Basis-Kopie zieht man **vor** der ersten Welle. `spec.json` nennt je Task die Voraussetzungstasks. Erster Einsatz am 2026-09-18 an vier Plänen der Trading Plattform: 35 Tasks, alle rot an der gemeinten Stelle, keiner grün ohne Umsetzung. Die Executer brauchen den Tanz mit dem Beiseitelegen der Produktivdatei dann nicht mehr; ihr Auftrag sagt das ausdrücklich.
7. **Rot-Nachweis je Task (seit 2026-09-18):** `rot_nachweis.py <basis-kopie> <planordner> <arbeitsordner> <spec.json> [--fixturen <ordner>] [--node-modules <pfad>] [--conftest-als-test]`. `tests/conftest.py` gilt dabei als Produktivseite und wird zurückgesetzt; nur wenn die neue Fixture eines Tasks dort liegt, lässt `--conftest-als-test` sie stehen (Beleg unten, 2026-09-22). `plan_materialisiere.py` wendet eine Taskdatei immer ganz an; „erst der Test, dann die Umsetzung" lässt sich damit nicht beobachten. Das Skript stellt den Zustand dazwischen auf Wegwerfkopien her — Basis plus Voraussetzungstasks plus der Task, danach die produktiven Zieldateien zurück auf den Stand vor dem Task — und fährt die Testdateien des Tasks (pytest in WSL, vitest unter Windows über eine Junction, die es vor dem Löschen löst). Es meldet je Task `ROT` mit der ersten Fehlerzeile oder `GRUEN`; ein Test, der ohne Umsetzung grün ist, misst sie nicht. Die Basis-Kopie zieht man **vor** der ersten Welle. `spec.json` nennt je Task die Voraussetzungstasks. Erster Einsatz am 2026-09-18 an vier Plänen der Trading Plattform: 35 Tasks, alle rot an der gemeinten Stelle, keiner grün ohne Umsetzung. Die Executer brauchen den Tanz mit dem Beiseitelegen der Produktivdatei dann nicht mehr; ihr Auftrag sagt das ausdrücklich.
## Was belegt ist
Seit 2026-09-18 nimmt `welle_vergleich.py` unter `## Zieldateien` auch Pfade relativ zum Projekt (ohne Laufwerk und ohne Wurzel), weil Pläne für einen Git-Worktree keine absoluten Pfade nennen; ein `..` darin ist ein Befund wie ein fremder absoluter Pfad. Jede Zeile braucht weiter die Klammer hinter dem Pfad (`(neu)`, `(geändert)`, `(gelöscht)`). `plan_materialisiere.py` erkennt eine Zieldatei ohne Schrägstrich nur mit den Endungen py, ts, tsx, toml, md, css und json — für `compose.yaml` in der Projektwurzel schreibt die Überschrift `./compose.yaml`. Der Treiber fährt dazu drei weitere Fälle (relative Grundlinie, relative Abweichung, `..` nach außen), zusammen 17.
Seit 2026-09-22 behandelt `rot_nachweis.py` `tests/conftest.py` als Produktivseite. Vorher zählte alles unter `tests/` als Testdatei — lag die Korrektur eines Tasks selbst in `conftest.py` (Trading Plattform, Task 369: die Ersatzfunktionen der Netzsperre trugen eine andere Vorgabe als die Originale), wendete der Lauf „ohne Umsetzung" sie mit an und meldete `GRUEN pytest: 147 passed` — der eine Zustand, in dem der Nachweis nichts misst, sah aus wie ein sauberer Befund. Gemessen an derselben Basis-Kopie und demselben Task, altes gegen neues Skript: `GRUEN 147 passed` → `ROT 3 failed, 144 passed` mit der gemeinten Fehlerzeile (`assert ('', '') == ('probe-thema', '')`). Die Gegenprobe für den anderen Fall — eine neue Fixture des Tasks liegt in `conftest.py` (Task 368) — mit `--conftest-als-test` `ROT 1 failed, 11 passed` wie vor der Änderung, ohne Schalter `ROT 6 failed, 6 passed` mit `AttributeError: module 'conftest' has no attribute '_gesperrte_pfade'` als erster Fehlerzeile: rot aus dem falschen Grund, aber sichtbar, und das Skript sagt je Task, wie es `conftest.py` behandelt hat. Was es weiter nicht sieht: ob ein Task beides in `conftest.py` legt, Fixture und Korrektur — dann ist keine der beiden Einstellungen richtig, und der Nachweis läuft von Hand.
Seit 2026-09-20 quotet `rot_nachweis.py` den Arbeitsordner für den WSL-Aufruf (`shlex.quote`). Ein Temp-Pfad mit Leerzeichen — der Benutzername steckt im Scratchpad-Pfad — ließ vorher das `cd` scheitern: Alle sieben Tasks eines Plans der Trading Plattform standen als „ROT pytest: keine Summenzeile" da, ohne dass ein einziger Test lief. Nach der Korrektur derselbe Lauf mit echten Summenzeilen (`3 failed, 17 passed`, `1 error`, …). Wer „keine Summenzeile" bei **jedem** Task sieht, hat kein Rot gemessen, sondern ein kaputtes Werkzeug.
`welle_vergleich_treiber.py` fährt 14 Angriffsfälle gegen `welle_vergleich.py` (Grundlinie zuerst; fremde Datei, unveränderte Zieldatei, Abweichung in erster und letzter Zeile und in der letzten Zieldatei, CRLF, Datei fehlt in der Kopie, Task ohne Zieldateien, Kopie fehlt, Löschung nicht ausgeführt, Prosa-Datei unverändert, Zieldatei außerhalb des Projekts, Datei länger als der Plan). `plan_zeichen.py` hat am 2026-09-17 an einem echten Fund rot gezeigt (U+2028 im Plan). `plan_materialisiere.py` reproduziert Task 108 des Teil-3b-Plans aus dem Stand vor den Wellen byte-genau. `kopie_bauen.py` ist am 2026-09-17 an drei kaputten Eingaben rot gesehen: Ziel existiert schon (Exit 2, nichts kopiert), Ausschluss `node_modules` ohne Gegenstück im Wurzelordner (Befund), und ein aus der Kopie entferntes Paket `trading/data` (die Paketprüfung nennt es; nach dem Zurücklegen leer). Einen Treiber dazu gibt es noch nicht — die drei Fälle sind von Hand gefahren.
Offen seit 2026-09-23: `plan_materialisiere.py` stirbt mit `FileNotFoundError`, wenn die Zieldatei eines „Häng diesen Block ans Ende"-Blocks in der Kopie fehlt (Trading Plattform, Task 384 hängte einen Nachtrag an die Planübersicht an; die Kopie war ohne `docs/plans` gebaut). Ein Absturz mitten im Task lässt die davor angewendeten Blöcke halb drin. Bis das ein Befund ist: Kopien für Pläne, die Plandateien selbst anfassen, mit dem Planordner bauen — und eine Kopie nie nach dem Start der Welle ziehen (sie trägt dann den halben Stand des Arbeitsbaums).
## Was die Skripte nicht sehen
Dateien, die `.gitignore` ausblendet; ob die Kopie selbst sauber ist (eine verschmutzte Kopie erzeugt Fehlalarm, kein falsches Grün); **ob die Kopie älter ist als der Plan** — wird eine Taskdatei nach dem Anwenden noch überarbeitet, meldet `welle_vergleich.py` eine Abweichung, die keine ist (2026-09-17, Teil 4c: der Planer lief noch, als die Kopie entstand). Dann entscheidet `plan_bloecke.py nach` gegen den echten Baum, und die betroffenen Dateien der Kopie werden aus `git show HEAD:<pfad>` neu aufgebaut und der Task erneut angewendet; verwechselbare sichtbare Zeichen (kyrillisches „с"). Sie sind ein Fangnetz, kein Nachweis — den liefert der Lauf mit echten Daten.
+27 -4
View File
@@ -12,6 +12,14 @@ Dann laufen die Testdateien des Tasks. Es tut etwas und berichtet; das Urteil fa
Geltungsbereich und Luecken:
- Testdateien sind Zieldateien unter tests/ sowie *.test.ts und *.test.tsx; alles unter tests/fixtures/
gilt als Testseite und bleibt stehen. Alles andere ist produktiv.
- tests/conftest.py gilt als PRODUKTIVSEITE und wird zurueckgesetzt (Projektvorgabe seit 2026-09-22):
Liegt die Korrektur eines Tasks selbst in conftest.py (Trading Plattform, Task 369: die Ersatzfunktionen
der Netzsperre), wendete das Skript sie im Lauf "ohne Umsetzung" mit an und meldete GRUEN -- der eine
Zustand, in dem der Nachweis nichts misst, sah aus wie ein sauberer Befund. Liegt dagegen eine neue
Fixture des Tasks in conftest.py (Task 368), fehlt sie jetzt im Lauf und die neuen Tests enden als
Sammelfehler -- das ist ROT mit "fixture ... not found" in der ersten Fehlerzeile, also sichtbar.
Wer diesen Fall hat, ruft mit --conftest-als-test auf; dann gilt conftest.py wie frueher als Testdatei.
Das Skript sagt je Task, wie es conftest.py behandelt hat.
- Python-Tests laufen in WSL (Debian, ~/venvs/trading), Oberflaechentests unter Windows mit npx vitest;
dafuer setzt das Skript eine Junction auf das node_modules des Projekts und loest sie vor dem Loeschen.
- Erzeugte Fixtures (der Plan laesst sie mit altem Code erzeugen) holt --fixturen aus einem Ordner nach,
@@ -20,8 +28,9 @@ Geltungsbereich und Luecken:
- Die Basis ist eine Kopie, die der Aufrufer VOR der ersten Welle gezogen hat; das Skript fasst das
Projekt selbst nie an.
Aufruf: python rot_nachweis.py <basis-kopie> <planordner> <arbeitsordner> <spec.json> [--fixturen <ordner>] [--node-modules <pfad>]
Aufruf: python rot_nachweis.py <basis-kopie> <planordner> <arbeitsordner> <spec.json> [--fixturen <ordner>] [--node-modules <pfad>] [--conftest-als-test]
--node-modules nennt das node_modules des Projekts, wenn die Basis-Kopie keines traegt.
--conftest-als-test laesst tests/conftest.py als Testdatei stehen (nur, wenn die neue Fixture des Tasks dort liegt).
spec.json: [{"task": "task-141-....md", "vor": ["task-...md", ...]}, ...]
"""
@@ -37,6 +46,7 @@ from pathlib import Path
HIER = Path(__file__).resolve().parent
ZIEL = re.compile(r"^- `(.+?)`")
PROJEKTNAME = "trading-plattform/"
CONFTEST = "tests/conftest.py"
def zieldateien(taskdatei: Path) -> list[str]:
@@ -59,7 +69,11 @@ def zieldateien(taskdatei: Path) -> list[str]:
return ziele
def ist_test(pfad: str) -> bool:
def ist_test(pfad: str, conftest_als_test: bool = False) -> bool:
if pfad == CONFTEST:
# Vorgabe: produktiv. Sonst wendet der Lauf "ohne Umsetzung" eine Korrektur an, die in
# conftest.py liegt, und meldet gruen (siehe Kopfkommentar).
return conftest_als_test
return pfad.startswith("tests/") or pfad.endswith((".test.ts", ".test.tsx"))
@@ -105,6 +119,10 @@ def main() -> int:
stelle = argumente.index("--node-modules")
node_modules_arg = Path(argumente[stelle + 1])
del argumente[stelle : stelle + 2]
conftest_als_test = False
if "--conftest-als-test" in argumente:
conftest_als_test = True
argumente.remove("--conftest-als-test")
if len(argumente) != 4:
print(__doc__)
return 3
@@ -134,9 +152,14 @@ def main() -> int:
print(f"{task}: ANWENDEN GESCHEITERT: {fehler[-300:]}")
continue
ziele = zieldateien(planordner / task)
tests = [z for z in ziele if ist_test(z) and not z.startswith("tests/fixtures/")]
tests = [z for z in ziele if ist_test(z, conftest_als_test) and not z.startswith("tests/fixtures/")]
if CONFTEST in ziele:
# Sichtbar machen, was mit conftest.py geschah -- der Koordinator liest die erste Fehlerzeile
# anders, wenn eine Fixture fehlt, als wenn eine Korrektur zurueckgesetzt wurde.
wie = "als Testdatei stehen gelassen (--conftest-als-test)" if conftest_als_test else "als Produktivseite auf den Stand vor dem Task zurueckgesetzt"
print(f"{task}: Hinweis: {CONFTEST} {wie}")
for ziel in ziele:
if ist_test(ziel):
if ist_test(ziel, conftest_als_test):
if not (rot / ziel).exists() and fixturen is not None and (fixturen / Path(ziel).name).is_file():
(rot / ziel).parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(fixturen / Path(ziel).name, rot / ziel)