0.5.218: evicting a device is one act that reaches every device; quorum leave/dissolve replicate - #700
Merged
Conversation
…dy joins without consent
EVICT (CSD-037, the stolen-device path). `POST /v1/self/nodes/{node}/release`
and `POST /v1/self/occurrence/revoke` converge on `self_devices::evict_device`:
withdraw the owner-binding(s) (owner-signed `withdraws`), revoke the device's
occurrence(s) through persist's SIGNED `put_identity_occurrence_revocation`
(signed by the owner's pen, so the IdentityOccurrenceRevocation plane carries
it), kick replication, and read both halves back from persist. Release now
revokes the node's content-KEM occurrence; revoking an occurrence that IS an
owned node withdraws its binding. The revoke moved to the self-device router
and authorises the owner's session (the app's bearer; it answered 401 before),
never a delegate. Every answer names each part done and each part that failed
(`self.evict_incomplete`), and states that already-shared history stays
readable by the evicted device (no DEK rotation, no re-encryption). A source
gate pins that `put_identity_occurrence_revocation_local` has no caller in src/.
CONSENT TO JOIN (maintainer's ruling 2026-09-30; CIRISConstitution#133,
CIRISPersist#955). Every roster-growing HTTP door answers 409
`membership.consent_required`: family and community direct adds, a quorum
envelope/cosign/assemble whose proposed roster grows, and a create whose
founding roster names anyone but the founder. Remove, role, leave, dissolve,
re-adding an active member and pair rooms are unaffected. Tests build
multi-member rosters through clearly named test-only fixtures; the devices
ladder's `family` rung asserts the refusal and the downstream family rungs are
red-expected on #955.
QUORUM LEAVE/DISSOLVE AMENDMENTS: stopped, not faked. persist v51.1.0's
`supersede_family_with_quorum` refuses an empty proposed roster ("malformed
accord family envelope: group has no members"), and a self-leave cannot meet a
quorum:M/N on the leaver's signature; documented at both sites, pinned by an
ignored red test.
STALE MARKERS: persist v49 closed #907/#908/#910 — the #907 widened-member
read runs un-ignored; communities.rs, the FSD and the devices ladder corrected
additively.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…vict-device-0.5.218 # Conflicts: # Cargo.toml
…vict-device-0.5.218 # Conflicts: # Cargo.toml
…vict-device-0.5.218 # Conflicts: # Cargo.toml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Into
chore/adopt-edge-v33(#697; edge v34.3.0 / persist v51.1.0 / verify v18.0.0).1. Evicting a device is ONE signed act (CSD-037, the stolen-device path)
POST /v1/self/nodes/{node}/releaseandPOST /v1/self/occurrence/revokenow share one function,self_devices::evict_device. It withdraws the owner-binding(s) with owner-signedwithdraws. It revokes the occurrence(s) through persist's signedput_identity_occurrence_revocation, signed by the owner's pen, so theIdentityOccurrenceRevocationplane carries it. It kicks replication. Then it reads both halves back from persist (nodes_owned_by,list_identity_occurrences_active).force_self.auth::occurrenceto the self-device router. It is now authorised like release: the owner's session, with the owner's pen signing on the server. The app's bearer is enough; before this change every call answered 401. Delegates and non-owners are still refused.Ok(_)arms: an incomplete part answersself.evict_incomplete, 500.history. It says that history already shared stays readable by the evicted device. There is no DEK rotation and no re-encryption; only new content and new room epochs are withheld. A test pins this: the grant on a file written before eviction stays, and a file written after eviction carries nokey_grantto the evicted occurrence.put_identity_occurrence_revocation_localhas no caller insrc/. Its allow-list is empty.2. Nobody joins without their own consent (maintainer's ruling 2026-09-30; CIRISConstitution#133, CIRISPersist#955)
These doors now answer 409
membership.consent_required, a literal id shared by families and communities:POST …/membersfor families and communities;Unaffected: remove, role changes, leave, dissolve, re-adding someone who is already active (still
*.already_member), and pair rooms. The refusal sits at the HTTP doors only.The tests now assert each refusal. Where a test is about what happens after a join, it builds the roster through
test_only_*fixtures undertests/. There is no production bypass. In the devices ladder, thefamilyrung now asserts the refusal, andfamily_on_b/family_file_*are marked red-expected on #955.3. Quorum leave and dissolve as replicating amendments: stopped, not faked
supersede_family_with_quorumwith an empty proposed roster. persist refuses it:verify_membership_quorum: membership change not authorized: malformed accord family envelope: group has no members. The ignored red testa_quorum_dissolve_replicates_as_an_amendmentpins this.quorum:M/N, so the leaver's single signature cannot meet it, and rule 5 says leaving is never put to a quorum.Both sites document what persist would need.
4. Stale #907/#908/#910 markers
communities.rs, FSD §1.1 / §2.2 / §4 / §6, and the devices ladder. The Cargo.toml 0.5.218 headline was also appended to.Localization
Two new ids, both added to
KNOWN_UNLOCALIZED:self.evict_incompleteandmembership.consent_required. The ratchet goes from 139 to 141. Withciris-client0.5.225,--strictpasses.🤖 Generated with Claude Code
https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf