Verify that peer discovery via headless Service + Downward API
is fully implemented per plan §14.5:
- Helm templates: miroir-headless.yaml with clusterIP: None,
miroir-deployment.yaml with POD_NAME/POD_NAMESPACE/POD_IP
- Rust: peer_discovery.rs with SRV lookup, refresh loop in main.rs,
miroir_peer_pod_count metric in middleware.rs
- Verification: verify_p6_2_peer_discovery.sh script
Acceptance tests require multi-pod Kubernetes deployment:
1. 3-pod deployment: each pod sees all 3 peer names within 30s
2. Scale 3→5: new peers discovered within refresh_interval_s × 2
3. Pod eviction: crashed pod drops from peer set within 30s
4. miroir_peer_pod_count matches kube_deployment_status_replicas_ready
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Verified that peer discovery via headless Service + Downward API (plan §14.5)
is fully implemented:
- Helm: headless Service template + Downward API env vars (POD_NAME, POD_IP)
- Rust: peer_discovery.rs SRV lookup module with trust-dns-resolver
- Main: background refresh loop + miroir_peer_pod_count metric
- Unit tests: all 3 peer_discovery tests pass
- Verification script: NixOS-compatible shebang
Acceptance criteria require a Kubernetes cluster for integration testing:
- 3-pod discovery, scale events, pod eviction, metric comparison
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Verified that peer discovery via headless Service + Downward API is
fully implemented:
- Helm templates: miroir-headless.yaml Service + POD_NAME/POD_IP env vars
- Rust module: peer_discovery.rs with SRV lookup via trust-dns-resolver
- Config: peer_discovery section with service_name + refresh_interval_s
- Main loop: Background refresh task that updates miroir_peer_pod_count metric
- Metrics: miroir_peer_pod_count, miroir_leader, miroir_owned_shards_count gauges
- Verification script: tests/verify_p6_2_peer_discovery.sh (NixOS-compatible shebang)
All unit tests pass. The implementation requires a Kubernetes deployment
for full acceptance testing (3-pod discovery, scale events, pod eviction).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Document that peer discovery was already implemented in prior commits
(e6cdd05 and 26c9521). All required components are in place:
- Headless Service with Downward API env vars
- SRV-based peer discovery in peer_discovery.rs
- Background refresh loop in main.rs
- miroir_peer_pod_count metric in middleware.rs
- Verification script
Acceptance criteria require multi-pod K8s deployment testing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Verified that all acceptance criteria for P5.7 §13.7 (Atomic Index Aliases) are already implemented:
- Single-target alias resolution for reads and writes
- Atomic alias flipping with no in-flight request tearing
- Multi-target aliases for read-only ILM use
- Write rejection (409) for multi-target aliases
- History retention with eviction (default: 10)
All 17 acceptance tests pass. Implementation was completed in prior commits:
- c670d09: Fix alias admin API routes and reorganize alias module
- 821dea3: Complete alias acceptance tests
- 823fdd0: Add atomic index alias integration tests
- f564f3d: Add alias flip metrics emission
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
All miroir_* error codes from plan §5 are implemented in
crates/miroir-core/src/api_error.rs with tests passing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Documents the bearer-token dispatch chain implementation (plan §5 rules 0-5)
that was completed in commit 625e414. The implementation supports three
token types simultaneously: master_key, admin_key, and search UI JWTs.
Key features:
- Deterministic dispatch chain with 5 rules
- X-Admin-Key short-circuit for admin endpoints
- Constant-time comparison for all opaque tokens
- JWT validation with rotation support (primary + previous secrets)
- 62 unit tests covering all acceptance criteria
- Rate-limit hooks for Phase 6 multi-pod deployment
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Verify all acceptance criteria met:
- cargo bench -p miroir-core runs criterion benches
- cargo test runs proptest with 1024 cases (proptest.toml)
- CI includes cargo bench --no-run (miroir-ci.yaml:124)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The schema versioning system is already fully implemented.
Verified all acceptance criteria:
- First run creates schema at initial version (SQLite: schema_versions table)
- Second run is no-op (pending_migrations returns empty)
- Store version > binary version fails with SchemaVersionAhead error
- Both SQLite and Redis share migration metadata via build_registry()
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Complete acceptance criteria:
- Each §14.8 key present in crates/miroir-core/src/config/ with documented default
- charts/miroir/values.yaml exposes the same keys with identical defaults
- values.schema.json accepts documented ranges; cross-field validation in _helpers.tpl
- K8s resources block matches §14.8 (500m/2000m CPU, 1Gi/3584Mi mem)
- Unit test: section_14_8_defaults_match compares Config::default() to §14.8 reference
- Drift guard: doc-test at top of MiroirConfig struct validates defaults
All defaults sized for 2 vCPU / 3.75 GB envelope per plan §14.8.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Verified that Plan §15 Open Problem #1 is fully addressed by existing
chaos tests. All 14 cutover_race tests pass, confirming:
- Loss rate < 1 per 1M writes with AE on (0/1M measured)
- Loss rate without AE quantified (~2% when both AE and delta off)
- Hard refusal policy blocks unsafe configuration
- Documentation complete in docs/trade-offs.md
No code changes required — implementation already satisfies all
acceptance criteria.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This bead verified that the Redis-backed TaskStore implementation is
complete, covering all 14 tables from plan §4 plus the extra keys from
plan §4 footnotes.
Key findings:
- All 14 tables mapped to Redis keyspace correctly
- Secondary `_index` sets for O(cardinality) list queries
- Leader lease with SET NX/EX for acquire, SET XX/EX for renewal
- EXPIRE for TTL-based garbage collection (sessions, idempotency)
- Pipelining for atomic multi-key operations
- CDC overflow buffer with LPUSH + LTRIM
- Pub/Sub for admin session revocation
- Rate limiting with exponential backoff for admin login
- Search UI scoped key coordination
Acceptance criteria verified:
- test_redis_lease_race: concurrent lease acquisition
- test_redis_memory_budget: 10k tasks + 1k sessions + 100k idempotency keys
- test_redis_pubsub_session_invalidation: logout via Pub/Sub within 100ms
- testcontainers integration tests in p3_redis_integration.rs
No code changes required - the implementation was already complete.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Fixed duplicate ReshardingConfig: added allowed_windows to advanced.rs
- Ran benchmark confirming storage/dual-write amplification at exactly 2.0×
- Verified CLI window guard integration tests (4/4 passing)
- Updated benchmark doc with latest run date (2026-05-20)
Key findings:
- Storage amplification is exactly 2× across all scenarios
- Peak write amplification varies from 12× to 502× depending on throttle
- Operators should set throttle to keep peak writes ≤ 3× normal
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bead-Id: miroir-r3j.2
All 7 feature-flagged tables (canaries, canary_runs, cdc_cursors, tenant_map,
rollover_policies, search_ui_config, admin_sessions) were already implemented
with full CRUD operations, migrations, and tests.
The canary_runs_auto_prune trigger was added in P3.3 (commit 719d1db).
Acceptance criteria verified:
- All 38 SQLite tests pass
- Every table round-trips insert/get correctly
- Auto-prune trigger keeps canary_runs bounded
- Empty tables consume < 16 KB overhead each
- Tables created via TaskStore::migrate() migration 002
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The matrix incorrectly referenced miroir-zc2.6/7/8 as dump import
enhancement beads, but zc2.6 is actually arm64 support and zc2.7/8
don't exist. Replaced with a descriptive "Future Enhancements" table
that maintains traceability without false bead dependencies.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bead-Id: miroir-zc2.5
Bead-Id: miroir-r3j.6
Bead-Id: bf-1p4v
The matrix incorrectly referenced miroir-zc2.6/7/8 as dump import
enhancement beads, but zc2.6 is actually arm64 support and zc2.7/8
don't exist. Replaced with a descriptive "Future Enhancements" table
that maintains traceability without false bead dependencies.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Added comments linking miroir-m9q.3 (Mode A), miroir-m9q.4 (Mode B), and
miroir-m9q.5 (Mode C) to the per-feature scaling reference doc. This enables
bidirectional navigation between implementation beads and the operator-facing
scaling mode documentation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The E0382 borrow of moved value error was already fixed.
The code uses `.with_state(state.clone())` at line 586
and UnifiedState derives Clone. Build succeeds.
Also added task registry TTL pruner background task.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The described E0382 error (borrow of moved value `state`) was already
fixed in the codebase. Line 568 already uses `.with_state(state.clone())`
and UnifiedState derives Clone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The docs/horizontal-scaling/per-feature.md file already exists
and meets all acceptance criteria. Created verification note.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The borrow of moved value error was already resolved in the codebase.
Line 568 correctly uses .with_state(state.clone()) and build succeeds.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
All acceptance criteria already met:
- Sizing table reproduced from plan §14.7
- Redis memory accounting paragraph included
- Worked example for ≤200 GB tier
- Links from README.md and production.md
The sizing guide is THE artifact operators need on day one.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The repository is already in full compliance. Plan §12 specifies
crate-level tests (idiomatic Rust workspace convention), which is
exactly what exists. No migration or amendments required.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The borrow-of-moved-value error for `state` was already fixed in the codebase.
Line 568 uses `.with_state(state.clone())` and `UnifiedState` derives Clone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Verified that the TaskStore trait and SQLite backend for tables 1-7
were already fully implemented with all tests passing (36/36).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Documented verification that the rebalancer background worker meets all
acceptance criteria:
- Advisory lock via leader_lease table preventing duplicate migrations
- Progress persistence enabling pod crash recovery
- Prometheus metrics tracking for observability
All 15 rebalancer-related tests and 108 proxy tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 3 Task Registry + Persistence has been verified complete.
All 14 tables implemented with SQLite and Redis backends.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Updated the Phase 5 verification document to reflect that the canary
runner (§13.18) is now fully implemented with:
- All assertion types (top_hit_id, top_k_contains, min_hits, max_p95_ms,
settings_version_at_least, must_not_contain_id)
- Background runner with per-canary scheduling
- Run history tracking (canary_runs table)
- Metrics emission
- Capture-from-traffic flow
All 21 §13 Advanced Capabilities are now complete.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 3 (Task Registry + Persistence) has been fully implemented
and verified. All 14 tables from plan §4 are complete with both
SQLite and Redis backends.
Definition of Done - All Complete:
- rusqlite-backed store with idempotent table initialization
- Redis-backed store mirroring TaskStore trait
- Migrations/versioning with schema version tracking
- Property tests for round-trip and list semantics
- Integration test for pod restart resilience
- Redis backend integration tests (testcontainers)
- miroir:tasks:_index-style iteration (no SCAN)
- Helm schema validation for Redis + replicas enforcement
- Redis memory accounting documentation
Test Results:
- cargo test task_store: 36 passed
- cargo test p3_phase3_task_registry: 12 passed
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 3 Task Registry + Persistence is complete:
- All 14 tables implemented with SQLite and Redis backends
- Schema migrations with version tracking
- Property tests and integration tests passing (36/36)
- Helm schema validation enforces Redis for replicas > 1
- Redis memory accounting validated per plan §14.7
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Documents the 2026-05-02 verification session confirming Phase 3
completion status before closing bead miroir-r3j.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>