Shay
6d62ac2f24
test(telemetry): isolate engine_state so emission-count tests are order-independent
...
The telemetry tests built ChatRuntime(config=RuntimeConfig()) against the
default (shared) engine_state/ store. In a full-suite run, earlier runtime
tests persist a checkpoint there, so these tests restored ambient state and
emitted an extra 'reboot' telemetry event (restored_turn_count=NNNN), breaking
the 'one line per turn' counts (assert 3 == 2). They passed alone, failed
after siblings — a classic order-dependent isolation bug, not a telemetry
regression.
Build with no_load_state=True so each test exercises clean per-turn emission.
No telemetry test asserts the reboot/restore path, so none lose coverage.
(engine_state/ data files are already gitignored per ADR-0146.)
2026-06-03 01:56:05 -07:00
Shay
226f14a941
feat(adr-0040): structured-logging sink for turn-event audit
...
Adds the canonical JSONL sink surface consuming TurnEvent records
that ADR-0039 made uniform across main and stub paths. One
deterministic line per turn; redact-by-default trust boundary;
opt-in content emission; runtime auto-emits on attached sink.
Trust boundary (CLAUDE.md):
- Metadata-only by default — no surfaces or input tokens emitted.
include_content=True opt-in at attachment time.
- Path fixed at construction for JsonlFileSink; no user-controlled
paths interpreted at emit time.
- Sink errors propagate — telemetry failures should surface, not
silently drop audit signal.
Determinism:
- sort_keys=True; compact separators. Same event → byte-identical line.
- No implicit wall-clock; timestamps caller-provided.
- Field set fixed; missing TurnEvent attrs fall back to safe defaults.
API:
- serialize_turn_event(event, **kwargs) -> dict (pure)
- format_turn_event_jsonl(event, **kwargs) -> str (pure, deterministic)
- TurnEventSink Protocol; JsonlBufferSink; JsonlFileSink
- ChatRuntime.attach_telemetry_sink(sink, *, include_content=False)
- _emit_turn_event invoked after both turn_log.append sites
Wire format (alphabetised, always present): cycle_cost_total,
dialogue_role, ethics_pack_id, ethics_runtime_checkable_count,
ethics_upheld, ethics_violated, flagged, hedge_injected,
identity_pack_id, refusal_emitted, safety_pack_id,
safety_runtime_checkable_count, safety_upheld, safety_violated,
stub_path, turn, vault_hits, versor_condition.
Conditional: identity_* (when score present), surface /
walk_surface / articulation_surface / input_tokens (when
include_content=True), timestamp (when provided).
Files:
- chat/telemetry.py (new) — serializer, formatter, sinks
- chat/runtime.py — attach + emit + post-append calls
- tests/test_telemetry_sink.py (new) — 29 tests
- docs/decisions/ADR-0040-telemetry-sink.md (new)
Verification:
- Combined pack-layer + telemetry suite: 199 green (was 170 after
ADR-0039; +29)
- CLI suites unchanged: smoke 67, runtime 19, cognition 121
- core eval cognition: intent 100%, versor_closure 100% (baseline)
2026-05-17 21:39:58 -07:00