6. Durchgang: Slots, JavaScript, Bibliotheken - jede Achse jetzt eine Pipeline-Stufe
Die vorigen Durchgaenge waren Handarbeit und liefen nur, wenn jemand daran
dachte. Jetzt sind alle drei automatisiert.
JAVASCRIPT - DIE RENDER-PROBE DECKTE 2 VON 15 FUNKTIONEN AB.
render_check.mjs schnitt per Regex genau ZWEI Funktionen heraus (renderM15,
renderBrk). renderKontext und 13 weitere waren nie abgedeckt - und genau dort
ist mir heute der d-statt-snap-Beinahefehler unterlaufen. Die Probe haette ihn
DURCHGELASSEN.
Neu geschrieben: die komplette app.js laeuft in einem VM-Kontext gegen ein
Minimal-DOM, jede render*-Funktion wird aufgerufen - zweimal, mit dem Fixture
UND mit einem leeren Snapshot (der Kaltstart, in dem jedes Feld fehlt).
13 Funktionen laufen durch. Mutationsprobe mit genau dem heutigen Fehler:
4 Treffer, waehrend node --check NICHTS meldet - der blinde Fleck ist damit zu.
Kein npm, kein jsdom: das DOM ist eine Attrappe von 20 Zeilen, Pruef- und
Laufumgebung bleiben derselbe Parser.
ZWEI NEUE STUFEN, beide mutationsgeprueft:
F) ELEMENT-IDs - JS gegen HTML. Stand: 133 IDs, keine verwaist, keine doppelt.
Kommentare werden vorher entfernt, sonst waeren die Beispiele im
Kopfkommentar zwei Dauer-Fehlalarme (die Lehre vom Linter).
G) ABHAENGIGKEITEN - jeder Import aus server.py/core/ gegen requirements.txt.
Stand: 39 Dateien, alle 9 externen Importe aufgefuehrt, keine Versionsdrift.
UND DIE PIPELINE HAT SICH SELBST ERWISCHT: mein erster Entwurf von Stufe G
importierte `ast` nicht. Der stille except-continue liess JEDE Datei
durchfallen, und die Stufe meldete "alle 0 externen Laufzeit-Importe sind
aufgefuehrt" - ein gruener Haken, hinter dem nichts geprueft wurde. Fuenfte
Wiederholung dieser Fehlerklasse. Gefangen hat es ruff F821 in derselben
Pipeline. Behoben doppelt: Import ergaenzt UND Plausibilitaetspruefung (weniger
Dateien gelesen als vorhanden oder 0 Importe -> Befund).
SLOTS - keine neuen Defekte, drei Punkte praezisiert:
· Kein geteilter Modul-Zustand. Die modulweiten Container in trailing.py und
trader.py sind reine Nachschlagetabellen, kein global-Statement. Die beiden
Instanzen sind tatsaechlich unabhaengig - Voraussetzung des ganzen Umbaus.
· set_sltp bleibt Slot-1-only, verhaelt sich aber SICHER: liegt nur eine
BRK-Position, gibt modify_sltp einen Fehlertext zurueck. Es fasst NICHT die
falsche Position an. Bekannte Grenze, kein Fehler.
· trail_brk.enabled wird nicht persistiert; _rebind_brk schaltet es nach einem
Neustart bedingungslos ein. Sichere Richtung, bewusst so gelassen.
BIBLIOTHEKEN: nichts fehlt, nichts driftet. pandas/scikit-learn stehen in
requirements-dev und werden in 0 Dateien importiert (so dokumentiert); numba,
joblib, tqdm, pandas_ta, rich, httpx sind Beifang und ungenutzt - kein
Handlungsbedarf, sie stehen nicht im Laufzeit-Pfad.
Struktureller Rest benannt: engine.py importiert weekly_review und
measurement_reminder, zwei Skripte der obersten Ebene - dieselbe Klasse wie der
frueher direkte backtest-Import. Hier entschaerft, weil lazy und in try, mit
sichtbarer Fehlermeldung. In Stufe G als projekteigen ausgenommen, mit
Begruendung im Code.
Pipeline jetzt A A2 A3 B B2 C C2 D E F G - alle gruen, 97 Tests, deployt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3391e04f32
commit
3fb9c3fd2e
@@ -16,6 +16,7 @@ Geprueft wird:
|
||||
naechste besteht nur aus einem Quote — die Signatur der beiden heutigen
|
||||
Faelle.
|
||||
"""
|
||||
import ast
|
||||
import pathlib
|
||||
import py_compile
|
||||
import re
|
||||
@@ -448,9 +449,120 @@ def _stufe_slots():
|
||||
befunde.append("SLOT Werkzeugfehler")
|
||||
|
||||
|
||||
# ⚠⚠ Zwei Pruefungen, die die Gesamtdurchsicht vom 2026-08-20 als Luecke
|
||||
# gezeigt hat — beide waren bis dahin HANDARBEIT und liefen nur, wenn jemand
|
||||
# daran dachte.
|
||||
def _stufe_ids():
|
||||
"""F) Greift die JS auf Element-IDs zu, die es in der HTML NICHT gibt?
|
||||
|
||||
⚠ Ein fehlendes Element wird seit v=150 vom Auffang-`$` abgefangen (die
|
||||
Regel war bei 0 von 95 Zugriffen befolgt) — aber `$streng` gibt weiter
|
||||
`None`, und genau dort haengt der ORDER-Pfad. Ausserdem ist eine verwaiste
|
||||
ID fast immer der Rest eines halb entfernten Features.
|
||||
⚠ Kommentare werden ENTFERNT, bevor gesucht wird: `$("neu")` und `$("x")`
|
||||
stehen als BEISPIELE im Kopfkommentar von `app.js` und waeren sonst zwei
|
||||
Dauer-Fehlalarme — und eine Pruefung mit Dauer-Treffern wird ignoriert.
|
||||
"""
|
||||
print("")
|
||||
print("=" * 88)
|
||||
print(" F) ELEMENT-IDs — JS gegen HTML")
|
||||
print("=" * 88)
|
||||
h = WURZEL / "web" / "index.html"
|
||||
j = WURZEL / "web" / "app.js"
|
||||
if not (h.exists() and j.exists()):
|
||||
print(" web/ fehlt — Stufe uebersprungen.")
|
||||
return
|
||||
html = h.read_text(encoding="utf-8")
|
||||
js = j.read_text(encoding="utf-8")
|
||||
js = re.sub(r"/\*.*?\*/", "", js, flags=re.S)
|
||||
js = re.sub(r"(?m)^\s*//.*$", "", js)
|
||||
html_ids = re.findall(r'id="([^"]+)"', html)
|
||||
doppelt = sorted({i for i in html_ids if html_ids.count(i) > 1})
|
||||
fehlt = sorted(set(re.findall(r'\$(?:streng)?\("([^"]+)"\)', js)) - set(html_ids))
|
||||
for i in fehlt:
|
||||
befunde.append(f"ID verwaist: $(\"{i}\") ohne Element in index.html")
|
||||
print(f" FEHLER verwaiste ID: {i}")
|
||||
for i in doppelt:
|
||||
befunde.append(f"ID doppelt in index.html: {i}")
|
||||
print(f" FEHLER doppelte ID: {i}")
|
||||
if not fehlt and not doppelt:
|
||||
print(f" {len(set(html_ids))} IDs, keine verwaist, keine doppelt.")
|
||||
|
||||
|
||||
def _stufe_requirements():
|
||||
"""G) Ist jeder LAUFZEIT-Import in `requirements.txt` aufgefuehrt?
|
||||
|
||||
⚠ Bis 2026-08-07 gab es gar keine Liste; nach einem Maschinenausfall waere
|
||||
die Rekonstruktion Raten gewesen. Die Liste zu HABEN reicht aber nicht — sie
|
||||
veraltet beim ersten neuen Import still. Geprueft wird nur `server.py` +
|
||||
`core/` (der Live-Pfad); Backtests duerfen dev-Pakete nutzen.
|
||||
"""
|
||||
print("")
|
||||
print("=" * 88)
|
||||
print(" G) ABHAENGIGKEITEN — Laufzeit-Importe gegen requirements.txt")
|
||||
print("=" * 88)
|
||||
req_p = WURZEL / "requirements.txt"
|
||||
if not req_p.exists():
|
||||
print(" requirements.txt fehlt — Stufe uebersprungen.")
|
||||
return
|
||||
req = req_p.read_text(encoding="utf-8").lower()
|
||||
alias = {"bs4": "beautifulsoup4", "deep_translator": "deep-translator",
|
||||
"yaml": "pyyaml", "dotenv": "python-dotenv"}
|
||||
stdlib = set(sys.stdlib_module_names)
|
||||
# ⚠ Projekt-EIGENE Module, keine pip-Pakete. `weekly_review` und
|
||||
# `measurement_reminder` sind Skripte auf oberster Ebene — `engine.py`
|
||||
# importiert sie beide LAZY (im Funktionskoerper, in `try`), also nur
|
||||
# 1x/Tag bzw. 1x/Woche. Das ist dieselbe Klasse wie der frueher direkte
|
||||
# `backtest_breakout_squeeze`-Import, der am 07.08. nach
|
||||
# `core/squeeze_scan.py` gezogen wurde — hier aber entschaerft, weil der
|
||||
# Live-Pfad sie nicht beim Start braucht und ein Fehlschlag gemeldet wird.
|
||||
eigen = {"core", "tools", "server", "weekly_review", "measurement_reminder"}
|
||||
dateien_ = [WURZEL / "server.py"] + sorted((WURZEL / "core").rglob("*.py"))
|
||||
mods = set()
|
||||
gelesen = 0
|
||||
for p_ in dateien_:
|
||||
try:
|
||||
b = ast.parse(p_.read_text(encoding="utf-8"))
|
||||
gelesen += 1
|
||||
except Exception as e:
|
||||
# ⚠⚠ NICHT still ueberspringen. Der erste Entwurf tat genau das —
|
||||
# `ast` war nicht importiert, JEDE Datei fiel in diesen Zweig, und
|
||||
# die Stufe meldete "alle 0 externen Laufzeit-Importe sind
|
||||
# aufgefuehrt". Ein gruener Haken, hinter dem NICHTS geprueft
|
||||
# wurde: die vierte Wiederholung dieser Fehlerklasse im Projekt.
|
||||
# Gefangen hat es `ruff F821` in derselben Pipeline.
|
||||
befunde.append(f"REQ {p_.name} nicht lesbar: {e}")
|
||||
print(f" FEHLER {p_.name} nicht analysierbar: {e}")
|
||||
continue
|
||||
for n in ast.walk(b):
|
||||
if isinstance(n, ast.Import):
|
||||
mods |= {a.name.split(".")[0] for a in n.names}
|
||||
elif isinstance(n, ast.ImportFrom) and n.level == 0 and n.module:
|
||||
mods.add(n.module.split(".")[0])
|
||||
fehlend = [m for m in sorted(mods)
|
||||
if m and m not in stdlib and m not in eigen
|
||||
and alias.get(m, m).lower() not in req]
|
||||
for m in fehlend:
|
||||
befunde.append(f"REQ Laufzeit-Import `{m}` fehlt in requirements.txt")
|
||||
print(f" FEHLER `{m}` wird im Live-Pfad importiert, steht aber nicht in "
|
||||
f"requirements.txt")
|
||||
extern = [m for m in mods if m and m not in stdlib and m not in eigen]
|
||||
if gelesen < len(dateien_) or not extern:
|
||||
# Eine Stufe, die nichts gelesen hat, darf nicht "sauber" melden.
|
||||
befunde.append(f"REQ nur {gelesen}/{len(dateien_)} Dateien gelesen, "
|
||||
f"{len(extern)} externe Importe gefunden — unplausibel")
|
||||
print(f" FEHLER nur {gelesen}/{len(dateien_)} Dateien gelesen, "
|
||||
f"{len(extern)} externe Importe — die Stufe hat nichts geprueft")
|
||||
elif not fehlend:
|
||||
print(f" {gelesen} Dateien gelesen, alle {len(extern)} externen "
|
||||
f"Laufzeit-Importe sind aufgefuehrt.")
|
||||
|
||||
|
||||
_stufe_typen()
|
||||
_stufe_render()
|
||||
_stufe_slots()
|
||||
_stufe_ids()
|
||||
_stufe_requirements()
|
||||
|
||||
print("")
|
||||
print("=" * 88)
|
||||
|
||||
Reference in New Issue
Block a user