Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
## 2026-07-18 — E-X265-HEVC-ANCHOR-1 — the §5 external HEVC anchor is RUN + VISUAL: x265 over the φ-spiral sprite scene, 641× / PSNR 60.94 dB, real I/P/B GOP

**Status:** FINDING (external anchor — plan `x265-sprite-replay-probe-v1.md` §5 "optional context, NOT a gate"; run this session in-sandbox). Reproducer committed as `crates/helix/examples/hevc_moving_scene.rs`.
**What:** the sprite-replay scene (8 gaussian sprites on φ-spiral / golden-angle hemisphere paths, alternating hemispheres by parity, NUM_SPRITES=8 × TOTAL=240) rendered to a 320×240 Y4M and encoded with x265 3.5 (preset medium, `--psnr`). x265 ran its OWN I/P/B GOP over our moving scene (the "replay x265's GOP grammar" made literal): 1 I · 56 P · 183 B, up to 5 consecutive B-frames. ffmpeg decoded frames back OUT of the `.265` into a 5-frame motion montage + animated GIF (delivered to the operator).
**Numbers:** raw Y4M 27,649,483 B → HEVC 43,115 B = **641×**; **1437.2 bits/frame** (180 B/frame); Global **PSNR 60.94 dB** (Y 47.5–52.0 by slice-type; chroma neutral); encode 316 fps. (Re-run after the codex/CodeRabbit #738 fix — the reproducer now uses `sprite_replay`'s canonical draw sequence + signed-z hemisphere projection, so the sign genuinely separates hemispheres; the earlier 578×/60.79 dB numbers were the pre-fix scene where `sign` was inert.)
**Reading (honest, load-bearing):** these are **x265's** numbers on a smooth-gaussian synthetic scene that compresses easily — an EXTERNAL ANCHOR for "what a stock HEVC encoder does with this content," NOT a claim that our primitives beat x265 and NOT a gate. The arc's own sprite-replay motion coding (`E-SPRITE-IPB-HELIX-1`: one Signed360 code per sprite per P-frame) is what this contextualizes. The genuine comparison — our object-level motion codes vs x265's per-block MV field on the SAME scene, bits + PSNR side by side — is a NAMED follow-up, not done here. In-sandbox now: x265 3.5 + ffmpeg apt-installed this session (were absent).
**Cross-ref:** plan `x265-sprite-replay-probe-v1.md` §Results (2026-07-18 — HEVC external anchor) + §5; `E-SPRITE-IPB-HELIX-1` + `E-X265-PROBE-WAVE-2-RESULTS` (the motion-coding result this anchors against); reproducer `crates/helix/examples/hevc_moving_scene.rs`.

## 2026-07-18 — E-X265-PROBE-GPU-LUT-1 — the shared wgpu decode-tier harness is REAL and the 256²-u16 palette-distance LUT texture-gather is proven buildable; harness pinned to a2ui-paint's `wgpu` seam (the one in-scope GPU path)

**Status:** FINDING (PROBE-GPU-LUT — CPU-reference leg ran green, GPU-exec leg compiled + skips-clean; main-thread-adjudicated; operator-directed harness choice this session). Un-gates the plan `x265-sprite-replay-probe-v1.md` §Decode tiers (c) + the ndarray probe-queue `a2ui N2` row structurally; only runtime-execution parity on silicon remains deferred (no adapter in this sandbox).
**Context:** the x265/H.268 sprite-replay arc's wgpu + wasm decode tiers were "deferred on the shared PROBE-GPU-LUT harness." This session measured where a WebGL/wgpu body actually lives in scope: q2 `sculpt` (`// No WebGL`, software z-buffer→PNG) and ndarray `splat3d` (`// Pure SIMD, no GPU, no wgpu`) both deliberately opt OUT; the ONE real in-scope GPU seam is **a2ui-paint's `wgpu = "22"`** (WebGPU + WebGL2), which already ships an adapter-guarded headless render-to-texture `GpuPainter`. Operator ruling: use that seam as the harness.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
**What (PROBE-GPU-LUT, `a2ui-rs crates/a2ui-paint/src/gpu_lut_probe.rs`):** two legs, split by what the sandbox can measure.
- **CPU-reference (RAN, GREEN):** the exact `textureLoad(lut,(q,k)).r` gather modelled in Rust == row-major `lut[q*256+k]`, bit-exact over all **65536** entries; 256²-u16 table symmetric + zero-diagonal + deterministic (SplitMix64); 128 KiB (the §10(i) materialized-table figure). **This is the falsifiable core** — the arithmetic is what could be wrong; the GPU only executes it.
- **GPU-exec (COMPILED + SHIPPED, adapter-deferred):** the full R16Uint-LUT → fragment `textureLoad` → R32Uint target → readback → full-table-parity path compiles clean under wgpu 22 (GL backend via `glow` builds; `clippy --features wgpu -D warnings` clean, fmt clean) and **SKIPS-green** here — measured: `libvulkan` loader present but **0 ICDs** → `request_adapter()` returns `None`. **Backend scope (codex P2, headless):** the probe requests a **surface-less** adapter, so its execution validates on WebGPU (native/browser) + native/software GL (lavapipe CI). Integer sampled texture + `textureLoad` + integer render target are all WebGL2-core, so the WGSL is WebGL2-**compatible** — but wgpu's WebGL backend needs a canvas-bound `compatible_surface`, so the wasm32 WebGL2 backend is OUT OF SCOPE for this headless probe (a surface-bound harness would run it). Runs the real 65536/65536 parity wherever a surface-less adapter exists.
**Ruling:** the bgz17 256²-u16 palette-distance table is **representable and COMPILES** through a real in-scope wgpu texture path (R16Uint sampled + `textureLoad` + integer render target) — the GPU LUT lane is **not** abandoned (KILL did not fire). Runtime gatherability + silicon parity stay DEFERRED until actual GPU execution (no adapter here). The harness capability is proven buildable; the shared harness the sprite-replay **wgpu decode tier (c)** waited on is real — the wasm tier (b) is a separate CPU-vs-wasm replay-determinism gate, untouched (codex + CodeRabbit #738).
**HONEST CAVEAT:** the GPU-exec *execution* was NOT run on silicon in this sandbox (no adapter). "GPU-exec green" = COMPILES + SKIPS-cleanly + is the shipped WGSL, NOT "65536 texels compared on a GPU here." The CPU-reference is the leg that actually ran; runtime-execution parity on silicon is the one piece still deferred (the `a2ui N2` render-parity-headless-vs-browser bar).
**Boundary:** no bgz17 dep added to a2ui-paint (a2ui charter: no consumer-crate deps) — the 256² table is built deterministically with bgz17's table STRUCTURE, so this is a HARNESS-CAPABILITY probe, not a bgz17 integration. `#[cfg(test)]`-only module; test-only `pollster` dev-dep for the async block. Charter T1/T2/T3 untouched (no new vocabulary, no behavior-on-surface, no hot-path serialization).
**Cross-ref:** ndarray `pr-x12-h268-morton-wgpu-synergies.md` §5 Wave-3 sub-table + PROBE-GPU-LUT queue-row verdict + §10(i) 128 KiB figure; plan `x265-sprite-replay-probe-v1.md` §Results (2026-07-18) + §Decode tiers (c); `E-X265-PROBE-WAVE-2-RESULTS` (the sprite-replay wave whose wgpu decode tier (c) this un-gates — the wasm tier (b) is a SEPARATE CPU-vs-wasm replay-determinism gate, NOT touched by this wave; corrected per codex P2 on ndarray #249); a2ui-paint `src/lib.rs` `mod gpu` (the shipped `GpuPainter` harness this extends). Probe asserts structural sanity + determinism only (never the verdict); the number adjudication is here.

## 2026-07-18 — E-WI3-CONTINUOUS-FIELD-ANALYTIC-1 — WI-3 resolved: the monotone-bounded continuous-field exit is ANALYTIC (helix RollingFloor at 1 byte), not the materialized ladder

**Status:** FINDING (PROBE-HELIX-CONTINUOUS-FIELD measured, main-thread-adjudicated; resolves WI-3 of `E-BGZ-TENSOR-LANE-REVIEW-1` axis (c) — the one open work-item that could move a lane assignment).
Expand Down
228 changes: 228 additions & 0 deletions crates/helix/examples/hevc_moving_scene.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
//! HEVC moving-scene anchor renderer (plan §5 external anchor, made visual).
//!
//! Renders the sprite-replay scene — 8 gaussian sprites tracing φ-spiral
//! (golden-angle hemisphere) paths, alternating hemispheres by index parity,
//! exactly as `helix/src/sprite_replay.rs` seeds them — to a Y4M (I420) clip.
//! x265 then encodes it (the arc's "replay x265's GOP grammar" made literal:
//! x265 runs its own I/P/B GOP over OUR moving scene) and reports bits/frame +
//! PSNR; ffmpeg decodes frames back for the screenshot montage.
//!
//! std-only, deterministic (SplitMix64, no rand) — matches the probe discipline.

use std::io::{BufWriter, Write};

const W: usize = 320;
const H: usize = 240;
const TOTAL: usize = 240; // frames == sprite-replay TOTAL
const NUM_SPRITES: usize = 8; // sprite-replay NUM_SPRITES

/// SplitMix64 — same generator + seed family as sprite_replay.rs.
struct SplitMix64(u64);
impl SplitMix64 {
fn new(seed: u64) -> Self {
Self(seed)
}
fn next_u64(&mut self) -> u64 {
self.0 = self.0.wrapping_add(0x9E37_79B9_7F4A_7C15);
let mut z = self.0;
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
z ^ (z >> 31)
}
fn unit(&mut self) -> f64 {
(self.next_u64() >> 11) as f64 / (1u64 << 53) as f64
}
fn range(&mut self, lo: f64, hi: f64) -> f64 {
lo + self.unit() * (hi - lo)
}
}

#[derive(Clone, Copy)]
struct Sprite {
cx: f64, // screen center x (px)
cy: f64, // screen center y (px)
radius: f64, // spiral radius (px)
sign: f64, // +1 upper hemisphere, -1 lower (parity, like sprite-replay)
bright: f64, // peak luma
sigma: f64, // gaussian spread (px)
}

/// φ-spiral (golden-angle Fibonacci hemisphere) point n of TOTAL, signed.
/// Returns the canonical `(x, z, y)` cartesian of the hemisphere point — the
/// SAME axis order `sprite_replay::sprite_position` uses (`HemispherePoint::
/// cartesian` → `(x, z, y)`, position = center + scale·[x, z, y]). The **signed
/// height is `z`** (the 2nd element), so `sign` genuinely selects the
/// hemisphere; the caller must project a signed axis to screen (not `abs`) or
/// the two hemispheres collapse onto one trajectory.
fn phi_spiral_cart(n: usize, total: usize, sign: f64) -> (f64, f64, f64) {
// Golden angle ≈ 2.399963 rad — the same irrational winding the arc's
// φ-spiral / CurveRuler uses (stride-4-over-17 is its integer cousin).
let ga = std::f64::consts::PI * (3.0 - 5.0_f64.sqrt());
let t = (n as f64 + 0.5) / total as f64; // 0..1 along the path
let z = sign * (1.0 - t); // signed hemisphere height (upper for +, lower for −)
let r = (1.0 - z * z).sqrt(); // disk radius at height z
let theta = n as f64 * ga;
(r * theta.cos(), z, r * theta.sin()) // (x, z=signed height, y)
}

fn seed_sprites() -> [Sprite; NUM_SPRITES] {
// Same seed constant as sprite_replay::seed_sprites (0x5350_5249_5445_5F31 = "SPRITE_1").
let mut rng = SplitMix64::new(0x5350_5249_5445_5F31);
core::array::from_fn(|i| {
// CANONICAL draw sequence — byte-for-byte the order sprite_replay uses:
// place (u64), then center[0..3] (3 range draws), then scale. Screen/render
// params are DERIVED from these canonical world values with NO extra RNG
// draws, so sprite i's place/center/scale stream matches the probe exactly.
let _place = rng.next_u64();
let c0 = rng.range(-50.0, 50.0); // center[0]
let c1 = rng.range(-50.0, 50.0); // center[1]
let c2 = rng.range(-50.0, 50.0); // center[2]
let scale_w = rng.range(5.0, 25.0); // scale
let sign = if i % 2 == 0 { 1.0 } else { -1.0 };
// Derive the on-screen envelope from the canonical world values.
let cx = W as f64 * 0.5 + (c0 / 50.0) * (W as f64 * 0.38); // [-50,50] → screen x
let cy = H as f64 * 0.5 + (c1 / 50.0) * (H as f64 * 0.30); // [-50,50] → screen y
let radius = 16.0 + (scale_w - 5.0) / 20.0 * 18.0; // [5,25] → [16,34] px
let bright = 175.0 + ((c2 + 50.0) / 100.0) * 70.0; // [-50,50] → [175,245]
let sigma = 6.0 + (scale_w - 5.0) / 20.0 * 5.0; // [5,25] → [6,11] px
Sprite {
cx,
cy,
radius,
sign,
bright,
sigma,
}
})
}

fn main() -> std::io::Result<()> {
let path = std::env::args()
.nth(1)
.unwrap_or_else(|| "scene.y4m".into());
let sprites = seed_sprites();
let f = std::fs::File::create(&path)?;
let mut out = BufWriter::new(f);

// Y4M header — I420, 25 fps, progressive.
write!(out, "YUV4MPEG2 W{W} H{H} F25:1 Ip A1:1 C420jpeg\n")?;

let mut y = vec![0u8; W * H];
let cw = W / 2;
let ch = H / 2;
let uv = vec![128u8; cw * ch]; // neutral chroma (grayscale scene)

for frame in 0..TOTAL {
// Background: a faint moving gradient so inter-frame prediction has
// global motion to track (a static bg would make every P-frame near-zero).
let pan = (frame as f64 / TOTAL as f64) * 40.0;
for py in 0..H {
for px in 0..W {
let g = 24.0
+ 10.0 * (((px as f64 + pan) * 0.03).sin())
+ 6.0 * ((py as f64 * 0.05).cos());
y[py * W + px] = g.clamp(0.0, 60.0) as u8;
}
}
// Splat each sprite at its φ-spiral point for this frame.
for s in &sprites {
// Canonical (x, z, y): x → screen-x, SIGNED z → screen-y (so the
// hemisphere sign mirrors the sprite vertically), y → depth.
let (cx_off, cz_signed, cy_depth) = phi_spiral_cart(frame, TOTAL, s.sign);
let px0 = s.cx + s.radius * cx_off;
let py0 = s.cy + s.radius * cz_signed;
// The remaining axis (y) modulates size: nearer = larger/brighter.
let depth = 0.6 + 0.4 * cy_depth.abs();
let sigma = s.sigma * depth;
let peak = s.bright * depth;
let rad = (sigma * 3.0).ceil() as i64;
let inv2s2 = 1.0 / (2.0 * sigma * sigma);
let cxi = px0.round() as i64;
let cyi = py0.round() as i64;
for dy in -rad..=rad {
let yy = cyi + dy;
if yy < 0 || yy >= H as i64 {
continue;
}
for dx in -rad..=rad {
let xx = cxi + dx;
if xx < 0 || xx >= W as i64 {
continue;
}
let d2 = (dx * dx + dy * dy) as f64;
let v = peak * (-d2 * inv2s2).exp();
let idx = yy as usize * W + xx as usize;
let cur = y[idx] as f64;
y[idx] = (cur + v).clamp(0.0, 255.0) as u8; // additive splat
}
}
}
out.write_all(b"FRAME\n")?;
out.write_all(&y)?;
out.write_all(&uv)?; // U
out.write_all(&uv)?; // V
}
out.flush()?;
eprintln!(
"rendered {TOTAL} frames {W}x{H} ({} sprites, φ-spiral motion) → {path}",
NUM_SPRITES
);
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

/// The SplitMix64 stream is deterministic for the sprite_replay seed — the
/// canonical-sequence contract the scene relies on.
#[test]
fn splitmix64_is_deterministic_for_the_sprite_seed() {
let mut a = SplitMix64::new(0x5350_5249_5445_5F31);
let mut b = SplitMix64::new(0x5350_5249_5445_5F31);
for _ in 0..8 {
assert_eq!(a.next_u64(), b.next_u64());
}
// Distinct successive outputs (not a stuck generator).
let mut c = SplitMix64::new(0x5350_5249_5445_5F31);
let x = c.next_u64();
let y = c.next_u64();
assert_ne!(x, y);
}

/// `sign` MUST select the hemisphere: the signed-height axis flips with it,
/// so opposite signs give different projected positions (the bug CodeRabbit
/// caught — `abs(z)` had cancelled the sign).
#[test]
fn phi_spiral_sign_separates_hemispheres() {
for n in [0usize, 37, 120, 239] {
let (xp, zp, _) = phi_spiral_cart(n, TOTAL, 1.0);
let (xn, zn, _) = phi_spiral_cart(n, TOTAL, -1.0);
// x (azimuth) is sign-independent; the height z is the discriminator.
assert!(
(xp - xn).abs() < 1e-12,
"azimuth is sign-independent at n={n}"
);
assert!(
zp > 0.0 && zn < 0.0,
"pos=upper / neg=lower hemisphere at n={n}"
);
assert!(
(zp - zn).abs() > 1e-9,
"sign must produce distinct projected height at n={n}"
);
}
}

/// seed_sprites is deterministic and alternates hemisphere by index parity.
#[test]
fn seed_sprites_deterministic_and_alternating() {
let a = seed_sprites();
let b = seed_sprites();
for i in 0..NUM_SPRITES {
assert_eq!(a[i].sign, b[i].sign);
assert_eq!(a[i].cx.to_bits(), b[i].cx.to_bits());
assert_eq!(a[i].sign, if i % 2 == 0 { 1.0 } else { -1.0 });
}
}
}
Loading