From self-improving-agent
Unabhaengiger Bewertungs-Agent der Worker-Ergebnisse gegen Akzeptanzkriterien prueft. Wird als separater claude -p Prozess gestartet um Confirmation Bias zu vermeiden. Trigger: 'ergebnis bewerten', 'arbeit pruefen', 'judge task', 'evaluate result', 'acceptance check', 'qualitaetspruefung'.
How this skill is triggered — by the user, by Claude, or both
Slash command
/self-improving-agent:judgeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Unabhaengiger Bewertungs-Agent der die Arbeit eines Worker-Agenten prueft. Wird als separater `claude -p` Prozess mit frischem Context gestartet, um Confirmation Bias zu vermeiden.
Unabhaengiger Bewertungs-Agent der die Arbeit eines Worker-Agenten prueft. Wird als separater
claude -pProzess mit frischem Context gestartet, um Confirmation Bias zu vermeiden.
Ein Agent der seine eigene Arbeit bewertet hat systematischen Confirmation Bias — er "sieht" Probleme nicht, die er selbst verursacht hat. Der Judge-Agent:
claude -p Subprozess vom Orchestrator gestartettasks.json enthaelt den zu bewertenden Task mit Akzeptanzkriterien# Der Orchestrator spawnt den Judge als separaten Prozess
TASK_ID="T003"
claude -p "$(cat <<JUDGE_PROMPT
Du bist ein Judge-Agent. Deine einzige Aufgabe: Bewerte ob Task ${TASK_ID} korrekt erledigt wurde.
REGELN:
1. Du hast den Task NICHT selbst ausgefuehrt — bewerte unvoreingenommen
2. Pruefe NUR gegen die definierten Akzeptanzkriterien
3. Fuehre Tests aus wenn moeglich — vertraue nicht auf Augenschein
4. Dein Urteil ist FINAL: pass, fail, oder partial
5. Schreibe dein Urteil nach .agent-memory/judgments/
Lies .claude/skills/judge/SKILL.md und fuehre die beschriebene Prozedur aus.
Task-ID: ${TASK_ID}
JUDGE_PROMPT
)"
# Task aus tasks.json extrahieren
TASK=$(jq --arg id "$TASK_ID" '.tasks[] | select(.id == $id)' tasks.json)
Extrahiere:
title: Was sollte getan werden?acceptance_criteria: Woran messen wir Erfolg?started_at / completed_at: Zeitrahmennotes: Eventuelle Hinweise vom WorkerFuehre alle automatisierbaren Checks aus:
# Teste ob die Projekt-Tests bestehen
# Erkennung: package.json (npm test), pytest.ini/setup.cfg (pytest), Makefile (make test)
# WICHTIG: Timeout von 120s um haengende Tests abzufangen
JUDGE_TEST_TIMEOUT=120
if [[ -f "package.json" ]]; then
timeout ${JUDGE_TEST_TIMEOUT} npm test 2>&1 | tail -50 > "${TMPDIR:-/tmp}/judge_test_output.txt"
TEST_EXIT=$?
elif [[ -f "pytest.ini" ]] || [[ -f "setup.cfg" ]] || [[ -f "pyproject.toml" ]]; then
timeout ${JUDGE_TEST_TIMEOUT} python3 -m pytest --tb=short 2>&1 | tail -50 > "${TMPDIR:-/tmp}/judge_test_output.txt"
TEST_EXIT=$?
elif [[ -f "Makefile" ]] && grep -q "^test:" Makefile; then
timeout ${JUDGE_TEST_TIMEOUT} make test 2>&1 | tail -50 > "${TMPDIR:-/tmp}/judge_test_output.txt"
TEST_EXIT=$?
else
echo "NO_TEST_SUITE" > "${TMPDIR:-/tmp}/judge_test_output.txt"
TEST_EXIT=-1
fi
# Exit-Code 124 = timeout wurde erreicht
if [[ $TEST_EXIT -eq 124 ]]; then
echo "TIMEOUT after ${JUDGE_TEST_TIMEOUT}s" >> "${TMPDIR:-/tmp}/judge_test_output.txt"
fi
# Lint-Check (wenn konfiguriert)
if [[ -f "package.json" ]] && jq -e '.scripts.lint' package.json > /dev/null 2>&1; then
npm run lint 2>&1 | tail -30 > "${TMPDIR:-/tmp}/judge_lint_output.txt"
LINT_EXIT=$?
elif command -v ruff &>/dev/null; then
ruff check . 2>&1 | tail -30 > "${TMPDIR:-/tmp}/judge_lint_output.txt"
LINT_EXIT=$?
else
LINT_EXIT=-1
fi
# Welche Dateien wurden geaendert?
git diff --stat HEAD~1 2>/dev/null > "${TMPDIR:-/tmp}/judge_diff.txt"
# Gibt es unerwartet grosse Aenderungen?
LINES_CHANGED=$(git diff --shortstat HEAD~1 2>/dev/null)
Gehe JEDES Akzeptanzkriterium einzeln durch:
| # | Kriterium | Pruefmethode | Ergebnis | Evidenz |
|---|-----------|-------------|----------|---------|
| 1 | {CRITERION_1} | {test/manual/lint} | {pass/fail} | {DETAILS} |
| 2 | {CRITERION_2} | ... | ... | ... |
Pruefmethoden:
PASS: Alle Kriterien erfuellt, Tests gruen, kein offensichtlicher Defekt
PARTIAL: Mindestens 1 Kriterium nicht erfuellt, aber substantieller Fortschritt
FAIL: Kernfunktionalitaet fehlt, Tests rot, oder kritischer Defekt
Schwellenwerte:
Speichere als .agent-memory/judgments/judgment_{TASK_ID}_{TIMESTAMP}.json:
{
"task_id": "T003",
"timestamp": "2026-03-24T14:30:00Z",
"verdict": "pass|partial|fail",
"criteria_results": [
{
"criterion": "API endpoint returns 200 for valid input",
"method": "test",
"result": "pass",
"evidence": "pytest test_api.py::test_valid_input PASSED"
},
{
"criterion": "Error handling for invalid JSON",
"method": "manual",
"result": "fail",
"evidence": "No try/catch around JSON.parse in handler.py:42"
}
],
"automated_checks": {
"tests": {"exit_code": 0, "summary": "14 passed, 0 failed"},
"lint": {"exit_code": 0, "summary": "No issues found"},
"diff_stats": "+142 -23 across 5 files"
},
"notes": "Hauptfunktionalitaet korrekt implementiert, aber Edge-Case bei Invalid-JSON nicht abgedeckt.",
"recommendation": "Task als partial markieren. Neuen Task T003a erstellen: Error-Handling fuer invalid JSON in handler.py"
}
Zusaetzlich als Markdown-Report .agent-memory/judgments/judgment_{TASK_ID}_{TIMESTAMP}.md:
# Judgment: {TASK_ID} — {TASK_TITLE}
**Verdict: {PASS|PARTIAL|FAIL}**
**Datum:** {TIMESTAMP}
## Kriterien-Bewertung
| # | Kriterium | Ergebnis | Evidenz |
|---|-----------|----------|---------|
| 1 | ... | PASS | ... |
| 2 | ... | FAIL | ... |
## Automatisierte Checks
- Tests: {PASS/FAIL} ({SUMMARY})
- Lint: {PASS/FAIL/SKIP}
- Diff: {STATS}
## Empfehlung
{RECOMMENDATION}
Basierend auf dem Urteil:
| Verdict | Aktion |
|---|---|
| PASS | Status → done, completed_at setzen |
| PARTIAL | Status bleibt in_progress, notes mit fehlenden Kriterien aktualisieren |
| FAIL | Status → blocked, blocked_reason mit Begruendung, ggf. neuen Fix-Task erstellen |
| Fehlerfall | Reaktion |
|---|---|
| Task-ID nicht in tasks.json | Abbruch mit Fehler |
| Keine Akzeptanzkriterien definiert | Warnung, nur automatisierte Checks ausfuehren |
| Test-Suite nicht ausfuehrbar | Als "untestable" markieren, nur manuelle Pruefung |
| Git-History nicht verfuegbar | Diff-Analyse ueberspringen |
| Judge kann Kriterium nicht bewerten | Als "inconclusive" markieren, nicht als pass zaehlen |
| Test-Suite haengt (Timeout) | Als "timeout" markieren, Ergebnis als FAIL werten, Hinweis in notes |
claude -p statt inline?Der Judge MUSS als separater Prozess laufen, weil:
npx claudepluginhub dynamic-dome/self-improving-agentCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.