From 5c9a2d3b50d12d01ceecc0ca0c05f0ec385dde0a Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 23:50:17 +0000 Subject: [PATCH 1/4] test(drf-w3): ordered same-facet writes apply by declared position Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg --- .../tests/integration/focus.rs | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/crates/drf-focus-probe/tests/integration/focus.rs b/crates/drf-focus-probe/tests/integration/focus.rs index 5f887ffbf..7c6b06689 100644 --- a/crates/drf-focus-probe/tests/integration/focus.rs +++ b/crates/drf-focus-probe/tests/integration/focus.rs @@ -490,3 +490,82 @@ fn w3_overlapping_facets_at_different_offsets_refuse_and_adjacent_facets_both_su assert_eq!(row[OFF..OFF + 4], 1i32.to_le_bytes()); assert_eq!(row[OFF + 4..OFF + 8], 2i32.to_le_bytes()); } + +#[test] +fn w3_ordered_same_facet_writes_apply_by_declared_position_in_every_staging_order() { + // Two slots alias row 500. The writes do not commute (overwrite), so the + // result must follow the declared stream position, not the staging order. + let r = rows(); + let soa = Soa { + rows: &r, + id: sid(1, 1, 1, 9), + }; + let m = map_from(304, 9, |s| if s < 3 { 500 } else { (s % NROWS) as u16 }); + let mgr = FocusManager::new(); + let f = mgr.load(&soa, &m, Scope(1), facet()).unwrap(); + let writes = [(0usize, 30i32, 3u64), (1, 10, 1), (2, 20, 2)]; + let perms = [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]; + for perm in perms { + let mut wb = f.writeback(); + for i in perm { + let (slot, value, pos) = writes[i]; + wb.stage_at(slot, facet(), value, pos).unwrap(); + } + let imgs = wb.flush(&soa).unwrap(); + assert_eq!(imgs.len(), 1); + assert_eq!(imgs[0].row[OFF..OFF + 4], 30i32.to_le_bytes(), "order {perm:?}"); + } + // 64 positioned writes over 4 rows in a scrambled staging order: each row + // ends with the value of its highest declared position (scalar oracle). + let m = map_from(305, 9, |s| [10u16, 20, 30, 40][s % 4]); + let f = mgr.load(&soa, &m, Scope(1), facet()).unwrap(); + let mut wb = f.writeback(); + let mut want = [(0u64, 0i32); 4]; + for k in 0..64usize { + let slot = (k * 37) % 64; + let pos = ((k * 23) % 64) as u64; + let value = (k as i32) * 7 - 100; + wb.stage_at(slot, facet(), value, pos).unwrap(); + if pos >= want[slot % 4].0 { + want[slot % 4] = (pos, value); + } + } + let imgs = wb.flush(&soa).unwrap(); + assert_eq!(imgs.len(), 4); + for (i, img) in imgs.iter().enumerate() { + assert_eq!(img.ord, [10u16, 20, 30, 40][i]); + assert_eq!(img.row[OFF..OFF + 4], want[i].1.to_le_bytes()); + } +} + +#[test] +fn w3_equal_positions_or_mixed_ordering_with_different_values_refuse() { + let r = rows(); + let soa = Soa { + rows: &r, + id: sid(1, 1, 1, 9), + }; + let m = map_from(306, 9, |s| if s < 2 { 500 } else { (s % NROWS) as u16 }); + let mgr = FocusManager::new(); + let f = mgr.load(&soa, &m, Scope(1), facet()).unwrap(); + let conflict = Some(Refusal::Conflict { ord: 500, offset: OFF }); + // Same declared position, different values: no order to apply them in. + let mut wb = f.writeback(); + wb.stage_at(0, facet(), 1, 5).unwrap(); + wb.stage_at(1, facet(), 2, 5).unwrap(); + assert_eq!(wb.flush(&soa).err(), conflict); + // An unordered write next to an ordered one, different values. + let mut wb = f.writeback(); + wb.stage(0, facet(), 1).unwrap(); + wb.stage_at(1, facet(), 2, 5).unwrap(); + assert_eq!(wb.flush(&soa).err(), conflict); + // Silence twins: equal values coalesce in both cases. + let mut wb = f.writeback(); + wb.stage_at(0, facet(), 4, 5).unwrap(); + wb.stage_at(1, facet(), 4, 5).unwrap(); + assert_eq!(wb.flush(&soa).unwrap().len(), 1); + let mut wb = f.writeback(); + wb.stage(0, facet(), 4).unwrap(); + wb.stage_at(1, facet(), 4, 9).unwrap(); + assert_eq!(wb.flush(&soa).unwrap()[0].row[OFF..OFF + 4], 4i32.to_le_bytes()); +} From a89021681eb1341ce685cbb29aa45d19319d08a0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 23:50:50 +0000 Subject: [PATCH 2/4] lab(drf-w3): same-facet writes apply by declared stream position stage_at carries a position; flush sorts by (ord, offset, pos) and applies in that order, so the highest position wins whatever the staging order. Different values at one position, or next to an unordered write, refuse. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg --- crates/drf-focus-probe/src/lib.rs | 48 +++++++++++++++---- .../tests/integration/focus.rs | 25 ++++++++-- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/crates/drf-focus-probe/src/lib.rs b/crates/drf-focus-probe/src/lib.rs index 124153213..d704240bf 100644 --- a/crates/drf-focus-probe/src/lib.rs +++ b/crates/drf-focus-probe/src/lib.rs @@ -294,6 +294,10 @@ struct Patch { ord: u16, offset: usize, value: i32, + /// Declared stream position. `None` sorts before every `Some`, so an + /// unordered write is applied first and can only coexist with ordered + /// writes of the same value (checked in `flush`). + pos: Option, } /// The final image of one dirty canonical row, owned for handoff to a writer. @@ -319,8 +323,32 @@ impl Focus { } impl Writeback<'_> { - /// Stage `value` into `facet` of the row behind `slot`. + /// Stage `value` into `facet` of the row behind `slot`, with no declared + /// order: a second write to the same facet must carry the same value. pub fn stage(&mut self, slot: usize, facet: Facet, value: i32) -> Result<(), Refusal> { + self.push(slot, facet, value, None) + } + + /// Stage `value` at declared stream position `pos`. Writes to one facet + /// apply in position order whatever order they were staged in; two + /// different values at one position refuse (W3). + pub fn stage_at( + &mut self, + slot: usize, + facet: Facet, + value: i32, + pos: u64, + ) -> Result<(), Refusal> { + self.push(slot, facet, value, Some(pos)) + } + + fn push( + &mut self, + slot: usize, + facet: Facet, + value: i32, + pos: Option, + ) -> Result<(), Refusal> { let ord = *self .focus .map @@ -331,6 +359,7 @@ impl Writeback<'_> { ord, offset: facet.offset(), value, + pos, }); Ok(()) } @@ -345,8 +374,9 @@ impl Writeback<'_> { /// One image per distinct dirty row, in ordinal order: the sealed source row /// with every staged facet applied. Writes to different facets of one row - /// all survive (W2); two different values for the same facet, or two - /// facets whose byte ranges overlap, refuse (W3). + /// all survive (W2). Writes to one facet apply in declared position + /// order; different values with no order between them (equal positions, + /// or an unordered write), or facets whose byte ranges overlap, refuse (W3). pub fn flush(mut self, soa: &Soa<'_>) -> Result, Refusal> { check_seal(soa, &self.focus.map)?; if self.focus.key.source != soa.id { @@ -355,16 +385,17 @@ impl Writeback<'_> { source_seal: soa.id.index_seal, }); } - self.patches.sort_by_key(|p| (p.ord, p.offset)); + self.patches.sort_by_key(|p| (p.ord, p.offset, p.pos)); for w in self.patches.windows(2) { if w[0].ord != w[1].ord { continue; } - // Same facet with a different value, or two facets whose byte - // ranges overlap: either would silently overwrite a staged write. - // Sorted by offset, so checking neighbours finds every overlap. + // Same facet: different values need two distinct declared + // positions, else nothing says which wins. Different facets must + // not overlap. Sorted by offset, so neighbours find every overlap. let same = w[0].offset == w[1].offset; - if (same && w[0].value != w[1].value) + let ordered = matches!((w[0].pos, w[1].pos), (Some(a), Some(b)) if a != b); + if (same && w[0].value != w[1].value && !ordered) || (!same && w[1].offset < w[0].offset + Facet::WIDTH) { return Err(Refusal::Conflict { @@ -373,6 +404,7 @@ impl Writeback<'_> { }); } } + // Applying in sorted order leaves each facet at its highest position. let mut out: Vec = Vec::new(); for p in &self.patches { if out.last().is_none_or(|img| img.ord != p.ord) { diff --git a/crates/drf-focus-probe/tests/integration/focus.rs b/crates/drf-focus-probe/tests/integration/focus.rs index 7c6b06689..40294daba 100644 --- a/crates/drf-focus-probe/tests/integration/focus.rs +++ b/crates/drf-focus-probe/tests/integration/focus.rs @@ -504,7 +504,14 @@ fn w3_ordered_same_facet_writes_apply_by_declared_position_in_every_staging_orde let mgr = FocusManager::new(); let f = mgr.load(&soa, &m, Scope(1), facet()).unwrap(); let writes = [(0usize, 30i32, 3u64), (1, 10, 1), (2, 20, 2)]; - let perms = [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]; + let perms = [ + [0, 1, 2], + [0, 2, 1], + [1, 0, 2], + [1, 2, 0], + [2, 0, 1], + [2, 1, 0], + ]; for perm in perms { let mut wb = f.writeback(); for i in perm { @@ -513,7 +520,11 @@ fn w3_ordered_same_facet_writes_apply_by_declared_position_in_every_staging_orde } let imgs = wb.flush(&soa).unwrap(); assert_eq!(imgs.len(), 1); - assert_eq!(imgs[0].row[OFF..OFF + 4], 30i32.to_le_bytes(), "order {perm:?}"); + assert_eq!( + imgs[0].row[OFF..OFF + 4], + 30i32.to_le_bytes(), + "order {perm:?}" + ); } // 64 positioned writes over 4 rows in a scrambled staging order: each row // ends with the value of its highest declared position (scalar oracle). @@ -548,7 +559,10 @@ fn w3_equal_positions_or_mixed_ordering_with_different_values_refuse() { let m = map_from(306, 9, |s| if s < 2 { 500 } else { (s % NROWS) as u16 }); let mgr = FocusManager::new(); let f = mgr.load(&soa, &m, Scope(1), facet()).unwrap(); - let conflict = Some(Refusal::Conflict { ord: 500, offset: OFF }); + let conflict = Some(Refusal::Conflict { + ord: 500, + offset: OFF, + }); // Same declared position, different values: no order to apply them in. let mut wb = f.writeback(); wb.stage_at(0, facet(), 1, 5).unwrap(); @@ -567,5 +581,8 @@ fn w3_equal_positions_or_mixed_ordering_with_different_values_refuse() { let mut wb = f.writeback(); wb.stage(0, facet(), 4).unwrap(); wb.stage_at(1, facet(), 4, 9).unwrap(); - assert_eq!(wb.flush(&soa).unwrap()[0].row[OFF..OFF + 4], 4i32.to_le_bytes()); + assert_eq!( + wb.flush(&soa).unwrap()[0].row[OFF..OFF + 4], + 4i32.to_le_bytes() + ); } From 64e5b8a04eef460f788e17b5477981242174c2bc Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 23:51:05 +0000 Subject: [PATCH 3/4] board: D-DRF W3 ordered apply entry Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg --- .../2026-10-25-drf-w3-ordered-apply.md | 19 +++++++++++++++++++ .claude/board/entries/README.md | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 .claude/board/entries/2026-10-25-drf-w3-ordered-apply.md diff --git a/.claude/board/entries/2026-10-25-drf-w3-ordered-apply.md b/.claude/board/entries/2026-10-25-drf-w3-ordered-apply.md new file mode 100644 index 000000000..0fa78b99e --- /dev/null +++ b/.claude/board/entries/2026-10-25-drf-w3-ordered-apply.md @@ -0,0 +1,19 @@ +# D-DRF W3 — ordered same-facet writes apply by declared stream position (lab) + +**Status:** TEST-PINNED (lab). **Code:** `crates/drf-focus-probe/src/lib.rs` +(`Writeback::stage_at`, `flush`). **Tests:** `tests/integration/focus.rs` +`w3_ordered_*`, `w3_equal_positions_or_mixed_ordering_*`. Plan: +`.claude/plans/d-dr64-focus-cache-falsifiers-v1.md` §4 W3. + +- **W3 PASS (ordered arm):** three noncommuting overwrites of one facet (positions 1, 2, 3) + through three aliasing slots give the position-3 value in all 6 staging orders. 64 writes + over 4 rows in a scrambled staging order match a scalar oracle (highest position per row). +- **W3 PASS (refusal arm):** different values at one declared position, or an unordered + `stage` next to a positioned one, refuse with `Conflict`. Equal values coalesce in both. +- **Mechanism:** patches sort by `(ord, offset, pos)` and apply in that order, so the + sort is the order of application; no second pass. +- **Disables, each red on its own test:** sort without `pos` (staging order wins); treat + equal positions as ordered; treat an unordered write as ordered. + +OPEN: positions are caller-declared `u64`s. Nothing yet ties them to a real stream +(CycleWriter sequence, WAL LSN); that is W4–W6. diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index db1c96dfe..c4fb7a638 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -25,10 +25,11 @@ index row, (3) no duplicate entry id. Checks 1 and 2 are deliberately opposite directions; the stranding this convention prevents shows up in exactly one of them, never both. -467 entries, 2026-08-06 .. 2026-10-25. +468 entries, 2026-08-06 .. 2026-10-25. | date | entry id | finding | file | |---|---|---|---| +| 2026-10-25 | `D-DRF` | | [2026-10-25-drf-w3-ordered-apply.md](2026-10-25-drf-w3-ordered-apply.md) | | 2026-10-25 | `D-DRF` | | [2026-10-25-drf-w1-writeback.md](2026-10-25-drf-w1-writeback.md) | | 2026-10-24 | `tanh-precision-symmetric-i8` | | [2026-10-24-tanh-precision-symmetric-i8.md](2026-10-24-tanh-precision-symmetric-i8.md) | | 2026-10-24 | `D-DRF-P2` | | [2026-10-24-drf-p2-breakeven.md](2026-10-24-drf-p2-breakeven.md) | From 960cb72c98979c6b15076c82673b8debe2ba9848 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 23:53:54 +0000 Subject: [PATCH 4/4] board: unique ids D-DRF-W1 / D-DRF-W3 for the writeback entries Both headings parsed as D-DRF, which entries_index --check rejects as a duplicate id. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg --- .claude/board/entries/2026-10-25-drf-w1-writeback.md | 2 +- .claude/board/entries/2026-10-25-drf-w3-ordered-apply.md | 2 +- .claude/board/entries/README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.claude/board/entries/2026-10-25-drf-w1-writeback.md b/.claude/board/entries/2026-10-25-drf-w1-writeback.md index 04549e092..ac5752422 100644 --- a/.claude/board/entries/2026-10-25-drf-w1-writeback.md +++ b/.claude/board/entries/2026-10-25-drf-w1-writeback.md @@ -1,4 +1,4 @@ -# D-DRF W1–W3 — staged writeback coalesced per canonical row (lab) +# D-DRF-W1 — W1–W3: staged writeback coalesced per canonical row (lab) **Status:** TEST-PINNED (lab). **Code:** `crates/drf-focus-probe/src/lib.rs` (`Focus::writeback`, `Writeback::{stage, dirty_rows, flush}`, `RowImage`). **Tests:** `w1_*`, `w2_*`, `w3_*` in diff --git a/.claude/board/entries/2026-10-25-drf-w3-ordered-apply.md b/.claude/board/entries/2026-10-25-drf-w3-ordered-apply.md index 0fa78b99e..575b1f0ef 100644 --- a/.claude/board/entries/2026-10-25-drf-w3-ordered-apply.md +++ b/.claude/board/entries/2026-10-25-drf-w3-ordered-apply.md @@ -1,4 +1,4 @@ -# D-DRF W3 — ordered same-facet writes apply by declared stream position (lab) +# D-DRF-W3 — ordered same-facet writes apply by declared stream position (lab) **Status:** TEST-PINNED (lab). **Code:** `crates/drf-focus-probe/src/lib.rs` (`Writeback::stage_at`, `flush`). **Tests:** `tests/integration/focus.rs` diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index c4fb7a638..b12cec492 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -29,8 +29,8 @@ exactly one of them, never both. | date | entry id | finding | file | |---|---|---|---| -| 2026-10-25 | `D-DRF` | | [2026-10-25-drf-w3-ordered-apply.md](2026-10-25-drf-w3-ordered-apply.md) | -| 2026-10-25 | `D-DRF` | | [2026-10-25-drf-w1-writeback.md](2026-10-25-drf-w1-writeback.md) | +| 2026-10-25 | `D-DRF-W3` | | [2026-10-25-drf-w3-ordered-apply.md](2026-10-25-drf-w3-ordered-apply.md) | +| 2026-10-25 | `D-DRF-W1` | | [2026-10-25-drf-w1-writeback.md](2026-10-25-drf-w1-writeback.md) | | 2026-10-24 | `tanh-precision-symmetric-i8` | | [2026-10-24-tanh-precision-symmetric-i8.md](2026-10-24-tanh-precision-symmetric-i8.md) | | 2026-10-24 | `D-DRF-P2` | | [2026-10-24-drf-p2-breakeven.md](2026-10-24-drf-p2-breakeven.md) | | 2026-10-24 | `D-DRF-P1` | | [2026-10-24-drf-p1-focus-lease-probe.md](2026-10-24-drf-p1-focus-lease-probe.md) |