Skip to content

Publish durable catalog generations - #64

Merged
flyingrobots merged 31 commits into
mainfrom
feature/catalog-generations
Jul 29, 2026
Merged

Publish durable catalog generations#64
flyingrobots merged 31 commits into
mainfrom
feature/catalog-generations

Conversation

@flyingrobots

Copy link
Copy Markdown
Owner

Closes #16.

Problem

Keep had immutable segments but no durable catalog generation that could atomically publish logical record locations without making physical location stable identity.

Invariant affected

For one logical identity, a reader observes one fully admitted catalog generation whose named immutable bytes verify exactly, or receives a typed refusal.

Approach

  • Add canonical catalog and publication-head codecs, checked generation transitions, exact segment-record admission, and immutable snapshots.
  • Add persistent writer exclusion and ordered filesystem publication with idempotent retry and explicit refusal boundaries.
  • Add bounded restart loading, model/corruption/golden tests, and seeded fuzzing for catalog and head parsers.
  • Keep initialization and explicit crash recovery assigned to Build the durable crash-injection and recovery matrix #17.

Alternatives rejected

Serializer-defined catalogs, location-bearing public handles, lock-file existence as writer authority, and silent stage cleanup or overwrite-on-conflict.

Failure modes

Stale expectations, retained stages, malformed or noncanonical state, dangling references, conflicting pool bytes, lock contention, I/O and sync failures, and resource-bound violations return typed refusals.

Tests

Workspace debug and release tests, doctests, all/minimal-feature Clippy and checks, Rust 1.96 compatibility, source/docs/workflow gates, root/fuzz dependency policy and audits, locked fuzz builds, and a catalog-format fuzz smoke run with 4,228,409 executions and no failures.

Benchmark impact

No performance claim. Admission is bounded and scans each referenced segment once; restart retains only caller-bounded segment bytes.

Format and API compatibility

Adds the v1 catalog and publication-head formats and public APIs. No existing public API is removed. Golden bytes freeze the new protocol.

Recovery implications

Forward publication and crash states are documented. Issue #17 owns initialization and explicit recovery; this slice refuses ambiguous retained stages.

Security implications

No unsafe code. Paths after root admission are capability-relative and no-follow; immutable coordinates are reverified; dependencies are pinned, policy-checked, and audited.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 144 files, which is 44 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 737917df-82cd-4893-85db-6386abccc7f1

📥 Commits

Reviewing files that changed from the base of the PR and between be57049 and 4bd62c8.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • fuzz/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (144)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • Cargo.toml
  • README.md
  • deny.toml
  • docs/dependencies/cap-std-and-cap-fs-ext-4.0.2.md
  • docs/dependencies/libfuzzer-sys-0.4.13.md
  • docs/dependencies/serde-and-serde-json-1.0.229-1.0.151.md
  • docs/formats/segment-store-v1/README.md
  • docs/formats/segment-store-v1/catalog.md
  • docs/formats/segment-store-v1/publication.md
  • docs/formats/segment-store-v1/rationale.md
  • docs/formats/segment-store-v1/requirements.md
  • fuzz/Cargo.toml
  • fuzz/README.md
  • fuzz/fuzz_targets/catalog_format.rs
  • src/adapters/admitted_catalog.rs
  • src/adapters/admitted_segment.rs
  • src/adapters/canonical_catalog.rs
  • src/adapters/canonical_publication_head.rs
  • src/adapters/catalog_admission.rs
  • src/adapters/catalog_admission_error.rs
  • src/adapters/catalog_admission_error_display.rs
  • src/adapters/catalog_allocation_phase.rs
  • src/adapters/catalog_decode_error.rs
  • src/adapters/catalog_decode_error_display.rs
  • src/adapters/catalog_decoder.rs
  • src/adapters/catalog_encode_error.rs
  • src/adapters/catalog_encoder.rs
  • src/adapters/catalog_encoding_entry.rs
  • src/adapters/catalog_entries.rs
  • src/adapters/catalog_entry_decode_error.rs
  • src/adapters/catalog_entry_decode_error_display.rs
  • src/adapters/catalog_entry_decoder.rs
  • src/adapters/catalog_entry_fields.rs
  • src/adapters/catalog_entry_plan.rs
  • src/adapters/catalog_entry_sequence.rs
  • src/adapters/catalog_header_decoder.rs
  • src/adapters/catalog_header_encoding.rs
  • src/adapters/catalog_integrity.rs
  • src/adapters/catalog_publication.rs
  • src/adapters/catalog_publication_error.rs
  • src/adapters/catalog_publication_execution.rs
  • src/adapters/catalog_publication_expectation.rs
  • src/adapters/catalog_publication_outcome.rs
  • src/adapters/catalog_publication_phase.rs
  • src/adapters/catalog_publication_readiness.rs
  • src/adapters/catalog_publication_receipt.rs
  • src/adapters/catalog_publication_storage.rs
  • src/adapters/catalog_record_binding.rs
  • src/adapters/catalog_restart_artifact.rs
  • src/adapters/catalog_restart_byte_limit.rs
  • src/adapters/catalog_restart_error.rs
  • src/adapters/catalog_restart_io.rs
  • src/adapters/catalog_restart_loader.rs
  • src/adapters/catalog_restart_phase.rs
  • src/adapters/catalog_restart_policy.rs
  • src/adapters/catalog_restart_segments.rs
  • src/adapters/catalog_snapshot.rs
  • src/adapters/catalog_snapshot_admission.rs
  • src/adapters/catalog_snapshot_error.rs
  • src/adapters/catalog_successor.rs
  • src/adapters/catalog_transition.rs
  • src/adapters/catalog_transition_error.rs
  • src/adapters/checksummed_catalog.rs
  • src/adapters/checksummed_publication_head.rs
  • src/adapters/closed_segment.rs
  • src/adapters/decoded_catalog_entry.rs
  • src/adapters/filesystem_catalog_artifact.rs
  • src/adapters/filesystem_catalog_catalog.rs
  • src/adapters/filesystem_catalog_current.rs
  • src/adapters/filesystem_catalog_head.rs
  • src/adapters/filesystem_catalog_publication_error.rs
  • src/adapters/filesystem_catalog_publisher.rs
  • src/adapters/filesystem_catalog_publisher_tests.rs
  • src/adapters/filesystem_catalog_segment.rs
  • src/adapters/filesystem_catalog_snapshot.rs
  • src/adapters/filesystem_catalog_storage.rs
  • src/adapters/filesystem_platform_admission.rs
  • src/adapters/filesystem_publisher_authority.rs
  • src/adapters/filesystem_segment_stage.rs
  • src/adapters/filesystem_segment_stage_tests.rs
  • src/adapters/filesystem_writer_lock.rs
  • src/adapters/framed_blake3.rs
  • src/adapters/loaded_segment.rs
  • src/adapters/mod.rs
  • src/adapters/physical_pool_name.rs
  • src/adapters/publication_head_decode_error.rs
  • src/adapters/publication_head_decode_error_display.rs
  • src/adapters/publication_head_decoder.rs
  • src/adapters/publication_head_encoder.rs
  • src/adapters/sealed_segment.rs
  • src/adapters/segment_publication.rs
  • src/adapters/segment_publication_error.rs
  • src/adapters/segment_record_checksum.rs
  • src/adapters/segment_record_header_encoding.rs
  • src/adapters/segment_record_identity_encoding.rs
  • src/adapters/segment_seal_hash.rs
  • src/adapters/sync_capable_directory.rs
  • src/adapters/writer_lock_acquire_error.rs
  • src/adapters/writer_lock_acquire_phase.rs
  • src/catalog/digest.rs
  • src/catalog/generation.rs
  • src/catalog/generation_error.rs
  • src/catalog/length.rs
  • src/catalog/length_error.rs
  • src/catalog/mod.rs
  • src/lib.rs
  • tests/catalog.rs
  • tests/catalog/entry_laws.rs
  • tests/catalog/format_oracle.rs
  • tests/catalog/header_laws.rs
  • tests/catalog/integrity_laws.rs
  • tests/catalog/mutation_support.rs
  • tests/catalog/ordering_laws.rs
  • tests/catalog_encoding.rs
  • tests/catalog_filesystem_publication/authority_laws.rs
  • tests/catalog_filesystem_publication/directory_laws.rs
  • tests/catalog_filesystem_publication/initialization_laws.rs
  • tests/catalog_filesystem_publication/refusal_laws.rs
  • tests/catalog_generation.rs
  • tests/catalog_locations.rs
  • tests/catalog_locations/refusal_laws.rs
  • tests/catalog_model.rs
  • tests/catalog_publication.rs
  • tests/catalog_publication/closed_stage_laws.rs
  • tests/catalog_publication/preflight_laws.rs
  • tests/catalog_publication/recording_storage.rs
  • tests/catalog_publication/segment_selection.rs
  • tests/catalog_restart.rs
  • tests/catalog_restart/refusal_laws.rs
  • tests/catalog_snapshot.rs
  • tests/catalog_transition.rs
  • tests/catalog_writer_lock.rs
  • tests/publication_head.rs
  • tests/publication_head/format_oracle.rs
  • tests/segment_filesystem_stage/sandbox.rs
  • xtask/src/fuzz_campaign/target/tests.rs
  • xtask/src/fuzz_seed_corpus.rs
  • xtask/src/fuzz_seed_corpus/catalog_seeds.rs
  • xtask/src/fuzz_seed_corpus/tests/materialization.rs
  • xtask/tests/dependency_policy_contract.rs
  • xtask/tests/segment_store_protocol_contract.rs
  • xtask/tests/segment_store_protocol_contract/parser_fuzz_laws.rs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Owner Author

Self-review activity summary

# Severity Area Finding Commit Outcome
1 P0 src/adapters/segment_publication.rs Publication admitted a still-writable segment stage. 2d2a777 Closed-stage token required before publication.
2 P0 src/adapters/filesystem_segment_stage.rs Stage creation could bypass persistent writer authority. 039ce7e Stage creation is bound to the held writer lock.
3 P0 src/adapters/filesystem_catalog_publisher.rs Publisher teardown could release authority before stage handles. 8ed7533 Field/drop ordering retains authority through handle teardown.
4 P1 src/adapters/catalog_admission.rs Admission rescanned records once per catalog entry. aad0309 Each referenced segment is indexed once under caller bounds.
5 P1 src/adapters/catalog_entry_plan.rs Admission accepted supplied segments not referenced by the catalog. 8fe1c5a Exact admitted-segment set is enforced.
6 P1 src/adapters/catalog_encoder.rs Encoding ignored unreferenced supplied segments, including empty ones. ddb5243 Exact input-set mismatch returns a typed refusal.
7 P3 src/adapters/canonical_catalog.rs Public documentation understated exact input-set behavior. 5ab28cd Rustdoc names exact segment-set contracts.
8 P0 src/adapters/catalog_publication.rs A successful durable publication could not be retried idempotently. f0b1527 Exact published retries reverify and return a synchronized receipt.
9 P0 src/adapters/filesystem_catalog_current.rs Retained stage evidence could be discovered after mutation or ignored. 98d8e80 Every retained stage is refused during preflight before mutation.
10 P1 .github/workflows/ci.yml Fuzz dependency policy used the wrong config path and incomplete exceptions. 45b4e9f CI uses the reviewed root policy with exact package/version exceptions.
11 P0 fuzz/Cargo.lock The committed fuzz lock omitted newly admitted capability dependencies. c3cc0bd Locked fuzz builds now reproduce from committed state.
12 P1 fuzz/fuzz_targets/catalog_format.rs New catalog and head decoders lacked parser fuzz coverage. a8e3af1 Bounded seeded fuzz target covers both format boundaries.

All findings were resolved with separate RED → GREEN → VERIFY → COMMIT cycles. Final local gates are green: debug/release workspace tests, all/minimal checks and Clippy, doctests, Rust 1.96 compatibility, documentation/source/workflow checks, root/fuzz dependency policy and audits, locked fuzz builds, and a 4,228,409-execution catalog-format smoke campaign with no failures.

Copy link
Copy Markdown
Owner Author

@codex review please

Copy link
Copy Markdown
Owner Author

CI repair update

# Severity File Finding Commit Outcome
13 P0 src/adapters/filesystem_catalog_artifact.rs:26 Linux opened no-follow protocol directories as O_PATH, causing every required directory sync_all to fail with EBADF. 7e33c16 Publisher directory admission now retains no-follow, nonblocking, read-capable handles and verifies directory type before use.

RED: Ubuntu CI failed four catalog publication laws at the exact SynchronizeSegments phase with OS error 9.

GREEN: 11/11 focused filesystem publication laws, full locked workspace tests, all-feature Clippy with -D warnings, Rust 1.96 check, source-structure gate, pinned documentation gate, formatting, and diff checks pass locally. New laws preserve exact non-directory and symlink refusal behavior.

@codex review please — latest head is 7e33c16.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e33c16d94

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/adapters/segment_publication.rs
Comment thread src/adapters/filesystem_catalog_current.rs
Comment thread src/adapters/catalog_decoder.rs Outdated
Comment thread src/adapters/filesystem_catalog_publisher.rs

Copy link
Copy Markdown
Owner Author

Review remediation activity summary

Severity File Finding Commit Outcome
P1 src/adapters/segment_publication.rs Metadata-equivalent external stages could authorize retained filesystem bytes. a1c5acb Segment selection now consumes the sealed stage through its creating publisher and verifies process-local authority.
P1 src/adapters/filesystem_catalog_current.rs Missing HEAD was treated as clean initialization even when immutable-pool crash evidence remained. e3e7c00 First publication now requires both durable pools to be empty and preserves every orphan as recovery evidence.
P1 src/adapters/filesystem_catalog_publisher.rs Publisher construction did not require proven platform semantics. e9cb1eb Production construction now consumes an opaque, root-bound FilesystemPlatformAdmission; issue #17 owns the crash-tested producer.
P2 src/adapters/catalog_decoder.rs Entry semantics could precede checksum and digest refusal. 4bd62c8 Catalog integrity now verifies after fixed framing and exact length, before interpreting entries.

All four review threads are resolved. Each finding used its own RED → GREEN → VERIFY → COMMIT cycle. Exact pushed head: 4bd62c8a792168bbfdc22f1f37979b37c90b91b2.

Local merge gates are green: debug and release workspace suites, doctests, all/minimal feature checks, all/minimal Clippy with -D warnings, Rust 1.96 compatibility, golden and conformance corpora, source structure, fuzz-workspace format/check/Clippy, malformed-documentation refusals, documentation/workflow integrity, formatting, and repository diff hygiene.

@codex review please — review the current head 4bd62c8a792168bbfdc22f1f37979b37c90b91b2.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 4bd62c8a79

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@flyingrobots
flyingrobots merged commit 3a42bd4 into main Jul 29, 2026
5 checks passed
@flyingrobots
flyingrobots deleted the feature/catalog-generations branch July 29, 2026 11:23
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.

Implement catalog generations and one-writer/many-reader publication

1 participant