session: Harness-Session-Variable schliesst die Luecke im Session-Id-Fallback (Telemetrie-Join, Iteration-Budget-Gate); SIGPIPE-Nebenbefund im Emitter behoben
CI / verify (push) Successful in 52s
Release / release (push) Successful in 36s

Files changed:
- CHANGES.md
- EVALS.md
- INSTALL.md
- VERSION
- instructions/session-setup.md
- tools/CONTRACT.md
- tools/chemenu/cli.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/run_budget.py
- tools/chemenu/session.py
- tools/chemenu/telemetry/writer.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_cli.py
- tools/chemenu/tests/test_run_budget.py
- tools/chemenu/tests/test_telemetry_emit.py
This commit is contained in:
2026-09-16 19:18:00 +02:00
parent 536093f6c9
commit e4e2332e01
15 changed files with 610 additions and 44 deletions
+51 -1
View File
@@ -59,11 +59,15 @@ concern - readable here, never shipped as something to parse.
---
## 6.1.0-beta.4 - 2026-09-16 - version notes antwortet auf einer ausgelieferten Instanz aus dem Release-Feed
## 6.1.0-beta.5 - 2026-09-16 - Session-Id-Fallback: Harness-Variable schliesst die Luecke zwischen Telemetrie-Join und Iteration-Budget-Gate
**Author:** Torben Nehmer
<!-- wikitool:bumps -->
**High impact**
- Session-Id-Fallback: Harness-Variable schliesst die Luecke zwischen Telemetrie-Join und Iteration-Budget-Gate
**Medium impact**
- Upgrade-Prozedur als eigene Instruktion statt als Prosa in INSTALL.md
- Migrationsdokument prueft gegen eine festgehaltene Vorher-Ausgabe, Beispielverweis auf die .template-Form
- dist upgrade: --take-release nimmt fuer einen lokal geaenderten Pfad die Release-Fassung
@@ -252,6 +256,52 @@ Bei der Gelegenheit zwei Eintraege aus `tools/CONTRACT.md` § "Future considerat
implemented)" entfernt, die dort seit ihrer Umsetzung falsch standen: der MCP-Server-Wrapper und
`dist upgrade` selbst. Beide sind im selben Dokument weiter oben als existierend beschrieben.
### Session-Id-Fallback: Harness-Variable schliesst die Luecke zwischen Telemetrie-Join und Iteration-Budget-Gate
Gemessen an einem getracten Lauf (33 `wikitool`-Aufrufe, eine Sitzung): unter Claude Code, dessen
Bash-Tool jeden Aufruf in einer frisch initialisierten Shell ausfuehrt, fiel `chemenu.session`
ohne gesetztes `WIKITOOL_SESSION_ID` auf `os.getppid()` zurueck - eine neue "Sitzung" pro Aufruf.
Der Lauf zerfiel so in 21 Telemetrie-Buckets (hoechster Bucket: 3 von 33 Aufrufen), und das
Iteration-Budget-Gate (60 Aufrufe, Loop-Breaker bei 3 identischen in Folge) sah nie mehr als 3 von
60 - strukturell unerreichbar, obwohl `AGENTS.md` es als eine der vier code-durchgesetzten
Sicherungen fuehrt. Derselbe Bruch traf den Telemetrie-Join: Hook-Events (`prompt.submitted`)
trugen die Harness-UUID, `wikitool.call`-Events die wechselnde PID - kein gemeinsamer Schluessel,
und `eval score` bewertete 1-3 Aufrufe statt 33.
`chemenu.session` bekommt eine dritte Stufe zwischen der expliziten Variable und dem
PID-Fallback: eine kleine Registry bekannter Harness-Session-Variablen (`HARNESS_ENV_VARS`),
heute mit einem verifizierten Eintrag, `CLAUDE_CODE_SESSION_ID`. Verifiziert heisst: gegen eine
echte Sitzung gemessen, dass die Variable ueber Tool-Aufrufe hinweg stabil bleibt (anders als die
Shell-PID) und exakt der Wert ist, den der `UserPromptSubmit`-Hook in die Trace schreibt - der
Wert wird unveraendert als Schluessel uebernommen, kein Praefix, keine Umschreibung, sonst waere
der Join wieder zerstoert. Ein Eintrag wird nur nach genau dieser Verifikation aufgenommen: ein
Variablenname, der zufaellig existiert und etwas anderes bedeutet, waere ein stillerer Fehler als
der PID-Fallback, den er ersetzt.
`run_budget`s Zustandsdatei (`budget.json`) traegt je Eintrag jetzt die Herkunft seiner Id; faellt
dieselbe Id-Zeichenkette unter eine andere Herkunft als die gespeicherte, beginnt ein neuer
Zaehler statt einen fremden zu erben - ein Eintrag ohne das Feld (vor dieser Aenderung
geschrieben) behaelt seinen Count unveraendert. `doctor` ist jetzt dreiwertig (`OK` fuer eine
explizite Variable oder eine erkannte Harness-Variable, `WARN` nur noch fuer den reinen
PID-Fallback), und sowohl `budget status` als auch der `session.start`-Event der `wikitool`-
Telemetriequelle nennen die Herkunft der Id.
Im selben Lauf gemessener Nebenbefund auf der Emitter-Seite: ein durch eine geschlossene Pipe
abgebrochener, ansonsten erfolgreicher Aufruf (`... | head`) stand mit `exit_code: 1` in der
Trace - Click faengt `BrokenPipeError` selbst ab und erzwingt `sys.exit(1)`, ununterscheidbar von
einem echten Fehler. `cli.py` installiert jetzt vor jedem Dispatch einen Wrapper um
`stdout`/`stderr`, der einen EPIPE-Schreibfehler schluckt, bevor Click ihn sieht, und markiert den
Trace-Eintrag stattdessen mit `stdout_truncated: true` bei unveraendertem, dem tatsaechlichen
Kommandoerfolg entsprechendem `exit_code`.
Reproduziert mit Tests, die echte Subprozesse statt In-Process-Aufrufe verwenden - `os.getppid()`
ist sonst ueber die Testlaufzeit hinweg konstant: 61 Aufrufe aus je eigenem Prozess mit nur der
Harness-Variablen loesen das Gate jetzt aus, drei identische ebenso den Loop-Breaker; vor dieser
Aenderung waeren beide Tests gruen und blind gewesen.
`--minor`: additiv (ein neues optionales `source`-Feld in `budget.json`, die Id faellt weiterhin
auf `getppid()` zurueck, wo keine Variable greift), keine der beiden Drop-in-Richtungen verletzt.
---
## 6.0.1 - 2026-09-16 - docs toc/verify erreichen die .template-Form einer Referenzdatei