core/chat
Shay 417f71917c feat(adr-0041): core chat --show-verdicts + FanOutSink
Two thin layers closing the audit story end-to-end:

- core chat --show-verdicts prints format_verdict_summary(verdicts)
  to stderr after each turn.  Stdout stays clean for piped
  consumers.  Format is dense and terse; designed to skim, not
  machine-parseable (the JSONL sink owns that contract).

- FanOutSink forwards every emitted line to N sinks in declaration
  order.  Fail-fast on first error — consistent with ADR-0040's
  single-sink contract (audit failures surface).  Composes with
  any combination of JsonlFileSink / JsonlBufferSink / future
  sinks.

Two formatters, one bundle: format_turn_event_jsonl (machine,
ADR-0040) and format_verdict_summary (operator, ADR-0041) both
consume the same TurnVerdicts.  No risk of drift.

Summary format:
  [identity=0.83 safety=ok ethics=VIOLATED:foo refusal=- hedge=YES]

Audit story now reads end-to-end:
  - TurnVerdicts bundle (ADR-0039)
  - Machine JSONL sink (ADR-0040)
  - Fan-out + operator CLI (ADR-0041)

Files:
- chat/telemetry.py — FanOutSink dataclass, format_verdict_summary,
  _format_verdict_short helper
- core/cli.py — --show-verdicts on chat subparser; cmd_chat prints
  summary to stderr when set
- tests/test_telemetry_fanout_and_summary.py (new) — 13 tests
- docs/decisions/ADR-0041-cli-verdicts-and-fanout.md (new)

Verification:
- Combined pack-layer + telemetry suite: 212 green (was 199; +13)
- CLI suites unchanged: smoke 67, runtime 19, cognition 121
- core eval cognition: intent 100%, versor_closure 100% (baseline)
- Manual smoke: echo "light is" | core chat --show-verdicts prints
  expected bracketed audit line to stderr alongside response.
2026-05-17 21:47:47 -07:00
..
__init__.py Add live chat runtime 2026-05-13 20:40:56 -07:00
__main__.py Add live chat runtime 2026-05-13 20:40:56 -07:00
refusal.py feat(adr-0037,adr-0038): per-predicate ethics refusal + hedge injection 2026-05-17 21:23:28 -07:00
runtime.py feat(adr-0040): structured-logging sink for turn-event audit 2026-05-17 21:39:58 -07:00
telemetry.py feat(adr-0041): core chat --show-verdicts + FanOutSink 2026-05-17 21:47:47 -07:00
verdicts.py feat(adr-0039): audit completeness — TurnVerdicts bundle, stub TurnEvent, hedge_injected 2026-05-17 21:32:46 -07:00