Skip to content

chore(engine): the audio rung's removals — the FIXME closes and the dead sync machinery goes - #2016

Merged
tato123 merged 5 commits into
mainfrom
chore/1993-audio-rung-removals
Aug 28, 2026
Merged

chore(engine): the audio rung's removals — the FIXME closes and the dead sync machinery goes#2016
tato123 merged 5 commits into
mainfrom
chore/1993-audio-rung-removals

Conversation

@tato123

@tato123 tato123 commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

The contract ticket for docs/plan/changes/dlopen-audio-backend-and-audio-blocks.md: it carries
every REMOVED: bullet the change declares, so /ship-change can 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 chain
    landed. 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. The
    plan decided A/V sync is block-level join-by-timestamp with no cross-modal machinery
    (ARCHITECTURE.md:584-587); a second, dead sync system in core/ made that entry false in the
    tree. 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_ms and sync_statistics.
  • SampledAudio / sample_audio (core/observability/perception.rs) — a second audio sample
    type. AudioBlock is the one audio data model. AgentPerception keeps its other members.
  • Two doc claims the rung falsifieddelivery_profile.rs told audio to use every_sample;
    docker/pipewire/10-virtual.conf asserted "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.mdclean: 7 REMOVED bullets, none referenced and none on disk.
  • The workspace builds with core/sync.rs and its re-exports deleted.
  • AgentPerception retains its non-audio members.
  • No doc in a swept path describes Linux audio as cpal → ALSA, and none tells audio to use every_sample.

Test plan

No new tests — this ticket deletes. Everything below was run by the reviewers, not self-reported.

  • The gate is not vacuous (negative test): on a worktree at origin/main, the same script
    reports all 7 bullets STILL PRESENT at exactly their definition sites, exit 1. On the branch,
    exit 0.
  • Full local gate battery: 26 passed, 2 failed, 5 skipped — both failures are environmental,
    detailed under Notes. Derived fresh from .github/workflows/*.yml and ALL_SOURCE_WALKING_GATES
    rather than from a remembered list.
  • cargo test --locked --workspace --no-fail-fast — 134/134 test result: ok, 0 failed, across all
    24 members plus doctests. (A first attempt aborted with the documented rare SIGABRT heap-corruption
    flake in the streamlib-engine lib-test binary; it did not reproduce on an isolated retry — 1452
    passed — nor on the full re-run. Pre-existing, not this diff.)
  • cargo run -p xtask -- check-all-source-gates — 11/11 PASS, including
    check-no-in-process-placement and check-clock-usage.
  • cargo check --workspace --all-targets — 0 errors; warning count unchanged from origin/main
    (31 → 31, verified by stashing the diff and re-running).
  • cargo clippy --locked --workspace exit 0; cargo fmt --all --check; cargo deny check licenses;
    scripts/check-license-headers.sh; cargo test -p xtask 255 passed — all pass.
  • pytest tests/ -m "not requires_gpu" 349 passed; mypy.stubtest streamlib._engine pass;
    pyright 0 errors.
  • cargo doc -p streamlib --no-deps — 0 rustdoc warnings, 0 broken intra-doc links.
  • The FIXME deletion is honest, verified not assumed. Its behavioural claim — a catch-up burst
    stamping N blocks with one wake time — is neutralised at the clock's only tick-timestamp
    consumer: silent_null_audio_device_backend.rs:194 uses tick.timestamp_ns solely as a
    one-time anchor and derives every later stamp from a wide-integer sample counter. Mental revert:
    stamping each block from tick.timestamp_ns directly fails
    block_timestamps_advance_by_one_block_even_when_ticks_share_a_wake_time. The FIXME's other
    clause (the discarded driver stamp) is answered by the device arms — alsa_audio_device_backend.rs:1667
    and pipewire_audio_device_backend.rs:655 both derive first_sample_timestamp_ns from the
    device'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.rs and docker/pipewire/10-virtual.conf. Correcting the first exposed two
near-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 the
    framing ("The realtime-media default"), kept both rationales. Overflow's own module doc
    already 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 public open_or_create_service doc, which was not merely
    duplicated but false: "reserve for muxers / file writers that need every sample in order"
    excluded SpeakerSink, which declares lossless today.

I invited both reviewers to contest this as ride-along and offered to pull all three out; both
declined, and review-pr corrected my reasoning in a way worth recording. My first framing — "a
claim my own diff falsified" — was wrong for node.rs: speaker_sink.rs:105 already declared
lossless on origin/main (git log -S dates it to 541c9eaa, #2013), so that claim was false
before 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:105 plus
Lossless.resolve() → Overflow::Block (locked by lossless_resolves_to_fifo_block_deep) without
being committed to anything new. Splitting it out would have parked a known-false public API
doc on main for the duration. DeliveryProfile is 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-pressure
test. 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_ns gained 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 pub and reachable as streamlib::sdk::context, and
the 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) and SoftwareAudioClock (:200) stamp per
tick, 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.rs and observability/tap.rs are orphaned source the compiler never sees.
core/observability/mod.rs declares only inspector and snapshots. Proof it is uncompiled
rather than merely unexported: grep -rl 'observability/perception.rs' target/debug/deps/*.d
→ 0, same for tap.rs → 0, while snapshots.rs → 172. So the ticket's "AgentPerception still
compiles 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 a
drive-by.

4. cargo check --target aarch64-apple-darwin could 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++ is
plain Linux GCC with no macOS cross-toolchain, so it rejects -arch arm64,
-mmacosx-version-min=11.0 and -stdlib=libc++. First failure is tatolab-vulkanalia-vma's
build.rs; ring, aws-lc-sys and iceoryx2-pal-posix fail the same way behind it. (The run
left the tree clean — git status empty, vendored VMA untouched.) Exposure is low but not zero:
the diff's only cross-platform surface is export removal from core/mod.rs, lib.rs and
sdk/lib.rs, apple/audio_clock.rs is 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-targets fails with
use of a disallowed macro std::println at runtime/streamlib-consumer-rhi/src/consumer_vulkan_device.rs:850.
Baseline established rather than assumed: git show origin/main: has the identical line and
git log -S dates it to 2d4e324c (#1348).

6. Real drift between the two CI gate lists, surfaced by the battery run. xtask's
run_local_ci_gates — whose own doc comment promises "any gate added to CI without being added
here breaks that promise" — is missing cargo test -p streamlib-consumer-rhi --lib, which
test.yml does run. Ran separately here: 31 tests, pass. Recommendation: one line in
run_local_ci_gates, folded into whatever next touches xtask. Not filed, not in this diff.

7. Expected consumer lag, not a defect. packages/mp4/processors/_apple_impl_pending_/mp4_writer.rs:7,101
is the sole surviving reference to a removed item (DEFAULT_SYNC_TOLERANCE_MS). Not a workspace
member, and cargo check --workspace --all-targets is unaffected. Upgrade backlog per CLAUDE.md.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Changes

    • Updated audio backend behavior to use PipeWire directly, with ALSA and null-backend fallbacks.
    • Removed the public synchronization API, including synchronization helpers and related actions.
    • Removed audio sampling from the perception interface.
  • Documentation

    • Clarified audio timestamp semantics, delivery profiles, overflow behavior, and buffering expectations.
    • Updated virtual audio device and backend documentation.

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.
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e40b3d5e-997e-4e19-9227-1794f049763a

📥 Commits

Reviewing files that changed from the base of the PR and between 6edd3cd and 6e38173.

📒 Files selected for processing (11)
  • docker/pipewire/10-virtual.conf
  • runtime/streamlib-engine/src/core/context/audio_clock.rs
  • runtime/streamlib-engine/src/core/mod.rs
  • runtime/streamlib-engine/src/core/observability/perception.rs
  • runtime/streamlib-engine/src/core/sync.rs
  • runtime/streamlib-engine/src/iceoryx2/delivery_profile.rs
  • runtime/streamlib-engine/src/iceoryx2/node.rs
  • runtime/streamlib-engine/src/iceoryx2/overflow.rs
  • runtime/streamlib-engine/src/lib.rs
  • runtime/streamlib-engine/src/linux/audio_clock.rs
  • sdk/streamlib-sdk/src/lib.rs
💤 Files with no reviewable changes (6)
  • sdk/streamlib-sdk/src/lib.rs
  • runtime/streamlib-engine/src/linux/audio_clock.rs
  • runtime/streamlib-engine/src/core/mod.rs
  • runtime/streamlib-engine/src/lib.rs
  • runtime/streamlib-engine/src/core/observability/perception.rs
  • runtime/streamlib-engine/src/core/sync.rs

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The 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.

Changes

Audio cleanup and contract updates

Layer / File(s) Summary
Remove synchronization API
runtime/streamlib-engine/src/core/mod.rs, runtime/streamlib-engine/src/core/sync.rs, runtime/streamlib-engine/src/lib.rs, sdk/streamlib-sdk/src/lib.rs
The synchronization module, helpers, constant, and SDK re-exports are removed.
Remove audio sampling API
runtime/streamlib-engine/src/core/observability/perception.rs
SampledAudio and AgentPerception::sample_audio are removed.
Clarify audio timing semantics
runtime/streamlib-engine/src/core/context/audio_clock.rs, runtime/streamlib-engine/src/linux/audio_clock.rs
The timestamp documentation describes wake-time and catch-up behavior. The obsolete backend FIXME is removed.
Update backend and delivery documentation
docker/pipewire/10-virtual.conf, runtime/streamlib-engine/src/iceoryx2/delivery_profile.rs, runtime/streamlib-engine/src/iceoryx2/node.rs, runtime/streamlib-engine/src/iceoryx2/overflow.rs
Comments describe the direct PipeWire backend chain and clarify audio delivery and overflow behavior. No runtime declarations or behavior change.
Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 6e381

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)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR removes the FIXME, synchronization module and re-exports, and audio perception API as required. However, delivery_profile.rs still lists audio under EverySample, which conflicts with the re… Remove audio from the EverySample documentation and retain it only under Lossless. Rerun the removed-items gate and workspace checks.
Out of Scope Changes check ⚠️ Warning The PR includes documentation changes in core/audio_clock.rs, iceoryx2/node.rs, and iceoryx2/overflow.rs that are not listed in the linked issue's objectives. The linked issue specifies only the… Remove the unrelated documentation edits, or update the linked issue to explicitly include the timestamp and overflow documentation changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the removal of the audio FIXME and obsolete synchronization machinery, which are the primary changes.
Docstring Coverage ✅ Passed 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 …
Full details: Linked Issues check

Explanation

The PR removes the FIXME, synchronization module and re-exports, and audio perception API as required. However, delivery_profile.rs still lists audio under EverySample, which conflicts with the requirement that audio use Lossless.

Full details: Out of Scope Changes check

Explanation

The PR includes documentation changes in core/audio_clock.rs, iceoryx2/node.rs, and iceoryx2/overflow.rs that are not listed in the linked issue's objectives. The linked issue specifies only the PipeWire and delivery-profile documentation corrections.

Full details: Docstring Coverage

Explanation

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.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/1993-audio-rung-removals

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tato123
tato123 merged commit 75f71db into main Aug 28, 2026
9 checks passed
@tato123
tato123 deleted the chore/1993-audio-rung-removals branch August 28, 2026 15:43
tato123 added a commit that referenced this pull request Aug 28, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(engine): the audio rung's removals — the FIXME closes and the dead sync machinery goes

1 participant