fix: unblock main CI + audit follow-ups (RT-safety, silent-drop FFI, docs)#124
fix: unblock main CI + audit follow-ups (RT-safety, silent-drop FFI, docs)#124proggeramlug wants to merge 1 commit into
Conversation
…docs) Main CI was red on ffi-parity, and fixing that exposed a second failure (the file-line gate) that had been hidden behind it — the EN-063 "gate nobody reads" pattern, recurring. CI: - Export bloom_is_key_repeated on web (input_ffi.rs) and watchOS (regenerated ffi_stubs.rs via gen_stubs.js). validate-ffi green. - Split renderer/mod.rs 13156 -> 12556 by moving ~30 GPU-uniform POD structs + build_card_ortho_v2 into types.rs (their documented home). Struct/field order is byte-identical, so this is layout-neutral; the golden-image suite (raster) and 128 unit tests pass. Baseline ratcheted to 12556. (EN-052) Silent-failure FFI bugs (TS API): - loadMaterial called bloom_set_material_params, which is NOT in the manifest, so Perry silently no-op'd it and every material's params array was dropped. Reroute through the working _scratch path. - createTextureArray/createTextureArrayEx were exported but uncallable from Perry (number[] into an i64 pointer). Reroute through the same scratch path so they work; non-breaking (no Perry caller could reach them before). Audio RT-safety (audio/render.rs): - The 65th concurrent voice reallocated the voices Vec ON the audio thread. Add voice-stealing (drop the quietest) so the render thread never grows past its preallocated cap; same for music. Add 2 regression tests to a file that had none. Docs: - README: Windows audio XAudio2 -> WASAPI, Linux PulseAudio -> ALSA, drop the Wayland claim. CLAUDE.md: same ALSA fix. - lumen-roadmap platform matrix: HW ray-query is opt-in, not auto. - pt-roadmap ticket table: add the shipped PT-3b/6/7/8 rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR reorganizes renderer parameter types, bounds audio allocations, routes material and texture uploads through scratch buffers, adds keyboard-repeat FFI bindings, and updates platform and rendering documentation. ChangesRenderer type organization
Audio allocation bounds
Keyboard repeat FFI
Scratch-based material and texture uploads
Platform and roadmap documentation
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
native/shared/src/renderer/types.rs (1)
588-590: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUpdate the
PtParamsCpubyte count. The doc comment says 672 bytes, but the current field layout is 944 bytes, so the comment is misleading for WGSL parity checks.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@native/shared/src/renderer/types.rs` around lines 588 - 590, Update the byte-count statement in the PtParamsCpu documentation to 944 bytes, keeping the existing WGSL mirror and alignment descriptions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/models/index.ts`:
- Around line 588-590: The packed texture integer passed to
bloom_mesh_scratch_push_u32 is signed when the high byte has its top bit set;
append an unsigned conversion (>>> 0) to the bitwise expression at
src/models/index.ts lines 588-590. Apply the identical fix to the matching
texture repacking logic at src/models/index.ts lines 630-632.
---
Nitpick comments:
In `@native/shared/src/renderer/types.rs`:
- Around line 588-590: Update the byte-count statement in the PtParamsCpu
documentation to 944 bytes, keeping the existing WGSL mirror and alignment
descriptions unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 35ce7988-b806-4d7c-8f26-96b8e76dbf13
📒 Files selected for processing (12)
CLAUDE.mdREADME.mddocs/perf/lumen-roadmap.mddocs/pt/pt-roadmap.mdnative/shared/src/audio/render.rsnative/shared/src/renderer/mod.rsnative/shared/src/renderer/types.rsnative/watchos/src/ffi_stubs.rsnative/web/src/input_ffi.rssrc/core/index.tssrc/models/index.tstools/file-lines-baseline.json
💤 Files with no reviewable changes (1)
- src/core/index.ts
| bloom_mesh_scratch_push_u32( | ||
| bytes[b] | (bytes[b + 1] << 8) | (bytes[b + 2] << 16) | (bytes[b + 3] << 24), | ||
| ); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win
Bitwise OR produces a signed integer, causing data corruption for high alpha values.
In JavaScript, bitwise operations evaluate to a signed 32-bit integer. If the highest bit is set (bytes[b + 3] >= 128), the result becomes a negative number. When this negative number is passed as an f64 to the Rust FFI, casting it to u32 saturates to 0, completely corrupting the packed texture data for those texels. The shared root cause across these sites is the missing unsigned conversion.
src/models/index.ts#L588-L590: Add>>> 0to convert the expression to an unsigned 32-bit integer:(bytes[b] | (bytes[b + 1] << 8) | (bytes[b + 2] << 16) | (bytes[b + 3] << 24)) >>> 0.src/models/index.ts#L630-L632: Apply the exact same>>> 0fix to this identical texture array repacking logic.
📍 Affects 1 file
src/models/index.ts#L588-L590(this comment)src/models/index.ts#L630-L632
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/models/index.ts` around lines 588 - 590, The packed texture integer
passed to bloom_mesh_scratch_push_u32 is signed when the high byte has its top
bit set; append an unsigned conversion (>>> 0) to the bitwise expression at
src/models/index.ts lines 588-590. Apply the identical fix to the matching
texture repacking logic at src/models/index.ts lines 630-632.
Follow-ups from the 2026-07-19 engine audit. This PR is the verified-safe batch — everything here compiles and passes tests on macOS; it's ready to merge. A second PR will carry the native platform work that needs on-device testing.
Main CI was red
ffi-paritywas failing onmain, and fixing it exposed a second failure that had been hidden behind it (the file-line gate — the EN-063 "gate nobody reads" pattern, recurring within 48h).bloom_is_key_repeated(added in isKeyRepeated + real Windows clipboard/file dialogs/window title + unloadModel wrapper #122) was never exported on web or watchOS. Added toinput_ffi.rs; regenerated watchOSffi_stubs.rsviagen_stubs.js. →validate-ffigreen.renderer/mod.rshad grown to 13,156 (past its 13,058 baseline) during the PT work while the gate sat behind the broken step. Split to 12,556 by moving ~30 GPU-uniform POD structs +build_card_ortho_v2intorenderer/types.rs(its documented home). Struct/field order is byte-identical → layout-neutral. Baseline ratcheted down. (EN-052)Silent-failure FFI bugs
loadMaterialcalledbloom_set_material_params, which isn't in the manifest → Perry silently no-op'd it, so every material'sparamsarray was dropped. Rerouted through the working_scratchpath.createTextureArray/createTextureArrayExwere exported but uncallable from Perry (number[]→i64 pointer). Rerouted through the scratch path so they work; non-breaking.Audio RT-safety (
audio/render.rs)voicesVec on the audio thread (a glitch / malloc-lock priority inversion). Added voice-stealing (drop the quietest) so the render thread never grows past its preallocated cap; same for music.Docs
XAudio2→WASAPI, LinuxPulseAudio→ALSA, dropped the Wayland claim. CLAUDE.md: same ALSA fix.lumen-roadmapplatform matrix: HW ray-query is opt-in, not auto.pt-roadmaptable: added the shipped PT-3b/6/7/8 rows.Verification
validate-ffi: 0 failures.check-file-lines: 0 failures.cargo test --lib(default features): 128 passed, incl. the 2 new audio tests.pt_progressive,pt_realtime_motion) are pre-existing, hardware-dependent (Monte-Carlo + HW ray-query, baked on different hardware — all raster goldens pass on this GPU). The moved-struct layout is provably byte-identical, so this PR cannot affect PT output. Goldens intentionally not regenerated.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation