Coverage-map bead (step 2, parent bf-1zn8a, grandparent bf-30m2j). For each of bf-30m2j's five acceptance criteria, cites the covering inline test + specific assertion (file:line), or marks the genuine GAP: - C1 COVERED — current API (with_mode_a/ModeACoordinator::new), no with_mode_a_scaling - C2 COVERED — exactly-one-owner anti_entropy.rs:1622-1635 (owner_count==1, total_owned==64) - C3 COVERED core / GAP minimal-reshuffle — pod-reassignment anti_entropy.rs:1714-1755 - C4 GAP — module is #[cfg(feature=peer-discovery)]-gated, non-default; not in plain cargo test - C5 orthogonal action item — inline tests live in src/, not the p13_8 tests/ file Proves acceptance_4 is redundant; directs later siblings at the narrow gaps (survivor-stability, scale-up, hash-vector, default-feature discoverability) and the stale-comment edit rather than a redundant rewrite. Co-Authored-By: Claude <noreply@anthropic.com>
9.4 KiB
bf-59oct — Map each inline Mode A test → grandparent bf-30m2j acceptance criteria
Coverage-map bead. Parent umbrella bf-1zn8a, grandparent bf-30m2j. Step 2 of the coverage investigation; builds on the empirical test-run evidence in sibling bf-qvrmh (which re-confirmed the three tests execute + pass).
This note is the crisp, decisive, per-test assertion-cited coverage map: for each
of grandparent bf-30m2j's five acceptance criteria, which of the three inline
tests covers it (with the specific assertion + file:line), and where the genuine
gap is. The point is to prove the disabled acceptance_4's criteria are already
covered inline so later siblings attack the narrow gap instead of rewriting a
redundant test.
Test inventory (crates/miroir-core/src/anti_entropy.rs, mod tests_mode_a_acceptance)
Whole module is gated #[cfg(all(test, feature = "peer-discovery"))] @
anti_entropy.rs:1532. All three are plain #[tokio::test] (no #[ignore]),
run against the in-memory crate::scatter::MockNodeClient (no docker).
| Task shorthand | Actual fn | Location |
|---|---|---|
| exactly-one-owner | test_mode_a_three_pods_each_shard_processed_once |
anti_entropy.rs:1541 |
| pod-reassignment | test_mode_a_pod_reassignment |
anti_entropy.rs:1665 |
| partitioning-wiring | test_mode_a_anti_entropy_partitioning |
anti_entropy.rs:1761 |
All three exercise the current API, not the removed with_mode_a_scaling:
ModeACoordinator::new + PeerDiscovery::new + PeerSet::new +
set_peer_set_for_test (mode_a_coordinator.rs:306) + with_mode_a
(anti_entropy.rs:199). Assertions query ModeACoordinator::owns_shard
(mode_a_coordinator.rs:151) → owner_for_shard (:123, top-1 by score) →
rendezvous_score (:112) = XxHash64(shard_id || "||" || peer_id) — i.e.
exactly top1_by_score(hash(s ‖ pid)) from plan §14.5 (plan.md:3520).
Coverage map (grandparent bf-30m2j criteria 1-5)
Criterion 1 — Rewrite/reinstate acceptance_4 using current ModeACoordinator/peer_discovery API (not removed with_mode_a_scaling) — [COVERED]
The criterion's substance ("exercise the current API, not the deleted
with_mode_a_scaling") is satisfied by all three tests. No with_mode_a_scaling
symbol exists in the tree (only with_mode_a @ anti_entropy.rs:199):
- partitioning-wiring —
ModeACoordinator::new@anti_entropy.rs:1768;with_mode_a(coordinator)@anti_entropy.rs:1790. - exactly-one-owner —
ModeACoordinator::new@anti_entropy.rs:1548/1555/1562;with_mode_a(coordinator_{1,2,3})@anti_entropy.rs:1581/1584/1587. - pod-reassignment —
ModeACoordinator::new@anti_entropy.rs:1672/1679/1686.
The "API drift" the parent cites is already resolved in-tree; any rewrite of
acceptance_4 would duplicate this. (The literal act of deleting the dead
acceptance_4 is a cleanup, see criterion 5.)
Criterion 2 — Each shard owned by EXACTLY ONE pod (no double-ownership, no orphan), matching top1_by_score(hash(shard_id ‖ pod_id)) — [COVERED by exactly-one-owner: anti_entropy.rs:1622-1635]
- No double-ownership: per-shard
assert_eq!(owner_count, 1, …)@anti_entropy.rs:1622-1626(counts how many of the 3 pods returnowns_shard == truefor each shard). - No orphan:
assert_eq!(total_owned, 64, …)@anti_entropy.rs:1631-1635(sum of pod1/pod2/pod3 shard counts == 64). - Even distribution (supplementary):
min_owned >= 15,max_owned <= 25@anti_entropy.rs:1649-1658. - Hash match:
owns_shardresolves throughowner_for_shard(top-1) +rendezvous_score=XxHash64(shard_id ‖ peer_id)(mode_a_coordinator.rs:112-145), the exacttop1_by_score(hash(s ‖ pid))of plan §14.5.
Reinforced by pod-reassignment @ anti_entropy.rs:1733-1737
(owner_count == 1 on pod-3's former shards) and :1751-1755 (total_owned == 64).
Criterion 3 — Ownership redistributes (minimal reshuffling) when peer set changes size — [COVERED for the core; "minimal reshuffling" sub-clause is a narrow GAP]
Core assertion covered by pod-reassignment: anti_entropy.rs:1714-1755:
- Peer set shrinks 3→2:
PeerSet::new(["pod-1","pod-2"])+set_peer_set_for_test@anti_entropy.rs:1714-1721. - Redistribution asserted: every shard pod-3 previously owned (captured @
:1705-1711) is now owned by exactly one of pod-1/pod-2 —assert_eq!(owner_count, 1)@anti_entropy.rs:1733-1737. - Full coverage preserved:
assert_eq!(total_owned, 64, …)@anti_entropy.rs:1751-1755.
Narrow GAP (the "minimal reshuffling" sub-clause): the test records only pod-3's initial shards (
:1705-1711) and re-checks only those. It never records pod-1/pod-2's initial shards and asserts they are unchanged after the resize. A buggy impl that reshuffled all shards on every peer-set change — while still preserving exactly-one-owner + full coverage — would pass. This is parent bf-1zn8a's gap (a): survivor-stability / minimal-reshuffling un-pinned for the Mode A background-work ownership path. (Also no 3→4 scale-up case exists — gap (b).)
So: the literal criterion-3 head ("ownership redistributes when peer set changes size") = COVERED; the parenthetical "minimal reshuffling" qualifier = GAP.
Criterion 4 — Test runs in default cargo test without --ignored or docker — [GAP for "default cargo test"; sub-parts covered]
- No
#[ignore]: ✓ — plain#[tokio::test]@anti_entropy.rs:1540/1664/1760. - No docker: ✓ — in-memory
MockNodeClient@anti_entropy.rs:1577/1787; synthetic peer set viaset_peer_set_for_test(mode_a_coordinator.rs:306), no SRV/DNS. - "Default
cargo test": GAP. The module is#[cfg(all(test, feature = "peer-discovery"))]@anti_entropy.rs:1532, andpeer-discoveryis a non-default feature (default = []@crates/miroir-core/Cargo.toml:67;peer-discovery = ["trust-dns-resolver"]@:71). Plaincargo test -p miroir-core mode_acompiles 0 of these tests (confirmed empirically by sibling bf-qvrmh, RUN 1). They execute + pass only undercargo test -p miroir-core --features peer-discoveryormake test(--all-features,Makefile:8).
⇒ This is the genuine remaining gap the later siblings should resolve. It is
not "rewrite acceptance_4" — it is "make the Mode A partitioning tests
discoverable/runnable in default cargo test" (e.g. move the module off the
peer-discovery gate; the coordinator only needs set_peer_set_for_test, which
already avoids SRV). This is the real narrow gap, per bf-1zn8a recommendation #5.
Criterion 5 — Update/remove stale comment at crates/miroir-core/tests/p13_8_anti_entropy.rs:240-244 — [orthogonal action item, NOT a coverage item]
The inline tests live in src/anti_entropy.rs, not in the tests/p13_8_anti_entropy.rs
file. The stale comment @ p13_8_anti_entropy.rs:241-244 still claims the disabled
acceptance_4_mode_a_shard_partitioning "uses an old API (with_mode_a_scaling)"
and "requires the peer-discovery feature and ModeACoordinator" — now misleading
since the live replacement exists at anti_entropy.rs:1532-1798. It cannot be
"covered" by the inline suite; it is a standalone ~4-line edit (point at the
inline module, drop the dead acceptance_4 reference). Track as its own action
under bf-1zn8a recommendation #4 — not marked [GAP] against the inline tests.
Verdict matrix
| # | Criterion | Verdict | Covering test : line | Key assertion |
|---|---|---|---|---|
| 1 | Current API (not with_mode_a_scaling) |
[COVERED] | partitioning-wiring :1790; exactly-one-owner :1581-1587; pod-reassignment :1672-1686 |
with_mode_a / ModeACoordinator::new |
| 2 | Exactly-one owner, no double/orphan, top1_by_score(hash(s‖pid)) |
[COVERED] | exactly-one-owner :1622-1635 |
owner_count == 1, total_owned == 64 |
| 3 | Redistribution on peer-set change (minimal reshuffling) | [COVERED] core / [GAP] minimal-reshuffle | pod-reassignment :1714-1755 |
owner_count == 1 @ :1733, total_owned == 64 @ 1751 |
| 4 | Runs in default cargo test, no --ignored/docker |
[GAP] (default cargo test); sub-parts ✓ |
— | gated #[cfg(… feature = "peer-discovery")] @ anti_entropy.rs:1532, default = [] Cargo.toml:67 |
| 5 | Update stale comment p13_8:240-244 |
orthogonal action item | — | inline tests are in src/, not the tests/ file |
Bottom line
- Criteria 1, 2: fully covered inline.
- Criterion 3: core covered inline; the minimal-reshuffling / survivor-stability sub-clause is the genuine narrow gap (a) — the thing a follow-on sibling should add (record pod-1/pod-2 initial shards, assert unchanged after resize).
- Criterion 4: the default-
cargo-testrequirement is the other genuine gap — the suite is feature-gated behind non-defaultpeer-discovery. Fixing discoverability (not rewriting a test) is the sibling work. - Criterion 5: orthogonal cleanup edit, not a coverage item.
The disabled acceptance_4 is redundant — do not rewrite it. Direct later
siblings at gaps (a) survivor-stability, (b) 3→4 scale-up, (c) pinned hash-vector,
(4) default-feature discoverability, and the criterion-5 comment edit.
Cross-refs
notes/bf-qvrmh.md— empirical "do the three tests run?" foundation (RUN 1-4).notes/bf-1zn8a.md— parent umbrella; full Step 2 map + gaps (a)/(b)/(c).