Automatischer Push: 11 Datei(en) geändert

- .claude/agents/planer.md
- .claude/workflows/plankritik.js
- .claude/workflows/quorum.js
- .claude/workflows/welle-mit-pruefung.js
- .vault-tools/plan-kopie/LIESMICH.md
- .vault-tools/plan-kopie/plan_bloecke.py
- .vault-tools/plan-kopie/plan_materialisiere.py
- .vault-tools/plan-kopie/plan_zaun_treiber.py
- .vault-tools/workflow-pruefung/LIESMICH.md
- .vault-tools/workflow-pruefung/faelle_workflows.mjs
- .vault-tools/workflow-pruefung/mutanten_workflows.py

Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Pascal MichelandClaude Opus 5 committed 2026-11-03 03:00:01 +01:00
1 parent 7f484f9be5
commit 22761eb186
11 files changed
+1520 -65

No files matched your search

+52 -8
View File
@@ -19,12 +19,35 @@ export const meta = {
// Verbrauch: Vor und nach der Prüfung liest dieser Workflow den Planverbrauch über verbrauch.js
// ab (nur messen); das Kind pruefung bekommt verbrauch: false, weil ein Kind keinen weiteren
// Workflow aufrufen kann.
// Planbefund (seit 2026-11-02): Meldet plan_materialisiere.py in der Phase Kopie einen Befund, also
// eine Zeile "BEFUND <taskdatei>:<zeile>:" (Exit 2, nach einem Absturz auch 1), startet keine Welle.
// Der Lauf endet vor executer-welle mit status plan_befund und den Zeilen in plan_befunde, ohne
// Vergleich, Prüfung und Ablesung. Vorher lief die Welle trotzdem, nur ohne Byte-Vergleich. Exit 2
// ohne eine solche Zeile ist ein gescheitertes Werkzeug (python endet auch bei "can't open file"
// mit 2) und nimmt den alten Weg, ebenso die BEFUND-Zeilen von kopie_bauen.py: Sie tragen keine
// Zeilennummer.
const MODELLE = ['haiku', 'sonnet', 'opus']
const EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max']
const VERBRAUCH = 'D:/Claude/.claude/workflows/verbrauch.js'
// Einfache Anführungszeichen: In Bash bleiben darin $, Backtick und Backslash wörtlich.
const q = s => "'" + String(s).replace(/'/g, "'\\''") + "'"
const PY = 'PYTHONIOENCODING=utf-8 python -X utf8'
// Befundzeile der Planwerkzeuge: "BEFUND <datei>:<zeile>:", bei plan_zeichen "<datei>:<zeile>:<spalte>:".
const BEFUNDZEILE = /^BEFUND [^\s:]+:\d+:/
const befundZeilen = text => String(text || '').split('\n').map(z => z.replace(/\r$/, '')).filter(z => BEFUNDZEILE.test(z))
// Ein Hilfsagent darf seine Ausgabe auf mehrere laeufe verteilen (Echtlauf wf_9ab7fd8e-ad1 am
// 2026-11-02: je Werkzeug ein Lauf). Jede Ausgabe eines Hilfsagenten wird deshalb über alle laeufe
// gelesen, in ihrer Reihenfolge und mit Zeilenumbruch verbunden: Befundzeilen, KOPIE-Zeile und
// angewendete Blöcke der Kopie, die Rohausgabe des Vergleichs. Sonst stünde ein Befund in laeufe[1],
// und die Welle liefe trotzdem.
const ausgabeAller = r => (r && Array.isArray(r.laeufe) ? r.laeufe : []).map(l => String((l && l.ausgabe) || '')).join('\n')
// Exit über alle laeufe: Der Befehl der Kopie ist eine Kette mit &&, sie endet nur mit 0, wenn jedes
// Glied mit 0 endet. Verwendbar ist die Kopie deshalb nur, wenn jeder Lauf Exit 0 hat; ein Lauf ohne
// Exit zählt nicht als 0 und steht im Log als undefined. Mit laeufe[0] allein galt ein erster Lauf
// mit 0 vor einem Absturz im zweiten als fertige Kopie.
const exitsAller = r => (r && Array.isArray(r.laeufe) ? r.laeufe : []).map(l => l && l.exit)
const alleExitNull = r => exitsAller(r).length > 0 && exitsAller(r).every(x => x === 0)
const tempHinweis = t => t ? `${t} bleibt liegen (Projektkopie ohne die Ausschlüsse); löschen, wenn der Diff nicht mehr gebraucht wird` : null
const LAUF = {
type: 'object',
@@ -98,12 +121,32 @@ if (!kopie) {
const befehl = `T=$(mktemp -d) && echo "KOPIE=$(cygpath -m "$T/mat")" && ${PY} ${q(W + '/kopie_bauen.py')} ${q(args.projekt)} "$T/mat" --ohne ${args.ohne.map(q).join(' ')} && ${PY} ${q(W + '/plan_materialisiere.py')} ${q(args.planordner)} "$T/mat" ${taskdateien.map(q).join(' ')}`
const r = await werkzeugAgent('werkzeug:kopie', 'Kopie', befehl, 'Stand vor der Welle kopieren und die Taskdateien der Welle darauf anwenden', 'haiku')
belege.kopie = r
const lauf = r && r.laeufe && r.laeufe[0]
const m = lauf && /^KOPIE=(.+?)\s*$/m.exec(lauf.ausgabe)
const aus = ausgabeAller(r)
const m = /^KOPIE=(.+?)\s*$/m.exec(aus)
if (m) temp = m[1].replace(/\/mat$/, '')
const angewendet = lauf && /'(neu|ersetzt|angehaengt)': [1-9]/.test(lauf.ausgabe)
if (lauf && lauf.exit === 0 && m && angewendet) kopie = m[1]
else log('Kopie nicht verwendbar (' + (!lauf ? 'Hilfsagent ohne Ergebnis' : lauf.exit !== 0 ? 'Exit ' + lauf.exit : !m ? 'kein KOPIE-Pfad' : 'kein Block angewendet') + '); der Byte-Vergleich entfällt, die Welle läuft trotzdem')
const planBefunde = befundZeilen(aus)
if (planBefunde.length) {
const grund = `plan_materialisiere.py meldet ${planBefunde.length} Befund(e) (Exit ${exitsAller(r).map(String).join('/')}); die Welle startet nicht`
log('Kopie: ' + grund)
return {
status: 'plan_befund',
plan_befunde: planBefunde,
kopie: null,
temp_ordner: tempHinweis(temp),
welle: null,
vergleich: null,
kopie_lauf: r,
pruefung: { uebersprungen: grund },
pruefung_args: null,
pruefung_grund: grund,
fehler,
verbrauch: ablesungen,
naechster_schritt: 'Den Plan an den Zeilen in plan_befunde korrigieren und welle-mit-pruefung neu starten. Kein Executer ist gelaufen.' + (temp ? ' Die Kopie unter temp_ordner löschen.' : ''),
}
}
const angewendet = /'(neu|ersetzt|angehaengt)': [1-9]/.test(aus)
if (alleExitNull(r) && m && angewendet) kopie = m[1]
else log('Kopie nicht verwendbar (' + (!exitsAller(r).length ? 'Hilfsagent ohne Ergebnis' : !alleExitNull(r) ? 'Exit ' + exitsAller(r).map(String).join('/') :!m ? 'kein KOPIE-Pfad' : 'kein Block angewendet') + '); der Byte-Vergleich entfällt, die Welle läuft trotzdem')
}
phase('Welle')
@@ -136,8 +179,9 @@ if (!welle) pruefungGrund = 'keine Welle'
else if (welle.ohne_bericht && welle.ohne_bericht.length) pruefungGrund = 'Welle unvollständig, ohne Bericht: ' + welle.ohne_bericht.join(', ')
let pruefungArgs = null
if (!pruefungGrund) {
const vl = belege.vergleich && belege.vergleich.laeufe && belege.vergleich.laeufe[0]
const vergleichstext = vl ? kopfUndEnde(vl.ausgabe, 1500, 2500) : ''
// Anfang und Ende des verbundenen Texts wie bei einem Lauf. Liefert der Hilfsagent die Suite vor
// einem langen Vergleich, fällt ihr Ergebnis heraus (benannte Lücke; der pruefer fährt die Suite selbst).
const vergleichstext = kopfUndEnde(ausgabeAller(belege.vergleich), 1500, 2500)
const schwerpunkt = [
args.schwerpunkt || '',
welle.mit_abweichung.length ? `Diese Tasks melden Abweichungen vom Plan: ${welle.mit_abweichung.join(', ')}.` : '',
@@ -149,7 +193,7 @@ if (!pruefungGrund) {
}
}
const tempText = temp ? `${temp} bleibt liegen (Projektkopie ohne die Ausschlüsse); löschen, wenn der Diff nicht mehr gebraucht wird` : null
const tempText = tempHinweis(temp)
if (args.bis === 'vergleich') {
if (pruefungGrund) log('Prüfung wäre übersprungen worden: ' + pruefungGrund)