Automated summary
Audits the M44 audio subsystem (kira backend, spatial sub-tracks, reverb send, underwater filter, voice and streaming music) along with the engine systems that are its only callers, producing deduplicated findings per dimension.
Strengths
- Orchestrates one Task agent per dimension (max 3 concurrent) on top of a shared delta-first scoping and finding-format protocol.
- Draws explicit handoff boundaries with neighbouring audits (water state to physics, ordering to ECS/concurrency) so findings are not duplicated.
- Clearly separates shipped from not-yet-shipped features and cites the open issues (#3816, #3086, #5526, #5464, #5912…) behind each gap.
- Grounds verification in concrete references: the lib.rs module docstring, docs/feature-matrix.md, and the crate's test and fuzz files.
Limitations
- Tightly bound to one specific repository (paths, component names, issue numbers), so it is hard to reuse as-is elsewhere.
- Relies on companion files (_audit-common.md, _audit-severity.md) that are missing from the supplied SKILL.md, and the text cuts off mid-sentence on issue #3086.
- Feature status is dated 2026-10-20 and must be re-verified on every run.
Use it when you need a deep review of the audio crate and its engine call sites, for example before a release or after changing audio code.
Do not use it for a different subsystem or repository, or when the shared audit protocol and expected crate layout are not present.
Security analysis
CautionThe skill is a read/verify-oriented audit workflow: git/grep inspection, targeted cargo test runs, subagent fan-out, and a report written into the repo. Its only destructive action is deleting its own /tmp scratch directory, and nothing sends data out or touches secrets. It is rated caution rather than safe because it drives an execution-capable toolchain (cargo test, ignored/device test lane, shell, 3 concurrent subagents) and mutates the working tree, so a reviewer should expect real command execution against a local repository.
- •Executes shell commands: `mkdir -p /tmp/audit/audio`, `cargo test -p byroredux-audio`, `git log`, `git grep` — cargo test compiles and runs arbitrary repository code, and the skill instructs re-running the suite with `-- --ignored` (device-gated/FFN-data lifecycle tests), expanding the executed surface.
- •Destructive command present but tightly scoped: `rm -rf /tmp/audit/audio` at merge time. Low blast radius, but a literal `rm -rf` on a path variable is a pattern worth hardening (quote/validate the path).
- •Spawns up to 3 concurrent Task subagents with open read access to the repo and tooling, then writes output into `docs/audits/AUDIT_AUDIO_<TODAY>.md`, mutating the working tree without an explicit confirmation step.
- •Depends on reading sibling instruction files (`.claude/commands/_audit-common.md`, `_audit-severity.md`) whose contents are not shown here; a modified/compromised common protocol file would silently steer this audit.
- •Recommends a follow-on command (`/audit-publish`) as the final step, chaining execution beyond the audited scope.
- •No network fetches, credential access, exfiltration, obfuscated payloads, or safety-disabling instructions found; no prompt-injection attempts detected in the skill body.
- •Directs the agent to execute repository build/test binaries (`cargo test -p byroredux-audio`, `cargo test -p byroredux -- audio dialogue_voice`, and `-- --ignored` device-gated lanes), i.e. compiling and running arbitrary in-repo code, plus `git log`/`git grep` shell invocations. Legitimate for an audit skill, but it is real code execution with no declared allowed-tools.
- •Contains a scoped destructive command: `mkdir -p /tmp/audit/audio` ... `rm -rf /tmp/audit/audio`. The path is narrow and self-owned, but an agent that mis-substitutes the variable could widen the blast radius; the cleanup should be quoted/guarded.
- •Describes a bridge that pipes untrusted game-asset WMA payloads through an external `ffmpeg` process (crates/audio/src/fuz.rs). Not an instruction to the auditor, but the audited surface parses attacker-controllable binary containers via a third-party binary — worth noting as a risk the skill is asking the agent to reason about.
- •No prompt-injection, exfiltration, credential access, obfuscated payload, or safety-disabling instruction found in the content; the document reads as genuine internal audit runbook material.
Examples
Run the M44 audio audit at deep depth, focusing on the kira backend and the spatial sub-tracks.Audit the reverb send, reverb zones and the underwater filter at shallow depth and report findings in the shared format.Check the engine-side callers of the audio crate — footsteps, water audio, REGN ambient music and voice — for stale or missing API usage.description: "Deep audit of the M44 audio subsystem — kira backend, spatial sub-tracks, listener/unit seam, reverb send, underwater filter, streaming music — plus its engine callers (footsteps, water audio, reverb zones, REGN ambient music)" argument-hint: "--focus <dimensions> --depth shallow|deep"
Audio Subsystem Audit (M44)
Read .claude/commands/_audit-common.md (delta-first scoping, dedup, finding format) and _audit-severity.md for shared protocol.
Audits crates/audio/ (kira 0.12, default-features = false with an explicit feature list in the workspace Cargo.toml — cpal, wav+pcm, ogg+vorbis, mp3, flac; 0.12 split container from codec features, so dropping a codec silently stops decoding (mp3 now carries Oblivion voice); src/lib.rs + src/tests.rs + src/fuz.rs, the .fuz/xWMA container reader and ffmpeg bridge) and the engine systems that are the ONLY callers of its API. Orchestrator; one Task agent per dimension (max 3 concurrent). Verify the shipped surface against the lib.rs module docstring and docs/feature-matrix.md (Audio); if lib.rs splits, re-derive each dimension's paths first.
Scope
- Crate:
AudioWorld(Option<AudioManager>resource;headless()is the no-device constructor),AudioListener/AudioEmitter/OneShotSoundcomponents,Attenuation,audio_system,SoundCache,VoiceSoundCache,load_*sound*,with_start_delay. - Engine side:
byroredux/src/systems/audio.rs(footstep_system,impact_audio_system,reverb_zone_system,water_audio_system), the combat-feedback sound half ofbyroredux/src/systems/combat_anim.rs(play_oneshot_cached; take/animation half is/audit-gameplay),byroredux/src/systems/dialogue_voice.rs(voice consumer),byroredux/src/systems/scripted_sound.rs(scriptSound.Play),SoundCache/VoiceSoundCacheboot inserts (boot/world.rs) + telemetry (ownership_sample.rs), the footstep / impact / water-audio resources inbyroredux/src/components/audio.rs(FootstepConfig,ImpactConfig,WaterAudioConfig) andRegionAmbientResinbyroredux/src/components/environment.rs,byroredux/src/asset_provider/{audio,texture}.rs(dispatch_region_ambient_music,SoundArchiveProvider,sound_is_folder,try_load_default_footstep), wired fromcell_loader/load.rsandscene::apply_cell_region_ambient. - Handoffs: water state (
SubmersionState, splash/ripple production) is/audit-physicsDim 5; stage/lock shape is/audit-ecs//audit-concurrency(report audio-specific ordering only).
Not shipped as of 2026-10-20 (re-verify against docs/feature-matrix.md; audit the mechanism that will carry them): FOOT/IPDS/IPCT records → per-material footstep and clutter-impact content (the Wave-4 mechanism is live — Havok surface_material u32 → FootstepConfig/ImpactConfig surface_sounds — but both maps and ImpactConfig::default_sound ship empty, so impact_audio_system is a production no-op and footsteps always take the default), CELL-level MUSC routing (default_music/music_type_form are parsed; every construction site still hardcodes music_type_form: None), per-cell acoustics beyond binary interior/exterior reverb, occlusion, REGN incidental/ambient-loop selection (#3301 open). Dialogue voice now covers every voiced title (Dim 5): Oblivion's race/sex .mp3 (#5526 fa7591ca2, through kira's mp3 feature) and Skyrim+ .fuz (FUZE + raw .lip + RIFF xWMA, not XMA2 — #5464 1c69389b7; crates/audio/src/fuz.rs parses it and bridges the WMA payload through the host's OPTIONAL ffmpeg to a hand-headed WAV, since no workspace decoder reads WMA — no ffmpeg ⇒ subtitle estimate, #5912 acd577a79).
Known-open (verified 2026-10-20): #3816 (MUSC/MUST/MSET/RDMD decode: REGN music_form never resolves as a SOUN on any supported game, so the dispatch mechanism is live and tested but plays nothing in production; audit the mechanism, cite #3816 for the gap). #3086 (entity-path spatial position frozen at dispatch) is closed (b4f08089b): sync_emitter_positions now follows the source GlobalTransform (Dim 1) — a frozen position is a regression. #4146 (reverb-zone ordering comment drift) is closed — a third drift is a regression. #5432 is closed (40b77828b): AudioWorld::stop_sounds_for (#5410) now has production callers through dialogue_voice::stop_line_voice — topic change, conversation close and speaker death cut the line (Dim 1/5); a new line-ending path that skips it is the regression. #5148 is closed (7208af67c): combat.status reports per-kind request counts (CombatSoundRequests: swing / impact / death_voice, counted only when play_oneshot_cached actually requested a one-shot) and the Skyrim P2 gate requires >= 1 impact + >= 1 death-voice, so oneshots_requested is no longer the gate's only signal. #4743 is closed (519bb02c4): impact one-shots queue per HitEvent ahead of the Dead / active-take branches (mid-stagger hits and the killing blow sound) and the swing sound rides the marked aggressor's own attack take; pinned by a_hit_during_an_active_take_still_sounds beside the existing killing-blow / aggressor-swing tests.
Parameters
--focus <dims> (default all 5) · --depth shallow|deep (deep traces per-frame data flow + lifecycle).
Extra field: Dimension: Spatial Dispatch & Listener | Send Graph (Reverb + Underwater) | Music & SoundCache | Manager & ECS Lifecycle | Engine Consumers.
Phase 1: Setup
mkdir -p /tmp/audit/audio; dedup per_audit-common.md; read the latestdocs/audits/AUDIT_AUDIO_*.md(date D = delta baseline). A re-flag of a closed finding is a regression claim: check its guard is gone before reporting.cargo test -p byroredux-audioandcargo test -p byroredux -- audio dialogue_voice; record counts. The lifecycle guards are#[ignore]d (need an audio device, some FNV data):looping_emitter_survives_natural_duration_and_stops_on_emitter_remove,non_looping_emitter_stops_on_emitter_remove_regression_858,play_music_looping_survives_track_end,play_music_drives_streaming_playback_on_real_ogg,emitter_position_follows_the_source_entity_regression_3086,anchored_voice_follows_survives_prune_and_stops, plus the playback/decode trioplay_oneshot_queue_drives_real_playback,audio_system_full_lifecycle_on_real_fnv_sound,real_fnv_sounds_decode_through_kira. Despawn truncation, follow, anchored-voice stop and music looping are unguarded in the default lane: run-- --ignoredor say so.
Phase 2: Dimensions
Dim 1: Spatial Dispatch, Listener & the Unit Seam
Paths: crates/audio/src/lib.rs (dispatch_new_oneshots, drain_pending_oneshots, build_spatial_track, prune_stopped_sounds, sync_listener_pose, sync_emitter_positions, bu_to_audio_space, linear_volume_to_db, ActiveSound, SoundSource, play_oneshot_following, stop_sounds_for)
First step: git log --since=D -- crates/audio/src/lib.rs
Guards (default lane): tests.rs::{every_kira_position_site_goes_through_the_unit_seam, emitter_at_max_distance_in_bu_lands_on_max_distance_in_audio_space, drain_pending_oneshots_drains_in_place_instead_of_stranding_capacity, play_oneshot_queue_caps_at_max_pending_when_active, oneshot_marker_is_consumed_on_both_dispatch_failure_arms, with_start_delay_sets_the_start_time_and_shares_frames, play_oneshot_following_drops_on_inactive_audio, stop_sounds_for_is_a_no_op_on_a_headless_world}; #[ignore]d device-gated emitter_position_follows_the_source_entity_regression_3086 (#3086) and anchored_voice_follows_survives_prune_and_stops (#5410).
- Two dispatch paths stay observably equivalent: entity path (
OneShotSound+AudioEmitter→ per-emitterSpatialTrackHandle,SoundSource::Emitter, marker removed,AudioEmitterkept) and queue path (PendingOneShot, never loops:play_oneshot→SoundSource::Detached, orplay_oneshot_following→SoundSource::Anchored(entity), #5410 d1a7ee8c6). Both early-return without a listener id and build their sub-track through the onebuild_spatial_track(distance window, reverb send, underwater filter, kira sub-track; each loop keeps only its play tail and error policy, #5738 eac602644) — a loop that hand-builds the chain again is the regression.stop_sounds_for(entity, fade_ms)fades every playingEmitter/Anchoredsound of the entity and drops its queued segments; its production caller isdialogue_voice::stop_line_voice(150 ms fade;apply_selection,end_open_conversation,reconcile_dead_actor, and ahead of each ObScriptSayline inscripted_line_voice_system; #5432). The entity path has NO engine producer —spawn_oneshot_atis test/tooling-only, so its dispatch is exercised bytests.rsalone (#5612 81207d34d). ActiveSound::trackis held for its Drop side effect AND carries the #3086 position pushes (renamed from_track; the track must still be kept alive): it must land inactive_soundsbefore the helper returns.Arc<StaticSoundData>is shared, never deep-cloned; volume applies via(*sound).clone().volume(db).oneshots_requestedis a monotonic count ofplay_oneshot/play_oneshot_followingcalls including headless discards (incremented before the manager gate; read bycombat.statusincommands/view.rsfor device-less smoke gates) — it proves a request, never audible playback.- Producer queue caps at 256 (in both
play_oneshot*entry points, each with its ownMAX_PENDING) with O(1)pop_frontand drops up front when the manager isNone; the manager-active gate precedes the drain; a drain of more than 32 warns once per tick (footstep tempo gone wrong).linear_volume_to_dbis the single dB conversion (floorSILENCE_DB-60). - Entity path reads post-propagation
GlobalTransform, notTransform. World is Bethesda units (70/m), kira is metres:bu_to_audio_spaceis the only seam, applied to the listener pose and both dispatch paths;Attenuationis authored in metres (min <= max,RangeInclusive) and callers must never pre-scale by 70. A missed site is silent (inaudible past ~43 cm, no log);every_kira_position_site_goes_through_the_unit_seamscans the listener sites, both dispatch paths and (since #5411, bb31c5fb3) the follow site, with a negative on rawset_position. - Emitter follow (#3086, b4f08089b):
sync_emitter_positions(pass 2, after the listener sync) pushes the sub-track of everyActiveSoundwhoseSoundSource::followed_entity()is set (EmitterandAnchored) to its source's currentGlobalTransformthrough the samebu_to_audio_space; change-gated onActiveSound::last_position(seeded at dispatch on both paths) so a stationary emitter costs one compare and zero kira commands;Detachedqueue sounds and music are never touched; a despawned/transform-less entity is skipped (prune ownsEmitteron emitter removal andAnchoredonGlobalTransformloss —orphaned_anchored_entity, #5678 74d841165 — andstop_sounds_forowns the explicitAnchoredstop).AudioWorld::emitter_position_updates()is the observable (kira has no position readback). The behaviour guards are#[ignore]d (device) — trace the code in the default lane. - Listener: created lazily on the first frame an
AudioListenerhas a resolvedGlobalTransform; the handle is sticky (never cleared on despawn: kira listener capacity is 8, a clear/re-add loop exhausts it); a failedadd_listenerretries next frame; multi-listener warns once and uses the first. Pose usesTween::default()(smooth follow); orientation is already renderer-space (no second Z-up conversion). Output:/tmp/audit/audio/dim_1.md
Dim 2: Send Graph: Reverb Send & Underwater Filter
Paths: crates/audio/src/lib.rs (AudioWorld::new, apply_reverb_send, reverb_send_gate_open, set_reverb_send_db, apply_underwater_filter, update_underwater_filters, set_underwater)
First step: git log --since=D -- crates/audio/src/lib.rs (send/filter regions)
Guards: tests.rs::{reverb_send_defaults_to_silent, reverb_send_gate_matches_silence_db_boundary, above_water_filter_state_is_a_dry_bypass, above_water_cutoff_never_reaches_the_kira_clamp_ceiling, both_dispatch_paths_build_the_filter_through_one_call_site}.
- One global reverb send is created in
AudioWorld::newfromREVERB_FEEDBACK/REVERB_DAMPING/REVERB_STEREO_WIDTH(0.85/0.6/1.0). They have no recorded provenance and are not kira's defaults: flag the doc gap, never invent a rationale.reverb_send: Nonenever cascades into anunwrap(). - Send opt-in is build-time only (
with_sendat track construction, gatedis_finite() && > -60 dB) and both paths use the shared helper. Default levelNEG_INFINITY(dry). Playing sounds keep their construction-time level: the documented "next-dispatch knob" contract, not a bug — kira 0.12'sSpatialTrackHandle::set_sendcould retarget an existing route, but the engine does not, and a track built while the send was muted has no route at all (doc corrected #5677 b0b9bc987; a live fader needs every track routed atSILENCE_DBfrom construction). - Every spatial sub-track carries a low-pass built by ONE shared
apply_underwater_filter;update_underwater_filtersretargets live tracks when the listener's submersion changes. Above water is a genuine bypass viaMix::DRY(a defaultFilterBuilderis fully wet and colours the signal); the parked 20 kHz cutoff stays below kira's Nyquist clamp (beyond it the filter degenerates rather than turning transparent).set_underwateris written each frame bywater_audio_system(Dim 5), beforeaudio_system. Output:/tmp/audit/audio/dim_2.md
Dim 3: Streaming Music & SoundCache
Paths: crates/audio/src/lib.rs (play_music, stop_music, is_music_active, load_streaming_sound_from_*, SoundCache, VoiceSoundCache)
First step: git log --since=D -- crates/audio/src/lib.rs
Guards: tests.rs::{play_music_no_op_when_inactive, sound_cache_hits_are_case_insensitive_and_share_arc, sound_cache_get_or_load_invokes_loader_only_on_miss, sound_cache_clear_drops_entries_and_bytes_estimate_tracks_pcm_size, voice_cache_evicts_lru_under_byte_budget, voice_cache_negatives_are_capped_and_counted}.
- Single music slot:
play_music(streaming_sound, volume, fade_in_secs, looping)(4 parameters,loopingsince #3775; re-verify the arity before citing) crossfades any existing handle. Music routes through the main track, never a spatial sub-track. It usesStreamingSoundData(from_cursor/from_file), neverStaticSoundData(full PCM decode = OOM on long tracks). stop_musicfades forfade_out_secs.max(0.0)then drops the handle (an instant stop clicks);is_music_activegoes false the momentstop_musicreturns (the slot is cleared while kira renders the fade tail): documented, so a caller must not read it as "audibly occupied".SoundCachekeys lowercase once per entry point (sound_archive_pathalso drops aData\game-root prefix that Skyrim.esm's pull-chain descriptors author);clear()never invalidatesArcs held by liveActiveSounds. It is live since 2026-09-27: inserted at boot (boot/world.rs), sampled byownership_sample.rs(len()+bytes_estimate()), and its consumer iscombat_anim.rs::play_oneshot_cached(three fixed combat paths; voice moved toVoiceSoundCache), which M47.2'sscripted_sound_systemnow also calls with script-chosen SNDR files — an open-ended key set landing onSoundCache, the shape this section calls the finding (every distinct file stays resident, no eviction). Footstep/splash loaders still bypass it intoFootstepConfig/WaterAudioConfig. The map isOption<Arc<_>>:Noneis a negative-cache entry (loader returned no bytes, or decode failed) thatget_or_loadnever re-probes andlen()/bytes_estimate()exclude — so a sound missing at first use stays missing untilclear(), which nothing in production calls (check whether the--sounds-bsaset can change at runtime). Still no eviction: a consumer keyed on open-ended paths (FOOT, REGN, per-NPC SFX) that lands onSoundCacheis the finding.VoiceSoundCache(#5382, 8410ad1e5) is the open-ended-key cache, used only by dialogue voice: sameget_or_loadcontract, LRU-evicted pastDEFAULT_BUDGET_BYTES(64 MiB; the just-inserted entry is never its own victim), negatives capped atVOICE_NEGATIVE_CAP(4096; the set clears and re-probes past it) and counted (negative_len). Telemetry reportsvoice_cache_{entries,bytes,negatives}throughownership_sample.rs; the save registry allowlists it. A new open-ended consumer belongs here (or in its own bounded cache), not inSoundCache. Output:/tmp/audit/audio/dim_3.md
Dim 4: Manager, ECS Lifecycle & Schedule
Paths: crates/audio/src/lib.rs (struct, AudioWorld::new/headless, audio_system, prune_stopped_sounds), byroredux/src/boot/schedule/late.rs, byroredux/src/cell_loader/{load,unload}.rs
First step: git log --since=D -- crates/audio/src/lib.rs byroredux/src/boot/schedule/late.rs
Guards: tests.rs::{audio_world_constructs_without_panic_on_any_environment, explicit_headless_world_discards_playback_without_retaining_sound, manager_capacities_exceed_kira_defaults}; scheduler_access_tests.rs::{footstep_runs_after_camera_follow_in_late, reverb_zone_is_parallel_and_audio_is_exclusive_in_late}.
- Graceful degradation:
AudioManager::newfailure leavesmanager = None; every public API gates on it with nounwrap(); headless/CI boot must succeed (report as PASS/FAIL in the summary).AudioWorld::headless()never contacts a device; tests use it, not the device-dependentdefault(). SUB_TRACK_CAPACITY(512) andSEND_TRACK_CAPACITY(32) exceed kira's defaults and are applied innew().- Field-drop order (single source of truth):
active_sounds→pending_oneshots→ (oneshots_requested) →music→reverb_send→reverb_send_db→listener→manager, then the trailingmulti_listener_warned/underwaterflags and theemitter_position_updatescounter. A reorder that movesmanagerup asserts in kira's Drop.AudioWorld::new()is boot-only, never on cell transition or resize. - Schedule (all
Stage::Late):audio_systemis an exclusive registered afterfootstep_system(exclusive, pinned to Late by #4185's test) andwater_audio_system(exclusive, aftersubmersion_system);reverb_zone_systemis a parallel registration, and the parallel batch finishing before any exclusive (not registration order) is what sets the send level before new tracks are built.audio_systembody order:sync_listener_pose→sync_emitter_positions→update_underwater_filters→drain_pending_oneshots→dispatch_new_oneshots→prune_stopped_sounds. The conversation voice producer (Latenpc_dialogue_selection_system) registers AFTERaudio_system, so a line's segments dispatch on the next frame — one frame of latency, not a loss; the ObScriptSayproducerscripted_line_voice_systemis Update, so its segments dispatch the same frame. - Despawn truncation: only
SoundSource::Emitterentries are emitter-coupled (emitter_coupled()): an entity that losesAudioEmittergets a tweenedstop()overActiveSound.unload_fade_ms(10 ms default, looping and not);stop_issueddebounces (and is set bystop_sounds_fortoo); retain drops only onStopped.Detachedruns to natural end;Anchoredsurvives SFX emitter churn on the same NPC by design and stops viastop_sounds_for(topic change, close, death, #5432) or, for a speaker despawned mid-line (cell unload), through the prune sweep's tweened stop once the followed entity has noGlobalTransform(#5678 74d841165; theanchored_voice_follows_survives_prune_and_stopslifecycle test is#[ignore]d, the orphan selection is pinned default-lane byonly_transformless_anchored_sources_are_prune_orphans). Guards are#[ignore]d (Phase 1): trace the code. - Cross-cell continuity:
dispatch_region_ambient_musicruns only whenmusic_formchanged (bothcell_loader/load.rspaths andscene::apply_cell_region_ambientcompare against the priorRegionAmbientRes); an unconditional redispatch audibly restarts the track on every connected-cell crossing. A future CELL-level MUSC caller needs its own gate. Output:/tmp/audit/audio/dim_4.md
Dim 5: Engine-Side Consumers
Paths: byroredux/src/systems/{audio,dialogue_voice,scripted_sound}.rs, crates/audio/src/fuz.rs, byroredux/src/components/{audio,environment}.rs (footstep/impact/water-audio/region resources), byroredux/src/asset_provider/{audio,texture}.rs, byroredux/src/scene.rs
First step: git log --since=D -- byroredux/src/systems/audio.rs byroredux/src/systems/dialogue_voice.rs byroredux/src/asset_provider/audio.rs
Guards (systems/audio.rs tests): first_tick_seeds_last_position_without_firing, stride_threshold_is_bethesda_units_not_metres, walking_for_one_second_fires_a_walking_cadence_not_one_per_frame, single_large_jump_fires_one_footstep_only, water_splash_event_reaches_audio_dispatcher, interior_to_exterior_transition_resets_send_to_dry, the #5146 trio orbiting_camera_with_stationary_body_fires_nothing / swimming_body_is_silent_and_exit_does_not_replay_the_swim_distance / airborne_body_is_silent_and_landing_does_not_replay_the_air_distance, plus the no_*_is_safe_noop pair. Highest-yield dimension in the 2026-08/09 reports.
- Callers:
footstep_system,impact_audio_system(Late exclusive registered right afterfootstep_system: drainsPhysicsWorld::take_contact_force_events— thestartedforce crossings, belowImpactConfig::min_force_magnitudeskipped — and plays one{1.0, 24.0}m one-shot per impact atPhysicsWorld::contact_event_position— the deepest solver contact, not the body-origin midpoint (a static ghost / exterior terrain tile parks its body at the placement or world origin, so the midpoint played 300 m impacts at ~150 m, #5675 0d8ea5d6e); material =resolve_impact_material(collider 1's non-zero, else collider 2's, else 0 while either handle lives, #5549);impact_sounds_to_playskips only an unmapped impact, neverbreaks the frame, #5554; the whole system returns early with nodefault_soundand nosurface_sounds, and first syncs the physics subscription to that verdict —set_contact_force_events_enabled(has_sound), so with no content dynamic colliders carry no force-event flag at all (#5711 e3a4d5e18;/audit-physicsDim 2)),water_audio_systemandcombat_anim.rs::play_oneshot_cached(PostUpdate, enqueued before Lateaudio_system) are liveplay_oneshotcallers, withsystems/scripted_sound.rs::scripted_sound_system(Update exclusive, M47.2 5046c7af8/f093e7393: drainsPendingSoundPlays, resolves the SNDR/SOUN throughindex.sounds, skips looping descriptors, takes multi-ANAMvariants in turn, positions at the source'sGlobalTransformand plays throughplay_oneshot_cached— note this puts script-authored, open-ended sound paths on the unboundedSoundCache, Dim 3) andbyroredux/src/systems/dialogue_voice.rsas further callers (#5367 Phase V: per-line voice — FO3/FNV.ogg, Oblivion race/sex.mp3#5526, Skyrim+.fuzthroughbyroredux_audio::fuz+ optionalffmpeg#5912 — fromapply_selectionand the Updatescripted_line_voice_system(ObScriptSay/SayTo, whose resolved duration timesSayToDone), throughplay_oneshot_following, anchored to the speaker and skipped when it has noGlobalTransform(#5410) and cut bystop_line_voiceon topic change / close / speaker death (#5432); segments chained viabyroredux_audio::with_start_delay, each named by its authoredresponse_number;Attenuation::default(), volume 1.0; gated onAudioWorld::is_activebefore any archive work; decoded throughVoiceSoundCachewith the provider read inside the loader (#5382/#5383); file name and owning plugin perdocs/engine/dialogue-trees.md(#5393/#5395, 5b68792b7;.ogg/.fuznames truncate only when quest + topic exceed 25 characters, one candidate, #5521; Oblivion's are untruncated); missing voice is a silent fallback to the subtitle estimate);reverb_zone_systemthe onlyset_reverb_send_dbcaller,dispatch_region_ambient_musicthe onlyplay_music/stop_musiccaller. Re-grep for any new caller (git grep -n 'play_oneshot\|play_music\|set_underwater\|stop_sounds_for\|take_contact_force_events' -- byroredux/src) and audit it. - Footsteps: XZ-only stride accumulation against
FootstepEmitter.stride_threshold, authored in Bethesda units (0.75 * BETHESDA_UNITS_PER_METER), compared toGlobalTransformdeltas with no conversion at the compare site; reset to 0 on fire (subtract-remainder multiplies footsteps on a teleport); first tick seedslast_positionand fires nothing. Attenuation{0.5, 12.0}in metres (no pre-scaling by 70, no widening). TheFootstepScratchVec(capacity 32) is restored on the success and theAudioWorld-absent path; no component lock is held acrossplay_oneshotand the scratch lock drops beforeAudioWorldis taken. The player-body gate (CharacterControllergrounded flag + body handle) is resolved as an owned(body, gated)pair BEFORE anyGlobalTransform/FootstepEmitter/scratch guard (#5305, 6915fe783: taking it inside closed three lock-order cycles) — a per-entity get back inside that scope is the regression. Every missing resource is a silent no-op (no per-frame log). Opt-in is component-driven. Surface selection (Wave 4): each trigger resolves its material at footstep cadence throughPhysicsWorld::surface_material_under, which takes a MANDATORYexcluded_body(the player'sRapierHandles.body, else the capsule centre self-hits at toi 0 and every player step reads material 0, #5545 3909778eb);select_footstep_soundis a pure function of aFootstepConfig.surface_soundssnapshot cloned once, after the no-trigger early return and BEFORE theAudioWorldguard (noAudioWorld→FootstepConfiglock edge, #5556 ac710964e); the Access row declares thePhysicsWorld/RapierHandlesreads (scheduler_access_tests.rs::footstep_declares_its_physics_reads). Material keys are u32 end to end (Skyrim's are CRC32s; 0 is STONE on Oblivion/FO3/FNV and the value of every unauthored body, #5542). Which entity walks (#5146, ccc743160; #5348 a9def9cb9): character mode adds an emitter on the player body, and only the stand-in camera emitter — theActiveCameraentity whilePlayerModeisCharacter, resolved once from those two resources (skipped_camera) — is re-seeded, never accumulated (the 180 BU third-person boom turned mouse-look into footsteps); every other emitter (a future per-NPC/FOOT one) walks, and FlyCam steps with the camera whether booted--flyor toggled. The body accumulates only whileCharacterController.is_grounded; the gate is!is_groundedALONE since #5347 (7068c16d3) becauseresolve_ground_contactnever grounds a swimmer (character::tests::a_swimmer_is_never_grounded) — if swimming ever stops clearingis_grounded, an explicit swim operand plus a test holding it true through the swim leg must come back. Gated frames re-seed so a landing or water exit never replays as a burst. A FlyCam toggle leaves the frozen body silent while the camera steps (pinned in #5348). With noPhysicsWorldeach stride trigger still keeps one surface result and takes the default sound instead of truncating the loop (#5714 77eea4311). The Access row (boot/schedule/late.rs) declares thePlayerEntity/PlayerMode/ActiveCamera/CharacterControllerreads and still lists aWaterContactread the system no longer takes (harmless over-declaration since #5347). - Water audio:
water_audio_systemwritesAudioWorld::set_underwaterfrom the active camera'sSubmersionState.head_submergedevery frame (before the config early-return), then playsSplashEventone-shots (range 1-24 m) and, when no splash fired, one cooldown-limitedRippleEvent(per-surface cooldown, 0.45 damping). The range and the 0.45 factor are uncited (no authored SOUN range): note as unsourced, never invent one.WaterAudioConfig.splash_soundisNonewithout an archive (valid headless state);try_load_default_footstepandtry_load_default_water_splash(asset_provider/texture.rs) no-op cleanly when the arg or archive is absent. - Combat feedback sounds (
play_oneshot_cached): registered outside theBYRO_NO_AI_LOCOMOTIONblock since #4709 (70d9896fb) — a move back inside silently mutes them; hardcoded Skyrim paths perdocs/engine/p2-combat-anim-sound-fixture.md, each request counted per kind inCombatSoundRequests(swing / impact / death_voice; incremented only when the one-shot was actually requested, surfaced bycombat.status, #5148 7208af67c), attenuation{0.5, 24.0}m (uncited, like the water range); lookup goes throughSoundCache::get_or_loadwhose loader readsSoundArchiveProviderwhile theSoundCachewrite guard is held (resource-in-resource nesting). Dialogue voice uses the same cache → provider order onVoiceSoundCache(#5383, 080b35f35; the old provider → cache order closed a lock-order cycle with this path);dialogue_voice.rs::voice_and_combat_sound_paths_share_one_cache_provider_orderdrives both consumers in one process — a third consumer taking the provider first is the regression. Headless / archive-less paths skip silently. reverb_zone_system:-12 dBinterior /NEG_INFINITYexterior; the transition is bit-equality gated (to_bits), no-ops withoutCellLightingRes(pre-load) orAudioWorld(headless).dispatch_region_ambient_music: stops outstanding playback on every failure layer (no provider, no--sounds-bsa, unresolved FormID, folder FNAM, archive miss, decode failure,music_form: None) because what is audible belonged to the previous directive; the authored-but-unresolved log fires once per process (std::sync::Once);loopingthreads fromsound_loops(SOUN Loop bit) intoplay_music.SounRecord::sound_pathis a file or a trailing-separator folder (about half of FNV's FNAM-bearing records):sound_is_folderfails closed before any archive lookup, and any futureresolve_sound_pathconsumer must gate on it (variant selection is an unmade policy, so no "extract any file under this folder" fallback exists).- Archive precedence:
SoundArchiveProvider::extractiterates.rev()(last-listed wins, as mesh/texture/material; FNV'sFallout - Sound.bsa+Update.bsaoverlap with differing bytes): forward iteration is the regression.ScriptProvideris the deliberate first-wins exception. Output:/tmp/audit/audio/dim_5.md
Phase 3: Merge
Combine /tmp/audit/audio/dim_*.md into docs/audits/AUDIT_AUDIO_<TODAY>.md (header per _audit-common.md Report finalization): Executive Summary (severity counts, headless-boot PASS/FAIL), Lifecycle Invariant Matrix (field-drop order, sticky listener, despawn truncation, schedule order: verified or drifted), Findings (deduplicated), Future-Phase Readiness (FOOT, MUSC/MUST/MSET, occlusion). Then rm -rf /tmp/audit/audio; suggest /audit-publish docs/audits/AUDIT_AUDIO_<TODAY>.md (labels audio, plus game:* when one title's sound data is the cause).
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/audio-subsystem-audit-m44-mvhm5m25/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/audio-subsystem-audit-m44-mvhm5m25' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/audio-subsystem-audit-m44-mvhm5m25/download' --output '.skill-downloads/audio-subsystem-audit-m44-mvhm5m25/SKILL.md.part' && mv '.skill-downloads/audio-subsystem-audit-m44-mvhm5m25/SKILL.md.part' '.skill-downloads/audio-subsystem-audit-m44-mvhm5m25/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
This file does not provide a usable name/description header for this native procedure. It remains available to download and inspect; use the manual method below.
Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/audio-subsystem-audit-m44-mvhm5m25/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.