Phase 9: Event journal — append-only mutation history

- journald crate: immutable event log for every data mutation
- Events: entity_type, entity_id, field, action, old_value, new_value,
  actor, source, workspace_id, timestamp
- In-memory buffer with configurable flush threshold (default 100 events)
- Flush writes events as Parquet to journal/ directory
- Query: GET /journal/history/{entity_id} — full history of any record
- Query: GET /journal/recent?limit=50 — latest events across all entities
- Convenience methods: record_insert, record_update, record_ingest
- Stats: GET /journal/stats — buffer size, persisted file count
- Manual flush: POST /journal/flush
- Per ADR-012: events are never modified or deleted

This is the single most important future-proofing decision.
Once history is lost, it's gone forever.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-03-27 09:09:33 -05:00
co-authored by Claude Opus 4.6
parent 3b695cd592
commit bf7cf96911
8 changed files with 499 additions and 1 deletions
Generated
+19
View File
@@ -2376,6 +2376,7 @@ dependencies = [
"axum",
"catalogd",
"ingestd",
"journald",
"object_store",
"opentelemetry",
"opentelemetry-stdout",
@@ -3018,6 +3019,24 @@ dependencies = [
"libc",
]
[[package]]
name = "journald"
version = "0.1.0"
dependencies = [
"arrow",
"axum",
"bytes",
"chrono",
"object_store",
"parquet",
"serde",
"serde_json",
"shared",
"storaged",
"tokio",
"tracing",
]
[[package]]
name = "js-sys"
version = "0.3.91"