protean eventstore
The protean eventstore command group inspects and maintains the event store.
Its first command, verify, runs a read-only integrity check.
All commands accept a --domain option to specify the domain module path
(defaults to the current directory).
Commands
| Command | Description |
|---|---|
protean eventstore verify |
Check the event store's internal consistency |
protean eventstore verify
Reads the whole store once and reports any violation of its internal invariants. It mutates nothing and works against any adapter (memory, MessageDB).
protean eventstore verify --domain=my_domain
It checks these invariants:
- Rows are well-formed. Every message carries its
id,stream_name, andposition. - Position is gapless. Each stream's
positionruns from 0 without gaps. - Global position is strictly increasing.
global_positionincreases store-wide across every message. - Message ids are unique. No message id appears twice.
- Snapshots are well-formed and do not run ahead. Each
:snapshot-stream carries an integer_versionthat stays at or below the head position of its aggregate stream.
A corrupt row is reported, not skipped: a missing field or a malformed snapshot becomes a violation rather than a silent pass.
Options
| Option | Description | Default |
|---|---|---|
--domain |
Domain module path | . (current directory) |
--json |
Emit the result as the shared CLI envelope | Off |
Output
A clean store prints a one-line summary and exits 0:
Event store is consistent: 42 message(s) across 7 stream(s), 0 violations.
When a violation is found, it prints a table naming each one and exits 1:
Event store integrity violations
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Kind ┃ Stream ┃ Position ┃ Detail ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ position_gap │ test::user-abc │ 2 │ Stream 'test::user-abc' │
│ │ │ │ jumps to position 2; │
│ │ │ │ expected 1. │
└───────────────┴─────────────────┴──────────┴─────────────────────────────┘
1 violation(s) across 2 message(s) and 1 stream(s).
JSON output
With --json, the command emits the shared CLI result envelope. The report is
under data, with the violation list under data.violations:
The command serializes with sorted keys, so real output is alphabetized:
{
"data": {
"message_count": 42,
"ok": true,
"stream_count": 7,
"violations": []
},
"diagnostics": [],
"status": "pass",
"version": "0.1.0"
}
Each violation carries a stable kind (malformed_message,
duplicate_message_id, position_gap, non_monotonic_global_position,
malformed_snapshot, or snapshot_ahead_of_stream), the stream and
position it was found at (either may be null), and a human-readable
detail.
Exit codes
| Code | Meaning |
|---|---|
| 0 | The store is consistent. |
| 1 | At least one violation was found. |
| 2 | Usage or environment error (no or unloadable domain), under --json. |
Without --json, a load error aborts with exit 1, the same as every other
protean command, so exit 1 in human mode covers both a real violation and a
domain that failed to load. Use --json when a script needs to tell the two
apart.
Backup and restore
verify checks the store's internal consistency. Physical backup and restore
stay with the database and its own tooling. For MessageDB, that means the
PostgreSQL tooling (pg_dump, pg_restore, and point-in-time recovery). Run
protean eventstore verify after a restore to confirm the recovered store is
internally consistent.
Domain discovery
The protean eventstore commands use the same domain discovery mechanism as
protean server. See Domain Discovery for the full
resolution logic.