Skip to content

feat(corpus): fill to the archive head and extend existing corpora - #8856

Open
shekhirin wants to merge 13 commits into
mainfrom
alexey/corpus-fill-to-head
Open

shekhirin wants to merge 13 commits into
mainfrom
alexey/corpus-fill-to-head

Conversation

@shekhirin

@shekhirin shekhirin commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

tempo corpus fill can now run without a range and extend an existing corpus. --to is optional and defaults to the archive head. Each run appends blocks after the published cursor, instead of rejecting any range other than the one the corpus was created with. A nightly corpus fill + corpus gc then keeps the corpus at the head.

The context no longer pins end, tip and end_tx. The published cursor already holds them. An extending fill checks that the published tip is still canonical and that the fork schedule agrees up to it, then stores its own schedule. Existing corpora need no migration: serde ignores the old fields, and the first extending fill rewrites the stored context. corpus replay reads the published blocks without requiring complete, so it keeps working while a fill runs. gc must still run after a fill, not alongside one.

Tested on a --dev chain. Fill to the head, a no-op refill, more blocks, then an extending fill, replay, gc and replay again all pass. A corpus written by main's binary extends with --verify-existing and replays.

@tempoxyz-bot

tempoxyz-bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

👁️ Cyclops Security Review

✅ Reviewed 6e90fba (latest) · Coverage: partial · ⚠️ 1 open finding · report
⚠️ Not checked: I did not read how the replay::run page-feeding and worker paths handle missing pages or records after an unleased checkpoint expires. I only read the final count check around replay.rs:250-260.
⚠️ Not checked: Incremental lease-acquisition fallback: snapshot substitution and validation bypass: ruled out without reading the cited code at this commit
⚠️ Not checked: Extending corpus publication and cursor-based replay boundaries: ruled out without reading the cited code at this commit
ℹ️ Not verifiable from the source alone (needs running code or deployed state): No runtime test was executed for permission-denied or timed-out lease acquisition followed by concurrent extension and checkpoint retirement. The conclusions distinguish snapshot integrity from unleas

# Severity Finding Introduced Status
1 ⚪ Informational gc can collect files of an extending fill that runs at the same time 36293e1 🟠 Open
2 ⚪ Informational Replay of a corpus being extended loses its pinned checkpoint after the 1h retire lifetime 1e18d9f ✅ Fixed in 3a67183
3 ⚪ Informational Extending fills can expire checkpoints still used by active replays 1e18d9f ✅ Fixed in 3a67183
4 ⚪ Informational A failed lease renewal does not stop the replay, so it keeps reading from a lease that expires 3a67183 ✅ Fixed in ac5fda8
5 ⚪ Informational Lease-renewal failure does not stop the replay before its checkpoint expires 3a67183 ✅ Fixed in ac5fda8
6 ⚪ Informational Extending fills can invalidate long-running block-list replay snapshots 035b346 ✅ Fixed in e989971

Comment thread crates/corpus/src/exec/fill.rs Resolved
@shekhirin shekhirin changed the title feat(corpus): fill up to the archive head when --to is omitted feat(corpus): fill to the archive head and extend existing corpora Nov 2, 2026
Comment on lines +174 to +182
if end <= catalog.cursor.next {
info!(
records = catalog.cursor.next - catalog.context.start,
verified = args.verify_existing,
"Corpus already complete; no writes"
"Corpus already reaches the requested end; no writes"
);
return Ok(());
}
catalog.complete = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational: gc can collect files of an extending fill that runs at the…

fill now reopens complete corpora and opens a writer on them, but gc still assumes a complete corpus has no writer. gc checks complete once, takes no claim, and then runs a GC pass with zero minimum file age. A fill that starts during gc can lose objects it has not yet referenced, and gc only notices the catalog change…

Full finding

gc can collect files of an extending fill that runs at the same time

fill now reopens complete corpora and opens a writer on them, but gc still assumes a complete corpus has no writer. gc checks complete once, takes no claim, and then runs a GC pass with zero minimum file age. A fill that starts during gc can lose objects it has not yet referenced, and gc only notices the catalog change after deleting.

Valid? React with 👍 / 👎.

Comment thread crates/corpus/src/gc.rs
Comment on lines +21 to +24
/// Fails unless the corpus is complete: a fill clears it before opening its writer, so
/// collection needs no minimum file age as long as no fill starts meanwhile. Run it after a
/// fill, not alongside one. Fails as well if the catalog changed meanwhile or its checkpoint
/// no longer opens.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the corpus. On the base, a complete corpus was never written again. Now fill.rs:182-189 claims a complete corpus and opens a writer. gc only checks catalog.complete once at gc.rs:27, then runs run_gc_once with min_age: Duration::ZERO and deletes every unpinned checkpoint. Fix: fence fills through the catalog CAS before gc deletes anything, e.g. publish a gc claim a fill refuses or whose version makes the fill's store.publish(&catalog, prior) fail. The doc's "not alongside one" leaves this to scheduling.

Why this was flagged

Trigger: gc starts on a corpus with complete = true, and a corpus fill (nightly, --to omitted) starts before gc finishes. gc reads the catalog and passes the catalog.complete check at gc.rs:27. The fill then reaches fill.rs:182-189, clears complete, CAS-publishes its claim and opens a SlateDB writer that writes WAL SSTs, manifests and new checkpoints. gc keeps going. At gc.rs:42-43 it deletes every checkpoint except the one pinned when gc started, which can include the fill's new checkpoint. At gc.rs:52-66 it collects manifests, WAL and compacted files with min_age: Duration::ZERO, so the live writer's files go too. The e_tag check at gc.rs:80-83 only runs after the deletions. It reports an error but cannot undo them. The fill can then publish a catalog whose checkpoint points at deleted files, or fail partway. On the base, fill returned early on a complete corpus and never opened a writer, so gc after completion was always safe. The new doc line "Run it after a fill, not alongside one" is the only safeguard, and nothing in the code enforces it.

Verification: On the base, fill returned early on a complete corpus, so no writer was ever opened on one. At HEAD, fill.rs:182 sets catalog.complete = false and fill.rs:189 CAS-publishes the claim. gc checks complete once (gc.rs:26-30), then runs run_gc_once with min_age: Duration::ZERO (gc.rs:45-66). The e_tag check at gc.rs:80-83 fails gc only after the deletions have happened.

Comment thread bin/tempo/src/corpus.rs Resolved
Comment thread crates/corpus/src/gc.rs Resolved

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review found no new issues

No new issues were found in this update; 2 findings from earlier reviews are still open above.

Still open from earlier reviews (2):

  • 🔴 bin/tempo/src/corpus.rs:150 — Long corpus replay runs can now fail partway when a nightly corpus fill extends the same corpus and its GC deletes file…
  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

Comment thread crates/corpus/src/exec/fill.rs Resolved
Comment thread crates/corpus/src/gc.rs Resolved

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still open from earlier reviews (2):

  • 🔴 bin/tempo/src/corpus.rs:150 — Long corpus replay runs can now fail partway when a nightly corpus fill extends the same corpus and its GC deletes file…
  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

Comment thread crates/corpus/src/replay.rs Resolved

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still open from earlier reviews (2):

  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…
  • 🔴 crates/corpus/src/replay.rs:73 — Operators who replay with read-only S3 credentials now fail at startup. Replay never wrote to the corpus before this ch…

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

Comment thread crates/corpus/src/store.rs Resolved

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review found no new issues

No new issues were found in this update; 3 findings from earlier reviews are still open above.

Still open from earlier reviews (3):

  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…
  • 🔴 crates/corpus/src/replay.rs:73 — Operators who replay with read-only S3 credentials now fail at startup. Replay never wrote to the corpus before this ch…
  • Also unresolved: 1 blocking on lines changed since (possibly already fixed).

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

Comment thread crates/corpus/src/replay.rs Resolved
Comment thread crates/corpus/src/exec/replay.rs Resolved

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review completed

Nothing new to post: everything this review found is already covered by existing comments on this pull request or didn't merit a separate one.

Still open from earlier reviews (2):

  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…
  • Also unresolved: 1 blocking on lines changed since (possibly already fixed).

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still open from earlier reviews (2):

  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…
  • Also unresolved: 1 blocking on lines changed since (possibly already fixed).

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

Comment thread crates/corpus/src/fuzz.rs Resolved
Comment thread crates/corpus/src/exec/replay.rs Resolved

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review completed

Nothing new to post: everything this review found is already covered by existing comments on this pull request or didn't merit a separate one.

Still open from earlier reviews (2):

  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…
  • Also unresolved: 1 blocking on lines changed since (possibly already fixed).

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review found no new issues

No new issues were found in this update; 1 finding from earlier reviews is still open above.

3 optional suggestions (nits or notes on pre-existing code) were found and not posted.

Still open from earlier reviews (1):

  • 🔴 crates/corpus/src/gc.rs:25 — Operators who schedule corpus gc next to the nightly corpus fill can now have live writer files deleted, corrupting the…

If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.

This branch has not been deployed

No deployments
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.

2 participants