Automatischer Push: 6 Datei(en) geändert
- .claude/workflows/verbrauch.js - .vault-tools/workflow-pruefung/LIESMICH.md - .vault-tools/workflow-pruefung/docs/plans/2026-10-16-ableser-abweichung/00-uebersicht.md - .vault-tools/workflow-pruefung/docs/plans/2026-10-16-ableser-abweichung/task-01-erkennung.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:
1 parent
5c997a23e2
commit
07675bf541
6 files changed
+309
-4
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
name: 'verbrauch',
|
name: 'verbrauch',
|
||||||
description: 'Liest den Planverbrauch (5-Stunden-Fenster, Woche) über get_usage und rechnet daraus, wie viele Opus-Agenten gleichzeitig laufen dürfen',
|
description: 'Liest den Planverbrauch (5-Stunden-Fenster, Woche) über get_usage und rechnet daraus, wie viele Opus-Agenten gleichzeitig laufen dürfen',
|
||||||
whenToUse: 'Vor jeder Opus-Staffel eines Workflows, als Kind aufgerufen: workflow({ scriptPath: "D:/Claude/.claude/workflows/verbrauch.js" }, { anlass, wunsch }). Args: {anlass, wunsch: ganze Zahl ab 0, probe?}. wunsch 0 heißt nur messen. Rückgabe {status: ok|nicht_gelesen|unbekannte_fenster, quelle, fuenf_stunden, woche, woche_opus, plaetze, gebremst, grund, fenster}. Ohne lesbare Ablesung gilt die alte Obergrenze zwei. Regel: AI/Regelwerk/codeworkflow.md, "Verbrauch und Opus-Plätze".',
|
whenToUse: 'Vor jeder Opus-Staffel eines Workflows, als Kind aufgerufen: workflow({ scriptPath: "D:/Claude/.claude/workflows/verbrauch.js" }, { anlass, wunsch }). Args: {anlass, wunsch: ganze Zahl ab 0, probe?}. wunsch 0 heißt nur messen. Rückgabe {status: ok|nicht_gelesen|abgewichen|unbekannte_fenster, quelle, fuenf_stunden, woche, woche_opus, plaetze, gebremst, grund, fenster}. Ohne lesbare Ablesung gilt die alte Obergrenze zwei; abgewichen heißt, der Ableser hat statt get_usage etwas anderes getan, und kommt mit einer WARNUNG im Log. Regel: AI/Regelwerk/codeworkflow.md, "Verbrauch und Opus-Plätze".',
|
||||||
phases: [{ title: 'Verbrauch', detail: 'ein Haiku-Agent liest get_usage ab, das Skript entscheidet' }],
|
phases: [{ title: 'Verbrauch', detail: 'ein Haiku-Agent liest get_usage ab, das Skript entscheidet' }],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,6 +16,15 @@ export const meta = {
|
|||||||
// - Die Stufen: Projektvorgabe, vorläufig (Pascal, 2026-09-24). Sie stehen nur hier und werden
|
// - Die Stufen: Projektvorgabe, vorläufig (Pascal, 2026-09-24). Sie stehen nur hier und werden
|
||||||
// nach der Messreihe mit .vault-tools/workflow-pruefung/verbrauch_reihe.py nachgestellt.
|
// nach der Messreihe mit .vault-tools/workflow-pruefung/verbrauch_reihe.py nachgestellt.
|
||||||
// - Ohne lesbare Ablesung: Projektvorgabe, die bisherige Stammregel von zwei Opus-Agenten.
|
// - Ohne lesbare Ablesung: Projektvorgabe, die bisherige Stammregel von zwei Opus-Agenten.
|
||||||
|
// - Ob der Ableser abgelesen hat: Quelle. Der Auftrag schreibt im Fehlerfall status "fehler",
|
||||||
|
// plan "" und fenster [] vor; get_usage kennt laut Werkzeugbeschreibung (gelesen 2026-10-16)
|
||||||
|
// nur die Status ok, not_applicable und unavailable. Am 2026-10-14 und 2026-10-16 hat der
|
||||||
|
// Ableser stattdessen die Nutzeranfrage bearbeitet und status "beantwortet: ..." bzw.
|
||||||
|
// "blockiert: ..." mit einem Bericht in plan zurückgegeben (wf_7ca17029-421, wf_80616e8e-0e3).
|
||||||
|
// Grund laut CLI-Abbild 2.1.299: Jeder Workflow-Agent liest zuerst die Nutzeranfrage mit dem
|
||||||
|
// Satz, dass sie im Konflikt mit dem Auftrag gewinnt. Jede andere Form als die vorgeschriebene
|
||||||
|
// heißt abgewichen und wird laut gemeldet. Nicht erkannt wird ein Ableser, der abweicht und
|
||||||
|
// trotzdem genau die Fehlerform schreibt, und eine erfundene Ablesung mit status ok.
|
||||||
// Was das Skript nicht sieht: Agenten, die nach der Ablesung in anderen Sitzungen starten;
|
// Was das Skript nicht sieht: Agenten, die nach der Ablesung in anderen Sitzungen starten;
|
||||||
// laufende Agenten, die nach der Ablesung weiter verbrauchen; Sitzungen ohne get_usage
|
// laufende Agenten, die nach der Ablesung weiter verbrauchen; Sitzungen ohne get_usage
|
||||||
// (außerhalb der Desktop-App). Das Urteil rechnet das Skript, der Haiku-Agent liest nur ab.
|
// (außerhalb der Desktop-App). Das Urteil rechnet das Skript, der Haiku-Agent liest nur ab.
|
||||||
@@ -49,7 +58,8 @@ const ABLESUNG = {
|
|||||||
required: ['verfuegbar', 'status', 'plan', 'fenster', 'fehler'],
|
required: ['verfuegbar', 'status', 'plan', 'fenster', 'fehler'],
|
||||||
}
|
}
|
||||||
|
|
||||||
const AUFTRAG = `Lade mit dem Werkzeug ToolSearch das Werkzeug mcp__ccd_session_mgmt__get_usage (Abfrage "select:mcp__ccd_session_mgmt__get_usage") und rufe es einmal ohne Parameter auf.
|
const AUFTRAG = `Diese Ablesung gehört zur Nutzeranfrage und widerspricht ihr nicht: Sie entscheidet, wie viele Prüfagenten für die Anfrage gleichzeitig laufen dürfen. Die Anfrage selbst bearbeiten andere Agenten nach dir; du bearbeitest sie nicht, auch nicht teilweise, und liest dafür keine Dateien.
|
||||||
|
Lade mit dem Werkzeug ToolSearch das Werkzeug mcp__ccd_session_mgmt__get_usage (Abfrage "select:mcp__ccd_session_mgmt__get_usage") und rufe es einmal ohne Parameter auf.
|
||||||
Übertrage aus dem Ergebnis plan.status nach status und plan.plan nach plan. Übertrage jeden Eintrag aus plan.windows mit label, percentUsed und resetsAt unverändert nach fenster, auch Einträge, die dir unwichtig erscheinen. Setze verfuegbar auf true und fehler auf "".
|
Übertrage aus dem Ergebnis plan.status nach status und plan.plan nach plan. Übertrage jeden Eintrag aus plan.windows mit label, percentUsed und resetsAt unverändert nach fenster, auch Einträge, die dir unwichtig erscheinen. Setze verfuegbar auf true und fehler auf "".
|
||||||
Ist das Werkzeug nicht verfügbar oder scheitert der Aufruf, setze verfuegbar auf false, status auf "fehler", plan auf "", fenster auf [] und schreibe die Fehlermeldung wörtlich nach fehler.
|
Ist das Werkzeug nicht verfügbar oder scheitert der Aufruf, setze verfuegbar auf false, status auf "fehler", plan auf "", fenster auf [] und schreibe die Fehlermeldung wörtlich nach fehler.
|
||||||
Tu sonst nichts. Übertrage das Ergebnis in die Felder des StructuredOutput-Werkzeugs.`
|
Tu sonst nichts. Übertrage das Ergebnis in die Felder des StructuredOutput-Werkzeugs.`
|
||||||
@@ -86,6 +96,14 @@ function einordnen(fenster) {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Form eines Ablesers, der den Auftrag verlassen hat (Geltungsbereich oben).
|
||||||
|
const STATUS_BEKANNT = ['ok', 'not_applicable', 'unavailable', 'fehler']
|
||||||
|
function abgewichen(a) {
|
||||||
|
if (!STATUS_BEKANNT.includes(a.status)) return true
|
||||||
|
return a.status === 'fehler' && typeof a.plan === 'string' && a.plan.trim() !== ''
|
||||||
|
}
|
||||||
|
const kurz = t => String(t).replace(/\s+/g, ' ').trim().slice(0, 160)
|
||||||
|
|
||||||
pruefeArgs(args)
|
pruefeArgs(args)
|
||||||
phase('Verbrauch')
|
phase('Verbrauch')
|
||||||
const wunsch = args.wunsch
|
const wunsch = args.wunsch
|
||||||
@@ -104,6 +122,10 @@ function ohneAblesung(status, grund) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ablesung || typeof ablesung !== 'object') return ohneAblesung('nicht_gelesen', 'kein Ergebnis vom Ableseagenten')
|
if (!ablesung || typeof ablesung !== 'object') return ohneAblesung('nicht_gelesen', 'kein Ergebnis vom Ableseagenten')
|
||||||
|
if (abgewichen(ablesung)) {
|
||||||
|
log(`WARNUNG Verbrauch ${args.anlass}: Der Ableser hat get_usage nicht gelesen und den Auftrag verlassen; die Bremse misst nicht. Seine Werkzeugaufrufe im Journal unter ▸ verbrauch ansehen.`)
|
||||||
|
return ohneAblesung('abgewichen', `Ableser hat den Auftrag verlassen: status ${kurz(ablesung.status)}${ablesung.fehler ? ', fehler ' + kurz(ablesung.fehler) : ''}`)
|
||||||
|
}
|
||||||
if (ablesung.verfuegbar !== true || ablesung.status !== 'ok') return ohneAblesung('nicht_gelesen', `get_usage: verfuegbar ${ablesung.verfuegbar}, status ${ablesung.status}${ablesung.fehler ? ', ' + ablesung.fehler : ''}`)
|
if (ablesung.verfuegbar !== true || ablesung.status !== 'ok') return ohneAblesung('nicht_gelesen', `get_usage: verfuegbar ${ablesung.verfuegbar}, status ${ablesung.status}${ablesung.fehler ? ', ' + ablesung.fehler : ''}`)
|
||||||
const e = einordnen(ablesung.fenster)
|
const e = einordnen(ablesung.fenster)
|
||||||
if (e.fehler) return ohneAblesung('unbekannte_fenster', e.fehler)
|
if (e.fehler) return ohneAblesung('unbekannte_fenster', e.fehler)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ title: "Workflow-Prüfung: Attrappe, Fälle und Messreihe zum Verbrauch"
|
|||||||
summary: "Node-Attrappe für die gespeicherten Workflows des Vaults mit Fällen je Workflow, dazu verbrauch_reihe.py, das aus den Workflow-Protokollen rechnet, wie viel vom 5-Stunden-Fenster und von der Woche zwischen zwei Verbrauchsablesungen verbraucht wurde. Entstanden 2026-09-24."
|
summary: "Node-Attrappe für die gespeicherten Workflows des Vaults mit Fällen je Workflow, dazu verbrauch_reihe.py, das aus den Workflow-Protokollen rechnet, wie viel vom 5-Stunden-Fenster und von der Woche zwischen zwei Verbrauchsablesungen verbraucht wurde. Entstanden 2026-09-24."
|
||||||
tags: [vault-tools, codeworkflow]
|
tags: [vault-tools, codeworkflow]
|
||||||
created: 2026-09-24
|
created: 2026-09-24
|
||||||
updated: 2026-09-24
|
updated: 2026-10-16
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow-Prüfung
|
# Workflow-Prüfung
|
||||||
@@ -16,7 +16,7 @@ Die Regel dazu steht in [[AI/Regelwerk/codeworkflow|codeworkflow.md]], Abschnitt
|
|||||||
|
|
||||||
1. **Nach jeder Änderung an einem Workflow unter `.claude/workflows/`:** `node .vault-tools/workflow-pruefung/faelle_workflows.mjs` im Vault-Wurzelordner. Mit einem Ordner als Argument prüft das Skript die Workflows dort, etwa eine Kopie mit angewendetem Plan. Jeder Workflow hat zuerst eine Grundlinie; scheitert sie, messen seine übrigen Fälle nichts.
|
1. **Nach jeder Änderung an einem Workflow unter `.claude/workflows/`:** `node .vault-tools/workflow-pruefung/faelle_workflows.mjs` im Vault-Wurzelordner. Mit einem Ordner als Argument prüft das Skript die Workflows dort, etwa eine Kopie mit angewendetem Plan. Jeder Workflow hat zuerst eine Grundlinie; scheitert sie, messen seine übrigen Fälle nichts.
|
||||||
2. **Ein neuer Fall braucht einen Rotlauf.** Die Fälle gegen den Stand vor der Änderung fahren, oder den Mutanten nachstellen, den der Fall fangen soll. Grün allein belegt nichts.
|
2. **Ein neuer Fall braucht einen Rotlauf.** Die Fälle gegen den Stand vor der Änderung fahren, oder den Mutanten nachstellen, den der Fall fangen soll. Grün allein belegt nichts.
|
||||||
3. **Mutanten:** `python .vault-tools/workflow-pruefung/mutanten_workflows.py` (einige Minuten) und `python .vault-tools/workflow-pruefung/mutanten_reihe.py`. Ein veraltetes Muster bricht mit Exit 2 ab und muss an den neuen Code angepasst werden; ein wirkungsloser Mutant steht mit Grund in `WIRKUNGSLOS`. Wer einen Workflow ändert, ergänzt hier den Mutanten, den sein neuer Fall fangen soll.
|
3. **Mutanten:** `python .vault-tools/workflow-pruefung/mutanten_workflows.py` (am 2026-10-16 knapp 50 Minuten, im Hintergrund fahren) und `python .vault-tools/workflow-pruefung/mutanten_reihe.py`. Ein veraltetes Muster bricht mit Exit 2 ab und muss an den neuen Code angepasst werden; ein wirkungsloser Mutant steht mit Grund in `WIRKUNGSLOS`. Wer einen Workflow ändert, ergänzt hier den Mutanten, den sein neuer Fall fangen soll.
|
||||||
4. **Messreihe:** `python .vault-tools/workflow-pruefung/verbrauch_reihe.py [--seit JJJJ-MM-TT]`. Die Ausgabe ist eine Tabelle je Paar aufeinanderfolgender Ablesungen eines Laufs: Minuten, Agentenminuten je Modellfamilie, Differenz im 5-Stunden-Fenster und in der Woche. Darunter steht eine Näherung in Prozent des 5-Stunden-Fensters je Opus-Agentenstunde. Ein `Reset` zwischen zwei Ablesungen zählt nicht mit.
|
4. **Messreihe:** `python .vault-tools/workflow-pruefung/verbrauch_reihe.py [--seit JJJJ-MM-TT]`. Die Ausgabe ist eine Tabelle je Paar aufeinanderfolgender Ablesungen eines Laufs: Minuten, Agentenminuten je Modellfamilie, Differenz im 5-Stunden-Fenster und in der Woche. Darunter steht eine Näherung in Prozent des 5-Stunden-Fensters je Opus-Agentenstunde. Ein `Reset` zwischen zwei Ablesungen zählt nicht mit.
|
||||||
|
|
||||||
## Was die Attrappe nachbildet
|
## Was die Attrappe nachbildet
|
||||||
@@ -39,6 +39,8 @@ Stand 2026-09-24 nach Plankritik, Prüfung und Nachbesserung. Die Zahlen gelten
|
|||||||
- **Neue `planung.js` im echten Laufzeitsystem** (wf_5df09faa-a4d, Probe mit drei Tasks im Scratchpad): Task 1 lief allein, Task 2 und 3 starteten erst nach seinem Ende und liefen gleichzeitig; beide übernahmen die Zieldatei-Zeile aus Task 1, haben seine Taskdatei also gelesen.
|
- **Neue `planung.js` im echten Laufzeitsystem** (wf_5df09faa-a4d, Probe mit drei Tasks im Scratchpad): Task 1 lief allein, Task 2 und 3 starteten erst nach seinem Ende und liefen gleichzeitig; beide übernahmen die Zieldatei-Zeile aus Task 1, haben seine Taskdatei also gelesen.
|
||||||
- **Erster Eichwert** am Abend des 2026-09-24, Plan laut App „Pro“: `verbrauch_reihe.py --seit 2026-09-24` ergab 8,1 % des 5-Stunden-Fensters je Opus-Agentenstunde (5 Paare, 1,7 Opus-Stunden, darunter ein Plankritik-Lauf der Trading-Sitzung). Die Woche stieg in denselben Paaren um 5 Punkte. Der Verbrauch anderer Sitzungen und der Hauptsitzung steckt mit drin; die Zahl ist also eher zu hoch. Für das Nachstellen der Stufen reicht ein Abend nicht.
|
- **Erster Eichwert** am Abend des 2026-09-24, Plan laut App „Pro“: `verbrauch_reihe.py --seit 2026-09-24` ergab 8,1 % des 5-Stunden-Fensters je Opus-Agentenstunde (5 Paare, 1,7 Opus-Stunden, darunter ein Plankritik-Lauf der Trading-Sitzung). Die Woche stieg in denselben Paaren um 5 Punkte. Der Verbrauch anderer Sitzungen und der Hauptsitzung steckt mit drin; die Zahl ist also eher zu hoch. Für das Nachstellen der Stufen reicht ein Abend nicht.
|
||||||
|
|
||||||
|
- **Ableser verlässt den Auftrag** (2026-10-16, Plan `docs/plans/2026-10-16-ableser-abweichung/`): Zweimal bearbeitete der Haiku-Ableser die Nutzeranfrage statt `get_usage` zu lesen und schrieb seine Antwort in `status` und `plan` (wf_7ca17029-421, wf_80616e8e-0e3). `verbrauch.js` meldet diese Form jetzt als `status: abgewichen` mit einer Logzeile, die mit `WARNUNG` beginnt; Plätze wie ohne Ablesung. Neun neue Fälle, sieben davon gegen den alten Stand rot; die zwei Gegenproben (ehrlicher Fehlschlag, `not_applicable`) bleiben auf beiden Ständen grün. Acht neue Mutanten, alle gefangen; der volle Mutantenlauf brauchte knapp 50 Minuten. Die drei echten Antworten aus den Journalen ergaben `abgewichen`, `abgewichen` und `nicht_gelesen`. **Ungemessen:** ob der neue Brückensatz im Auftrag einen echten Ableser vom Abweichen abhält; der Fall misst nur, dass der Satz dasteht. Ein abweichender Ableser hat weiterhin alle Werkzeuge.
|
||||||
|
|
||||||
**Offen:** Die Trading-Sitzung hat `plankritik.js` am 2026-09-24 nach einem echten Lauf nachgebessert (Ausgabe der Planwerkzeuge nur bei `EXIT 0`). Für diese Stelle gibt es noch keinen Fall.
|
**Offen:** Die Trading-Sitzung hat `plankritik.js` am 2026-09-24 nach einem echten Lauf nachgebessert (Ausgabe der Planwerkzeuge nur bei `EXIT 0`). Für diese Stelle gibt es noch keinen Fall.
|
||||||
|
|
||||||
## Was die Skripte nicht sehen
|
## Was die Skripte nicht sehen
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
type: plan
|
||||||
|
title: "verbrauch.js: Ableser, der den Auftrag verlässt, erkennen und laut melden"
|
||||||
|
status: active
|
||||||
|
summary: "Nach dem Plan erkennt verbrauch.js an status und plan, dass der Haiku-Ableser statt get_usage die Nutzeranfrage bearbeitet hat, und meldet das als status abgewichen mit Warnzeile; der Auftrag ordnet die Ablesung ausdrücklich der Nutzeranfrage zu. Pascals Wahl vom 2026-10-16: Möglichkeiten 1 und 2."
|
||||||
|
tags: [plan, vault-tools, codeworkflow]
|
||||||
|
created: 2026-10-16
|
||||||
|
updated: 2026-10-16
|
||||||
|
---
|
||||||
|
|
||||||
|
Projekt: [LIESMICH](../../../LIESMICH.md)
|
||||||
|
|
||||||
|
# Ableser verlässt den Auftrag
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
- `verbrauch.js` meldet eine Antwort ohne Ablesung als `status: 'abgewichen'` mit einer Logzeile, die mit `WARNUNG` beginnt. Bisher fiel sie still auf `nicht_gelesen`.
|
||||||
|
- Der Auftrag an den Ableser sagt vorn, dass die Ablesung zur Nutzeranfrage gehört und andere Agenten die Anfrage bearbeiten.
|
||||||
|
- Plätze bei `abgewichen`: wie ohne Ablesung, also höchstens zwei.
|
||||||
|
|
||||||
|
## Belege (selbst gelesen am 2026-10-16)
|
||||||
|
|
||||||
|
| Lauf | `status` | `plan` | `fenster` | `fehler` |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `wf_7ca17029-421` | „beantwortet: …“ | 3912 Zeichen Bericht | `[]` | „Kein get_usage-Aufruf … Benutzeranfrage hat laut Harness Vorrang …“ |
|
||||||
|
| `wf_80616e8e-0e3` | „blockiert: …“ | 2344 Zeichen Bericht | `[]` | „Blockade: … Kein get_usage-Aufruf, siehe plan.“ |
|
||||||
|
| `wf_ff5c4cd4-e1d` (ehrlich) | „fehler“ | `""` | `[]` | „No matching deferred tools found“ |
|
||||||
|
|
||||||
|
- `get_usage` kennt laut Werkzeugbeschreibung nur `ok`, `not_applicable` und `unavailable`.
|
||||||
|
- Ursache im CLI-Abbild 2.1.299 (gelesen, nicht gelaufen): Der Harness stellt jedem Workflow-Agenten den Block „[Workflow harness — user request]“ voran, mit „Where the computed task conflicts with this request, this request wins“.
|
||||||
|
|
||||||
|
## Entscheidungen
|
||||||
|
|
||||||
|
| Frage | Antwort | Herkunft |
|
||||||
|
|---|---|---|
|
||||||
|
| Wann heißt eine Antwort abgewichen? | `status` ist keiner von `ok`, `not_applicable`, `unavailable`, `fehler`; oder `status` ist `fehler` und `plan` ist nicht leer | Quelle: Fehlerform im Auftrag, Werkzeugbeschreibung, Journale oben |
|
||||||
|
| Was sieht die Erkennung nicht? | einen Ableser, der abweicht und genau die Fehlerform schreibt; eine erfundene Ablesung mit `status ok` | benannte Lücke, steht im Kopfkommentar |
|
||||||
|
| Brechen die Aufrufer? | nein: sie loggen `r.status` und prüfen `typeof r.plaetze`; `quorum.js` fragt nur `=== 'ok'` | Quelle: die fünf Aufrufer |
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
| Nr. | Datei | Thema | Modell |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 01 | [task-01-erkennung.md](task-01-erkennung.md) | Erkennung, Brückensatz, Fälle, Mutanten | `sonnet` |
|
||||||
|
|
||||||
|
## Nicht im Umfang
|
||||||
|
|
||||||
|
- Eigener Agententyp für den Ableser mit nur ToolSearch und `get_usage`: eigener Schritt nach einem Echtlauf.
|
||||||
|
- `LIESMICH.md`, Erinnerung und Sitzungsprotokoll schreibt der Koordinator.
|
||||||
|
- Kein Commit. Im Vault-Repo committet nur Pascal oder die Aufgabe um 04:00.
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
---
|
||||||
|
type: plan-task
|
||||||
|
title: "Task 01 — verbrauch.js: Abweichung erkennen, Brückensatz, Fälle und Mutanten"
|
||||||
|
status: draft
|
||||||
|
summary: "verbrauch.js bekommt den Brückensatz im Auftrag, die Erkennung abgewichen mit Warnzeile und den neuen Status in meta; faelle_workflows.mjs bekommt die Fälle dazu, mutanten_workflows.py die Mutanten. Alles in Kopien im Scratchpad."
|
||||||
|
tags: [plan-task, vault-tools, codeworkflow]
|
||||||
|
created: 2026-10-16
|
||||||
|
updated: 2026-10-16
|
||||||
|
modell: sonnet
|
||||||
|
modell_begruendung: "verbrauch.js ist Abschrift, die Fälle sind nur als Eingabe und Erwartung vorgegeben und brauchen Autorschaft."
|
||||||
|
---
|
||||||
|
|
||||||
|
Übersicht: [00-uebersicht.md](00-uebersicht.md)
|
||||||
|
|
||||||
|
# Task 01 — Abweichung erkennen
|
||||||
|
|
||||||
|
## Arbeitsorte
|
||||||
|
|
||||||
|
`S` ist `D:/ClaudeData/claude/D--Claude/8a6a0a87-ddcf-462b-90e2-83ab3ba2be28/scratchpad`. Du schreibst **nur** diese drei Dateien:
|
||||||
|
|
||||||
|
- `S/wf-neu/verbrauch.js` (Kopie von `D:/Claude/.claude/workflows/verbrauch.js`)
|
||||||
|
- `S/wp-neu/faelle_workflows.mjs` (Kopie aus `D:/Claude/.vault-tools/workflow-pruefung/`)
|
||||||
|
- `S/wp-neu/mutanten_workflows.py` (Kopie, ebenda)
|
||||||
|
|
||||||
|
Nichts unter `D:/Claude/` anfassen. Keine Hilfsdateien. Kein Commit.
|
||||||
|
|
||||||
|
## 1 verbrauch.js
|
||||||
|
|
||||||
|
Ersetze genau diese Stellen, Zeichen für Zeichen. Die Datei hat LF-Zeilenenden; behalte sie.
|
||||||
|
|
||||||
|
**1a, in `meta.whenToUse`:** `Rückgabe {status: ok|nicht_gelesen|unbekannte_fenster,` wird zu `Rückgabe {status: ok|nicht_gelesen|abgewichen|unbekannte_fenster,`. Und `Ohne lesbare Ablesung gilt die alte Obergrenze zwei.` wird zu `Ohne lesbare Ablesung gilt die alte Obergrenze zwei; abgewichen heißt, der Ableser hat statt get_usage etwas anderes getan, und kommt mit einer WARNUNG im Log.`
|
||||||
|
|
||||||
|
**1b, Kopfkommentar:** Vor der Zeile `// Was das Skript nicht sieht: Agenten, die nach der Ablesung in anderen Sitzungen starten;` kommen diese Zeilen:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// - Ob der Ableser abgelesen hat: Quelle. Der Auftrag schreibt im Fehlerfall status "fehler",
|
||||||
|
// plan "" und fenster [] vor; get_usage kennt laut Werkzeugbeschreibung (gelesen 2026-10-16)
|
||||||
|
// nur die Status ok, not_applicable und unavailable. Am 2026-10-14 und 2026-10-16 hat der
|
||||||
|
// Ableser stattdessen die Nutzeranfrage bearbeitet und status "beantwortet: ..." bzw.
|
||||||
|
// "blockiert: ..." mit einem Bericht in plan zurückgegeben (wf_7ca17029-421, wf_80616e8e-0e3).
|
||||||
|
// Grund laut CLI-Abbild 2.1.299: Jeder Workflow-Agent liest zuerst die Nutzeranfrage mit dem
|
||||||
|
// Satz, dass sie im Konflikt mit dem Auftrag gewinnt. Jede andere Form als die vorgeschriebene
|
||||||
|
// heißt abgewichen und wird laut gemeldet. Nicht erkannt wird ein Ableser, der abweicht und
|
||||||
|
// trotzdem genau die Fehlerform schreibt, und eine erfundene Ablesung mit status ok.
|
||||||
|
```
|
||||||
|
|
||||||
|
**1c, Auftrag:** Die erste Zeile des Template-Strings `AUFTRAG` ist bisher `const AUFTRAG = \`Lade mit dem Werkzeug ToolSearch ...`. Davor, als neue erste Zeile im String, kommt dieser Satz; der Rest bleibt unverändert:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const AUFTRAG = `Diese Ablesung gehört zur Nutzeranfrage und widerspricht ihr nicht: Sie entscheidet, wie viele Prüfagenten für die Anfrage gleichzeitig laufen dürfen. Die Anfrage selbst bearbeiten andere Agenten nach dir; du bearbeitest sie nicht, auch nicht teilweise, und liest dafür keine Dateien.
|
||||||
|
Lade mit dem Werkzeug ToolSearch das Werkzeug mcp__ccd_session_mgmt__get_usage (Abfrage "select:mcp__ccd_session_mgmt__get_usage") und rufe es einmal ohne Parameter auf.
|
||||||
|
```
|
||||||
|
|
||||||
|
**1d, Erkennung:** Direkt nach der Funktion `einordnen` (nach ihrer schließenden `}` und vor der Leerzeile, auf die `pruefeArgs(args)` folgt) kommt:
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
// Form eines Ablesers, der den Auftrag verlassen hat (Geltungsbereich oben).
|
||||||
|
const STATUS_BEKANNT = ['ok', 'not_applicable', 'unavailable', 'fehler']
|
||||||
|
function abgewichen(a) {
|
||||||
|
if (!STATUS_BEKANNT.includes(a.status)) return true
|
||||||
|
return a.status === 'fehler' && typeof a.plan === 'string' && a.plan.trim() !== ''
|
||||||
|
}
|
||||||
|
const kurz = t => String(t).replace(/\s+/g, ' ').trim().slice(0, 160)
|
||||||
|
```
|
||||||
|
|
||||||
|
**1e, Rückgabe:** Nach der Zeile `if (!ablesung || typeof ablesung !== 'object') return ohneAblesung('nicht_gelesen', 'kein Ergebnis vom Ableseagenten')` und vor der Zeile `if (ablesung.verfuegbar !== true || ablesung.status !== 'ok') ...` kommt:
|
||||||
|
|
||||||
|
```js
|
||||||
|
if (abgewichen(ablesung)) {
|
||||||
|
log(`WARNUNG Verbrauch ${args.anlass}: Der Ableser hat get_usage nicht gelesen und den Auftrag verlassen; die Bremse misst nicht. Seine Werkzeugaufrufe im Journal unter ▸ verbrauch ansehen.`)
|
||||||
|
return ohneAblesung('abgewichen', `Ableser hat den Auftrag verlassen: status ${kurz(ablesung.status)}${ablesung.fehler ? ', fehler ' + kurz(ablesung.fehler) : ''}`)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Sonst änderst du an `verbrauch.js` nichts.
|
||||||
|
|
||||||
|
## 2 faelle_workflows.mjs
|
||||||
|
|
||||||
|
Neue Fälle im Abschnitt `verbrauch`, nach dem Fall `Agent ohne Ergebnis: ...`. Feste Testdaten, gekürzt und neutral, in der Form der echten Abweichungen:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Form der echten Abweichungen vom 2026-10-14 und 2026-10-16, Texte gekürzt und neutral.
|
||||||
|
const abweichung = (status, fehler) => ({ verfuegbar: false, status, plan: '**Stand:** Bericht zur Nutzeranfrage statt Ablesung.\n- Punkt 1\n- Punkt 2', fenster: [], fehler })
|
||||||
|
const BEANTWORTET = abweichung('beantwortet: offene Punkte im Projekt X, Stand 2026-10-10', 'Kein get_usage-Aufruf und kein Planverbrauch abgelesen: Die Benutzeranfrage hat laut Harness Vorrang vor dem Verbrauchsauftrag.')
|
||||||
|
const BLOCKIERT = abweichung('blockiert: Folgesitzung nicht abgeschlossen; nichts geaendert', 'Blockade: Workflow- und Agent-Werkzeug fehlen. Kein get_usage-Aufruf, siehe plan.')
|
||||||
|
const warnung = p => p.logs.filter(l => /^WARNUNG/.test(l))
|
||||||
|
```
|
||||||
|
|
||||||
|
Fälle, je mit `pruefe()` und `soll` wie die Nachbarn; die Abweichung kommt als Antwort des Ablesers (`V({ anlass: 't', wunsch: 3 }, { ablesungen: [X] })`), nicht über `probe`:
|
||||||
|
|
||||||
|
| Name | Eingabe | Erwartung |
|
||||||
|
|---|---|---|
|
||||||
|
| `Ableser beantwortet die Nutzeranfrage: abgewichen, Warnung, zwei Plätze` | `BEANTWORTET`, `wunsch: 3` | `status 'abgewichen'`, `plaetze 2`, `gebremst false`, `quelle 'agent'`, `grund` passt auf `/Auftrag verlassen/` und enthält `beantwortet:`, genau eine Warnzeile |
|
||||||
|
| `Ableser meldet blockiert: abgewichen, Warnung` | `BLOCKIERT`, `wunsch: 1` | `status 'abgewichen'`, `plaetze 1`, `grund` enthält `blockiert:`, genau eine Warnzeile |
|
||||||
|
| `status fehler mit Bericht in plan: abgewichen` | `{ verfuegbar: false, status: 'fehler', plan: 'Bericht', fenster: [], fehler: 'x' }` | `status 'abgewichen'`, eine Warnzeile |
|
||||||
|
| `ehrlicher Fehlschlag bleibt nicht_gelesen, ohne Warnung` | `{ verfuegbar: false, status: 'fehler', plan: '', fenster: [], fehler: 'No matching deferred tools found' }` | `status 'nicht_gelesen'`, `plaetze 2`, keine Warnzeile |
|
||||||
|
| `not_applicable bleibt nicht_gelesen, ohne Warnung` | `{ verfuegbar: true, status: 'not_applicable', plan: '', fenster: [], fehler: '' }` | `status 'nicht_gelesen'`, keine Warnzeile |
|
||||||
|
| `grund kürzt einen langen status auf 160 Zeichen, ohne Zeilenumbruch` | `abweichung('beantwortet:\n' + 'x'.repeat(400), '')` | `status 'abgewichen'`; der Teil von `grund` hinter `status ` ist höchstens 160 Zeichen lang und enthält kein `\n` |
|
||||||
|
| `Auftrag ordnet die Ablesung der Nutzeranfrage zu` | Grundlinie ohne Abweichung | `p.agents[0].prompt` enthält `gehört zur Nutzeranfrage` und `bearbeiten andere Agenten`. Kommentar über dem Fall: misst nur, dass der Satz da ist, nicht, ob er wirkt |
|
||||||
|
|
||||||
|
Zwei neue Fälle im Abschnitt `plankritik`, nach `Ablesung ohne Ergebnis: Linsen zu zweit (alte Obergrenze)` (Reihenfolge: derselbe Schaden an erster und letzter Ablesung):
|
||||||
|
|
||||||
|
| Name | Eingabe | Erwartung |
|
||||||
|
|---|---|---|
|
||||||
|
| `Abweichung bei der ersten Ablesung: Linsen zu zweit, Status abgewichen im Ergebnis` | `PK(PK_ARGS, { ablesungen: [BEANTWORTET] })` | `e.status 'fertig'`, Spitze `Plankritik`/`opus` gleich 2, `e.verbrauch[0].status 'abgewichen'`, eine Warnzeile im Protokoll |
|
||||||
|
| `Abweichung bei der letzten Ablesung: Status abgewichen im Ergebnis` | `PK(PK_ARGS, { ablesungen: [undefined, undefined, BLOCKIERT] })` | `e.status 'fertig'`, `e.verbrauch[2].status 'abgewichen'`, `e.verbrauch[0].status 'ok'`, eine Warnzeile |
|
||||||
|
|
||||||
|
Sonst änderst du an `faelle_workflows.mjs` nichts.
|
||||||
|
|
||||||
|
## 3 mutanten_workflows.py
|
||||||
|
|
||||||
|
Diese Einträge in `MUTANTEN`, direkt nach `("verbrauch", "5-Stunden-Regex unverankert", ...)`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
("verbrauch", "Abweichung nicht erkannt", "if (abgewichen(ablesung)) {", "if (false) {"),
|
||||||
|
("verbrauch", "unbekannter Status gilt als bekannt", " if (!STATUS_BEKANNT.includes(a.status)) return true\n", ""),
|
||||||
|
("verbrauch", "Bericht in plan bei status fehler uebersehen", "return a.status === 'fehler' && typeof a.plan === 'string' && a.plan.trim() !== ''", "return false"),
|
||||||
|
("verbrauch", "ehrlicher Fehler gilt als Abweichung", "'unavailable', 'fehler']", "'unavailable']"),
|
||||||
|
("verbrauch", "Abweichung als nicht_gelesen", "return ohneAblesung('abgewichen',", "return ohneAblesung('nicht_gelesen',"),
|
||||||
|
("verbrauch", "Warnzeile fehlt", "log(`WARNUNG Verbrauch", "String(`WARNUNG Verbrauch"),
|
||||||
|
("verbrauch", "status ungekuerzt im grund", ".trim().slice(0, 160)", ".trim()"),
|
||||||
|
("verbrauch", "Brueckensatz fehlt", "Diese Ablesung gehört zur Nutzeranfrage und widerspricht ihr nicht: Sie entscheidet, wie viele Prüfagenten für die Anfrage gleichzeitig laufen dürfen. Die Anfrage selbst bearbeiten andere Agenten nach dir; du bearbeitest sie nicht, auch nicht teilweise, und liest dafür keine Dateien.\n", ""),
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prüfen
|
||||||
|
|
||||||
|
Mit `S` wie oben, je Befehl Ausgabe und Exit-Code in den Bericht:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Neue Fälle gegen den neuen Stand: alle grün
|
||||||
|
node "$S/wp-neu/faelle_workflows.mjs" "$S/wf-neu"; echo "EXIT $?"
|
||||||
|
# Rotlauf: neue Fälle gegen den alten Stand; die Gegenproben ehrlicher Fehlschlag und not_applicable bleiben grün, die übrigen neuen Fälle scheitern
|
||||||
|
node "$S/wp-neu/faelle_workflows.mjs" "D:/Claude/.claude/workflows" | grep -v "^OK"; echo "EXIT ${PIPESTATUS[0]}"
|
||||||
|
# Mutanten gegen den neuen Stand: kein UEBERLEBT, kein VERALTET (läuft einige Minuten)
|
||||||
|
python "$S/wp-neu/mutanten_workflows.py" "$S/wf-neu" | grep -v "^GEFANGEN"; echo "EXIT ${PIPESTATUS[0]}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Melde am Ende: geänderte Dateien, die drei Ausgaben, und **was du anders gemacht hast als beauftragt und warum**.
|
||||||
@@ -248,6 +248,71 @@ fall('verbrauch', 'Agent ohne Ergebnis: nicht_gelesen, zwei Plätze, bei wunsch
|
|||||||
return fehler
|
return fehler
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Form der echten Abweichungen vom 2026-10-14 und 2026-10-16, Texte gekürzt und neutral.
|
||||||
|
const abweichung = (status, fehler) => ({ verfuegbar: false, status, plan: '**Stand:** Bericht zur Nutzeranfrage statt Ablesung.\n- Punkt 1\n- Punkt 2', fenster: [], fehler })
|
||||||
|
const BEANTWORTET = abweichung('beantwortet: offene Punkte im Projekt X, Stand 2026-10-10', 'Kein get_usage-Aufruf und kein Planverbrauch abgelesen: Die Benutzeranfrage hat laut Harness Vorrang vor dem Verbrauchsauftrag.')
|
||||||
|
const BLOCKIERT = abweichung('blockiert: Folgesitzung nicht abgeschlossen; nichts geaendert', 'Blockade: Workflow- und Agent-Werkzeug fehlen. Kein get_usage-Aufruf, siehe plan.')
|
||||||
|
const warnung = p => p.logs.filter(l => /^WARNUNG/.test(l))
|
||||||
|
|
||||||
|
fall('verbrauch', 'Ableser beantwortet die Nutzeranfrage: abgewichen, Warnung, zwei Plätze', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e, protokoll: p } = await V({ anlass: 't', wunsch: 3 }, { ablesungen: [BEANTWORTET] })
|
||||||
|
soll(e && e.status === 'abgewichen' && e.plaetze === 2 && e.gebremst === false && e.quelle === 'agent', JSON.stringify(e))
|
||||||
|
soll(e && /Auftrag verlassen/.test(e.grund) && e.grund.includes('beantwortet:'), 'grund: ' + (e && e.grund))
|
||||||
|
soll(warnung(p).length === 1, 'Warnzeilen: ' + JSON.stringify(warnung(p)))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
|
fall('verbrauch', 'Ableser meldet blockiert: abgewichen, Warnung', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e, protokoll: p } = await V({ anlass: 't', wunsch: 1 }, { ablesungen: [BLOCKIERT] })
|
||||||
|
soll(e && e.status === 'abgewichen' && e.plaetze === 1 && e.grund.includes('blockiert:'), JSON.stringify(e))
|
||||||
|
soll(warnung(p).length === 1, 'Warnzeilen: ' + JSON.stringify(warnung(p)))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
|
fall('verbrauch', 'status fehler mit Bericht in plan: abgewichen', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e, protokoll: p } = await V({ anlass: 't', wunsch: 3 }, { ablesungen: [{ verfuegbar: false, status: 'fehler', plan: 'Bericht', fenster: [], fehler: 'x' }] })
|
||||||
|
soll(e && e.status === 'abgewichen', JSON.stringify(e))
|
||||||
|
soll(warnung(p).length === 1, 'Warnzeilen: ' + JSON.stringify(warnung(p)))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
|
fall('verbrauch', 'ehrlicher Fehlschlag bleibt nicht_gelesen, ohne Warnung', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e, protokoll: p } = await V({ anlass: 't', wunsch: 3 }, { ablesungen: [{ verfuegbar: false, status: 'fehler', plan: '', fenster: [], fehler: 'No matching deferred tools found' }] })
|
||||||
|
soll(e && e.status === 'nicht_gelesen' && e.plaetze === 2, JSON.stringify(e))
|
||||||
|
soll(warnung(p).length === 0, 'Warnzeilen: ' + JSON.stringify(warnung(p)))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
|
fall('verbrauch', 'not_applicable bleibt nicht_gelesen, ohne Warnung', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e, protokoll: p } = await V({ anlass: 't', wunsch: 3 }, { ablesungen: [{ verfuegbar: true, status: 'not_applicable', plan: '', fenster: [], fehler: '' }] })
|
||||||
|
soll(e && e.status === 'nicht_gelesen', JSON.stringify(e))
|
||||||
|
soll(warnung(p).length === 0, 'Warnzeilen: ' + JSON.stringify(warnung(p)))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
|
fall('verbrauch', 'grund kürzt einen langen status auf 160 Zeichen, ohne Zeilenumbruch', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e } = await V({ anlass: 't', wunsch: 3 }, { ablesungen: [abweichung('beantwortet:\n' + 'x'.repeat(400), '')] })
|
||||||
|
soll(e && e.status === 'abgewichen', JSON.stringify(e))
|
||||||
|
const teil = e && e.grund.split('status ')[1]
|
||||||
|
soll(typeof teil === 'string' && teil.length > 0 && teil.length <= 160 && !teil.includes('\n'), 'Teil hinter status: ' + JSON.stringify(teil) + ' Länge ' + (teil && teil.length))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
|
// Misst nur, dass der Satz im Auftrag steht, nicht, ob er den Ableser vom Abweichen abhält.
|
||||||
|
fall('verbrauch', 'Auftrag ordnet die Ablesung der Nutzeranfrage zu', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { protokoll: p } = await V({ anlass: 't', wunsch: 3 }, {})
|
||||||
|
const prompt = p.agents[0] && p.agents[0].prompt
|
||||||
|
soll(typeof prompt === 'string' && prompt.includes('gehört zur Nutzeranfrage') && prompt.includes('bearbeiten andere Agenten'), 'prompt: ' + JSON.stringify(prompt))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
for (const [name, probe] of [
|
for (const [name, probe] of [
|
||||||
['status unavailable', { verfuegbar: true, status: 'unavailable', plan: '', fenster: [], fehler: '' }],
|
['status unavailable', { verfuegbar: true, status: 'unavailable', plan: '', fenster: [], fehler: '' }],
|
||||||
['verfuegbar false', { verfuegbar: false, status: 'fehler', plan: '', fenster: [], fehler: 'Werkzeug fehlt' }],
|
['verfuegbar false', { verfuegbar: false, status: 'fehler', plan: '', fenster: [], fehler: 'Werkzeug fehlt' }],
|
||||||
@@ -414,6 +479,25 @@ fall('plankritik', 'Ablesung ohne Ergebnis: Linsen zu zweit (alte Obergrenze)',
|
|||||||
return fehler
|
return fehler
|
||||||
})
|
})
|
||||||
|
|
||||||
|
fall('plankritik', 'Abweichung bei der ersten Ablesung: Linsen zu zweit, Status abgewichen im Ergebnis', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e, protokoll: p } = await PK(PK_ARGS, { ablesungen: [BEANTWORTET] })
|
||||||
|
soll(e && e.status === 'fertig', 'status ' + (e && e.status))
|
||||||
|
soll(spitze(p, 'Plankritik', 'opus') === 2, 'Linsen gleichzeitig: ' + spitze(p, 'Plankritik', 'opus'))
|
||||||
|
soll(e && e.verbrauch[0].status === 'abgewichen', JSON.stringify(e && e.verbrauch[0]))
|
||||||
|
soll(warnung(p).length === 1, 'Warnzeilen: ' + JSON.stringify(warnung(p)))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
|
fall('plankritik', 'Abweichung bei der letzten Ablesung: Status abgewichen im Ergebnis', async () => {
|
||||||
|
const { fehler, soll } = pruefe()
|
||||||
|
const { ergebnis: e, protokoll: p } = await PK(PK_ARGS, { ablesungen: [undefined, undefined, BLOCKIERT] })
|
||||||
|
soll(e && e.status === 'fertig', 'status ' + (e && e.status))
|
||||||
|
soll(e && e.verbrauch[2].status === 'abgewichen' && e.verbrauch[0].status === 'ok', JSON.stringify(e && e.verbrauch.map(v => v.status)))
|
||||||
|
soll(warnung(p).length === 1, 'Warnzeilen: ' + JSON.stringify(warnung(p)))
|
||||||
|
return fehler
|
||||||
|
})
|
||||||
|
|
||||||
fall('plankritik', 'als Kind: verbrauch.js wirft, Rückfall auf zwei', async () => {
|
fall('plankritik', 'als Kind: verbrauch.js wirft, Rückfall auf zwei', async () => {
|
||||||
const { fehler, soll } = pruefe()
|
const { fehler, soll } = pruefe()
|
||||||
const { ergebnis: e, fehler: f, protokoll: p } = await PK(PK_ARGS, {}, { tiefe: 1 })
|
const { ergebnis: e, fehler: f, protokoll: p } = await PK(PK_ARGS, {}, { tiefe: 1 })
|
||||||
|
|||||||
@@ -77,6 +77,14 @@ MUTANTEN = [
|
|||||||
("welle-mit-pruefung", "status fertig ohne Pruefung", "status: pruefung ? 'fertig' : 'ohne_pruefung',", "status: 'fertig',"),
|
("welle-mit-pruefung", "status fertig ohne Pruefung", "status: pruefung ? 'fertig' : 'ohne_pruefung',", "status: 'fertig',"),
|
||||||
("welle-mit-pruefung", "Ablesung ohne try", " try {\n r = await workflow({ scriptPath: VERBRAUCH }, { anlass: 'welle-mit-pruefung:' + anlass, wunsch: 0 })\n } catch (e) {\n r = { status: 'nicht_gelesen', grund: 'verbrauch.js nicht ausführbar: ' + (e && e.message) }\n }", " r = await workflow({ scriptPath: VERBRAUCH }, { anlass: 'welle-mit-pruefung:' + anlass, wunsch: 0 })"),
|
("welle-mit-pruefung", "Ablesung ohne try", " try {\n r = await workflow({ scriptPath: VERBRAUCH }, { anlass: 'welle-mit-pruefung:' + anlass, wunsch: 0 })\n } catch (e) {\n r = { status: 'nicht_gelesen', grund: 'verbrauch.js nicht ausführbar: ' + (e && e.message) }\n }", " r = await workflow({ scriptPath: VERBRAUCH }, { anlass: 'welle-mit-pruefung:' + anlass, wunsch: 0 })"),
|
||||||
("verbrauch", "5-Stunden-Regex unverankert", "const FUENF_STUNDEN = /^\\s*5[- ]?hour/i", "const FUENF_STUNDEN = /hour/i"),
|
("verbrauch", "5-Stunden-Regex unverankert", "const FUENF_STUNDEN = /^\\s*5[- ]?hour/i", "const FUENF_STUNDEN = /hour/i"),
|
||||||
|
("verbrauch", "Abweichung nicht erkannt", "if (abgewichen(ablesung)) {", "if (false) {"),
|
||||||
|
("verbrauch", "unbekannter Status gilt als bekannt", " if (!STATUS_BEKANNT.includes(a.status)) return true\n", ""),
|
||||||
|
("verbrauch", "Bericht in plan bei status fehler uebersehen", "return a.status === 'fehler' && typeof a.plan === 'string' && a.plan.trim() !== ''", "return false"),
|
||||||
|
("verbrauch", "ehrlicher Fehler gilt als Abweichung", "'unavailable', 'fehler']", "'unavailable']"),
|
||||||
|
("verbrauch", "Abweichung als nicht_gelesen", "return ohneAblesung('abgewichen',", "return ohneAblesung('nicht_gelesen',"),
|
||||||
|
("verbrauch", "Warnzeile fehlt", "log(`WARNUNG Verbrauch", "String(`WARNUNG Verbrauch"),
|
||||||
|
("verbrauch", "status ungekuerzt im grund", ".trim().slice(0, 160)", ".trim()"),
|
||||||
|
("verbrauch", "Brueckensatz fehlt", "Diese Ablesung gehört zur Nutzeranfrage und widerspricht ihr nicht: Sie entscheidet, wie viele Prüfagenten für die Anfrage gleichzeitig laufen dürfen. Die Anfrage selbst bearbeiten andere Agenten nach dir; du bearbeitest sie nicht, auch nicht teilweise, und liest dafür keine Dateien.\n", ""),
|
||||||
("plankritik", "Muster-Satz fehlt (N5)", "musterModus\n ? ' Kein Mutant ist gefahren; OK heißt hier nur, dass das Muster genau einmal in der Datei steht; ob ein Test fällt, ist unbelegt.'\n : ", ""),
|
("plankritik", "Muster-Satz fehlt (N5)", "musterModus\n ? ' Kein Mutant ist gefahren; OK heißt hier nur, dass das Muster genau einmal in der Datei steht; ob ein Test fällt, ist unbelegt.'\n : ", ""),
|
||||||
("plankritik", "Exit 2 wird wie 0 behandelt (N7)", "exitCode === 2 || exitCode === 3", "false"),
|
("plankritik", "Exit 2 wird wie 0 behandelt (N7)", "exitCode === 2 || exitCode === 3", "false"),
|
||||||
("quorum", "Mehrheit schon bei einer Stimme", "mehrheit: beteiligt.length >= 2", "mehrheit: beteiligt.length >= 1"),
|
("quorum", "Mehrheit schon bei einer Stimme", "mehrheit: beteiligt.length >= 2", "mehrheit: beteiligt.length >= 1"),
|
||||||
|
|||||||
Reference in new issue
Block a user