- .claude/agents/planer.md - .claude/skills/plan-executer-pruefung/SKILL.md - .claude/workflows/plankritik.js - .claude/workflows/planung.js - .claude/workflows/pruefung.js - .claude/workflows/verbrauch.js - .claude/workflows/welle-mit-pruefung.js - .vault-tools/plan-kopie/LIESMICH.md - .vault-tools/plan-kopie/plan_zeichen.py - .vault-tools/plan-kopie/rot_nachweis.py - .vault-tools/trading-plattform-pruefung/LIESMICH.md - .vault-tools/trading-plattform-pruefung/abendkontrolle.py - … und 34 weitere Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py. Co-Authored-By: Claude Opus 5 <[email protected]>
87 lines
3.4 KiB
Python
87 lines
3.4 KiB
Python
"""Vor dem Push: kommt ein Wert aus der Geheimnis- oder Zugangsdatei in den neuen Commits vor?
|
|
|
|
Koordinator-Werkzeug, nicht fuers Repo (Pascal 2026-09-24: Push jederzeit, vorher dieser Scan).
|
|
Regressionsnachweis vor jedem Scan: SCAN_PROBE=<bekannter Text aus dem Verlauf> muss einen Treffer melden.
|
|
|
|
Liest die Werte, gibt sie nie aus, nur Schluesselname und Trefferzahl. Laeuft in WSL als claude.
|
|
Aufruf: python geheimnis_scan.py <repo> <von> <bis> [<bis> ...]
|
|
"""
|
|
import subprocess
|
|
import sys
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
GEHEIM = Path("/home/claude/.config/trading-plattform/secrets.toml")
|
|
repo = Path(sys.argv[1])
|
|
von = sys.argv[2]
|
|
ziele = sys.argv[3:]
|
|
|
|
|
|
def blaetter(tabelle, pfad=""):
|
|
for schluessel, wert in tabelle.items():
|
|
name = f"{pfad}.{schluessel}" if pfad else schluessel
|
|
if isinstance(wert, dict):
|
|
yield from blaetter(wert, name)
|
|
elif isinstance(wert, str):
|
|
yield name, wert
|
|
|
|
|
|
werte = []
|
|
for datei in (GEHEIM, repo / "config" / "zugang.toml"):
|
|
if not datei.exists():
|
|
print(f"BEFUND: {datei.name} fehlt, Scan ohne diese Werte")
|
|
continue
|
|
with datei.open("rb") as f:
|
|
daten = tomllib.load(f)
|
|
for name, wert in blaetter(daten):
|
|
# Kurze Werte (true/false, Hostnamen wie localhost, Modellnamen) treffen Prosa.
|
|
if len(wert) >= 12:
|
|
werte.append((f"{datei.name}:{name}", wert))
|
|
schluessel_json = repo / "config" / "zugang-schluessel.json"
|
|
if schluessel_json.exists():
|
|
import json
|
|
for i, eintrag in enumerate(json.loads(schluessel_json.read_text(encoding="utf-8")) or []):
|
|
if isinstance(eintrag, dict):
|
|
for k, v in eintrag.items():
|
|
if isinstance(v, str) and len(v) >= 12:
|
|
werte.append((f"zugang-schluessel.json:{i}.{k}", v))
|
|
# Seit 2026-09-24 (Paket IB): die IBKR-Zugangsdateien. Die Kontonummer hat 9 Zeichen, deshalb
|
|
# hier ab 6 statt ab 12; diese drei Werte stehen in keiner Prosa.
|
|
IBKR = Path("/home/claude/.config/trading-plattform/ibkr")
|
|
for name in ("paper_benutzer", "paper_passwort", "paper_konto"):
|
|
datei = IBKR / name
|
|
if datei.exists():
|
|
wert = datei.read_text(encoding="utf-8").strip()
|
|
if len(wert) >= 6:
|
|
werte.append((f"ibkr:{name}", wert))
|
|
else:
|
|
print(f"BEFUND: ibkr/{name} fehlt, Scan ohne diesen Wert")
|
|
import os
|
|
if os.environ.get("SCAN_PROBE"):
|
|
# Regressionsnachweis: ein bekannter Text aus dem Verlauf muss als Treffer erscheinen.
|
|
werte.append(("probe", os.environ["SCAN_PROBE"]))
|
|
print(f"geprueft: {len(werte)} Werte ab 12 Zeichen")
|
|
|
|
befunde = 0
|
|
for ziel in ziele:
|
|
text = subprocess.run(
|
|
["git", "-c", "safe.directory=*", "-C", str(repo), "log", "-p", "--all-match", f"{von}..{ziel}"],
|
|
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
).stdout
|
|
print(f"{von}..{ziel}: {len(text)} Zeichen Verlauf")
|
|
for name, wert in werte:
|
|
n = text.count(wert)
|
|
if n:
|
|
befunde += 1
|
|
print(f" TREFFER {name}: {n}")
|
|
verfolgt = subprocess.run(
|
|
["git", "-c", "safe.directory=*", "-C", str(repo), "ls-tree", "-r", "--name-only", ziel],
|
|
capture_output=True, text=True,
|
|
).stdout.splitlines()
|
|
for gesperrt in ("config/secrets.toml", "config/zugang.toml", "config/zugang-schluessel.json"):
|
|
if gesperrt in verfolgt:
|
|
befunde += 1
|
|
print(f" TREFFER verfolgt: {gesperrt}")
|
|
print(f"ERGEBNIS: {befunde} Treffer")
|
|
sys.exit(1 if befunde else 0)
|