chore(engine): the audio rung's removals — the FIXME closes and the dead sync machinery goes - #2016
Conversation
Its premise expired when the backend chain landed: the clock no longer paces a capture path, and the null backend anchors once and derives every block timestamp from samples-delivered, so a catch-up burst carrying one wake time produces an exact, gap-free timeline anyway.
A/V sync is block-level join-by-timestamp and no cross-modal machinery exists (ARCHITECTURE.md:584-587). core/sync.rs had zero callers in the engine tree; its re-export chain went from core/mod.rs through the engine root to the SDK, so the module goes with all of it.
AudioBlock is the one audio data model. AgentPerception keeps its other members, which are a separate concern.
Audio declares lossless, not every_sample (ARCHITECTURE.md:597-602), and the container reaches PipeWire through the dlopen'd backend chain rather than through cpal and an ALSA bridge.
…k stamp is Overflow is no longer an authoring knob, so restating which ports declare which profile put a second copy of the delivery-profile fact one file over, where it drifted. Both variants keep their rationale; only the enumeration goes, leaving DeliveryProfile the single place a declaration is described. AudioTickContext::timestamp_ns is public, and the Linux arm shares one read's wake time across a catch-up burst — recorded nowhere once the FIXME went, and the Apple and software arms stamp per tick, so the field doc states the contract that holds for every arm.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
💤 Files with no reviewable changes (6)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe change removes obsolete synchronization and audio sampling APIs. It updates audio timestamp documentation, removes an obsolete timer comment, and corrects PipeWire, delivery-profile, and overflow documentation. ChangesAudio cleanup and contract updates
Merge Risk: ⚪ Minimal · up to This change removes unused synchronization and audio machinery and corrects outdated documentation without changing active runtime behavior. No actionable merge-blocking risk remains after normal checks and review. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Linked Issues checkExplanation The PR removes the FIXME, synchronization module and re-exports, and audio perception API as required. However, Full details: Out of Scope Changes checkExplanation The PR includes documentation changes in Full details: Docstring CoverageExplanation Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 4 files. (1 skipped: 1 unsupported.)
✨ 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 |
…edia I/O and archive (#2020) Every ticket of the change is merged: #1988 (the AudioBlock bag, PR #1995), #1989 (the device seam and the null backend, PR #1997), #1998 (the loopback fixture, PR #2001), #2002 (per-processor tap verification, PR #2003), #2004 (the unconnected-output log storm, PR #2005), #1990 (the PipeWire arm, PR #2008), #1991 (the ALSA arm, PR #2010), #1992 (SpeakerSink, PR #2013), #1993 (the removals, PR #2016), #1999 (/verify-audio, PR #2017) and #2012 (stream death reaches its owner, PR #2018) — the last landing 2026-08-28, the archive date. The REMOVED gate is clean at the archived path: 7 bullets, none referenced and none on disk. Eleven DECIDED entries fold into §Media I/O. Six are new — the device seam as one engine primitive, runtime symbol binding, the SPA shim that calls nothing, vendored headers, the unweakened portability gate, and the four AudioBlock entries (wire contract, msgpack bin, the Python cast, the zero-copy claim stated as a claim about the cast, and the harness bin-decode fix). Five existing [audio-subsystem] entries are sharpened in place and gain their SHIPPED citations: the backend chain gains "chosen by opening, not by loading" and the named-device raise; the pacing entry gains the clock starting only when something needs it; A/V sync, the data model and the two built-ins gain theirs. The built-ins entry cites partially — conditioning and immediate cancel are a later rung, and the citation says so. The section stays IN-FLIGHT rather than flipping to SHIPPED: its audio-plugins OPEN entry is still live, and a section ships only when it holds no OPEN. Only the (→ dlopen-audio-backend-and-audio-blocks) pointer goes. #2012 was a follow-up filed during implementation, not part of the approved delta, so it folds into the device-seam entry rather than becoming a plan entry of its own. Every verify marker was run before it was written, on this rig with the wheel rebuilt first: 20 engine and media-builtins tests pass, the PipeWire and ALSA arms pass their hardware tier against a live daemon and /dev/snd (13 tests that otherwise skip), and 29 wheel tests pass. readelf -d on the rebuilt _engine.abi3.so names exactly the five permitted host libraries — the design's own pass/fail, proven rather than asserted. The diagram gains the vendored-shim and DT_NEEDED clause on the media node, and the previously unlabelled media → engine edge now carries the seam and the device-stamping rule. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
The contract ticket for
docs/plan/changes/dlopen-audio-backend-and-audio-blocks.md: it carriesevery
REMOVED:bullet the change declares, so/ship-changecan fold the delta into the plan.Nothing new is built — this deletes.
FIXME(audio-backend)(linux/audio_clock.rs) — its premise expired when the backend chainlanded. The timerfd clock stays as the deviceless cadence source.
core/sync.rs— a drop-or-duplicate-the-video-frame A/V sync model with zero callers. Theplan decided A/V sync is block-level join-by-timestamp with no cross-modal machinery
(
ARCHITECTURE.md:584-587); a second, dead sync system incore/made that entry false in thetree. The file goes with its whole re-export chain —
core/mod.rs, the engine root, the SDK —which also takes
DEFAULT_SYNC_TOLERANCE_MS,timestamp_delta_msandsync_statistics.SampledAudio/sample_audio(core/observability/perception.rs) — a second audio sampletype.
AudioBlockis the one audio data model.AgentPerceptionkeeps its other members.delivery_profile.rstold audio to useevery_sample;docker/pipewire/10-virtual.confasserted "StreamLib's Linux audio is cpal -> ALSA(packages/audio)", describing a package that cannot compile and a backend that no longer exists.
Closes
Closes #1993
Exit criteria
bash .claude/scripts/ship-change-removed-gate.sh docs/plan/changes/dlopen-audio-backend-and-audio-blocks.md→clean: 7 REMOVED bullets, none referenced and none on disk.core/sync.rsand its re-exports deleted.AgentPerceptionretains its non-audio members.every_sample.Test plan
No new tests — this ticket deletes. Everything below was run by the reviewers, not self-reported.
origin/main, the same scriptreports all 7 bullets
STILL PRESENTat exactly their definition sites, exit 1. On the branch,exit 0.
detailed under Notes. Derived fresh from
.github/workflows/*.ymlandALL_SOURCE_WALKING_GATESrather than from a remembered list.
cargo test --locked --workspace --no-fail-fast— 134/134test result: ok, 0 failed, across all24 members plus doctests. (A first attempt aborted with the documented rare
SIGABRTheap-corruptionflake in the
streamlib-enginelib-test binary; it did not reproduce on an isolated retry — 1452passed — nor on the full re-run. Pre-existing, not this diff.)
cargo run -p xtask -- check-all-source-gates— 11/11 PASS, includingcheck-no-in-process-placementandcheck-clock-usage.cargo check --workspace --all-targets— 0 errors; warning count unchanged fromorigin/main(31 → 31, verified by stashing the diff and re-running).
cargo clippy --locked --workspaceexit 0;cargo fmt --all --check;cargo deny check licenses;scripts/check-license-headers.sh;cargo test -p xtask255 passed — all pass.pytest tests/ -m "not requires_gpu"349 passed;mypy.stubtest streamlib._enginepass;pyright0 errors.cargo doc -p streamlib --no-deps— 0 rustdoc warnings, 0 broken intra-doc links.stamping N blocks with one wake time — is neutralised at the clock's only tick-timestamp
consumer:
silent_null_audio_device_backend.rs:194usestick.timestamp_nssolely as aone-time anchor and derives every later stamp from a wide-integer sample counter. Mental revert:
stamping each block from
tick.timestamp_nsdirectly failsblock_timestamps_advance_by_one_block_even_when_ticks_share_a_wake_time. The FIXME's otherclause (the discarded driver stamp) is answered by the device arms —
alsa_audio_device_backend.rs:1667and
pipewire_audio_device_backend.rs:655both derivefirst_sample_timestamp_nsfrom thedevice's own status/delay. Zero FIXMEs now remain under
runtime/ sdk/ adapters/ xtask/ docker/.Notes for owner
Nothing here blocks the merge; none of it is filed as a ticket, per the P0-only rule.
1. Three doc edits beyond the two the ticket names. The ticket names
delivery_profile.rsanddocker/pipewire/10-virtual.conf. Correcting the first exposed twonear-verbatim twins of the same use-case list, which the reviewers' sweep found:
iceoryx2/overflow.rs:23-31— dropped the roster ("file writers, muxers, loggers") and theframing ("The realtime-media default"), kept both rationales.
Overflow's own module docalready says it is "No longer an authoring knob", so enumerating which ports declare what had
no business being restated there.
iceoryx2/node.rs:106-111— the publicopen_or_create_servicedoc, which was not merelyduplicated but false: "reserve for muxers / file writers that need every sample in order"
excluded
SpeakerSink, which declareslosslesstoday.I invited both reviewers to contest this as ride-along and offered to pull all three out; both
declined, and
review-prcorrected my reasoning in a way worth recording. My first framing — "aclaim my own diff falsified" — was wrong for
node.rs:speaker_sink.rs:105already declaredlosslessonorigin/main(git log -Sdates it to541c9eaa, #2013), so that claim was falsebefore I branched. What falsified it is the rung, not this ticket's diff. That is what earns
the scope claim rather than costing it, two ways: #1993's own charter is rung-scoped — "plus the
two doc claims the rung falsified" — so a third claim the rung falsified is the same category
of work arriving at the ticket that exists to close them; and independently it passes CLAUDE.md's
fact test, since a careful reader derives it from
speaker_sink.rs:105plusLossless.resolve() → Overflow::Block(locked bylossless_resolves_to_fifo_block_deep) withoutbeing committed to anything new. Splitting it out would have parked a known-false public API
doc on
mainfor the duration.DeliveryProfileis now the single site describing declarations,so the class is closed at the root rather than patched per-site.
One instance is knowingly left:
node.rs:471, inside a#[cfg(test)]doc on the back-pressuretest. It names the same audience ("invariant we promise muxer / file-writer callers") but is
descriptive of what that test asserts rather than prescriptive to a caller, and it is not public
API. Both reviewers agreed leaving it beats over-correcting into the test tree. Naming it here so
the sweep's result is not read as absolute.
2.
AudioTickContext::timestamp_nsgained a contract note (core/context/audio_clock.rs:53).Deleting the FIXME removed the tree's only statement that the Linux arm shares one read's wake
time across a catch-up burst; the field is
puband reachable asstreamlib::sdk::context, andthe only surviving statement of the fact was a private struct doc. I checked all three arms
before wording it — Apple (
apple/audio_clock.rs:156) andSoftwareAudioClock(:200) stamp pertick, and the software clock skips rather than bursts — so it states a contract true of every arm.
Flagging it because prose added by a deletion ticket should be named, not slipped in.
3.
perception.rsandobservability/tap.rsare orphaned source the compiler never sees.core/observability/mod.rsdeclares onlyinspectorandsnapshots. Proof it is uncompiledrather than merely unexported:
grep -rl 'observability/perception.rs' target/debug/deps/*.d→ 0, same for
tap.rs→ 0, whilesnapshots.rs→ 172. So the ticket's "AgentPerception stillcompiles with only its audio members removed" is unfalsifiable, and the change file's rationale
("a trait with no implementor and no caller") understates it. Deleting the orphans is outside this
ticket's REMOVED contract so I did not widen the diff. Recommendation: delete both in their own
change — but that is a plan-visible removal, so it wants a
REMOVED:bullet rather than adrive-by.
4.
cargo check --target aarch64-apple-darwincould not run here — the change file requires it,so treat the Apple path as unverified by me. I ran it myself rather than relaying it. It dies in
third-party C/C++ build scripts, never reaching any StreamLib Rust: this box's
cc/c++isplain Linux GCC with no macOS cross-toolchain, so it rejects
-arch arm64,-mmacosx-version-min=11.0and-stdlib=libc++. First failure istatolab-vulkanalia-vma'sbuild.rs;ring,aws-lc-sysandiceoryx2-pal-posixfail the same way behind it. (The runleft the tree clean —
git statusempty, vendored VMA untouched.) Exposure is low but not zero:the diff's only cross-platform surface is export removal from
core/mod.rs,lib.rsandsdk/lib.rs,apple/audio_clock.rsis untouched, and the tree-wide grep proves nothing under any#[cfg]referenced the deleted symbols. CI covers what I could not.5. Pre-existing, untouched by this branch.
cargo clippy --workspace --all-targetsfails withuse of a disallowed macro std::printlnatruntime/streamlib-consumer-rhi/src/consumer_vulkan_device.rs:850.Baseline established rather than assumed:
git show origin/main:has the identical line andgit log -Sdates it to2d4e324c(#1348).6. Real drift between the two CI gate lists, surfaced by the battery run.
xtask'srun_local_ci_gates— whose own doc comment promises "any gate added to CI without being addedhere breaks that promise" — is missing
cargo test -p streamlib-consumer-rhi --lib, whichtest.ymldoes run. Ran separately here: 31 tests, pass. Recommendation: one line inrun_local_ci_gates, folded into whatever next touchesxtask. Not filed, not in this diff.7. Expected consumer lag, not a defect.
packages/mp4/processors/_apple_impl_pending_/mp4_writer.rs:7,101is the sole surviving reference to a removed item (
DEFAULT_SYNC_TOLERANCE_MS). Not a workspacemember, and
cargo check --workspace --all-targetsis unaffected. Upgrade backlog per CLAUDE.md.🤖 Generated with Claude Code
Summary by CodeRabbit
Changes
Documentation