Repository navigation
release(40.0.1): six durability fixes from the v40.0.0 review (#763) - #804
Conversation
) - A self/family holding claim is decided by persist's cohort audience before the scope table's arming check: on a runtime with no table, the unarmed Announce admitted an outsider's claim into rarity and repair. With no directory, the holding is withheld (CC 5.2), never announced to an unknown peer. The v18 'no table means open' pin now covers only the tiers the table governs. - The converger's holding target is a CohortTarget { Full(n), Tuple, Unknown }: an unreadable audience keeps the content this tick, rather than falling through to the tuple's eviction. - Full holding counts each signed holder once, plus the local copy, not the #582 weighted equivalents (those guard deletes), so a fully held content is kept, not repaired forever. - A Revoked cohort content skips the full-holding branch, so EjectHardDelete stays its retry path. - The durability sweep runs as its own task (one at a time, aborted on exit), so the puller keeps receiving rows, retries and key wakes. - The bounded sweep rolls: it saves its room and page cursor and resumes there, so a room past MAX_FILES is eventually visited in full. Witnesses (each fails with its fix reverted): a_cohort_claim_is_refused_from_an_outsider_without_a_scope_table_802, a_fully_held_cohort_content_is_kept_not_repaired_802, a_revoked_cohort_content_is_not_kept_by_the_full_holding_branch_802, the_durability_pass_rolls_past_its_file_budget_802. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011ksniaWCvWoUwFQHRG3HQL
PATCH, same pins (persist v53.0.1, verify v19.0.0), no API change. Evidence TSV at ciris-edge@v40.0.1. Notes: docs/RELEASE_NOTES.md § v40.0.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011ksniaWCvWoUwFQHRG3HQL
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70e38d86c0
ℹ️ 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".
| let claimed = u32::try_from(all_claims.len()).unwrap_or(u32::MAX); | ||
| let holders = claimed.saturating_add(u32::from(local_holds)); |
There was a problem hiding this comment.
Revalidate claimants against the current audience
When cohort membership changes within the 600-second claim TTL, all_claims can still contain a signed claim from a node that has left while full_holding_audience returns only the new audience's size. For example, replacing member B with C leaves A/B's two claims satisfying an audience size of two, so this branch emits Keep even though new member C has no copy. Preserve the resolved audience node set and count only claims whose peer remains in it before deciding that full holding is satisfied.
Useful? React with 👍 / 👎.
| let local_holds = local_by_content.contains_key(&content_id) | ||
| && !all_claims.iter().any(|c| c.peer_id == local_peer_id); |
There was a problem hiding this comment.
Verify the local copy is whole before counting it
HeldFountainContent represents the symbol IDs currently retained and can therefore describe a partial or damaged fountain copy, but this test counts any map entry as a full holder. In a two-node full-holding audience, one remote claim plus a local entry containing only a subset of the required symbols produces holders == audience and emits Keep, suppressing the repair that should restore the local whole copy. Count the local node only after verifying that its retained symbols constitute a complete copy.
Useful? React with 👍 / 👎.
Release PR for v40.0.1 (PATCH from v40.0.0; same pins: persist
v53.0.1, verifyv19.0.0; no API change).Fixes the six defects Codex found in #802's #763 self/family durability code:
CohortTarget { Full, Tuple, Unknown }, andUnknownkeeps the content.Revokedskips the full-holding branch, soEjectHardDeletestays its retry path.Witnesses (each fails with its fix reverted):
a_cohort_claim_is_refused_from_an_outsider_without_a_scope_table_802,a_fully_held_cohort_content_is_kept_not_repaired_802,a_revoked_cohort_content_is_not_kept_by_the_full_holding_branch_802,the_durability_pass_rolls_past_its_file_budget_802. (2) has no direct witness, since no failing-directory double exists.Local gates: fmt; clippy -D warnings on both feature sets; lib suite 1869 (two halves); integration family_files_wire_736, delivery_receipts_738, blob_federation_e2e, self_dag_field_path_717, owned_devices_route_682, chat_message_federates; evidence and hash tests on the release commit.
🤖 Generated with Claude Code
https://claude.ai/code/session_011ksniaWCvWoUwFQHRG3HQL