fix(engine): journal a root-only debt when a dropped version's staged root is gone - #2105
Conversation
… root is gone A drop whose staged root is gone, fails its own CID, or does not decode now journals a retire-ledger entry of the new origin dropped root, keyed by the root CID the op record names and priced at its size. The settle fetches the root, reads the owing node as unconfirmed and retires the whole version under the node's record. A root no source serves stays owed as a TargetUnexpandable stall. The preserved-set trim now journals this debt for an entry whose root stopped opening, where it dropped the entry in silence before. Implements ADR 0059 D1 and its blueprint rewords.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: FSM1/cipher-box/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (8)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. WalkthroughDropped staged versions now journal root-only retirement debt when their staged root is unavailable or cannot be expanded. Reclaim processing fetches and expands that root; unexpandable debt remains pending. The retirement ledger, staging reconciliation, tests, and related documentation were updated. ChangesDropped-root retirement debt
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant DroppedVersionDebts
participant RetirementLedger
participant expand_owed
participant RootSource
participant expand_staged_root
participant RetireBatches
DroppedVersionDebts->>RetirementLedger: journal DroppedRoot with root CID and quoted figure
expand_owed->>RootSource: fetch root CID
RootSource-->>expand_owed: return root block
expand_owed->>expand_staged_root: expand root block
expand_staged_root-->>expand_owed: return targets or unexpandable result
expand_owed->>RetireBatches: send batches for expanded targets
Merge Risk: ⚪ Minimal · up to The change preserves retirement debt when staged roots are unusable and settles it when the root is available. No merge-blocking issue was found; merge after normal checks pass. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change makes previously untracked retirement work recoverable while retaining record-scoped retirement and content validation. No introduced security vulnerability was established. Risk remains low rather than minimal because concurrent recovery behavior and server-side authorization were not fully established. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
… expand, and record ADR 0059 in the ADRs
…arm of expand_owed expand_staged_root checks the root CID and decodes the root itself, so the manifest gate before it adds no condition. The settle match names each origin, so a new origin does not fall into the quoted-total arm silently.
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Summary
This change implements ADR 0059 D1.
OwingRecord::Unconfirmed, and retires the whole version under the node's record.TargetUnexpandablestall. Its figure stays in the pending-reclaim figure.blueprint/engine.md"Retirement" and "Referenced equals kept" carry the rewords that ADR 0059 Consequences 1 and 2 name.Test plan
write_plane::a_discarded_version_whose_staged_root_is_gone_still_retires_its_rows: a parked version loses its staged root, the member discards it, and the settle retires every block under the node's record. This test fails without the fix.retireunit tests: a dropped root round-trips, and a tail reads as unwritten. The settle retires it off the fetched root under the node's record, as unconfirmed. A root that no source serves stalls asTargetUnexpandableat its quoted figure. Hand-framed bytes of a dropped-version entry from the previous release still decode.stagingunit tests: a trimmed version whose root is gone owes its root alone. A root that fails its CID is released and owes a dropped-root debt.cargo fmt --all,cargo clippy --workspace --all-targets -- -D warnings,cargo test -p cipherbox-engine,cargo check -p cipherbox-wasm --target wasm32-unknown-unknown,pnpm lint:md,pnpm lint:tracker-refs.Closes #2065.
Summary by CodeRabbit
Note
Journal root-only
DroppedRootdebt when a dropped version's staged root is gonePreviously, dropping a staged version whose root was missing, failed CID verification, could not be decoded, or did not expand would silently lose registry debt. Now such drops journal a root-only debt.
DroppedRootvariant toDebtOriginin retire_ledger.rs, encoded as a versioned ledger entry with no target-set tail. Entries with an unexpected tail are treated as unwritten.DroppedVersionDebts.drop_stagedin staging.rs always journals a debt: readable roots still carry a full target set, others journal the root alone with the operation's plaintext size (or zero).reconcile_preserved_dead_lettersalso converts preserved entries with missing roots into debt.DroppedRootdebts asUnconfirmed, fetches the root before deriving its target set, and expands with the staged-root profile instead of the quoted manifest size. If no source serves the root, the debt stays owed at its quoted figure.DroppedRootdebts settle via the unconfirmed-record path, so a fetchable-but-wrong gateway root could retire a derived target set under the node's name; checknet.retire.expand_owed'sDroppedRootbranch.Macroscope summarized 6788a4d.