jedarden
d130f25400
fix(migration): implement drain timeout and fix concurrent migration tracking
...
Un-ignore and fix two flaky cutover race tests:
1. cutover_chaos_drain_timeout_boundary:
- Implement actual drain timeout checking in complete_drain()
- The drain_timeout config was previously stored but never checked
- Now returns DrainTimeout error when writes exceed timeout
2. cutover_chaos_concurrent_migrations:
- Fix in-flight write tracking to be per-migration instead of global
- Previously, in_flight Vec was shared across all migrations
- When complete_drain(mid_a) cleared writes, it also removed writes
that migration B still needed, causing race conditions
- Now tracked in HashMap<MigrationId, Vec<InFlightWrite>>
Changes:
- MigrationCoordinator: in_flight → in_flight_by_migration HashMap
- complete_drain(): Check write submitted_at vs drain_timeout
- register_in_flight(): Track writes for all active migrations
- collect_delta_candidates(): Include writes that failed on NEW node
- Test: Fix delta pass simulation to copy docs to NEW node
Closes: bf-25flp
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 19:28:25 -04:00
jedarden
1f686c646b
Merge remote-tracking branch 'origin/master'
...
# Conflicts:
# .beads/issues.jsonl
# .beads/traces/bf-5xqk/metadata.json
# .beads/traces/bf-5xqk/stdout.txt
# .beads/traces/miroir-9dj/metadata.json
# .beads/traces/miroir-9dj/stdout.txt
# .beads/traces/miroir-cdo/metadata.json
# .beads/traces/miroir-cdo/stdout.txt
# .beads/traces/miroir-mkk/metadata.json
# .beads/traces/miroir-mkk/stdout.txt
# .beads/traces/miroir-r3j/metadata.json
# .beads/traces/miroir-r3j/stdout.txt
# .beads/traces/miroir-uhj/metadata.json
# .beads/traces/miroir-uhj/stdout.txt
# .beads/traces/miroir-zc2.6/metadata.json
# .beads/traces/miroir-zc2.6/stdout.txt
# .needle-predispatch-sha
# Cargo.lock
# charts/miroir/Chart.yaml
# charts/miroir/templates/NOTES.txt
# charts/miroir/templates/_helpers.tpl
# charts/miroir/templates/redis-deployment.yaml
# charts/miroir/templates/serviceaccount.yaml
# charts/miroir/tests/README.md
# charts/miroir/values.schema.json
# charts/miroir/values.yaml
# crates/miroir-core/Cargo.toml
# crates/miroir-core/src/config.rs
# crates/miroir-core/src/hedging.rs
# crates/miroir-core/src/lib.rs
# crates/miroir-core/src/merger.rs
# crates/miroir-core/src/query_planner.rs
# crates/miroir-core/src/raft_proto/mod.rs
# crates/miroir-core/src/replica_selection.rs
# crates/miroir-core/src/router.rs
# crates/miroir-core/src/scatter.rs
# crates/miroir-core/src/task_store/mod.rs
# crates/miroir-core/src/task_store/redis.rs
# crates/miroir-core/src/task_store/sqlite.rs
# crates/miroir-core/src/topology.rs
# crates/miroir-ctl/src/credentials.rs
# crates/miroir-proxy/Cargo.toml
# crates/miroir-proxy/src/auth.rs
# crates/miroir-proxy/src/client.rs
# crates/miroir-proxy/src/lib.rs
# crates/miroir-proxy/src/main.rs
# crates/miroir-proxy/src/middleware.rs
# crates/miroir-proxy/src/routes/admin.rs
# crates/miroir-proxy/src/routes/documents.rs
# crates/miroir-proxy/src/routes/indexes.rs
# crates/miroir-proxy/src/routes/search.rs
# crates/miroir-proxy/src/routes/settings.rs
# crates/miroir-proxy/src/routes/tasks.rs
# docs/research/score-normalization-at-scale.md
# notes/miroir-cdo.md
# notes/miroir-r3j-final-verification.md
# notes/miroir-r3j-verification.md
# notes/miroir-r3j.1.md
# notes/miroir-r3j.md
# notes/miroir-zc2.1.md
# notes/miroir-zc2.3.md
# notes/miroir-zc2.4.md
# notes/miroir-zc2.5.md
2026-05-24 05:21:32 -04:00
jedarden
158752fe7b
feat(multi-search): implement timeout enforcement and acceptance tests (§13.11)
...
- Add per-query and total timeout enforcement to MultiSearchExecutor
- Improve SearchResult with helper methods (ok, err, timeout, is_success)
- Fix ModeACoordinator feature-gate compilation issues
- Add comprehensive acceptance tests for multi-search:
- 5-query batch completion
- Slow query doesn't block fast queries (parallel execution)
- Partial failure handling
- Per-query timeout
- Total timeout
- 100-query batch completion
Closes: miroir-uhj.11
2026-05-24 01:54:20 -04:00
jedarden
4d3f952699
Phase 1 — Core Routing: Verified implementation
...
Complete verification of Phase 1 — Core Routing (rendezvous hash, topology, covering set).
## Definition of Done Checklist - ALL VERIFIED ✓
### Router Tests (router.rs)
- ✓ test_determinism: Rendezvous assignment is deterministic (1000 iterations)
- ✓ test_reshuffle_bound_on_add: 64 shards, 3→4 nodes moves ≤32 edges
- ✓ test_reshuffle_bound_on_remove: 64 shards, 4→3 nodes
- ✓ test_uniformity: 64 shards / 3 nodes / RF=1 → 17-26 shards per node
- ✓ test_rf2_placement_stability: Top-RF placement changes minimally on add/remove
- ✓ test_write_targets_returns_rg_x_rf_nodes: write_targets returns exactly RG × RF nodes
- ✓ test_write_targets_one_per_group: One-per-group assignment
- ✓ test_query_group_uniform_distribution: Chi-square test passes
- ✓ test_covering_set_covers_all_shards: All shards represented
- ✓ test_covering_set_size_bound: Bounded by group node count
- ✓ test_covering_set_determinism: Identical topologies produce identical results
- ✓ test_covering_set_rotates_replicas: Replica rotation by query_seq
### Merger Tests (merger.rs)
- ✓ 39 tests pass for RRF and score-based merge strategies
- ✓ Global sort, offset/limit, facet aggregation
- ✓ Deterministic tie-breaking, reserved field stripping
- ✓ Score-based merge for global-IDF preflight (OP#4)
### Coverage (cargo-tarpaulin)
- ✓ router.rs: 65/65 lines (100%)
- ✓ topology.rs: 130/130 lines (100%)
- ✓ merger.rs: 148/157 lines (94.3%)
- ✓ scatter.rs: 269/348 lines (77.3% - stub methods excluded)
## Implementation Summary
All Phase 1 core routing primitives are fully implemented and verified:
1. Rendezvous hashing (HRW) with XxHash64 seed 0
2. Topology management with node health state machine
3. Write path: write_targets returns RG × RF nodes, one per group
4. Read path: query_group round-robin, covering_set with replica rotation
5. Result merger: RRF (default) and score-based merge strategies
6. Scatter orchestration: plan_search_scatter, execute_scatter
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 15:27:55 -04:00
jedarden
ce3c0cb73c
P4.2 Node addition: migration-aware dual-write routing + admin routes
...
- Add write_targets_with_migration() to router: includes new node in write
targets when a shard is in dual-write phase during node addition
- Wire migration-aware routing into write_documents_impl (documents.rs)
- Expose get_all_migrations() accessor on MigrationCoordinator for router use
- Add node management API routes: POST /nodes, DELETE /nodes/{id},
POST /nodes/{id}/drain, GET /rebalance/status, replica_group CRUD
- Improve compute_shard_moves_for_new_node: prefer displaced node as
migration source; fall back to lowest-scored old owner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:43:40 -04:00
jedarden
6c32dd8efc
Phase 0 (miroir-qon): Rust 1.88 upgrade + test infrastructure
...
- Bump Rust toolchain from 1.87 to 1.88
- Add testcontainers and arbitrary dependencies for property testing
- Update router with rendezvous hashing improvements
- Fix credential handling in miroir-ctl
- Update reshard and migration modules
- Add Helm chart scaffolding
- Add Redis memory accounting documentation
All Phase 0 DoD checks pass:
- cargo build --all succeeds
- cargo test --all succeeds (103 tests)
- cargo clippy --all-targets --all-features -- -D warnings passes
- cargo fmt --all -- --check passes
- Config round-trip YAML test passes
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 02:05:44 -04:00
jedarden
554a705794
Phase 0 (miroir-qon): Foundation verification — formatting fix
...
Apply rustfmt to migration.rs for consistency with project style.
All Phase 0 DoD items verified:
- cargo build --all: ✅ passes
- cargo test --all: ✅ 42 tests pass
- cargo clippy: ✅ passes (without --all-features due to known openraft/Rust 1.87 incompatibility)
- cargo fmt --check: ✅ passes
- Config round-trip: ✅ tested
- Workspace, crates, config struct: ✅ complete
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 20:16:22 -04:00
jedarden
379ad5457f
Phase 0 (miroir-qon): Foundation verification complete
...
Verified all Phase 0 requirements are satisfied:
- Cargo workspace with three crates (miroir-core, miroir-proxy, miroir-ctl)
- rust-toolchain.toml pinning Rust 1.87
- Key dependencies wired (axum, tokio, reqwest, serde, config, etc.)
- Config struct with full YAML schema (plan §4)
- Style configs (rustfmt.toml, clippy.toml, .editorconfig)
- Project files (CHANGELOG.md, LICENSE, .gitignore, Cargo.lock)
Code improvements included:
- migration.rs: Fix in-flight write clearing to only affect migration shards
- score_comparability.rs: Add Serialize/Deserialize, clean up imports, formatting
- lib.rs: Alphabetize module declarations
- cutover_race.rs: Fix drain timeout test to fail writes on both old and new nodes
- benchmarks: Improve code formatting
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 19:49:03 -04:00
jedarden
8e5aa344ba
P4: Complete Phase 4 Topology Operations integration
...
- Add remove_node and remove_group methods to Topology
- Add MigrationNodeId type alias for external use
- Integrate Rebalancer and MigrationCoordinator into AppState
- Wire up rebalancer config from MiroirConfig
- All chaos tests passing
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 16:50:42 -04:00
jedarden
b201f0ff58
P12.OP4: Finalize score normalization validation — RRF τ=0.14, score τ=0.79
...
Research complete: both score-based and RRF merge fail 0.95 threshold.
Updated research doc with full RRF validation results and confidence intervals.
Added benchmark result reports and helper tests. Follow-up bead miroir-n6v
created for global-IDF preflight (dfs_query_then_fetch pattern).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 02:40:54 -04:00
jedarden
fec5aa5e74
P12.OP1: Chaos-test cutover race window + hard refusal policy
...
14 chaos tests validate shard migration write safety at every cutover
boundary. Key findings:
- AE on + delta pass: 0/1M loss (production default)
- AE off + delta pass: 0/50K loss (delta pass is sufficient alone)
- AE off + delta skipped: ~2% loss → hard refusal at config validation
- 3-node cluster cutover: 0 loss with delta pass
Hard-coded policy: MigrationCoordinator refuses migrations when both
anti-entropy is disabled and delta pass is skipped. Warning logged when
AE is disabled but delta pass remains active.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 22:00:21 -04:00
jedarden
9b5cf0ddcd
P0.3: Scaffold miroir-proxy crate
...
- Added Cargo.toml with axum, tokio, reqwest, serde, tracing, prometheus
- Created main.rs: binds :7700 (main API) and :9090 (metrics)
- Route handler stubs: documents, search, indexes, settings, tasks, health, admin
- auth.rs: bearer-token dispatch skeleton (client/admin token kinds)
- middleware.rs: tracing/logging + Prometheus middleware stubs
- Fixed miroir-core/migration.rs: Display impls, Instant serialization, borrow fixes
Acceptance:
- Binary builds successfully
- Health endpoint returns {"status":"available"}
- Stripped binary: 2.3 MB (< 20 MB target)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 20:57:58 -04:00
jedarden
93891cd03b
P0.2: Scaffold miroir-core crate
...
Create core library module skeleton with public API surface:
- router.rs: rendezvous hash primitives (twox-hash based)
- topology.rs: Topology, Group, Node, NodeId, NodeStatus types
- scatter.rs: scatter orchestration trait/stubs
- merger.rs: result merge trait/stubs
- task.rs: task registry trait/stubs
- config.rs: Config struct (full YAML shape)
- error.rs: MiroirError enum + Result<T> alias
All acceptance criteria met:
- cargo build -p miroir-core succeeds
- cargo doc -p miroir-core produces rustdoc without warnings
- cargo test -p miroir-core runs (zero tests) successfully
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 20:57:47 -04:00