mikebridge opened a new pull request, #44012: URL: https://github.com/apache/superset/pull/44012
### SUMMARY Fixes SC-115615 — two retention-interaction races in the versioning backend, both confirmed by two independent review panels (10-lens capstone + Codex capstone Highs #4/#5), sharing test scaffolding. Both scale with `SUPERSET_VERSION_HISTORY_RETENTION_DAYS` set and capture on — the fleet-enablement configuration. **1. Freshly captured baselines could immediately expire** (`superset/versioning/baseline/insertion.py`). The baseline transaction's `issued_at` was sourced from the entity's historical `changed_on`, but the retention prune keys on `issued_at` — and the baseline's shadow row is closed by the same flush's real edit, so the prune's live-row preservation rule doesn't protect it. Capture a baseline for an entity last edited outside the retention window and the very next prune deleted it: the entity's pre-edit history gone permanently. The baseline is now stamped with **capture time on one clock** (naive-UTC, matching Continuum's storage and the prune's cutoff derivation; the old `sa.func.now()` fallback mixed in the DB server's local clock). Panel chronology is unaffected — baseline-first ordering is by `operation_type`, not `issued_at` — and attribution stays with the pre-versioning author via `user_id`. **2. Snapshot fetch by OFFSET shifted under a concurrent prune** (`superset/versioning/queries.py`). `get_version` resolved the target to a stable `transaction_id`, threw it away, and re-fetched by positional OFFSET — a prune committing in between shifts the offset and silently surfaces a **different version's snapshot under the requested version uuid**, on the preview/restore read path. The fetch now addresses the row by the resolved `transaction_id` (identity filter kept, so a transaction id recycled on another entity can never match). The restore command already addressed by `transaction_id`; this closes the read side. ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF N/A — backend correctness. ### TESTING INSTRUCTIONS ```bash python -m pytest tests/unit_tests/versioning -q # 149 passed (4 new in test_retention_races.py) ``` The new tests drive the **real** production functions against a shared Continuum-shaped in-memory store. Reverted-fix control (both fixed files checked out from the base commit): exactly the two race tests flip — `test_baseline_survives_a_full_retention_window_from_capture` (baseline expires immediately) and `test_get_version_returns_resolved_tx_after_concurrent_prune` (OFFSET returns the successor's snapshot) — while the attribution/shadow-shape and no-prune controls stay green in both states (`2 failed, 2 passed`). ### ADDITIONAL INFORMATION - [x] Has associated issue: SC-115615 (refs apache/superset#41551 capstone; sc-111918 rollout) - [x] Required feature flags: `ENABLE_VERSIONING_CAPTURE` (+ retention configured, for the code paths involved) - [ ] Changes UI - [ ] Includes DB Migration (follow approval process in [SIP-59](https://github.com/apache/superset/issues/13351)) - [ ] Introduces new feature or API - [ ] Removes existing feature or API 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01JRLEJS4mUqKBoPjSjviKUW -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
