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:
torben committed 2026-09-16 19:18:00 +02:00
1 parent 536093f6c9
commit e4e2332e01
15 files changed
+610 -44

No files matched your search

+13 -1
View File
@@ -24,6 +24,7 @@ from chemenu import config, conventions, kb_collections, version as version_mod
from chemenu.commands import git_publish, instructions_cmd
from chemenu.commands._util import rel_path
from chemenu.session import ENV_VAR as SESSION_ENV_VAR
from chemenu.session import session_id_source as _session_id_source
console = Console()
@@ -414,12 +415,23 @@ def check_upload_intake() -> Check:
def check_session_id() -> Check:
"""Three-valued, not two: an explicit `WIKITOOL_SESSION_ID` and a
recognised harness variable (see `chemenu.session.HARNESS_ENV_VARS`) both
keep a session's calls in one telemetry/budget bucket, so both are `OK`.
Only the `getppid()` fallback - a fresh "session" on every call, on a
harness that runs each tool call in its own shell - is a `WARN` (see
Gitea #110)."""
import os
if os.environ.get(SESSION_ENV_VAR, "").strip():
return Check("session-id", "OK", f"{SESSION_ENV_VAR}={os.environ[SESSION_ENV_VAR]}")
source = _session_id_source()
if source != "getppid() fallback":
return Check("session-id", "OK", f"scoped by harness variable {source}")
return Check(
"session-id", "WARN", f"{SESSION_ENV_VAR} is not set - budget falls back to the parent PID",
"session-id", "WARN",
f"{SESSION_ENV_VAR} is not set and no harness session variable was found - "
"budget falls back to the parent PID",
"See instructions/session-setup.md",
)
+22 -1
View File
@@ -144,6 +144,27 @@ def _session_id_source() -> str:
return _shared_session_id_source()
def _entry_for(state: dict, session_id: str) -> dict:
"""The state entry for this session id, starting a fresh counter if the
same id string now carries a different origin than the one that wrote it.
Two different id spaces (a `getppid()` integer, a harness UUID, an
explicit `WIKITOOL_SESSION_ID`) are vanishingly unlikely to collide as
strings - but "unlikely" is not "impossible", and inheriting a stranger's
count on collision is exactly the silent mis-key #110 exists to close.
An entry written before this field existed carries no `source` at all and
is treated as compatible: it keeps its count rather than being reset the
first time this ships, which would throw away real, in-flight state.
"""
source = _session_id_source()
entry = state.get(session_id)
if entry is None or (entry.get("source") is not None and entry["source"] != source):
entry = {"count": 0, "recent": []}
state[session_id] = entry
entry.setdefault("source", source)
return entry
def _load_state() -> dict:
if not STATE_FILE.exists():
return {}
@@ -247,7 +268,7 @@ def record_and_check(
with _state_lock():
session_id = _session_id()
state = _load_state()
entry = state.setdefault(session_id, {"count": 0, "recent": []})
entry = _entry_for(state, session_id)
recent = entry["recent"]
call_signature = f"{command} {' '.join(args)}".strip()