EMRY-014: JSONL store + v1 compat #59

Merged
vxfemboy merged 2 commits from emry-014-jsonl-store into main 2026-06-25 03:00:56 +00:00
vxfemboy commented 2026-06-25 02:58:14 +00:00 (Migrated from github.com)

Closes EMRY-014 (#12). Branched off main. First emry-store work; first real I/O.

What

  • writer.rs — synchronous JsonlWriter owning events.jsonl (full Event audit trail) + metrics.jsonl (wide MetricRecord rows). Opens append (create if absent) so re-opening a run dir continues the log. Directly testable by reading files back.
  • sink.rs — background JsonlSink: a writer thread fed by a bounded crossbeam channel; batches and flushes every 64 records or 100ms; drops+counts on overflow (project queue invariant); finish() flushes all pending and joins; Drop flushes best-effort.
  • test_util.rs — self-cleaning temp-dir helper (no external dep).

metrics.jsonl stays wide / v1-parseable: resolved metric names + SCREAMING_SNAKE phase. Test feeds an external v1 line and parses it.

Verification

  • ./scripts/pre-commit-rust.sh green: clippy -D warnings, 10 store tests, writer.rs 100% / sink.rs 92% lines, total 98.12% lines
  • Tests: separate-file writes, event + metric roundtrip, external-v1 line, reopen-appends, finish flushes 200 records, full-channel drop-count, Drop-without-finish flush, missing-dir error

Review-driven changes

  • Append mode instead of File::create truncation (conf 85) — protects the audit trail on sidecar restart.
  • Drain-on-disconnect always flushes even on a mid-drain write error (conf 83).
  • Drop surfaces flush failures on stderr rather than swallowing them (conf 80).
  • Declined: hardcoding a scratchpad path into committed tests (env::temp_dir is the portable idiom); converting the documented thread-panic to an error variant (hot path never calls finish(); Drop already absorbs it).
Closes EMRY-014 (#12). Branched off `main`. First emry-store work; first real I/O. ## What - `writer.rs` — synchronous `JsonlWriter` owning `events.jsonl` (full `Event` audit trail) + `metrics.jsonl` (wide `MetricRecord` rows). Opens **append** (create if absent) so re-opening a run dir continues the log. Directly testable by reading files back. - `sink.rs` — background `JsonlSink`: a writer thread fed by a **bounded** crossbeam channel; batches and flushes every 64 records or 100ms; drops+counts on overflow (project queue invariant); `finish()` flushes all pending and joins; `Drop` flushes best-effort. - `test_util.rs` — self-cleaning temp-dir helper (no external dep). `metrics.jsonl` stays wide / v1-parseable: resolved metric names + SCREAMING_SNAKE `phase`. Test feeds an external v1 line and parses it. ## Verification - `./scripts/pre-commit-rust.sh` green: clippy `-D warnings`, 10 store tests, writer.rs 100% / sink.rs 92% lines, total 98.12% lines - Tests: separate-file writes, event + metric roundtrip, external-v1 line, reopen-appends, finish flushes 200 records, full-channel drop-count, Drop-without-finish flush, missing-dir error ## Review-driven changes - **Append mode** instead of `File::create` truncation (conf 85) — protects the audit trail on sidecar restart. - Drain-on-disconnect **always flushes** even on a mid-drain write error (conf 83). - `Drop` surfaces flush failures on **stderr** rather than swallowing them (conf 80). - Declined: hardcoding a scratchpad path into committed tests (env::temp_dir is the portable idiom); converting the documented thread-panic to an error variant (hot path never calls finish(); Drop already absorbs it).
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
femboy/emry!59
No description provided.