Automatischer Push: 25 Datei(en) geändert
- .claude/agents/executer.md - .claude/agents/recherche.md - .claude/skills/anleitung-straffen/SKILL.md - .vault-tools/linkcheck/docs/plans/2026-09-29-waisen/00-uebersicht.md - .vault-tools/linkcheck/docs/plans/2026-09-29-waisen/task-01-zaehler.md - .vault-tools/linkcheck/docs/plans/2026-09-29-waisen/task-02-sitzungsstart.md - .vault-tools/linkcheck/docs/plans/2026-09-29-waisen/task-03-regeltexte.md - .vault-tools/linkcheck/docs/plans/2026-09-29-waisen/task-04-bestandsskript.md - .vault-tools/linkcheck/docs/plans/2026-09-29-waisen/task-05-bestandslauf.md - .vault-tools/workflow-pruefung/docs/plans/2026-09-29-quorum/00-uebersicht.md - .vault-tools/workflow-pruefung/docs/plans/2026-09-29-quorum/task-01-quorum-werkzeug.md - .vault-tools/workflow-pruefung/docs/plans/2026-09-29-quorum/task-02-quorum-workflow.md - … und 13 weitere Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
1 parent
e28dd9c280
commit
60dee0ab68
25 files changed
+6403
-86
No files matched your search
@@ -0,0 +1,178 @@
|
||||
---
|
||||
type: plan
|
||||
title: "Waisen im Graphen: Hub-Regel, Zähler im Sitzungsstart, Bestandslauf"
|
||||
status: draft
|
||||
summary: "waisen.py zählt verwaiste Notizen so, wie Obsidian den Graphen baut, der Sitzungsstart meldet die Zahl, Regeltexte und Planer verlinken künftig den Hub, und ein einmaliger Bestandslauf hängt den Bestand an, nur anhängend und mit Probelauf."
|
||||
tags: [plan, vault-tools]
|
||||
created: 2026-09-29
|
||||
updated: 2026-09-29
|
||||
---
|
||||
|
||||
# Waisen im Graphen
|
||||
|
||||
Anforderung: Spec `Inbox/2026-09-29-spec-vernetzung.md` (Pascals Entscheidungen vom 2026-09-29). Die Spec liegt nicht im veröffentlichten Umfang, dieser Plan schon. Deshalb stehen hier keine Kunden-, Domain- oder Projektnamen.
|
||||
|
||||
## Ziel
|
||||
|
||||
Heute hat laut Spec fast die Hälfte der Notizen im Graphen keine Kante, vor allem Plandateien, Codedoku und SEO-Einzelbefunde. Nach diesem Plan zählt `.vault-tools/linkcheck/waisen.py` die Waisen reproduzierbar, der Sitzungsstart zeigt die Zahl als eine Zeile, die Regel „jede neue Datei verlinkt ihren Hub“ steht an einer Stelle (`navigation.md`) und ist in Planer, Codedoku- und SEO-Regel verankert, und ein einmaliger Lauf hängt den Bestand an seine Hubs, ohne eine Zeile zu ersetzen.
|
||||
|
||||
## Nicht im Umfang
|
||||
|
||||
- Taskdateien im Bestand. Der Bestandslauf fasst sie nie an, sie werden über ihre Übersicht angebunden.
|
||||
- Querverweise zwischen IT-Workspace-Artikeln, ein Graph-Filter in Obsidian, die Dateien mit nur ausgehenden Links, die Verbindung Projekt und Themen-Seed (alles laut Spec).
|
||||
- Die Gruppe „Einzelne“ der Spec und alles, wofür kein Muster greift. Das landet auf der Liste für den Koordinator und wird von Hand entschieden.
|
||||
- Commits. Weder Skript noch Executer committen. Der Koordinator committet je Repo nach Pascals Ja.
|
||||
- Der SEO-Audit-Skill selbst. Er liegt außerhalb des Vaults und wird nicht geändert.
|
||||
|
||||
## Architektur
|
||||
|
||||
| Datei | Rolle | Task |
|
||||
|---|---|---|
|
||||
| `.vault-tools/linkcheck/waisen.py` | Zähler, Prüfwerkzeug nach `pruefwerkzeuge.md` | 01 |
|
||||
| `.vault-tools/linkcheck/waisen-ausnahmen.txt` | Positivliste der Ausnahmen, nur allgemeine Muster | 01 |
|
||||
| `.vault-tools/linkcheck/faelle_waisen.py` | Angriffsliste, Rotlauf mit eingebauten Mutanten, `--echt` misst die Laufzeit | 01 |
|
||||
| `.vault-tools/linkcheck/ENTWURF-waisen.md` | Entscheidungsliste mit Herkunft je Antwort, Angriffsklassen, Abbruchbedingung | 01 |
|
||||
| `.vault-tools/session-hooks/sitzungsstart.py` | neue Zeile `- Waisen außerhalb der Ausnahmen: N`, `waisen.py --zahl` als eigener Prozess, 15 s Grenze | 02 |
|
||||
| `.vault-tools/session-hooks/faelle_sitzungsstart.py`, `ENTWURF.md` | Grundlinie mit `.obsidian/app.json`, neue Fälle, Nachtrag | 02 |
|
||||
| `AI/Regelwerk/navigation.md`, `CLAUDE.md`, `.claude/agents/planer.md`, `AI/Regelwerk/codedoku.md`, `AI/Regelwerk/seo.md` | Hub-Regel und ihre Verweise | 03 |
|
||||
| `.vault-tools/linkcheck/waisen_bestand.py` | einmaliger Bestandslauf, Probelauf ohne Schalter | 04 |
|
||||
| `.vault-tools/linkcheck/faelle_waisen_bestand.py` | Angriffsliste mit Git-Fällen, Rotlauf | 04 |
|
||||
|
||||
`waisen.py` nutzt `strip_code()` aus `linkcheck.py` und nicht das Navigator-Toolkit. `waisen_bestand.py` importiert `waisen.py` und nimmt dessen Waisenliste und ausgehende Kanten, damit Zähler und Bestandslauf dieselbe Wahrheit haben.
|
||||
|
||||
Die Entscheidungsliste des Zählers mit Herkunft je Antwort steht wörtlich in `task-01-zaehler.md`, Block `ENTWURF-waisen.md`. Nach der Umsetzung gilt die Datei im Baum.
|
||||
|
||||
## Erzeuger-Inventar
|
||||
|
||||
Gelesen am 2026-09-29: sechs gespeicherte Workflows, vier Skills im Vault, vier Agentendateien.
|
||||
|
||||
| Erzeuger | Fundstelle | Legt an | Folge im Plan |
|
||||
|---|---|---|---|
|
||||
| Agent `planer` | `.claude/agents/planer.md` Zeile 16 (Ablageform) und 25 (Nachbesserung, Folgenliste) | Übersicht, Taskdateien, Nachbesserungen, Folgenliste in `docs/plans/` | neue Regelzeile nach Zeile 16 (Task 03) |
|
||||
| Workflow `planung` | `.claude/workflows/planung.js` Zeile 112 („Schreib genau eine Datei“), Zeile 136 (`agentType: 'planer'`) | Taskdateien, geschrieben vom `planer` | keine eigene Änderung: der Auftrag geht an `agentType: 'planer'`, die Regel kommt aus `planer.md` |
|
||||
| Workflows `executer-welle`, `pruefung`, `plankritik`, `welle-mit-pruefung`, `verbrauch` | kein Schreibauftrag für Markdown in den Prompts (grep nach `anleg`, `ableg`, `.md`) | nichts | keine |
|
||||
| Agent `executer` | `.claude/agents/executer.md` Zeile 15: nur die genannten Zieldateien | was der Plan vorgibt | keine, die Zeile steht dann im Plan |
|
||||
| Agent `pruefer` | Zeile 6: Werkzeuge ohne `Write` | nichts | keine |
|
||||
| Agent `recherche` | Zeile 15: Hilfsdatei nur mit genanntem Ablageort | nur auf Anweisung | keine, die Regel gilt über den Stamm |
|
||||
| Skill `anleitung-straffen` | `.claude/skills/anleitung-straffen/SKILL.md` Zeile 22 und 23 | `<name>-hintergrund.md` neben der Anleitung | keine: Zeile 23 verlinkt Anleitung und Hintergrund schon in beide Richtungen |
|
||||
| Skills `bookstack-upload`, `plane-abgleich` | schreiben nur Frontmatter-Felder bzw. `todo.md` | keine neue Markdown-Datei | keine |
|
||||
| SEO-Audit-Skill (`/seo`, `/seo-audit`) | liegt nicht unter `.claude/skills/` im Vault | Befunddateien unter `findings/` | Regel in `seo.md`: der Bericht listet seine Befunddateien (Task 03) |
|
||||
| Koordinator selbst | `AI/Regelwerk/codeworkflow.md` Zeile 38 und 113 | Anforderungen, Prüfberichte, Specs, Dumps | allgemeine Regel in `navigation.md` und Stammzeile (Task 03) |
|
||||
|
||||
## Planwerkzeuge und die neue Linkzeile
|
||||
|
||||
Frage: Vertragen die Planwerkzeuge eine Zeile `Übersicht: [00-uebersicht.md](00-uebersicht.md)` direkt unter dem Frontmatter einer Taskdatei und einen angehängten Abschnitt am Ende einer `00-uebersicht.md`? Gelesen, nicht gemessen:
|
||||
|
||||
| Werkzeug | Was es auswertet | Fundstelle | Wirkung der Linkzeile |
|
||||
|---|---|---|---|
|
||||
| `plan-kopie/plan_materialisiere.py` | Zieldatei nur aus Überschriften `^#{2,4} ` mit Pfad in Backticks; Zaun per `lstrip().startswith("```")`; Marke ist die letzte nicht leere Zeile vor dem Zaun; Löschziele nur unter `## Zieldateien` | Zeile 26 bis 27, 40 bis 44, 57 bis 60, 76 bis 81 | keine: die Zeile ist weder Überschrift noch Zaun und steht nie zwischen Marke und Zaun |
|
||||
| `plan-kopie/plan_bloecke.py` | dieselbe Logik | Zeile 23 bis 25, 39 bis 42, 54 bis 60 | keine |
|
||||
| `plan-diff/plan_diff.py` | Pfadzeile nur mit Pfad in Backticks, höchstens zehn Zeilen vor dem Zaun; Zieldateien nur unter `## Zieldateien` | Zeile 32, 44 bis 55, 78 bis 88 | keine: ein Markdown-Link trägt keine Backticks |
|
||||
| `plan-kopie/welle_vergleich.py` | nur `## Zieldateien` | Zeile 40 bis 47 | keine |
|
||||
| `plan-kopie/rot_nachweis.py` | nur `## Zieldateien` | Zeile 75 bis 81 | keine |
|
||||
| `plan-kopie/plan_zeichen.py` | nur Inhalte von Codeblöcken | Zeile 35 | keine |
|
||||
|
||||
Die Übersicht selbst parst kein Werkzeug: `grep uebersicht` über `plan-kopie/*.py` trifft nichts, die Workflows nennen sie nur als Lesehinweis (`executer-welle.js` Zeile 63, `plankritik.js` Zeile 71). Ein angehängter Abschnitt ändert keinen Aus-Block, weil nur hinten angefügt wird. Ein späteres „Häng diesen Block ans Ende“ auf eine Übersicht landet hinter dem neuen Abschnitt, das ist harmlos. Der bekannte Fall, ein Absatz zwischen Marke und Codeblock, kann durch die Linkzeile nicht entstehen.
|
||||
|
||||
Die Taskdateien dieses Plans tragen die Linkzeile schon. Die Plankritik fährt `plan_bloecke.py` und `plan_zeichen.py` darüber und materialisiert sie. Das ist Messschritt M4.
|
||||
|
||||
## Prüfschritte in der App (Pascal)
|
||||
|
||||
Keine Quelle im Vault belegt, wie Obsidian relative Markdown-Links zählt (Grep über `AI/` und `IT Workspace/` nach `Markdown-Link`, `resolvedLinks`, `getFirstLinkpathDest` ohne Treffer). Deshalb drei Handgriffe in Obsidian, bevor Task 03 und Phase B von Task 05 starten:
|
||||
|
||||
1. Lege `Inbox/test-links.md` an mit diesem Inhalt:
|
||||
|
||||
```markdown
|
||||
---
|
||||
verwandt: "[[AI/Regelwerk/frontmatter]]"
|
||||
---
|
||||
[eins](../AI/Regelwerk/navigation.md)
|
||||
[zwei](../IT%20Workspace/Nextcloud/_MOC-nextcloud.md)
|
||||
[drei](../AI/Regelwerk/schreibstil)
|
||||
```
|
||||
|
||||
2. Öffne die Notiz, dann die lokale Graphansicht und den Bereich „Ausgehende Links“.
|
||||
- **P1:** `navigation` und `_MOC-nextcloud` erscheinen als verknüpft, der Graph zeigt beide Kanten. Das belegt relative Links mit `../` und URL-kodierte Leerzeichen.
|
||||
- **P2:** `frontmatter` erscheint als verknüpft. Das belegt Wikilinks im Frontmatter.
|
||||
- **P3:** `schreibstil` erscheint als verknüpft. Das belegt Markdown-Links ohne `.md`.
|
||||
3. Notiz löschen.
|
||||
|
||||
Ein Nein bei P1 stoppt Task 03 und Task 05, weil die Hub-Regel dann in Projekt-Repos nichts verbindet. Ein Nein bei P2 oder P3 heißt: Entscheidung 7 bzw. 8 im Entwurf ändern, bevor der Zähler gilt.
|
||||
|
||||
## Globale Vorgaben
|
||||
|
||||
- Nur die Zieldateien der eigenen Taskdatei. Kein Commit, kein `git add`.
|
||||
- Codeblöcke wörtlich anwenden mit `python D:/Claude/.vault-tools/plan-kopie/plan_materialisiere.py D:/Claude/.vault-tools/linkcheck/docs/plans/2026-09-29-waisen D:/Claude <taskdatei>`. Nichts von Hand nachschreiben, auch keinen „offensichtlichen“ Tippfehler korrigieren.
|
||||
- Befehle im Bash-Werkzeug (Git-Bash), nicht in der PowerShell. `python` ist das Windows-Python.
|
||||
- Läuft ein Befehl anders als im Plan erwartet: nichts anpassen, die vollständige Ausgabe melden. Ein Widerspruch im Plan wird gemeldet, nicht still aufgelöst.
|
||||
- Das Feld `updated` in geänderten Regelwerk-Dateien setzt der Koordinator beim Commit, weil das Datum der Umsetzung beim Planen nicht feststeht. `status` bleibt, wie er ist: Pascal hat die Änderung mit der Spec angeordnet.
|
||||
- In Dateien unter `.vault-tools/` stehen keine Kunden-, Domain- oder Projektnamen. Die Testfälle nutzen erfundene Namen (`active - Alpha`, `kunde-audit`, `Projekt X`).
|
||||
|
||||
## Tasks
|
||||
|
||||
| Task | Inhalt | Modell | Voraussetzung | Welle |
|
||||
|---|---|---|---|---|
|
||||
| `task-01-zaehler.md` | `waisen.py`, Ausnahmedatei, Treiber, Entwurf | haiku | keine | 1 |
|
||||
| `task-02-sitzungsstart.md` | Zeile im SessionStart-Hook, Treiber, Nachtrag im Entwurf | haiku | Task 01 | 2 |
|
||||
| `task-03-regeltexte.md` | Hub-Regel in `navigation.md`, Stamm, Planer, Codedoku, SEO | sonnet, effort low | P1 in der App | 1 oder 2 |
|
||||
| `task-04-bestandsskript.md` | `waisen_bestand.py` und Treiber | haiku | Task 01 | 2 |
|
||||
| `task-05-bestandslauf.md` | Probelauf, Halt, nach Freigabe echter Lauf | sonnet | Tasks 01, 02, 04; P1 bis P3 | 3 |
|
||||
|
||||
Die Zieldateien der Tasks 01 bis 04 sind disjunkt. Task 02 und 04 brauchen die Dateien aus Task 01 zur Laufzeit, deshalb Welle 2. Task 05 ändert keine Datei im Plan-Sinn, er fährt Skripte gegen den echten Vault und hält nach Phase A an.
|
||||
|
||||
## Messschritte
|
||||
|
||||
Der Planer hatte keine Shell. Was gemessen werden muss, steht als Schritt in einem Task:
|
||||
|
||||
| Nr. | Was | Wo | Erwartung |
|
||||
|---|---|---|---|
|
||||
| M1 | Laufzeit von `waisen.py` über den ganzen Vault | Task 01, `faelle_waisen.py --echt` | unter 10 s |
|
||||
| M2 | Laufzeit des ganzen Sitzungsstarts mit der neuen Zeile | Task 02, `faelle_sitzungsstart.py --echt` | Ziel des Treibers bleibt 5 s; darüber ist ein offener Punkt, kein Fehler von Task 02 |
|
||||
| M3 | Zahl der Plan-Übersichten und Anhänge je Gruppe | Task 05, Phase A, Auszählung von `probelauf.txt` | Größenordnung wie in der Spec |
|
||||
| M4 | Planwerkzeuge mit Linkzeile unter dem Frontmatter | Plankritik über diesen Plan | `plan_bloecke.py vor`: `0 Befund(e).`; Materialisieren ohne Befund |
|
||||
|
||||
## Fertig heißt
|
||||
|
||||
1. `python D:/Claude/.vault-tools/linkcheck/faelle_waisen.py` endet mit Exit 0, und `--rotlauf` endet mit Exit 0, jeder Mutant `GETOETET`.
|
||||
2. `python D:/Claude/.vault-tools/linkcheck/faelle_waisen.py --echt` endet mit Exit 0 (M1).
|
||||
3. `python D:/Claude/.vault-tools/session-hooks/faelle_sitzungsstart.py` endet mit Exit 0; `--echt` zeigt die Zeile `- Waisen außerhalb der Ausnahmen: ` mit einer Zahl (M2).
|
||||
4. `python D:/Claude/.vault-tools/linkcheck/faelle_waisen_bestand.py` endet mit Exit 0, `--rotlauf` ebenfalls, jeder Mutant `GETOETET`.
|
||||
5. `python D:/Claude/.vault-tools/linkcheck/faelle.py` endet weiter mit Exit 0.
|
||||
6. `regelwerk_check.py` meldet nach Task 03 keine Befundzeile, die vorher nicht da war.
|
||||
7. Je Welle sind die Zieldateien byte-gleich mit der Kopie, auf die der Koordinator den Plan vorher angewendet hat (`welle_vergleich.py`).
|
||||
8. Phase A von Task 05 liegt als `probelauf.txt` vor, der Koordinator hat die Liste gelesen, Pascal hat Phase B freigegeben.
|
||||
9. Nach Phase B: Probelauf und echter Lauf nennen dieselben Anhänge, die Sicherung liegt außerhalb des Vaults, und Pascals Bildschirmfoto des Graphen ist die Abnahme.
|
||||
|
||||
## Lauf mit echten Daten
|
||||
|
||||
- **Zähler:** `PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/waisen.py --vault D:/Claude --liste`. Die Spec maß am 2026-09-29 1.996 Notizen und 852 Waisen, darunter 10 in `Bookstack/` und 7 unter `data/`. Ohne diese Ausnahmen sind rund 835 zu erwarten, dazu die seitdem entstandenen Dateien. Weicht die Zahl um mehr als etwa 20 ab, vergleicht der Koordinator die Gruppen der Spec mit der Liste, bevor Task 05 startet. Stichprobe: zehn Pfade aus der Liste in Obsidian öffnen, Rückverweise und ausgehende Links müssen leer sein.
|
||||
- **Sitzungsstart:** nächste Sitzung nach Task 02, die Zeile steht im Kontext, und die Zahl ist dieselbe wie beim Zähler.
|
||||
- **Bestandslauf:** Task 05. Auffallen müsste: jede Übersicht unter `Code Projekte/*/docs/plans/*/` mit verwaisten Tasks erscheint als `ZIEL`, jede Taskdatei nie. Die Liste für den Koordinator enthält die Gruppe „Einzelne“, die Administrator-Anleitungen und alles ohne Muster.
|
||||
|
||||
## Risiken
|
||||
|
||||
- **Obsidian zählt anders als nachgebaut.** Dann weicht die Zahl vom Graphen ab. Erkennbar an P1 bis P3 und an der Stichprobe. Die Auflösung mehrdeutiger Namen ist nachgebaut, das steht als Lücke im Kopf von `waisen.py`.
|
||||
- **Der Sitzungsstart wird zu langsam.** Über 15 s bricht die Waisenzeile ab und erscheint als Fehlerzeile, die übrigen Zeilen bleiben. Über 30 s gesamt verwirft Claude Code die ganze Ausgabe. M1 und M2 messen das.
|
||||
- **Ein anderer Agent schreibt während Phase B.** Das Skript liest jede Zieldatei direkt vor dem Anhängen noch einmal und bricht ab, wenn sie sich geändert hat. Was bis dahin angehängt war, nennt die Ausgabe, die Sicherung liegt vor.
|
||||
- **Eine Executer-Welle läuft vor dem Commit der Bestandsänderungen in einem Repo.** Dann meldet `welle_vergleich.py` die angehängten Übersichten als „außerhalb der Zieldateien“. Abhilfe: erst committen oder die Meldung erwarten.
|
||||
- **Obsidian Sync auf einem zweiten Gerät.** Phase B ändert viele Dateien auf einmal. Während des Laufs Obsidian auf anderen Geräten schließen.
|
||||
- **Veröffentlichung um 04:00.** Die Dateien unter `.vault-tools/` gehen halbfertig hinaus, sobald sie auf der Platte liegen. Sie enthalten keine Namen. Die angehängten Zeilen in `AI/`, `IT Workspace/`, `Inbox/` und in den Projekt-Repos werden nicht veröffentlicht.
|
||||
|
||||
## Getroffene Annahmen
|
||||
|
||||
- Relative Markdown-Links, URL-kodierte Pfade, Wikilinks im Frontmatter und Markdown-Links ohne `.md` zählen im Graphen. Prüfschritte P1 bis P3.
|
||||
- Die Git-Prüfung gilt für jede Zieldatei in einem Repo, nicht nur für Übersichten, und eine nie committete Zieldatei zählt als geändert. Das ist strenger als die Spec, damit ein Commit je Repo keine fremde halbe Arbeit mitnimmt.
|
||||
- Unter `Code Projekte/<projekt>/docs/` bekommt jede verwaiste Datei außerhalb von `docs/plans/` die README-Zeile. Die Spec nennt Codedoku, Specs, Abnahme und Recherche; das Muster ist `docs/**`. Pascal sieht im Probelauf, was darunter fällt.
|
||||
- Die Administrator-Anleitung hat keinen festen Namen. Sie kommt auf die Liste für den Koordinator, statt geraten zu werden.
|
||||
- Bericht eines SEO-Laufs ist `ABSCHLUSSBERICHT.md` im Ordner über `findings/`, sonst `FULL-AUDIT-REPORT.md`. Beide Namen stammen aus dem Audit-Skill, nicht aus einem Kundennamen.
|
||||
- Die Projektübersicht eines IT-Workspace-Projekts mit `_arbeitsstand` ist die einzige `_MOC-*.md` im Ordner darüber. Gibt es keine oder mehrere, kommt die Datei auf die Liste.
|
||||
- Der Abschnitt „Dateien in diesem Ordner“ listet jede `.md` im Ordner außer der Übersicht, auch schon verlinkte, wie in der Spec.
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
1. **P1 bis P3 in der App**, vor Task 03 und vor Phase B von Task 05.
|
||||
2. **Abweichung von der Spec, Workflows:** Die Spec sieht vor, dass gespeicherte Workflows, die in Planordner schreiben, dieselbe Zeile bekommen. Das Inventar zeigt: Nur `planung.js` lässt schreiben, und zwar über `agentType: 'planer'`. Die Regel kommt aus `planer.md`, eine zweite Fassung im Workflow würde driften. Vorschlag: keine Änderung an Workflows.
|
||||
3. **Abweichung von der Spec, Administrator-Anleitung:** Die Spec nennt sie in der Bestandstabelle bei „eine Zeile mit Link aufs README“. Ohne festen Dateinamen gibt es kein Muster; sie kommt auf die Liste für den Koordinator.
|
||||
4. **Laufzeitziel des Sitzungsstarts:** `faelle_sitzungsstart.py` erwartet bisher unter 5 s. Liegt M2 darüber, entscheidet Pascal, ob das Ziel steigt (der Hook hat 30 s).
|
||||
5. **IT-Workspace-Projekte ohne `_arbeitsstand`:** Die Spec-Zeile „Arbeitsdatei eines Projekts im IT Workspace“ ist für den Bestand nur für `_arbeitsstand` als Muster umgesetzt. Andere Arbeitsdateien kommen auf die Liste.
|
||||
6. **Specs in der Inbox** wie die Spec zu diesem Plan haben laut Hub-Tabelle das Projekt-README als Hub, liegen aber außerhalb eines Projekts. Die Regel sagt dazu nichts. Vorschlag: bei Abnahme in den Projektordner verschieben oder aus der Tagesnotiz verlinken.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,450 @@
|
||||
---
|
||||
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-29
|
||||
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 — 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 3 — 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 4 — 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, 3 und 4, von Schritt 2 die Schlusszeile und jede Zeile, die nicht mit `BESTANDEN` beginnt. Läuft etwas anders als erwartet: nichts anpassen, melden.
|
||||
@@ -0,0 +1,215 @@
|
||||
---
|
||||
type: plan-task
|
||||
title: "Task 03 — Hub-Regel in navigation.md und ihre Verweise in Stamm, Planer, Codedoku und SEO"
|
||||
status: draft
|
||||
summary: "navigation.md bekommt die Hub-Regel mit Tabelle als einzigen Ort der Regel und einen Abschnitt zu waisen.py; CLAUDE.md, planer.md, codedoku.md und seo.md bekommen je einen knappen Punkt mit Verweis."
|
||||
tags: [plan-task, vault-tools]
|
||||
created: 2026-09-29
|
||||
updated: 2026-09-29
|
||||
modell: sonnet
|
||||
effort: low
|
||||
modell_begruendung: "Reine Abschrift per Skript, aber die Codeblöcke enthalten typografische Anführungszeichen, die Haiku still ersetzt."
|
||||
---
|
||||
Übersicht: [00-uebersicht.md](00-uebersicht.md)
|
||||
|
||||
# Task 03 — Hub-Regel und Verweise
|
||||
|
||||
Globale Vorgaben: `00-uebersicht.md` im selben Ordner, Abschnitt „Globale Vorgaben“.
|
||||
|
||||
Voraussetzung: Pascal hat Prüfschritt P1 aus der Übersicht in Obsidian mit Ja beantwortet. Ohne dieses Ja startet der Task nicht.
|
||||
|
||||
## Zieldateien
|
||||
|
||||
- `D:\Claude\AI\Regelwerk\navigation.md` (geändert)
|
||||
- `D:\Claude\CLAUDE.md` (geändert)
|
||||
- `D:\Claude\.claude\agents\planer.md` (geändert)
|
||||
- `D:\Claude\AI\Regelwerk\codedoku.md` (geändert)
|
||||
- `D:\Claude\AI\Regelwerk\seo.md` (geändert)
|
||||
|
||||
## Verbote
|
||||
|
||||
- Frontmatter der Zieldateien nicht anfassen, auch nicht `updated` oder `status`. Das macht der Koordinator.
|
||||
- Kein Skill, kein Workflow, keine andere Regelwerk-Datei.
|
||||
- Keine Formulierung glätten oder ergänzen. Steht ein Aus-Block nicht genau einmal in der Datei, bricht das Skript mit Befund ab: dann melden, nicht von Hand einfügen.
|
||||
|
||||
## Schritt 0 — Stand vorher festhalten
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/regelwerk-check/regelwerk_check.py --vault D:/Claude > /tmp/regelwerk-vorher.txt; echo "exit=$?"; PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/linkcheck.py --vault D:/Claude --alle > /tmp/linkcheck-vorher.txt; echo "exit=$?"
|
||||
```
|
||||
|
||||
Der Exit-Code ist hier egal, er wird nur mitgemeldet.
|
||||
|
||||
## 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-03-regeltexte.md
|
||||
```
|
||||
|
||||
Erwartet: eine Zeile mit `'ersetzt': 7` und die Schlusszeile `0 Befund(e).`
|
||||
|
||||
### Abschnitt zu waisen.py in `AI/Regelwerk/navigation.md`
|
||||
|
||||
Aus:
|
||||
|
||||
```
|
||||
Der erste Befehl meldet die echten toten Wikilinks, weil er Codeblöcke ausnimmt. Der zweite fährt die Angriffsfälle gegen die Codeblock-Erkennung. Entwurf, Herkunft je Regel und benannte Lücken: `.vault-tools/linkcheck/ENTWURF-codeblock-erkennung.md`.
|
||||
```
|
||||
|
||||
wird:
|
||||
|
||||
````
|
||||
Der erste Befehl meldet die echten toten Wikilinks, weil er Codeblöcke ausnimmt. Der zweite fährt die Angriffsfälle gegen die Codeblock-Erkennung. Entwurf, Herkunft je Regel und benannte Lücken: `.vault-tools/linkcheck/ENTWURF-codeblock-erkennung.md`.
|
||||
|
||||
## Waisen: waisen.py
|
||||
|
||||
Eine Waise ist eine Notiz ohne Kante im Graphen, weder eingehend noch ausgehend. `waisen.py` zählt sie so, wie Obsidian den Graphen baut, und zieht die Muster aus `waisen-ausnahmen.txt` ab.
|
||||
|
||||
```bash
|
||||
PYTHONIOENCODING=utf-8 python .vault-tools/linkcheck/waisen.py --vault . --liste
|
||||
python .vault-tools/linkcheck/faelle_waisen.py
|
||||
```
|
||||
|
||||
- Der Sitzungsstart zeigt dieselbe Zahl als Zeile „Waisen außerhalb der Ausnahmen“. Steigt sie, hat eine neue Datei ihren Hub nicht verlinkt (Regel unten unter „Links schreiben und Dateien verschieben“).
|
||||
- In `waisen-ausnahmen.txt` stehen nur allgemeine Muster, keine Kunden- oder Projektnamen, weil `.vault-tools/` veröffentlicht wird.
|
||||
- Entwurf, Herkunft je Regel und benannte Lücken: `.vault-tools/linkcheck/ENTWURF-waisen.md`. Ein Fangnetz, kein Nachweis: Wie der Graph aussieht, zeigt nur Obsidian.
|
||||
````
|
||||
|
||||
### Sitzungsstart in `AI/Regelwerk/navigation.md`
|
||||
|
||||
Aus:
|
||||
|
||||
```
|
||||
- **`sitzungsstart.py`** (SessionStart) gibt beim Start nur Zahlen in den Kontext: ob die Tagesnotiz existiert, offene Inbox-Notizen, Notizen mit `#needs-review`, `#review` ohne `#review-done`, Regelwerk-Dateien auf `pending-review` und die Sitzungsdateien von heute, damit eine Namenskollision auffällt.
|
||||
```
|
||||
|
||||
wird:
|
||||
|
||||
```
|
||||
- **`sitzungsstart.py`** (SessionStart) gibt beim Start nur Zahlen in den Kontext: ob die Tagesnotiz existiert, offene Inbox-Notizen, Notizen mit `#needs-review`, `#review` ohne `#review-done`, Regelwerk-Dateien auf `pending-review` und die Sitzungsdateien von heute, damit eine Namenskollision auffällt. Dazu kommt die Zahl der Waisen außerhalb der Ausnahmen aus `waisen.py`, nur die Zahl, keine Liste.
|
||||
```
|
||||
|
||||
### Hub-Regel in `AI/Regelwerk/navigation.md`
|
||||
|
||||
Aus:
|
||||
|
||||
```
|
||||
## Links schreiben und Dateien verschieben
|
||||
|
||||
- **Wikilinks mit vollem Vault-Pfad:** `[[AI/Regelwerk/navigation|navigation.md]]`. In Tabellenzellen schreibst du den Alias-Trenner als `\|`.
|
||||
```
|
||||
|
||||
wird:
|
||||
|
||||
```
|
||||
## Links schreiben und Dateien verschieben
|
||||
|
||||
### Jede neue Datei hängt an ihrem Hub
|
||||
|
||||
**Wer eine Datei anlegt, verlinkt darin ihren Hub, und zwar nach oben.** Das gilt für dich, für jeden Subagenten, Skill und Workflow. Der Erzeuger kennt den Hub beim Anlegen, der Hub selbst braucht keine Pflege, und seine Rückverweise zeigen alle Kinder. Ein Pfad in Backticks ist kein Link.
|
||||
|
||||
| Datei | Hub | Linkform |
|
||||
|---|---|---|
|
||||
| Plan-Übersicht `00-uebersicht.md`, Einzeldatei-Plan | Projekt-README | relativer Markdown-Link |
|
||||
| alles andere im Planordner (Task, Anforderung, Prüfbericht, Nachbesserung) | `00-uebersicht.md` desselben Ordners | relativer Markdown-Link |
|
||||
| Codedoku `docs/code/*.md`, Spec, Quorum-Bericht, CHANGELOG, Administrator-Anleitung | Projekt-README | relativer Markdown-Link |
|
||||
| SEO-Einzelbefund | Bericht des Laufs | Wikilink mit vollem Pfad |
|
||||
| Bericht eines SEO-Laufs | SEO-Seed | Wikilink mit vollem Pfad |
|
||||
| Arbeitsdatei eines Projekts im IT Workspace | Übersicht bzw. README des Projekts | Wikilink mit vollem Pfad |
|
||||
| Dump | Tagesnotiz | Wikilink `[[Inbox/JJJJ-MM-TT]]` |
|
||||
|
||||
- **Wo die Zeile steht:** direkt unter dem Frontmatter, ohne Frontmatter in der ersten Zeile. In einer Taskdatei lautet sie `Übersicht: [00-uebersicht.md](00-uebersicht.md)`, in einer Übersicht `Projekt: [README](../../../README.md)`, die Tiefe passend zum Ort.
|
||||
- **Relative Markdown-Links in Projekt-Repos, entgegen der Vault-Gewohnheit.** Der Projektstatus steht im Ordnerpräfix, und aus `active - X` wird irgendwann `inactive - X`. Wikilinks mit vollem Pfad brechen dabei, wenn nicht in Obsidian umbenannt wird. Gitea zeigt Markdown-Links an, Wikilinks nicht. Leerzeichen und Umlaute im Pfad schreibst du URL-kodiert, ein Leerzeichen als `%20`.
|
||||
- **Außerhalb der Projekt-Repos** bleibt es beim Wikilink mit vollem Pfad.
|
||||
- **SEO-Befunde verlinkt der Bericht nach unten**, weil der Audit-Skill außerhalb des Vaults liegt und seine Befunddateien ohne Link ablegt. Wie, steht in [[AI/Regelwerk/seo|seo.md]], Abschnitt 1, Punkt 5.
|
||||
- **Bewusste Ausnahmen** sind `Bookstack/` (Warteschlange und Archiv) und Programmausgaben unter `data/` in Code-Projekten. Sie stehen als Muster in `.vault-tools/linkcheck/waisen-ausnahmen.txt` und zählen nicht als Waisen.
|
||||
|
||||
### Links allgemein
|
||||
|
||||
- **Wikilinks mit vollem Vault-Pfad:** `[[AI/Regelwerk/navigation|navigation.md]]`. In Tabellenzellen schreibst du den Alias-Trenner als `\|`.
|
||||
```
|
||||
|
||||
### Pflegepunkt in `CLAUDE.md`
|
||||
|
||||
Aus:
|
||||
|
||||
```
|
||||
- Neues Projekt in Code Projekte / Security-Compliance → im jeweiligen Oberseed mit Link aufs README eintragen und mit dem passenden Themen-Seed verbinden ([[AI/Regelwerk/projekte|projekte.md]]).
|
||||
```
|
||||
|
||||
wird:
|
||||
|
||||
```
|
||||
- Neues Projekt in Code Projekte / Security-Compliance → im jeweiligen Oberseed mit Link aufs README eintragen und mit dem passenden Themen-Seed verbinden ([[AI/Regelwerk/projekte|projekte.md]]).
|
||||
- Jede Datei, die du, ein Subagent, Skill oder Workflow anlegt, verlinkt ihren Hub nach oben: Plan, Codedoku und CHANGELOG das Projekt-README, Task die Plan-Übersicht, Dump die Tagesnotiz. Tabelle und Linkform: [[AI/Regelwerk/navigation|navigation.md]], „Links schreiben und Dateien verschieben“. Der Sitzungsstart meldet die Zahl der Waisen.
|
||||
```
|
||||
|
||||
### Hub-Zeile in `.claude/agents/planer.md`
|
||||
|
||||
Aus:
|
||||
|
||||
```
|
||||
- **Ablageform hängt am Umfang.** Bis zwei Tasks eine Datei `docs/plans/JJJJ-MM-TT-<thema>.md`. **Ab etwa drei Tasks ein Ordner** `docs/plans/JJJJ-MM-TT-<thema>/` mit `00-uebersicht.md` (Ziel, Architektur, globale Vorgaben, Dateiübersicht, Tasktabelle, Abnahme) und je Task einer Datei `task-NN-<thema>.md`. Jede Taskdatei verweist im Kopf auf die globalen Vorgaben der Übersicht, statt sie zu wiederholen — zwei Fassungen derselben Vorgabe laufen auseinander.
|
||||
```
|
||||
|
||||
wird:
|
||||
|
||||
```
|
||||
- **Ablageform hängt am Umfang.** Bis zwei Tasks eine Datei `docs/plans/JJJJ-MM-TT-<thema>.md`. **Ab etwa drei Tasks ein Ordner** `docs/plans/JJJJ-MM-TT-<thema>/` mit `00-uebersicht.md` (Ziel, Architektur, globale Vorgaben, Dateiübersicht, Tasktabelle, Abnahme) und je Task einer Datei `task-NN-<thema>.md`. Jede Taskdatei verweist im Kopf auf die globalen Vorgaben der Übersicht, statt sie zu wiederholen — zwei Fassungen derselben Vorgabe laufen auseinander.
|
||||
- **Jede Plandatei verlinkt ihren Hub direkt unter dem Frontmatter**, als relativen Markdown-Link, nicht nur als Pfad in Backticks. Die Übersicht und ein Einzeldatei-Plan verlinken das Projekt-README (`Projekt: [README](../../../README.md)`, die Tiefe passend zum Ort), jede andere Datei im Planordner die Übersicht (`Übersicht: [00-uebersicht.md](00-uebersicht.md)`). Leerzeichen und Umlaute im Pfad schreibst du URL-kodiert. Hat das Projekt kein `README.md`, entfällt die README-Zeile. Die Planwerkzeuge vertragen die Zeile an dieser Stelle, weil sie nur Überschriften, Codezäune und den Abschnitt `## Zieldateien` auswerten (Befund im Plan `.vault-tools/linkcheck/docs/plans/2026-09-29-waisen/`). Regel und Begründung: `AI/Regelwerk/navigation.md`, Abschnitt „Links schreiben und Dateien verschieben“.
|
||||
```
|
||||
|
||||
### README-Zeile in `AI/Regelwerk/codedoku.md`
|
||||
|
||||
Aus:
|
||||
|
||||
```
|
||||
- Ort: Projektordner unter `docs/code/`, eine Datei je Modul oder Skript, gleicher Name.
|
||||
```
|
||||
|
||||
wird:
|
||||
|
||||
```
|
||||
- Ort: Projektordner unter `docs/code/`, eine Datei je Modul oder Skript, gleicher Name.
|
||||
- Direkt unter dem Frontmatter, ohne Frontmatter in der ersten Zeile, steht ein relativer Markdown-Link aufs Projekt-README, zum Beispiel `Projekt: [README](../../README.md)`. Der Dateikopf im Code nennt die Codedoku nur als Pfad, ohne diese Zeile ist sie im Graphen eine Waise. Regel: [[AI/Regelwerk/navigation|navigation.md]], Abschnitt „Links schreiben und Dateien verschieben“.
|
||||
```
|
||||
|
||||
### Befundliste im Bericht in `AI/Regelwerk/seo.md`
|
||||
|
||||
Aus:
|
||||
|
||||
```
|
||||
`findings/`, Rohdaten und die Preisliste bekommen keinen Seed-Eintrag. Befunde früherer Läufe sind oft längst behoben (Punkt 1) und sollen nicht prominent verlinkt sein.
|
||||
```
|
||||
|
||||
wird:
|
||||
|
||||
```
|
||||
`findings/`, Rohdaten und die Preisliste bekommen keinen Seed-Eintrag. Befunde früherer Läufe sind oft längst behoben (Punkt 1) und sollen nicht prominent verlinkt sein. Der Bericht verlinkt sie trotzdem, damit sie im Graphen nicht lose hängen: Nach jedem Lauf bekommt `ABSCHLUSSBERICHT.md` am Ende einen Abschnitt `## Befunddateien dieses Laufs` mit einem Wikilink mit vollem Pfad je Datei unter `findings/`. Der Audit-Skill liegt außerhalb des Vaults und legt die Befunddateien ohne Link ab ([[AI/Regelwerk/navigation|navigation.md]], „Links schreiben und Dateien verschieben“).
|
||||
```
|
||||
|
||||
## Schritt 2 — Stand nachher vergleichen
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/regelwerk-check/regelwerk_check.py --vault D:/Claude > /tmp/regelwerk-nachher.txt; echo "exit=$?"; diff <(grep '^\[' /tmp/regelwerk-vorher.txt) <(grep '^\[' /tmp/regelwerk-nachher.txt) && echo "keine neue Befundzeile"
|
||||
```
|
||||
|
||||
Erwartet: `keine neue Befundzeile`. Zeigt `diff` eine Zeile, die mit `>` beginnt, ist das ein neuer Befund: melden.
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/linkcheck.py --vault D:/Claude --alle > /tmp/linkcheck-nachher.txt; echo "exit=$?"; diff <(grep '^ - ' /tmp/linkcheck-vorher.txt) <(grep '^ - ' /tmp/linkcheck-nachher.txt) && echo "keine neuen toten Links"
|
||||
```
|
||||
|
||||
Erwartet: `keine neuen toten Links`.
|
||||
|
||||
## Schritt 3 — Planablage-Prüfung
|
||||
|
||||
```
|
||||
grep -c "Jede Plandatei verlinkt ihren Hub" D:/Claude/.claude/agents/planer.md; grep -c "### Jede neue Datei hängt an ihrem Hub" D:/Claude/AI/Regelwerk/navigation.md
|
||||
```
|
||||
|
||||
Erwartet: zweimal `1`.
|
||||
|
||||
## Bericht
|
||||
|
||||
Melde die vollständige Ausgabe der Schritte 0 bis 3. Läuft etwas anders als erwartet: nichts anpassen, melden.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,134 @@
|
||||
---
|
||||
type: plan-task
|
||||
title: "Task 05 — Bestandslauf: Probelauf, Halt, echter Lauf nach Freigabe"
|
||||
status: draft
|
||||
summary: "Fährt Zähler und Bestandsskript gegen den echten Vault: Phase A nur Probelauf mit Auszählung und Halt, Phase B erst nach ausdrücklicher Freigabe mit Sicherung außerhalb des Vaults; kein Commit."
|
||||
tags: [plan-task, vault-tools]
|
||||
created: 2026-09-29
|
||||
updated: 2026-09-29
|
||||
modell: sonnet
|
||||
modell_begruendung: "Keine Codeänderung, aber Befehle gegen den echten Vault mit einem harten Halt, einem Datumswert aus der Laufzeit und Ausgaben, die vor dem Weitermachen gelesen werden müssen."
|
||||
---
|
||||
Übersicht: [00-uebersicht.md](00-uebersicht.md)
|
||||
|
||||
# Task 05 — Bestandslauf
|
||||
|
||||
Globale Vorgaben: `00-uebersicht.md` im selben Ordner, Abschnitt „Globale Vorgaben“.
|
||||
|
||||
Voraussetzungen: Tasks 01, 02 und 04 sind umgesetzt und geprüft. Pascal hat die Prüfschritte P1 bis P3 aus der Übersicht in Obsidian beantwortet.
|
||||
|
||||
Der Task hat zwei Phasen. **Phase A** fährst du, wenn der Auftrag „Phase A“ sagt. **Phase B** fährst du nur, wenn im Auftrag wörtlich „Phase B freigegeben“ steht. Steht das nicht da, endet dein Lauf nach Phase A.
|
||||
|
||||
## Zieldateien
|
||||
|
||||
Im Vault und in den Projekt-Repos ändert nur `waisen_bestand.py` selbst Dateien, und nur in Phase B. Du legst von Hand nur an:
|
||||
|
||||
- `D:\Claude-waisen-protokoll\` (neu, außerhalb des Vaults, Ausgaben der Läufe)
|
||||
- `D:\Claude-Sicherung-<Datum>-waisen\` (neu, außerhalb des Vaults, legt das Skript in Phase B selbst an)
|
||||
|
||||
## Verbote
|
||||
|
||||
- Kein Commit, kein `git add`, kein `git stash`, kein `git checkout` in irgendeinem Repo.
|
||||
- Keine Datei im Vault von Hand anfassen, auch nicht, um einen Befund „schnell“ zu beheben.
|
||||
- Phase B nie ohne die wörtliche Freigabe im Auftrag. Bricht ein Lauf ab, nicht wiederholen und nichts zurückkopieren: melden.
|
||||
- Befehle im Bash-Werkzeug, nicht in der PowerShell. Dort schreibt `>` UTF-16.
|
||||
|
||||
## Phase A — Probelauf
|
||||
|
||||
### A1 — Treiber im echten Baum
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/faelle_waisen.py > /dev/null; echo "faelle_waisen exit=$?"; PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/faelle_waisen_bestand.py > /dev/null; echo "faelle_waisen_bestand exit=$?"
|
||||
```
|
||||
|
||||
Erwartet: zweimal `exit=0`. Sonst Halt und melden.
|
||||
|
||||
### A2 — Protokollordner
|
||||
|
||||
```
|
||||
test ! -e D:/Claude-waisen-protokoll && mkdir D:/Claude-waisen-protokoll && echo "angelegt"
|
||||
```
|
||||
|
||||
Erwartet: `angelegt`. Gibt es den Ordner schon, Halt und melden.
|
||||
|
||||
### A3 — Zählung vorher
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/waisen.py --vault D:/Claude --liste > D:/Claude-waisen-protokoll/waisen-vorher.txt; echo "exit=$?"; grep -E '^(Notizen im Graphen|Einträge in userIgnoreFilters|Ausgenommene Waisen|Muster ohne Treffer|Waisen außerhalb)' D:/Claude-waisen-protokoll/waisen-vorher.txt
|
||||
```
|
||||
|
||||
Erwartet: `exit=1` und die Zahlenzeilen. `exit=2` heißt abgebrochen: Halt und melden.
|
||||
|
||||
### A4 — Probelauf
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/waisen_bestand.py --vault D:/Claude > D:/Claude-waisen-protokoll/probelauf.txt; echo "exit=$?"
|
||||
```
|
||||
|
||||
Erwartet: `exit=0`.
|
||||
|
||||
### A5 — Auszählung (Messschritt M3)
|
||||
|
||||
```
|
||||
P=D:/Claude-waisen-protokoll/probelauf.txt; echo "ZIEL gesamt: $(grep -c '^ZIEL ' "$P")"; echo "davon Plan-Uebersichten: $(grep -c '^ZIEL .*/00-uebersicht\.md \[' "$P")"; echo "davon Code Projekte: $(grep -c '^ZIEL Code Projekte/' "$P")"; echo "davon IT Workspace: $(grep -c '^ZIEL IT Workspace/' "$P")"; echo "davon AI/secondbrain: $(grep -c '^ZIEL AI/secondbrain/' "$P")"; echo "UEBERSPRUNGEN: $(grep -c '^UEBERSPRUNGEN ' "$P")"; echo "REST: $(grep -c '^REST ' "$P")"; grep -E '^(Waisen außerhalb|Durch Anhänge)' "$P"
|
||||
```
|
||||
|
||||
### A6 — Stichproben gegen die Verbote
|
||||
|
||||
```
|
||||
P=D:/Claude-waisen-protokoll/probelauf.txt; echo "Taskdateien als Ziel:"; grep -E '^ZIEL .*/task-[^/]*\.md \[' "$P"; echo "Ausnahmen als Ziel:"; grep -E '^ZIEL (Bookstack/|Code Projekte/[^/]*/data/)' "$P"; echo "Ende der Stichprobe"
|
||||
```
|
||||
|
||||
Erwartet: zwischen den Überschriften und `Ende der Stichprobe` steht nichts. Steht dort eine Zeile, Halt und melden.
|
||||
|
||||
### A7 — Halt
|
||||
|
||||
Melde die vollständige Ausgabe von A1 bis A6 und den Pfad `D:/Claude-waisen-protokoll/probelauf.txt`. Dann endet dein Lauf. Den Probelauf liest der Koordinator, die Freigabe für Phase B gibt Pascal.
|
||||
|
||||
## Phase B — echter Lauf, nur mit „Phase B freigegeben“
|
||||
|
||||
### B1 — Vault seit Phase A unverändert?
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/waisen_bestand.py --vault D:/Claude > D:/Claude-waisen-protokoll/probelauf-2.txt; echo "exit=$?"; diff <(grep -E '^(ZIEL | \| |UEBERSPRUNGEN |REST )' D:/Claude-waisen-protokoll/probelauf.txt) <(grep -E '^(ZIEL | \| |UEBERSPRUNGEN |REST )' D:/Claude-waisen-protokoll/probelauf-2.txt) && echo "GLEICH"
|
||||
```
|
||||
|
||||
Erwartet: `exit=0` und `GLEICH`. Zeigt `diff` Unterschiede, hat sich der Vault seit Phase A geändert: Halt, die `diff`-Ausgabe melden, nichts anwenden.
|
||||
|
||||
### B2 — Anwenden
|
||||
|
||||
```
|
||||
S="D:/Claude-Sicherung-$(date +%F)-waisen"; echo "Sicherung: $S"; test ! -e "$S" && PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/waisen_bestand.py --vault D:/Claude --anwenden --sicherung "$S" > D:/Claude-waisen-protokoll/anwenden.txt; echo "exit=$?"
|
||||
```
|
||||
|
||||
Erwartet: die Zeile `Sicherung: D:/Claude-Sicherung-<Datum>-waisen` und `exit=0`. Prüfe, ob das Datum mit dem Sitzungsdatum aus deinem Kontext übereinstimmt, und melde es. Bei `exit=2` die ganze Datei `anwenden.txt` melden, besonders die Zeilen unter `Vor dem Abbruch schon angehängt`, und nichts weiter tun.
|
||||
|
||||
### B3 — Anwenden hat getan, was der Probelauf zeigte
|
||||
|
||||
```
|
||||
diff <(grep -E '^(ZIEL | \| |UEBERSPRUNGEN |REST )' D:/Claude-waisen-protokoll/probelauf-2.txt) <(grep -E '^(ZIEL | \| |UEBERSPRUNGEN |REST )' D:/Claude-waisen-protokoll/anwenden.txt) && echo "GLEICH"; grep -E '^(Angehängt an|Waisen außerhalb der Ausnahmen)' D:/Claude-waisen-protokoll/anwenden.txt
|
||||
```
|
||||
|
||||
Erwartet: `GLEICH`, dazu die Zeilen mit „vorher“ und „nachher“.
|
||||
|
||||
### B4 — Zählung nachher
|
||||
|
||||
```
|
||||
PYTHONIOENCODING=utf-8 python D:/Claude/.vault-tools/linkcheck/waisen.py --vault D:/Claude --liste > D:/Claude-waisen-protokoll/waisen-nachher.txt; echo "exit=$?"; grep '^Waisen außerhalb' D:/Claude-waisen-protokoll/waisen-nachher.txt
|
||||
```
|
||||
|
||||
Erwartet: dieselbe Zahl wie in der Zeile „nachher“ aus B3.
|
||||
|
||||
### B5 — Stand der Projekt-Repos
|
||||
|
||||
Setze `S` auf den Pfad aus B2, Zeile `Sicherung:`, und fahre:
|
||||
|
||||
```
|
||||
cut -d/ -f1-2 "$S/GEAENDERT.txt" | grep '^Code Projekte/' | sort -u | while IFS= read -r r; do echo "== $r"; git -C "D:/Claude/$r" status --short; done
|
||||
```
|
||||
|
||||
Erwartet: je Repo eine Überschrift `== Code Projekte/<projekt>` und darunter nur Zeilen mit ` M` für Dateien aus `GEAENDERT.txt`. Committen tut der Koordinator nach Pascals Ja, je Repo einzeln.
|
||||
|
||||
### B6 — Bericht
|
||||
|
||||
Melde die vollständige Ausgabe von B1 bis B5, den Sicherungspfad und die Pfade der vier Protokolldateien. Nichts committen, nichts zurückkopieren.
|
||||
Reference in new issue
Block a user