Skip to content

feat(31): shared invariants module in quickwit-dst#6246

Merged
g-talbot merged 55 commits intomainfrom
gtt/phase-31-execute
Apr 8, 2026
Merged

feat(31): shared invariants module in quickwit-dst#6246
g-talbot merged 55 commits intomainfrom
gtt/phase-31-execute

Conversation

@g-talbot
Copy link
Copy Markdown
Contributor

Summary

  • Adds invariants/ module to quickwit-dst — the single source of truth for invariant definitions shared across the verification pyramid (TLA+ specs, stateright models, production code)
  • InvariantId enum catalogs all 20 invariants (SS-1..5, TW-1..3, CS-1..3, MC-1..4, DM-1..5) with Display and descriptions
  • Shared pure functions: window_start_secs(), is_valid_window_duration(), compare_with_null_ordering()
  • check_invariant! macro always evaluates the condition (debug and release), implementing both Layer 3 (Prevention — debug_assert! panic in debug) and Layer 4 (Production — pluggable InvariantRecorder for Datadog metrics)
  • set_invariant_recorder(fn) wires up statsd at process startup; no recorder = no-op (single OnceLock load)
  • stateright is now an optional dependency behind model-checking feature — production crates pull only the invariant definitions, not the model checker
  • quickwit-parquet-engine uses shared functions and check_invariant! macro instead of inline debug_assert!

Stacks on gtt/phase-31-pg-metastore (PR #6245).

Test plan

  • cargo test -p quickwit-dst — 11 invariant unit tests + 2 doctests pass
  • cargo test -p quickwit-dst --features model-checking — all 24 tests pass (stateright models use shared functions)
  • cargo test -p quickwit-parquet-engine — all 153 tests pass
  • cargo test -p quickwit-metastore --all-features — all 187 tests pass (including postgres)
  • cargo test -p quickwit-indexing --all-features — 234 pass (8 pre-existing Pulsar/GCP PubSub flakes skipped)
  • cargo test -p quickwit-integration-tests --all-features — all 46 pass
  • cargo clippy -p quickwit-dst --all-features --tests — clean
  • cargo clippy -p quickwit-parquet-engine --all-features --tests — clean

🤖 Generated with Claude Code

@g-talbot g-talbot force-pushed the gtt/phase-31-pg-metastore branch from c8836d6 to eccf657 Compare March 31, 2026 20:41
@g-talbot g-talbot force-pushed the gtt/phase-31-execute branch 2 times, most recently from 3eb3316 to c4418dd Compare March 31, 2026 20:55
@g-talbot g-talbot force-pushed the gtt/phase-31-pg-metastore branch 2 times, most recently from 6eeaecd to f2113e5 Compare March 31, 2026 21:03
@g-talbot g-talbot force-pushed the gtt/phase-31-execute branch 2 times, most recently from aa5ff45 to 142ddd6 Compare March 31, 2026 21:08
@g-talbot g-talbot force-pushed the gtt/phase-31-pg-metastore branch from f2113e5 to 0d561b4 Compare March 31, 2026 21:08
@g-talbot g-talbot force-pushed the gtt/phase-31-execute branch from 142ddd6 to 972bd20 Compare March 31, 2026 21:26
@g-talbot g-talbot force-pushed the gtt/phase-31-pg-metastore branch from 0d561b4 to 8ba9201 Compare March 31, 2026 21:26
@g-talbot g-talbot force-pushed the gtt/phase-31-execute branch from 972bd20 to 73c90c4 Compare March 31, 2026 21:29
@g-talbot g-talbot force-pushed the gtt/phase-31-pg-metastore branch from 8ba9201 to 0761d11 Compare March 31, 2026 21:30
@g-talbot g-talbot force-pushed the gtt/phase-31-execute branch from 73c90c4 to 44bd6bb Compare March 31, 2026 21:31
@g-talbot g-talbot force-pushed the gtt/phase-31-pg-metastore branch from 0761d11 to b551b13 Compare March 31, 2026 21:31
g-talbot and others added 24 commits April 6, 2026 12:46
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…arquet-engine

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Matthew Kim <matthew.kim@datadoghq.com>
Co-authored-by: Matthew Kim <matthew.kim@datadoghq.com>
Resolve merge conflicts by taking main's versions of otel_metrics.rs
and arrow_metrics.rs (the PR didn't modify these files — conflicts
came from the base branch divergence). Kept PR's table_config module
export in quickwit-parquet-engine/src/lib.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pre-existing splits were serialized before the parquet_file field was
added, so their JSON doesn't contain it. Adding #[serde(default)]
makes deserialization fall back to empty string for old splits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the commit timeout fires and the accumulator contains only
zero-column batches, union_fields is empty and concat_batches fails
with "must either specify a row count or at least one column".
Now flush_internal treats empty union_fields the same as empty
pending_batches — resets state and returns None.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve Cargo.lock/Cargo.toml merge conflicts
- P1 (sort column lookup): Already addressed by sort fields tag_ prefix
  fix — sort field names now match Parquet column names
- P2 (window_start at epoch 0): Remove time_range.start_secs > 0 guard
  so window_start is computed for all batches when window_duration > 0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve writer.rs conflict: keep META-07 self-describing roundtrip test
- P1 (create_timestamp serde): Add #[serde(default)] to
  StoredMetricsSplit.create_timestamp for backward-compatible reads
  of pre-existing file-backed index JSON
- P1 (compaction window overlap): No change needed — Bound::Included
  vs Bound::Excluded already handles half-open interval semantics
  correctly, and the edge case (zero duration) is impossible
- fields.rs: No change — Matt noted it resolves with wide schema rebase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Base automatically changed from gtt/phase-31-pg-metastore to main April 8, 2026 15:24
g-talbot and others added 2 commits April 8, 2026 14:45
- Resolve postgres.rs conflict: keep check_invariant! macros, add
  window_duration_secs consistency check
- Group setup_dogstatsd_exporter + setup_invariant_recorder into
  single setup_metrics() function (fulmicoton-dd review)
- Rename `id` to `invariant_id` in invariant_recorder (fulmicoton-dd review)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@g-talbot g-talbot merged commit 777a338 into main Apr 8, 2026
8 checks passed
@g-talbot g-talbot deleted the gtt/phase-31-execute branch April 8, 2026 19:02
g-talbot added a commit that referenced this pull request Apr 9, 2026
UPSTREAM-CANDIDATES.md incorrectly stated TLA+ specs and Stateright
models don't exist. They do (contributed in #6246): ParquetDataModel.tla,
SortSchema.tla, TimeWindowedCompaction.tla, plus quickwit-dst invariants
and Stateright model tests. Updated to accurately reflect that the
remaining aspirational piece is the simulation infrastructure (SimClock,
FaultInjector, etc.).

Also removed the /sesh-mode aspirational entry — it's actively being
used and the underlying specs/models are real.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants