Skip to content

membership: allow non-overlapping re-entry for the same member/group/role identity #606

Open

Description

@seonghobae

Finding

MembershipNetwork::insert currently indexes only (member_id, group_id, role) and therefore rejects every later assignment with the same identity, even when the event-time validity intervals are strictly disjoint. This contradicts the membership model's own time-varying contract and prevents a member from leaving and later re-entering the same group/role.

This is scientifically material for longitudinal composition: a caller cannot represent repeated organizational/community membership spells without either changing identity artificially or flattening event-time history. The new single-membership admission in #605 would inherit the same defect because admit_single_membership reads MembershipNetwork state.

Public RED

On the #605 single-writer branch, add a repository-owned contract showing that two assignments with the same (member, group, role) but disjoint closed validity intervals must both be accepted, must admit at their respective event times, and must be inactive in the gap. The current implementation should fail on the second insert.

Also preserve fail-closed behavior for overlapping or endpoint-touching closed intervals of the same identity; because membership validity uses included bounds, two intervals that share an endpoint are simultaneously active at that instant and must not both be admitted.

Causal repair

Repair MembershipNetwork::insert so assignment identity and temporal overlap are considered together. Do not relax cross-group/cross-role multiple-membership preservation and do not rewrite event-time history. Keep exact duplicate/overlapping same-identity inserts rejected; allow only strictly disjoint repeated spells.

Acceptance

  • realistic RED on the current feat(membership): add owner-issued single-membership admission #605 lineage before production repair;
  • disjoint same-identity re-entry accepted and queryable at both periods;
  • gap remains inactive;
  • overlapping and touching closed intervals fail closed;
  • existing simultaneous group/role membership behavior is unchanged;
  • exact-head Rust/rustdoc/tests/coverage/security/CodeQL/Semgrep and independent current-head review before protected-main landing;
  • ordinary-forward only; no force push, destructive rebase, skip/xfail, or gate weakening.

This issue is a Membership bounded-context repair prerequisite for #604; it does not broaden the CWC estimand.

Activity

  1. seonghobae commented on Sep 19, 2026

    @seonghobae
    ContributorAuthor

    Owner single-writer lineage is now executable on #605.

    • RED 2233c2cce9eac1817f1dcf3542a002ed98beacca: public contract proves current MembershipNetwork rejects a strictly disjoint same (member, group, role) re-entry and also pins overlap/touching fail-closed semantics.
    • Causal repair 71c85c7260f968be6f68680d57222e3bfa007f86: MembershipNetwork::insert now uses the canonical Allen interval relation and accepts same-identity history only when the existing and candidate spells are strictly Before/After; every intersecting/touching/equal relation remains DuplicateMembershipAssignment.
    • Edge coverage 86808b8f972112e7448e49f101d2dfc0b1a544a2: exercises reverse chronological insertion so both Before and After disjoint cases are contractual.
    • Doctoring/current exact head f5cc802b15dd0ce2da4764b8d532ec31f5b0e1fd: aligns the public error rustdoc with overlap-aware identity semantics. Base compare is ahead 8 / behind 0 with exactly six changed files; no estimator, persistence, or Analysis schema delta.

    The issue remains open. Exact-head Rust/rustdoc/tests/coverage/security/CodeQL/Semgrep and qualifying independent review are still required before ordinary protected-main landing; #604 downstream ACL remains separate.

  2. seonghobae commented on Sep 19, 2026

    @seonghobae
    ContributorAuthor

    Surviving owner-head update: #605 advanced ordinary-forward to b653eed5963efde246a9224078e1a51d979c53e6 for separate #607/#608/#609 findings. #606's disjoint same-identity re-entry RED/repair remains inherited unchanged. Predecessor exact-head receipts do not transfer; acceptance must be reacquired on b653eed... before protected-main landing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions