Skip to content

build(id): voiding_scenarios tests fail at main — nixos-rebuild switch cannot complete (blocks code#3720 fold) #3787

Closed

Description

@dezren39

What

nix build .#nixosConfigurations.amd.config.system.build.toplevel fails at current main: the id package's checkPhase fails in the voiding_scenarios test suite — 9 passed, 3 failed:

  • test_s2_mutual_removal_removes_both
  • test_s2_concurrent_re_add_is_voided
  • test_s2_three_cycle_removes_every_member

The lib-test compile breakage from PR #3738 was fixed by 47b0620; these are runtime test failures, present at e764f4e and still present at 51919e9 (no pkgs/id changes since). Full log: nix log /nix/store/4fzywg1xa5mxdlss9c7ik1drv4ic077r-id-0.1.0.drv (on the laptop).

Impact

Any nixos-rebuild switch of the laptop at main exits 1 — the toplevel cannot build (unit-id-primary.service → system-units → etc → toplevel all fail on the one dependency). This blocks the code#3720 flake-fold activation: two switch attempts on 2026-11-01 (08:59 and 09:54 CST, the second at e764f4e with this exact failure) both ended SWITCH_EXIT=1. The six folded systems (github-backup, worktree-reaper, quota exporters, dashboard-backup, oc-password-sync) remain on their restored plain-file units, timers verified active — service is unaffected, but the fold cannot land until this passes.

Unblock

Make the three voiding_scenarios tests pass in the nix build (they may behave differently under the sandbox than under cargo test). Afterwards the fold completes with one run of the staged runbook on the laptop (~/.local/state/flake-fold-backup-2026-11-01/README.md): pull, ~/run-switch.sh, verify.

Activity

  1. developing-today commented on Nov 1, 2026

    @developing-today
    Contributor
  2. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    Fixed — PR #3871

    Root cause. PR #3725 wired groups::fold into event_store::resolve() as a gate: the fold's member judge (Engine::member in pkgs/id/src/groups/fold.rs) evaluates each membership op against the fold's sequential current state, in canonical (causal + event-ID) order. For removals entangled with concurrent removals, that sequential pre-judgment contradicts the strong-remove concurrency semantics the membership layer owns (resolve.rs rule 2: authority judged at the op's causal position; the layer's mutual_removes exemption):

    • Mutual removal: A removes B applies; B's concurrent removal of A is then refused NotActive (B already struck in fold state) — but B authored it while active. Fold roster {A, C} instead of {C}.
    • Three-cycle: C's removal of creator A is refused NotAdmin (creator policy evaluated against post-removal state). Fold roster {A, C} instead of {}.
    • Concurrent re-add: C's removal of B is voided NotAMember (A's concurrent removal landed first), flipping the op's applied flag, and C's causally-later re-add of B is then handed to the fold's internal layer as a no-op, corrupting its causal frontier (Invalid: attempted to add a member who is already active).

    The standalone membership scenarios (tests/membership_scenarios.rs, same scenarios) were green throughout — only the store-level suite, which runs through the fold gate added in #3725, failed. Reproduced identically with host cargo test (not a nix-sandbox effect), and the fold's wrong verdicts were measured directly with a fold-level harness before fixing.

    Fix (pkgs/id/src/groups/fold.rs, +56/−2): when a removal is entangled — another removal in the same group, concurrent with it (neither in the other's causal past), names this op's author or its target member — the fold defers arbitration to the membership layer instead of pre-judging against sequential state. The concurrency test is the discriminator that preserves the pinned #168 behavior: a manager's unilateral removal of an Admin is still fold-refused, because the Admin's answering removal is causally later, not concurrent. Role changes remain Admin-only; friendships keep their dissolve path.

    Verification (laptop, branch fix/id-voiding-scenarios-3787 @ fea193a):

    • cargo test --test voiding_scenarios: 12 passed, 0 failed (was 9/3).
    • cargo test --lib: 1678 passed, 0 failed. Neighbors membership_scenarios (16), voiding_properties (7), production_ingest (11), content_removal (2): all pass.
    • Nix build test #1: nix build .#id-web — green; checkPhase log shows 41 test suites ok, 0 failed; all three S2 tests ok. Output /nix/store/qhnanvlf9sh3qy572ip6w00m2q5040x2-id-0.1.0.
    • Nix build Bump checkmarx/ast-github-action from 2.0.11 to 2.0.18 #2: nix build .#id-web --rebuild — green again (41 ok, 0 failed) and reproduced the identical output path (deterministic).
    • Hermetic id-clippy-lint / id-rustfmt-check: still red, but every finding is pre-existing at main in files this PR does not touch (clippy: web/markdown.rs, web/world_ws.rs, world/tests.rs, web/identity.rs — tracked in id: clippy-lint red on main — expect_used at src/tags.rs:1484,1499 (clippy 1.99) #2401; rustfmt: 16 files, groups/fold.rs not among them). This PR introduces no new lint/format findings.

    The unit-id-primary → toplevel cascade should now clear; the fold-activation switch sequence can resume once #3871 merges.

  3. added a commit that references this issue on Nov 1, 2026
  4. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    Completion note from the fold run: this issue's fix (#3871 → 2250410a) is verified in main and did its job — the switch build now gets past the voiding scenarios. The fold remains blocked by successor breakages that were queued behind this one: #3951 (vt100 dev-dep; fixed on main by d488f321c) and now #4015 (stale shell-contract expectation + sqlx-sqlite lock guard). Full record on #3720.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions