Verified all Definition of Done requirements for miroir-cdo bead: Router Module (router.rs): - ✅ Determinism verified by test_determinism() - ✅ Minimal reshuffle on add (test_reshuffle_bound_on_add) - ✅ Uniformity: 64 shards / 3 nodes / RF=1 → 17-26 shards/node - ✅ RF=2 placement stability (test_rf2_placement_stability) - ✅ write_targets returns RG × RF nodes - ✅ query_group distributes evenly (chi-square test) - ✅ covering_set covers all shards with replica rotation Topology Module (topology.rs): - ✅ Topology struct with node grouping - ✅ Complete health state machine - ✅ YAML serialization (plan §4 format) Scatter Module (scatter.rs): - ✅ Fan-out orchestration with plan_search_scatter() - ✅ Execution primitives with mock client - ✅ OP#4 Global-IDF preflight (dfs_query_then_fetch) - ✅ Session pinning support - ✅ Settings version floor filtering Merger Module (merger.rs): - ✅ RRF merge strategy (k=60 default) - ✅ Score-based merge for global-IDF - ✅ Global sort, offset/limit, facet aggregation - ✅ Field stripping, tie-breaking, degraded handling Test Results: 103 Phase 1 tests, all passing Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
86 lines
4.1 KiB
Markdown
86 lines
4.1 KiB
Markdown
# Phase 1 - Core Routing: Completion Summary
|
||
|
||
## Bead: miroir-cdo
|
||
|
||
**Status**: ✅ COMPLETE
|
||
|
||
## Definition of Done Verification
|
||
|
||
### Router Module (router.rs)
|
||
- ✅ **Determinism**: `test_determinism()` verifies same inputs produce same output
|
||
- ✅ **Minimal reshuffle on add**: `test_reshuffle_bound_on_add()` verifies adding 4th node to 3-node group moves at most ~2 × (1/4) shards
|
||
- ✅ **Uniformity**: `test_uniformity()` verifies 64 shards / 3 nodes / RF=1 → each node holds 17-26 shards
|
||
- ✅ **RF=2 placement stability**: `test_rf2_placement_stability()` and `test_reshuffle_bound_on_remove()` verify minimal changes on add/remove
|
||
- ✅ **write_targets**: `test_write_targets_returns_rg_x_rf_nodes()` and `test_write_targets_one_per_group()` verify RG × RF nodes, one per group
|
||
- ✅ **query_group**: `test_query_group_uniform_distribution()` verifies even distribution (chi-square test)
|
||
- ✅ **covering_set**: `test_covering_set_covers_all_shards()`, `test_covering_set_size_bound()`, `test_covering_set_determinism()`, `test_covering_set_rotates_replicas()` verify correct coverage
|
||
- ✅ **shard_for_key**: `test_shard_for_key_fixture()` verifies hash-based routing
|
||
|
||
### Topology Module (topology.rs)
|
||
- ✅ **Topology struct**: Holds nodes grouped by `replica_group`
|
||
- ✅ **Node health state machine**: Full state transition table (Joining → Active → Draining → Removed, with Degraded/Failed states)
|
||
- ✅ **Group isolation**: `each_group_holds_exactly_its_configured_nodes()` verifies groups are independent
|
||
- ✅ **YAML serialization**: `deserialize_plan_s4_yaml_example()` verifies plan §4 format
|
||
|
||
### Scatter Module (scatter.rs)
|
||
- ✅ **Fan-out orchestration**: `plan_search_scatter()` builds shard→node mapping
|
||
- ✅ **Execution primitives**: `execute_scatter()` fans out to nodes with mock client support
|
||
- ✅ **OP#4 Global-IDF preflight**: `execute_preflight()` and `dfs_query_then_fetch_search()` implement the preflight phase
|
||
- ✅ **Session pinning**: `plan_search_scatter_for_group()` supports pinned group reads
|
||
- ✅ **Settings version floor**: `plan_search_scatter_with_version_floor()` implements plan §13.5
|
||
|
||
### Merger Module (merger.rs)
|
||
- ✅ **RRF merge**: Default strategy with k=60, fully tested
|
||
- ✅ **Score-based merge**: For OP#4 global-IDF queries
|
||
- ✅ **Global sort by score**: `test_score_merge_global_sorting()`
|
||
- ✅ **Offset/limit**: `test_merge_offset_limit()`, `test_page_reconstruction()`
|
||
- ✅ **Facet aggregation**: `test_merge_facets()`, `test_merge_facets_filter()`
|
||
- ✅ **Field stripping**: `test_merge_strips_miroir_fields()`
|
||
- ✅ **Tie-breaking**: Deterministic by primary key
|
||
- ✅ **Degraded handling**: `test_merge_degraded_flag()`
|
||
|
||
## Test Results
|
||
|
||
```
|
||
running 15 tests (router)
|
||
test result: ok. 15 passed
|
||
|
||
running 24 tests (topology)
|
||
test result: ok. 24 passed
|
||
|
||
running 25 tests (scatter)
|
||
test result: ok. 25 passed
|
||
|
||
running 39 tests (merger)
|
||
test result: ok. 39 passed
|
||
|
||
Total: 103 Phase 1 tests, all passing
|
||
```
|
||
|
||
## Implementation Details
|
||
|
||
### Rendezvous Hashing (HRW)
|
||
- Uses `twox_hash::XxHash64` with seed 0 (matches Meilisearch Enterprise)
|
||
- Scores are `hash(shard_id, node_id)` → 64-bit integer
|
||
- Top-RF nodes selected by score descending, with lexicographic tie-breaking
|
||
|
||
### Properties Verified
|
||
1. **Determinism**: All pods compute identical assignments given fixed topology
|
||
2. **Minimal reshuffling**: Adding node moves ~1/(Ng+1) of shards
|
||
3. **Group isolation**: Intra-group hashing prevents both replicas in same group
|
||
|
||
### Dependencies
|
||
- `twox-hash` for rendezvous hashing
|
||
- `serde` for serialization
|
||
- `tokio` for async execution
|
||
|
||
## Notes
|
||
|
||
Phase 1 - Core Routing was already fully implemented with comprehensive test coverage. The rendezvous hashing, topology management, scatter orchestration, and result merger primitives are all in place and passing all tests.
|
||
|
||
The implementation correctly handles:
|
||
- Deterministic shard assignment without coordination
|
||
- Minimal data movement on topology changes
|
||
- Group-scoped assignment for replica isolation
|
||
- Global sort with RRF and score-based merge
|
||
- OP#4 global-IDF preflight for cross-shard score comparability
|