# Client logbook (#38) Issue: #38. Before this, the daemon left nothing on disk — a "why did my session drop" report from a Windows user had no local evidence at all. ## Two files under `~/.hnx/logs/` (0700; `HNX_LOG_DIR` overrides) | file | content | rotation | | --- | --- | --- | | `ops.log` | one line per OPERATION the daemon performs on this machine: adapter provisioning, harness install/upgrade/pin, profile deploys, runtime-config applies, CC marketplace deploys, and manual `hnx install`/`uninstall`. Fields: time, op, target, outcome, ms, squashed single-line detail. No content, no secrets. | 256KB × 3 | | `comm.log` | the /ctl socket traffic at METADATA level: direction, event name, byte size. `-- connect` / `-- disconnect ` lifecycle markers are the headline for drop debugging. | 1MB × 5 | `HNX_LOG_COMM=payload` opts into full payload lines (4KB/line cap) — DEBUG ONLY, payloads carry chat content; the HELP text says so. ## Volume: why full printing was rejected (user-approved design) A chat turn emits `chat:event` per stream delta (hundreds per turn); `chat:history` is a single multi-hundred-KB event; `sessions:list` fires every 15s. Full logging would (a) churn the 1MB×5 window so the interesting lines rotate away, and (b) put chat content on disk. The comm log therefore: - one line per ordinary event; - **burst aggregation**: consecutive same-name `chat:event` runs collapse to an opening marker + ONE summary line (`tx chat:event ×212 total 78.4KB over 4.1s`) — closed by a different event, a 2s idle, or disconnect; - big single events are one line each — "chat:history 412KB" IS the datum. ## Architecture (TUI groundwork, #39) Nothing writes to disk directly. Every entry is published to `logbook` — a ring-buffered **bus** (`subscribe` / `recent(500)`) — and the rotating file sinks are ordinary subscribers. A future `hnx tui` (#39) runs the daemon in-process (`runDaemon` is importable) and subscribes to the same bus for its panes: the live feed is UNAGGREGATED (aggregation is a property of the file sink, not the bus). tx capture wraps the socket instance's `emit` (socket.io-client has no `onAnyOutbound` — that is server-only). Bug found on the way (fixed + tested): the first rotation aborted its whole shift chain on an ENOENT rename of a nonexistent `.1`; each shift now tolerates gaps separately or the file grows past the cap forever. ## `hnx logs` `hnx logs [--tail N] [--bundle ]` — lists the log files (size, mtime) with a tail each; `--bundle` writes a single shareable text file (client/OS/ Node header from #37 + last 200 lines of every log) — the artifact to attach to a bug report instead of screenshots.