.vault-tools (ohne trading-plattform-pruefung und watermarks-remover), .claude/agents, .claude/skills, .claude/workflows, .claude/settings.json. Co-Authored-By: Claude Opus 5.5 <[email protected]>
493 lines
18 KiB
Markdown
493 lines
18 KiB
Markdown
---
|
|
type: plan-task
|
|
title: "Task 02 — Zeile „Waisen außerhalb der Ausnahmen“ im SessionStart-Hook"
|
|
status: draft
|
|
summary: "sitzungsstart.py ruft waisen.py --zahl als eigenen Prozess mit 15 s Grenze und meldet die Zahl als Zeile; der Treiber bekommt eine Grundlinie mit .obsidian/app.json, neue Fälle und angepasste Erwartungen; ENTWURF.md bekommt einen Nachtrag."
|
|
tags: [plan-task, vault-tools]
|
|
created: 2026-09-29
|
|
updated: 2026-09-30
|
|
modell: haiku
|
|
modell_begruendung: "Fünfzehn Aus-wird-Blöcke und ein angehängter Abschnitt stehen wörtlich im Plan und werden per Skript angewendet; keine typografischen Zeichen in den Codeblöcken."
|
|
---
|
|
Übersicht: [00-uebersicht.md](00-uebersicht.md)
|
|
|
|
# Task 02 — Zeile im SessionStart-Hook
|
|
|
|
Globale Vorgaben: `00-uebersicht.md` im selben Ordner, Abschnitt „Globale Vorgaben“.
|
|
|
|
Voraussetzung: Task 01 ist umgesetzt, `waisen.py` und `waisen-ausnahmen.txt` liegen unter `.vault-tools/linkcheck/`.
|
|
|
|
## Zieldateien
|
|
|
|
- `D:\Claude\.vault-tools\session-hooks\sitzungsstart.py` (geändert)
|
|
- `D:\Claude\.vault-tools\session-hooks\faelle_sitzungsstart.py` (geändert)
|
|
- `D:\Claude\.vault-tools\session-hooks\ENTWURF.md` (geändert)
|
|
|
|
## Verbote
|
|
|
|
- `.claude/settings.json` bleibt, wie es ist. Der Timeout von 30 s wird nicht geändert.
|
|
- `regelwerk_nach_edit.py` und `faelle_nach_edit.py` bleiben unverändert.
|
|
- `ZIEL_LAUFZEIT_S` in `faelle_sitzungsstart.py` bleibt bei 5.0, auch wenn die Messung darüber liegt.
|
|
- Nichts unter `.vault-tools/linkcheck/` ändern.
|
|
|
|
## Schritt 1 — Blöcke anwenden
|
|
|
|
```
|
|
python D:/Claude/.vault-tools/plan-kopie/plan_materialisiere.py D:/Claude/.vault-tools/linkcheck/docs/plans/2026-09-29-waisen D:/Claude task-02-sitzungsstart.md
|
|
```
|
|
|
|
Erwartet: eine Zeile mit `'ersetzt': 15` und `'angehaengt': 1` und die Schlusszeile `0 Befund(e).`
|
|
|
|
### Geltungsbereich im Kopf von `.vault-tools/session-hooks/sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
Die Punkte aus dem Abschnitt Sitzungsprotokoll in CLAUDE.md, gezählt und
|
|
nicht bewertet: Datum laut Maschinenuhr, Tagesnotiz, Inbox-Notizen ohne
|
|
type: daily, Notizen mit Tag needs-review, Notizen mit Tag review ohne
|
|
review-done, Regelwerk-Dateien mit status: pending-review, heutige
|
|
Sitzungsdateien. Die Vault-Wurzel ist ausschließlich der Ordner zwei Ebenen
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
Die Punkte aus dem Abschnitt Sitzungsprotokoll in CLAUDE.md, gezählt und
|
|
nicht bewertet: Datum laut Maschinenuhr, Tagesnotiz, Inbox-Notizen ohne
|
|
type: daily, Notizen mit Tag needs-review, Notizen mit Tag review ohne
|
|
review-done, Regelwerk-Dateien mit status: pending-review, heutige
|
|
Sitzungsdateien, dazu die Zahl der Waisen außerhalb der Ausnahmen aus
|
|
.vault-tools/linkcheck/waisen.py (eigener Prozess, nach 15 s abgebrochen;
|
|
Regeln und Lücken stehen im Kopf von waisen.py). Die Vault-Wurzel ist
|
|
ausschließlich der Ordner zwei Ebenen
|
|
```
|
|
|
|
### Importe in `.vault-tools/session-hooks/sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
import re
|
|
import sys
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
```
|
|
|
|
### Konstanten in `.vault-tools/session-hooks/sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
SKRIPT = Path(__file__).resolve()
|
|
LINKCHECK = SKRIPT.parent.parent / "linkcheck"
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
SKRIPT = Path(__file__).resolve()
|
|
LINKCHECK = SKRIPT.parent.parent / "linkcheck"
|
|
WAISEN = LINKCHECK / "waisen.py"
|
|
# Das Budget des Hooks in .claude/settings.json sind 30 s für alles.
|
|
ZEITGRENZE_WAISEN_S = 15.0
|
|
```
|
|
|
|
### Neuer Punkt in `.vault-tools/session-hooks/sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
PUNKTE = [
|
|
("Datum", punkt_datum),
|
|
("Tagesnotiz", punkt_tagesnotiz),
|
|
("Inbox", punkt_inbox),
|
|
("needs-review/review", punkt_tags),
|
|
("Regelwerk", punkt_regelwerk),
|
|
("Sitzungen", punkt_sitzungen),
|
|
]
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
def punkt_waisen(wurzel: Path, heute: str) -> list[str]:
|
|
if not WAISEN.is_file():
|
|
raise RuntimeError(f"waisen.py fehlt unter {WAISEN}")
|
|
umgebung = dict(os.environ)
|
|
umgebung["PYTHONIOENCODING"] = "utf-8"
|
|
try:
|
|
lauf = subprocess.run(
|
|
[sys.executable, str(WAISEN), "--vault", str(wurzel), "--zahl"],
|
|
capture_output=True,
|
|
stdin=subprocess.DEVNULL,
|
|
timeout=ZEITGRENZE_WAISEN_S,
|
|
env=umgebung,
|
|
)
|
|
except subprocess.TimeoutExpired:
|
|
raise RuntimeError(
|
|
f"waisen.py nach {ZEITGRENZE_WAISEN_S:g} s abgebrochen, nicht gezählt"
|
|
) from None
|
|
ausgabe = lauf.stdout.decode("utf-8", errors="replace").strip()
|
|
if lauf.returncode in (0, 1) and ausgabe.isdigit():
|
|
return [f"- Waisen außerhalb der Ausnahmen: {ausgabe}"]
|
|
erste = ausgabe or lauf.stderr.decode("utf-8", errors="replace").strip()
|
|
raise RuntimeError(f"waisen.py Exit {lauf.returncode}: {erste.split(chr(10))[0].strip()}")
|
|
|
|
|
|
PUNKTE = [
|
|
("Datum", punkt_datum),
|
|
("Tagesnotiz", punkt_tagesnotiz),
|
|
("Inbox", punkt_inbox),
|
|
("needs-review/review", punkt_tags),
|
|
("Regelwerk", punkt_regelwerk),
|
|
("Sitzungen", punkt_sitzungen),
|
|
("Waisen", punkt_waisen),
|
|
]
|
|
```
|
|
|
|
### Konstanten in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
SI = f"- Sitzungsdateien AI/sessions/{HEUTE}-*.md: "
|
|
FEHLERZEILE = "Sitzungsstart-Hook:"
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
SI = f"- Sitzungsdateien AI/sessions/{HEUTE}-*.md: "
|
|
WA = "- Waisen außerhalb der Ausnahmen: "
|
|
FEHLERZEILE = "Sitzungsstart-Hook:"
|
|
WAISEN = HIER.parent / "linkcheck" / "waisen.py"
|
|
AUSNAHMEN = HIER.parent / "linkcheck" / "waisen-ausnahmen.txt"
|
|
```
|
|
|
|
### Grundlinie in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
schreibe(v, "Notizen/sauber.md",
|
|
"---\ntype: note\ntags: [thema]\n---\n\nKein Tag hier, nur das Wort review ohne Raute.\n")
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
schreibe(v, "Notizen/sauber.md",
|
|
"---\ntype: note\ntags: [thema]\n---\n\nKein Tag hier, nur das Wort review ohne Raute.\n")
|
|
# waisen.py braucht einen Obsidian-Vault; ohne Filter hat die Grundlinie sechs Waisen.
|
|
schreibe(v, ".obsidian/app.json", '{"userIgnoreFilters": []}')
|
|
```
|
|
|
|
### Erwartete Zeilen der Grundlinie in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
SI + f"1 ({HEUTE}-10.md)",
|
|
]
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
SI + f"1 ({HEUTE}-10.md)",
|
|
WA + "6",
|
|
]
|
|
```
|
|
|
|
### Kopf von kopiere_hook in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
def kopiere_hook(v: Path, linkcheck_kopieren: bool = True) -> Path:
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
def kopiere_hook(v: Path, linkcheck_kopieren: bool = True, waisen_kopieren: bool = True) -> Path:
|
|
```
|
|
|
|
### Rumpf von kopiere_hook in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
if linkcheck_kopieren:
|
|
lc_ziel = v / ".vault-tools" / "linkcheck"
|
|
lc_ziel.mkdir(parents=True, exist_ok=True)
|
|
shutil.copy2(LINKCHECK, lc_ziel / "linkcheck.py")
|
|
return skript
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
lc_ziel = v / ".vault-tools" / "linkcheck"
|
|
lc_ziel.mkdir(parents=True, exist_ok=True)
|
|
if linkcheck_kopieren:
|
|
shutil.copy2(LINKCHECK, lc_ziel / "linkcheck.py")
|
|
if waisen_kopieren:
|
|
shutil.copy2(WAISEN, lc_ziel / "waisen.py")
|
|
shutil.copy2(AUSNAHMEN, lc_ziel / "waisen-ausnahmen.txt")
|
|
return skript
|
|
```
|
|
|
|
### Feld im Fall in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
stdin: Callable[[Path], bytes] | None = None
|
|
linkcheck_kopieren: bool = True
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
stdin: Callable[[Path], bytes] | None = None
|
|
linkcheck_kopieren: bool = True
|
|
waisen_kopieren: bool = True
|
|
```
|
|
|
|
### Fall ohne jeden Ordner in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
Fall("leer | Vault ohne jeden Ordner",
|
|
lambda v: [shutil.rmtree(p) for p in list(v.iterdir())],
|
|
[TN + "fehlt", IN + "Ordner Inbox/ fehlt", NR + "0", RV + "0",
|
|
PR + "Ordner AI/Regelwerk/ fehlt", SI + "Ordner AI/sessions/ fehlt"]),
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
Fall("leer | Vault ohne jeden Ordner",
|
|
lambda v: [shutil.rmtree(p) for p in list(v.iterdir())],
|
|
[TN + "fehlt", IN + "Ordner Inbox/ fehlt", NR + "0", RV + "0",
|
|
PR + "Ordner AI/Regelwerk/ fehlt", SI + "Ordner AI/sessions/ fehlt"],
|
|
verboten=[WA],
|
|
praefixe=["Sitzungsstart-Hook: Waisen: RuntimeError: waisen.py Exit 2: Waisen - ABGEBROCHEN: kein Obsidian-Vault"]),
|
|
```
|
|
|
|
### Fall ohne linkcheck.py und neue Fälle in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
verboten=[NR, RV],
|
|
praefixe=["Sitzungsstart-Hook: needs-review/review: RuntimeError: linkcheck.py nicht importierbar"],
|
|
stdin=lambda v: b"{}",
|
|
linkcheck_kopieren=False),
|
|
]
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
verboten=[NR, RV, WA],
|
|
praefixe=["Sitzungsstart-Hook: needs-review/review: RuntimeError: linkcheck.py nicht importierbar",
|
|
"Sitzungsstart-Hook: Waisen: RuntimeError: waisen.py Exit 2: Waisen - ABGEBROCHEN: linkcheck.py nicht importierbar"],
|
|
stdin=lambda v: b"{}",
|
|
linkcheck_kopieren=False),
|
|
Fall("waisen | verlinkte Notiz senkt die Zahl",
|
|
lambda v: schreibe(v, "Notizen/verweis.md", "[[Notizen/sauber]]\n"),
|
|
[WA + "5"]),
|
|
Fall("waisen | Waise an erster und an letzter Stelle",
|
|
lambda v: (schreibe(v, "0-erste/a.md", "x\n"), schreibe(v, "zz-letzte/z.md", "x\n")),
|
|
[WA + "8"]),
|
|
Fall("waisen | Muster aus der Ausnahmedatei greift",
|
|
lambda v: schreibe(v, "Bookstack/archiv/seite.md", "x\n"),
|
|
[WA + "6"]),
|
|
Fall("waisen | waisen.py fehlt", nichts,
|
|
[DA, TN + "vorhanden", IN + "1 (offen.md)", NR + "0", RV + "0", PR + "0", SI + f"1 ({HEUTE}-10.md)"],
|
|
verboten=[WA],
|
|
praefixe=["Sitzungsstart-Hook: Waisen: RuntimeError: waisen.py fehlt"],
|
|
waisen_kopieren=False),
|
|
Fall("waisen | kaputte app.json meldet Fehler statt Zahl",
|
|
lambda v: schreibe(v, ".obsidian/app.json", "{kaputt"),
|
|
[DA, TN + "vorhanden", NR + "0", SI + f"1 ({HEUTE}-10.md)"],
|
|
verboten=[WA],
|
|
praefixe=["Sitzungsstart-Hook: Waisen: RuntimeError: waisen.py Exit 2: Waisen - ABGEBROCHEN: .obsidian/app.json nicht lesbar"]),
|
|
Fall("umgebung | ohne PYTHONIOENCODING zaehlt Waisen mit Umlaut im Namen",
|
|
lambda v: schreibe(v, "Notizen/Übersicht 🚀.md", "x\n"),
|
|
[WA + "7"],
|
|
umgebung=ohne_pythonioencoding),
|
|
]
|
|
```
|
|
|
|
### Aufruf von kopiere_hook in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
skript = kopiere_hook(v, fall.linkcheck_kopieren)
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
skript = kopiere_hook(v, fall.linkcheck_kopieren, fall.waisen_kopieren)
|
|
```
|
|
|
|
### Gesperrte Datei in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
erwartet = grundzeilen(v) + ["Sitzungsstart-Hook: 1 Datei(en) nicht lesbar (erste: Notizen/gesperrt.md)"]
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
# gesperrt.md ist für waisen.py lesbar und die siebte Waise.
|
|
erwartet = [z for z in grundzeilen(v) if not z.startswith(WA)] + [WA + "7"]
|
|
erwartet.append("Sitzungsstart-Hook: 1 Datei(en) nicht lesbar (erste: Notizen/gesperrt.md)")
|
|
```
|
|
|
|
### Zeitgrenze im Prozess in `.vault-tools/session-hooks/faelle_sitzungsstart.py`
|
|
|
|
Aus:
|
|
|
|
```
|
|
IM_PROZESS = [
|
|
("absturz | ein Punkt wirft", ip_punkt_wirft),
|
|
("absturz | Hauptablauf wirft", ip_hauptablauf_wirft),
|
|
("lesen | Datei nicht lesbar", ip_datei_gesperrt),
|
|
("lesen | Ordner nicht lesbar", ip_ordner_gesperrt),
|
|
]
|
|
```
|
|
|
|
wird:
|
|
|
|
```
|
|
def ip_waisen_zeitgrenze(v: Path) -> tuple[bool, str]:
|
|
"""Die Zeitgrenze lässt sich von außen nicht billig überschreiten:
|
|
im Prozess auf eine Millisekunde gesetzt, startet waisen.py nicht rechtzeitig."""
|
|
skript = kopiere_hook(v)
|
|
modul = lade_hook("hook_waisen_zeitgrenze", skript)
|
|
modul.ZEITGRENZE_WAISEN_S = 0.001
|
|
zeilen = im_prozess(modul, v)
|
|
if zeilen is None:
|
|
return False, " keine gueltige Ausgabe"
|
|
erwartet = [z for z in grundzeilen(v) if not z.startswith(WA)]
|
|
erwartet.append("Sitzungsstart-Hook: Waisen: RuntimeError: waisen.py nach 0.001 s abgebrochen, nicht gezählt")
|
|
probleme = bewerte(zeilen, erwartet, [WA], [])
|
|
return not probleme, "\n".join(" " + p for p in probleme)
|
|
|
|
|
|
IM_PROZESS = [
|
|
("absturz | ein Punkt wirft", ip_punkt_wirft),
|
|
("absturz | Hauptablauf wirft", ip_hauptablauf_wirft),
|
|
("lesen | Datei nicht lesbar", ip_datei_gesperrt),
|
|
("lesen | Ordner nicht lesbar", ip_ordner_gesperrt),
|
|
("waisen | Zeitgrenze ueberschritten", ip_waisen_zeitgrenze),
|
|
]
|
|
```
|
|
|
|
### Nachtrag am Ende von `.vault-tools/session-hooks/ENTWURF.md`
|
|
|
|
Häng diesen Block ans Ende:
|
|
|
|
````markdown
|
|
|
|
## Nachtrag 2026-09-29: Zahl der Waisen
|
|
|
|
**Anlass.** Die Spec Waisen im Graphen vom 2026-09-29 verlangt beim Sitzungsstart eine Zeile mit der Zahl der Waisen außerhalb der Ausnahmen, nur die Zahl, keine Liste. Plan: `.vault-tools/linkcheck/docs/plans/2026-09-29-waisen/`.
|
|
|
|
| # | Frage | Antwort | Herkunft |
|
|
|---|---|---|---|
|
|
| 16 | Woher kommt die Zahl? | `waisen.py --zahl` aus `.vault-tools/linkcheck/`, als eigener Prozess mit `sys.executable`, stdin geschlossen, `PYTHONIOENCODING=utf-8`. Die Regeln des Zählers stehen in `.vault-tools/linkcheck/ENTWURF-waisen.md`. | **Projektvorgabe**: Plan |
|
|
| 17 | Wie lange darf sie dauern? | 15 s, dann bricht der Hook den Zähler ab und meldet eine Fehlerzeile. Das Budget des Hooks in `.claude/settings.json` sind 30 s für alles. | **Projektvorgabe** |
|
|
| 18 | Was, wenn `waisen.py` fehlt, abbricht oder keine Zahl liefert? | Fehlerzeile `Sitzungsstart-Hook: Waisen:` mit der ersten Ausgabezeile des Zählers, keine Zahl. | **Projektvorgabe**: `pruefwerkzeuge.md` Abschnitt 6 |
|
|
|
|
**Treiber.** Die Grundlinie trägt jetzt `.obsidian/app.json` und hat sechs Waisen. `kopiere_hook()` kopiert `waisen.py` und `waisen-ausnahmen.txt` mit. Neue Fälle: ein Link senkt die Zahl, Waisen an erster und letzter Stelle, ein Muster aus der Ausnahmedatei greift, `waisen.py` fehlt, kaputte `app.json`, Umlaut und Emoji im Namen ohne `PYTHONIOENCODING`, und im Prozess die überschrittene Zeitgrenze. Zwei bestehende Fälle erwarten zusätzlich die Fehlerzeile des Zählers: Vault ohne jeden Ordner (dann fehlt `.obsidian`) und `linkcheck.py` fehlt. Dass der Hook die Zahl wirklich vom Zähler übernimmt, zeigen die verschiedenen erwarteten Zahlen 5, 6, 7 und 8 in den neuen Fällen.
|
|
|
|
**Laufzeit.** Frage 15 peilt unter 5 s an. Ob das mit dem Zähler hält, misst `faelle_sitzungsstart.py --echt`.
|
|
````
|
|
|
|
## Schritt 2 — Rot zuerst
|
|
|
|
Die neuen und geänderten Fälle müssen gegen den Hook ohne die Änderung aus Schritt 1 rot werden. Der Stand ohne Änderung ist `sitzungsstart.py` aus `HEAD` des Vault-Repos; dieser Task committet nicht. Alles in einem einzigen Bash-Aufruf, damit die neue Fassung sicher zurückkommt:
|
|
|
|
```
|
|
H=D:/Claude/.vault-tools/session-hooks
|
|
mv "$H/sitzungsstart.py" "$H/sitzungsstart.py.neu" && git -C D:/Claude show HEAD:.vault-tools/session-hooks/sitzungsstart.py > "$H/sitzungsstart.py"
|
|
grep -c punkt_waisen "$H/sitzungsstart.py"
|
|
PYTHONIOENCODING=utf-8 python -B "$H/faelle_sitzungsstart.py"; echo "exit=$?"
|
|
PYTHONIOENCODING=utf-8 python -B -c '
|
|
import shutil, sys, tempfile
|
|
from pathlib import Path
|
|
sys.path.insert(0, "D:/Claude/.vault-tools/session-hooks")
|
|
import faelle_sitzungsstart as f
|
|
arbeit = Path(tempfile.mkdtemp(prefix="sitzungsstart-rot-")).resolve()
|
|
basis = arbeit / "grundlinie"
|
|
f.baue_grundlinie(basis)
|
|
auswahl = [(x.name, lambda x=x: f.lauf_fall(x, basis, arbeit)) for x in f.FAELLE
|
|
if "aisen" in x.name or "ohne jeden Ordner" in x.name or "linkcheck.py fehlt" in x.name]
|
|
auswahl += [(n, lambda fn=fn: fn(f.frische_kopie(basis, arbeit))) for n, fn in f.IM_PROZESS
|
|
if "aisen" in n or "Datei nicht lesbar" in n]
|
|
for name, lauf in auswahl:
|
|
try:
|
|
ok, text = lauf()
|
|
except Exception as exc:
|
|
ok, text = None, "ABSTURZ " + type(exc).__name__ + ": " + str(exc)
|
|
print({True: "GRUEN", False: "ROT", None: "ABSTURZ"}[ok].ljust(8) + name + "\n" + text)
|
|
shutil.rmtree(arbeit, ignore_errors=True)
|
|
'; echo "exit=$?"
|
|
mv -f "$H/sitzungsstart.py.neu" "$H/sitzungsstart.py"
|
|
grep -c punkt_waisen "$H/sitzungsstart.py"
|
|
ls "$H"
|
|
```
|
|
|
|
Erwartet, in dieser Reihenfolge:
|
|
|
|
- Das erste `grep` gibt `0`. Steht dort eine andere Zahl, enthält `HEAD` schon die Änderung, und der Schritt misst nichts: melden.
|
|
- Der Treiber endet mit `ABBRUCH: Die Grundlinie ist nicht gruen. Der Rest misst nichts.` und `exit=2`. Unter `erwartet:` steht als letzte Zeile `- Waisen außerhalb der Ausnahmen: 6`, unter `bekommen (stdout):` fehlt sie.
|
|
- Die Einzelfälle: je Fall ein Block, der mit `ROT` beginnt, für genau diese Fälle: `leer | Vault ohne jeden Ordner`, `umgebung | linkcheck.py fehlt`, die fünf Fälle, die mit `waisen |` beginnen, `umgebung | ohne PYTHONIOENCODING zaehlt Waisen mit Umlaut im Namen`, `lesen | Datei nicht lesbar` und `waisen | Zeitgrenze ueberschritten`. Jeder Block nennt eine Zeile `fehlt:` mit der Waisenzeile oder eine Zeile `fehlt Zeile mit Anfang: Sitzungsstart-Hook: Waisen:`. Kein Block beginnt mit `GRUEN` oder `ABSTURZ`. Danach `exit=0`.
|
|
- Das zweite `grep` gibt `2`: `sitzungsstart.py` ist wieder die Fassung aus Schritt 1.
|
|
- `ls` zeigt keine Datei `sitzungsstart.py.neu`.
|
|
|
|
## Schritt 3 — Angriffsliste
|
|
|
|
```
|
|
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/session-hooks/faelle_sitzungsstart.py; echo "exit=$?"
|
|
```
|
|
|
|
Erwartet: `Grundlinie gruen`, keine Zeile, die mit `FEHLER` beginnt, die Fälle mit `waisen` im Namen als `BESTANDEN`, Schlusszeile `N von N Faellen bestanden.` mit zweimal derselben Zahl, `exit=0`.
|
|
|
|
## Schritt 4 — Messung M2 über den echten Vault
|
|
|
|
```
|
|
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/session-hooks/faelle_sitzungsstart.py --echt; echo "exit=$?"
|
|
```
|
|
|
|
Erwartet: die Kontextzeilen des echten Vaults, darunter eine Zeile `- Waisen außerhalb der Ausnahmen: ` mit einer Zahl und keine Zeile `Sitzungsstart-Hook: Waisen:`. Steht dort `LAUFZEIT UEBER ZIEL` und `exit=1`: nichts ändern, die Laufzeit melden. Das ist Offener Punkt 4 der Übersicht, kein Fehler dieses Tasks.
|
|
|
|
## Schritt 5 — Nachbarn unverändert grün
|
|
|
|
```
|
|
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/session-hooks/faelle_nach_edit.py; echo "exit=$?"
|
|
```
|
|
|
|
Erwartet: `exit=0`.
|
|
|
|
## Bericht
|
|
|
|
Melde die vollständige Ausgabe von Schritt 1, 2, 4 und 5, von Schritt 3 die Schlusszeile und jede Zeile, die nicht mit `BESTANDEN` beginnt. Läuft etwas anders als erwartet: nichts anpassen, melden.
|