Files
claude-regelwerk/.vault-tools/trading-plattform-pruefung/geheimnis_scan.py
T
Pascal MichelandClaude Opus 5 ea278dc24f Automatischer Push: 46 Datei(en) geändert
- .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]>
2026-09-25 04:00:02 +02:00

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)