Regelwerk, Agenten, Skills und Werkzeuge veröffentlichen
Erster Stand des öffentlichen Ausschnitts aus dem Vault. Die .gitignore arbeitet als Positivliste: ausgeschlossen ist alles, eingeschlossen nur, was ausdrücklich wieder aufgenommen wird. Notizen, Projekte, Finanzen, das Sitzungsgedächtnis und settings.local.json bleiben damit außen vor. Der Kundenname in AI/Regelwerk/seo.md ist durch eine neutrale Bezeichnung ersetzt; die Regeln selbst sind unverändert. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
commit
2c9a4475fc
97 files changed
+14627
No files matched your search
@@ -0,0 +1,116 @@
|
||||
"""Mutantenlauf Frontend auf der materialisierten Kopie (Windows-Python, vitest je Datei).
|
||||
|
||||
Je Mutant: Datei als Bytes sichern, genau eine Stelle ersetzen, die Testdatei fahren, zurueckspielen.
|
||||
Erwartet ist ROT; ein gruener Mutant ist ein Befund. Zuerst die Grundlinie.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
DASH = Path(sys.argv[1]) / "dashboard" # Windows-Pfad der Kopie mit dem angewendeten Plan
|
||||
|
||||
MUTANTEN = [
|
||||
(
|
||||
"stufe() gibt den rohen Index zurueck",
|
||||
"src/components/LaufKampagne.tsx",
|
||||
" const wert = aktion - (verteilung.length - 1) / 2;",
|
||||
" const wert = aktion;",
|
||||
"src/components/LaufKampagne.test.tsx",
|
||||
),
|
||||
(
|
||||
"stufe() ohne Pruefung der Verteilung",
|
||||
"src/components/LaufKampagne.tsx",
|
||||
" if (!Array.isArray(verteilung) || verteilung.length % 2 === 0) return STRICH;",
|
||||
" if (!Array.isArray(verteilung)) return STRICH;",
|
||||
"src/components/LaufKampagne.test.tsx",
|
||||
),
|
||||
(
|
||||
"stufe() ohne Pruefung des Bereichs",
|
||||
"src/components/LaufKampagne.tsx",
|
||||
" if (aktion < 0 || aktion >= verteilung.length) return STRICH;\n",
|
||||
"",
|
||||
"src/components/LaufKampagne.test.tsx",
|
||||
),
|
||||
(
|
||||
"Stille Fenster als Ertrag formatiert",
|
||||
"src/components/LaufKampagne.tsx",
|
||||
" wert={anteil(abschluss.anteil_fenster_ohne_trade)}",
|
||||
" wert={prozent(abschluss.anteil_fenster_ohne_trade)}",
|
||||
"src/components/LaufKampagne.test.tsx",
|
||||
),
|
||||
(
|
||||
"close() merkt sich das Ende nicht",
|
||||
"src/lib/api.ts",
|
||||
" beendet = true;\n",
|
||||
"",
|
||||
"src/lib/api.test.ts",
|
||||
),
|
||||
(
|
||||
"close() raeumt den Zeitgeber nicht",
|
||||
"src/lib/api.ts",
|
||||
" if (zeitgeber !== null) clearTimeout(zeitgeber);\n",
|
||||
"",
|
||||
"src/lib/api.test.ts",
|
||||
),
|
||||
(
|
||||
# Der Backslash kommt aus chr(92): Eine Escape-Folge im eigenen Quelltext wertet sonst
|
||||
# irgendeine Schicht aus -- genau das ist bei der Umsetzung passiert.
|
||||
"Lizenztext mit doppeltem Backslash (Escape-Folge als Klartext auf der Seite)",
|
||||
"src/components/Markt.tsx",
|
||||
"Charts" + chr(92) + "u2122 Copyright (" + chr(92) + "u0441) 2025",
|
||||
"Charts" + chr(92) * 2 + "u2122 Copyright (" + chr(92) * 2 + "u0441) 2025",
|
||||
"src/components/Markt.test.tsx",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def fahre(testdatei: str) -> tuple[bool, str]:
|
||||
ergebnis = subprocess.run(
|
||||
f"npx vitest run {testdatei}",
|
||||
cwd=DASH,
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
stdin=subprocess.DEVNULL,
|
||||
)
|
||||
ausgabe = ergebnis.stdout + ergebnis.stderr
|
||||
rote = [z.strip() for z in ausgabe.splitlines() if z.strip().startswith(("×", "FAIL", "✗")) or " > " in z and "FAIL" in z]
|
||||
return ergebnis.returncode == 0, "; ".join(rote[:4])
|
||||
|
||||
|
||||
def main() -> int:
|
||||
befunde = 0
|
||||
for testdatei in sorted({m[4] for m in MUTANTEN}):
|
||||
gruen, _ = fahre(testdatei)
|
||||
if not gruen:
|
||||
print(f"BEFUND Grundlinie: {testdatei} ist ohne Mutant nicht gruen")
|
||||
return 2
|
||||
print("Grundlinie gruen.")
|
||||
for name, datei, alt, neu, testdatei in MUTANTEN:
|
||||
pfad = DASH / datei
|
||||
sicherung = pfad.read_bytes()
|
||||
text = sicherung.decode("utf-8")
|
||||
anzahl = text.count(alt)
|
||||
if anzahl != 1:
|
||||
print(f"BEFUND Mutant '{name}': Stelle steht {anzahl}-mal in {datei}")
|
||||
befunde += 1
|
||||
continue
|
||||
try:
|
||||
pfad.write_bytes(text.replace(alt, neu).encode("utf-8"))
|
||||
gruen, rote = fahre(testdatei)
|
||||
finally:
|
||||
pfad.write_bytes(sicherung)
|
||||
if gruen:
|
||||
print(f"BEFUND Mutant '{name}' bleibt GRUEN ({testdatei})")
|
||||
befunde += 1
|
||||
else:
|
||||
print(f"rot {name} [{rote}]")
|
||||
print(f"{befunde} Befund(e).")
|
||||
return 2 if befunde else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user