Copies of design docs removed in Phase 09, preserved in sw-block/docs/archive/ for historical reference. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.0 KiB
A5-A8 Acceptance Traceability
Date: 2026-03-29 Status: historical evidence traceability
Purpose
Map each acceptance criterion to specific executable evidence. Two evidence layers:
- Simulator (distsim): protocol-level proof
- Prototype (enginev2): ownership/session-level proof
A5: Non-Convergent Catch-Up Escalates Explicitly
Must prove: tail-chasing or failed catch-up does not pretend success.
Pass condition: explicit CatchingUp → NeedsRebuild transition.
| Evidence | Test | File | Layer | Status |
|---|---|---|---|---|
| Tail-chasing converges or aborts | TestS6_TailChasing_ConvergesOrAborts |
cluster_test.go |
distsim | PASS |
| Tail-chasing non-convergent → NeedsRebuild | TestS6_TailChasing_NonConvergent_EscalatesToNeedsRebuild |
phase02_advanced_test.go |
distsim | PASS |
| Catch-up timeout → NeedsRebuild | TestP03_CatchupTimeout_EscalatesToNeedsRebuild |
phase03_timeout_test.go |
distsim | PASS |
| Reservation expiry aborts catch-up | TestReservationExpiryAbortsCatchup |
cluster_test.go |
distsim | PASS |
| Flapping budget exceeded → NeedsRebuild | TestP02_S5_FlappingExceedsBudget_EscalatesToNeedsRebuild |
phase02_advanced_test.go |
distsim | PASS |
| Catch-up converges or escalates (I3) | TestI3_CatchUpConvergesOrEscalates |
phase045_crash_test.go |
distsim | PASS |
| Catch-up timeout in enginev2 | TestE2E_NeedsRebuild_Escalation |
p2_test.go |
enginev2 | PASS |
Verdict: A5 is well-covered. Both simulator and prototype prove explicit escalation. No pretend-success path exists.
A6: Recoverability Boundary Is Explicit
Must prove: recoverable vs unrecoverable gap is decided explicitly.
Pass condition: recovery aborts when reservation/payload availability is lost; rebuild is explicit fallback.
| Evidence | Test | File | Layer | Status |
|---|---|---|---|---|
| Reservation expiry aborts catch-up | TestReservationExpiryAbortsCatchup |
cluster_test.go |
distsim | PASS |
| WAL GC beyond replica → NeedsRebuild | TestI5_CheckpointGC_PreservesAckedBoundary |
phase045_crash_test.go |
distsim | PASS |
| Rebuild from snapshot + tail | TestReplicaRebuildFromSnapshotAndTail |
cluster_test.go |
distsim | PASS |
| Smart WAL: resolvable → unresolvable | TestP02_SmartWAL_RecoverableThenUnrecoverable |
phase02_advanced_test.go |
distsim | PASS |
| Time-varying payload availability | TestP02_SmartWAL_TimeVaryingAvailability |
phase02_advanced_test.go |
distsim | PASS |
| RecoverableLSN is replayability proof | RecoverableLSN() in storage.go |
storage.go |
distsim | Implemented |
| Handshake outcome: NeedsRebuild | TestExec_HandshakeOutcome_NeedsRebuild_InvalidatesSession |
execution_test.go |
enginev2 | PASS |
Verdict: A6 is covered. Recovery boundary is decided by explicit reservation + recoverability check, not by optimistic assumption. RecoverableLSN() verifies contiguous WAL coverage.
A7: Historical Data Correctness Holds
Must prove: recovered data for target LSN is historically correct; current extent cannot fake old history.
Pass condition: snapshot + tail rebuild matches reference; current-extent reconstruction of old LSN fails correctness.
| Evidence | Test | File | Layer | Status |
|---|---|---|---|---|
| Snapshot + tail matches reference | TestReplicaRebuildFromSnapshotAndTail |
cluster_test.go |
distsim | PASS |
| Historical state not reconstructable after GC | TestA7_HistoricalState_NotReconstructableAfterGC |
phase045_crash_test.go |
distsim | PASS |
CanReconstructAt() rejects faked history |
CanReconstructAt() in storage.go |
storage.go |
distsim | Implemented |
| Checkpoint does not leak applied state | TestI2_CheckpointDoesNotLeakAppliedState |
phase045_crash_test.go |
distsim | PASS |
| Extent-referenced resolvable records | TestExtentReferencedResolvableRecordsAreRecoverable |
cluster_test.go |
distsim | PASS |
| Extent-referenced unresolvable → rebuild | TestExtentReferencedUnresolvableForcesRebuild |
cluster_test.go |
distsim | PASS |
| ACK'd flush recoverable after crash (I1) | TestI1_AckedFlush_RecoverableAfterPrimaryCrash |
phase045_crash_test.go |
distsim | PASS |
Verdict: A7 is now covered with the Phase 4.5 crash-consistency additions. The critical gap ("current extent cannot fake old history") is proven by CanReconstructAt() + TestA7_HistoricalState_NotReconstructableAfterGC.
A8: Durability Mode Semantics Are Correct
Must prove: best_effort, sync_all, sync_quorum behave as intended under mixed replica states.
Pass condition: sync_all strict, sync_quorum commits only with true durable quorum, invalid topology rejected.
| Evidence | Test | File | Layer | Status |
|---|---|---|---|---|
| sync_quorum continues with one lagging | TestSyncQuorumContinuesWithOneLaggingReplica |
cluster_test.go |
distsim | PASS |
| sync_all blocks with one lagging | TestSyncAllBlocksWithOneLaggingReplica |
cluster_test.go |
distsim | PASS |
| sync_quorum mixed states | TestSyncQuorumWithMixedReplicaStates |
cluster_test.go |
distsim | PASS |
| sync_all mixed states | TestSyncAllBlocksWithMixedReplicaStates |
cluster_test.go |
distsim | PASS |
| Barrier timeout: sync_all blocked | TestP03_BarrierTimeout_SyncAll_Blocked |
phase03_timeout_test.go |
distsim | PASS |
| Barrier timeout: sync_quorum commits | TestP03_BarrierTimeout_SyncQuorum_StillCommits |
phase03_timeout_test.go |
distsim | PASS |
| Promotion uses RecoverableLSN | EvaluateCandidateEligibility() |
cluster.go |
distsim | Implemented |
| Promoted replica has committed prefix (I4) | TestI4_PromotedReplica_HasCommittedPrefix |
phase045_crash_test.go |
distsim | PASS |
Verdict: A8 is well-covered. sync_all is strict (blocks on lagging), sync_quorum uses true durable quorum (not connection count). Promotion now uses RecoverableLSN() for committed-prefix check.
Summary
| Criterion | Simulator Evidence | Prototype Evidence | Status |
|---|---|---|---|
| A5 (catch-up escalation) | 6 tests | 1 test | Strong |
| A6 (recoverability boundary) | 6 tests + RecoverableLSN() | 1 test | Strong |
| A7 (historical correctness) | 7 tests + CanReconstructAt() | — | Strong (new in Phase 4.5) |
| A8 (durability modes) | 7 tests + RecoverableLSN() | — | Strong |
Total executable evidence: 26 simulator tests + 2 prototype tests + 2 new storage methods.
All A5-A8 acceptance criteria have direct test evidence. No criterion depends solely on design-doc claims.
Still Open (Not Blocking)
| Item | Priority | Why not blocking |
|---|---|---|
| Predicate exploration / adversarial search | P2 | Manual scenarios already cover known failure classes |
| Catch-up convergence under sustained load | P2 | I3 proves escalation; load-rate modeling is optimization |
| A5-A8 in a single grouped runner view | P3 | Traceability doc serves as grouped evidence for now |