fix(simulation): VoxelCache precondition doc + sec_phase decontamination + cache blend test (T-1042)
Addresses PR #167 review (Hoshe H1/H2/H3, Tyre T2). H1 — the VoxelCache 'same (seed, body_id, tile_pos) -> same column' invariant is no longer unconditional after the T-1042 blend (the key omits blend_weight/ secondary). Replaced with an explicit precondition on the struct + get_or_derive: the caller must pass the ChunkContext of the chunk that contains the tile. H2/T2 — sec_phase claimed to be 'position-independent' but mixed in primary_meander_phase/2 (the primary's per-position seed), making the secondary phase proxy asymmetric and primary-contaminated. Dropped that term; sec_phase is now the secondary's own morphology scalars (slope_q + moisture_q), with a comment honestly naming it a bounded cosmetic approximation and where to thread the real secondary seed if needed. H3 — added cache_boundary_tile_blend_is_stable: derives a boundary ChunkContext (blend_weight=128, secondary=Some), calls get_or_derive twice, asserts a cache hit + identical blended elevation + that the Cow::Owned blend path actually ran. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -292,15 +292,22 @@ pub fn derive_chunk_context(
|
||||
let sec_wavelength = derive_meander_wavelength(sec);
|
||||
let sec_channel_width = derive_channel_width(sec);
|
||||
let sec_phase = {
|
||||
// Secondary district's meander phase uses a secondary seed so it
|
||||
// differs from the primary (different district-scale chunk id).
|
||||
// We approximate: use the secondary's wavelength-derived phase
|
||||
// as an integer representation of its channel geometry. For a
|
||||
// well-defined phase, we re-derive from the secondary's slope and
|
||||
// moisture as a deterministic position-independent proxy.
|
||||
// Integer arithmetic (D-010).
|
||||
(sec.slope_q.wrapping_add(sec.moisture_q) as u8)
|
||||
.wrapping_add(primary_meander_phase / 2)
|
||||
// The secondary district's true meander phase would require its
|
||||
// district-scale seed, which in turn requires knowing the adjacent
|
||||
// district's chunk coordinates — information not available at this
|
||||
// call site. We use a bounded structural approximation: a hash of
|
||||
// the secondary's morphology scalars (slope_q, moisture_q), which
|
||||
// are the same inputs that drive `derive_meander_wavelength` and
|
||||
// therefore capture the secondary district's channel character.
|
||||
//
|
||||
// This approximation is intentionally asymmetric in an acknowledged
|
||||
// way: the blended phase is a cosmetic continuity aid at the 2 km
|
||||
// seam (meander phase), not a structural gate decision. The seam
|
||||
// is already invisible at the elevation level from elev_q blending;
|
||||
// the phase contribution is second-order. If the real secondary seed
|
||||
// is ever threaded through here, replace this with the proper
|
||||
// district-scale derivation. Integer arithmetic (D-010).
|
||||
sec.slope_q.wrapping_add(sec.moisture_q) as u8
|
||||
};
|
||||
let w = weight as i32;
|
||||
let w_sec = 255 - w;
|
||||
|
||||
Reference in New Issue
Block a user