You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**FR-003**: `populate()` creates a MemoryTier entry with `write_ref=1`
275
+
-**FR-004**: The background writer downgrades `write_ref` to a `read_ref` after GPU copy, holds that read reference during SSD write, then releases it on completion via `convert_to_storage`
276
+
-**FR-005**: The entry remains in the memory-tier after write-through completes
277
+
-**Edge case**: *"The background writer holds a read reference on each entry while write-through is in progress. The reference is released after write completes or fails."*
278
+
279
+
The system-level invariant this implies: **an entry can only be cleanly evicted after its data is durably on SSD and no reference is held**. An entry being written through is never cleanly evictable.
280
+
281
+
### What was proved
282
+
283
+
The lifecycle proof `lifecycle_write_through_safety` in `components/dispatch-map/verif/src/lib.rs` traces the exact sequence the background writer follows and proves:
Three existing functions needed additional postconditions to carry enough information through the proof chain — the SMT solver cannot chain what it cannot see:
303
+
304
+
1.**`create_memory_tier_entry`** — added: location is `MemoryTier{ssd_offset: None}`. Without this, the solver did not know the structural type of the location field after creation.
305
+
306
+
2.**`downgrade_reference`** — added: location is preserved (`(^entry).location == (*entry).location`). Without this, the solver could not confirm the entry was still MemoryTier before calling `convert_to_storage`.
307
+
308
+
3.**`convert_to_storage`** — added: when called on a MemoryTier entry with `read_ref=1` and `write_ref=0`, both ref counts are zero after the call. This is the targeted postcondition that closes the final step of the proof.
309
+
310
+
### Key lesson: system-level proofs require richer function specs
311
+
312
+
The individual operations were already proved correct in isolation (by Daniel). But proving the SYSTEM-LEVEL property required strengthening their postconditions to expose information that individual callers never needed but the lifecycle proof did. This is a general pattern: operation-level proofs and system-level proofs have different informational requirements, and moving from one to the other often reveals gaps in the existing specs.
313
+
314
+
### Coq was not needed
315
+
316
+
Unlike the LBA adjacency proof, this property was fully discharged by the SMT solvers (alt-ergo, z3, cvc5, cvc4). The key was providing the right structural information about the `location` field — once the prover could case-split on the enum variant, the arithmetic (1-1=0) was trivial.
|`lifecycle_write_through_safety`|**System-level (spec FR-003/FR-004/FR-005):** entry is NOT evictable during write-through; becomes evictable only after write-through completes and the background writer releases its read reference |
0 commit comments