Skip to content

docs(plan): ship dlopen-audio-backend-and-audio-blocks — fold into §Media I/O and archive - #2020

Merged
tato123 merged 1 commit into
mainfrom
ship/dlopen-audio-backend-and-audio-blocks
Aug 28, 2026
Merged

docs(plan): ship dlopen-audio-backend-and-audio-blocks — fold into §Media I/O and archive#2020
tato123 merged 1 commit into
mainfrom
ship/dlopen-audio-backend-and-audio-blocks

Conversation

@tato123

@tato123 tato123 commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Ships dlopen-audio-backend-and-audio-blocks — rung one of the [audio-subsystem]
ladder. Audio exists: a microphone reaches a processor as timestamped samples over a
backend the wheel never links, and a processor's samples reach a speaker.

Plan changes merge only with the owner's review.

Precondition — every ticket merged

Ticket What PR Merged
#1988 AudioBlock — samples ride the bag as msgpack bin #1995 2026-08-27
#1989 the device seam and the null backend #1997 2026-08-27
#1998 headless known-signal loopback fixture #2001 2026-08-27
#2002 verify audio per processor by tapping its channel #2003 2026-08-27
#2004 an unconnected audio output logged ~94 errors a second #2005 2026-08-27
#1990 the PipeWire arm — dlopen'd libpipewire, vendored SPA shim #2008 2026-08-28
#1991 the ALSA arm — dlopen'd libasound, chain demotes in order #2010 2026-08-28
#1992 SpeakerSink — playback on every arm #2013 2026-08-28
#1993 the rung's removals — the FIXME closes, dead sync machinery goes #2016 2026-08-28
#1999 /verify-audio as a callable skill #2017 2026-08-28
#2012 a stream that dies tells its owner, not just the log #2018 2026-08-28

#2018 merged 2026-08-28T22:10:12Z — the archive date, not today's guess.

#2015 is the one ticket that did not ship. It was closed NOT_PLANNED, not
implemented: the drop counter it would fix turns on whether lossless and
every_sample are distinct concepts, and that vocabulary needs an /align before the
windower rung. Recorded here as a fact; no plan entry claims the fix.

Gate — clean at the archived path

$ bash .claude/scripts/ship-change-removed-gate.sh \
    docs/plan/changes/archive/2026-08-28-dlopen-audio-backend-and-audio-blocks.md
clean: 7 REMOVED bullets, none referenced and none on disk.
EXIT=0

All 11 source-walking gates pass, including check-no-in-process-placement (7408 files,
19 exempt prohibition lines matched) — this change file pinned no gate key, so archiving
it moved nothing the placement gate depends on.

The fold — eleven DECIDED entries into §Media I/O

Six new entries. The device seam as one engine primitive (AudioDeviceBackend
opening capture and playback streams beside the audio clock, no second audio device
path); every audio symbol binding at runtime through libloading against the versioned
soname; SPA's header-only layer as a cc-compiled shim that references no external
symbol; the headers vendored rather than taken from the build machine; the portability
gate unchanged and unweakened. Then the AudioBlock half — the wire contract and its
six keys, samples as msgpack bin rather than a typed vector, the pure-Python cast
that composes nothing surface-shaped, "zero-copy" stated as a claim about the cast
alone, and the harness bin-decode defect fixed at the engine layer.

Five existing [audio-subsystem] entries sharpened in place, each gaining its
SHIPPED citation: the backend chain gains an arm is chosen by opening, not by
loading
and the named-device_id raise at setup(); the pacing entry gains the clock
starting only when something needs it, which is what makes "exactly one cadence source"
true in the tree rather than merely stated; A/V sync, the data model, and the two
built-ins gain theirs. The built-ins entry cites partially#1989, #1992 for the
built-ins, their execution mode and the drop-at-the-edge clause, with conditioning and
immediate cancel named as a later rung.

The section stays IN-FLIGHT. Its audio-plugins entry is still OPEN, and the
convention here is that a section ships only when it holds no OPEN. Only the
(→ dlopen-audio-backend-and-audio-blocks) pointer goes.

#2012 folds rather than adding an entry. It was filed during implementation, not
part of the approved delta, so its contract lands as a clause on the device-seam entry
instead of becoming architecture this session made.

Every verify marker was run before it was written

The wheel's .so predated HEAD, so maturin develop ran first — otherwise the PASS
would describe the old code.

  • 20 Rust tests across streamlib-engine --lib, streamlib-media-builtins --lib,
    and the audio_clock_paces_only_what_needs_it / silent_null_arm_* integration
    binaries.
  • 13 hardware-tier tests that skip on a bare machine actually ran here — this rig
    has /dev/snd and a live PipeWire session, so pipewire_arm_* and alsa_arm_* were
    executed under --features streamlib/hardware-tests, not merely listed. The device
    stamping the block is proven against a real daemon and a real driver.
  • 29 wheel tests: test_audio_block_cast.py, test_microphone_source.py,
    test_speaker_sink.py (22), plus test_wheel_portability.py and
    test_third_party_notices.py (7).

The design's own pass/fail, run directly rather than asserted:

$ readelf -d python/streamlib/_engine.abi3.so | grep NEEDED
 [libstdc++.so.6]  [libc.so.6]  [ld-linux-x86-64.so.2]  [libgcc_s.so.1]  [libm.so.6]

Five libraries after audio, the same five as before. No audio library entered
DT_NEEDED.

Diagram

system.mmd gains the vendored-shim and DT_NEEDED clause on the media node, and the
previously unlabelled media → engine edge now carries the seam, the liveness report,
and the device-stamps-the-block rule.

Note, not a ticket

packages/audio, packages/opus and packages/clap remain read-only reference for
rungs two and three (the rubato wiring, the rechunker, the Opus framing). They are
deleted as REMOVED: facts when the last of that logic is re-homed, not before.

🤖 Generated with Claude Code

…edia I/O and archive

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

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 20 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e9106418-3d00-4892-bbca-9d8fe26eb380

📥 Commits

Reviewing files that changed from the base of the PR and between 357963d and 44c3d03.

📒 Files selected for processing (3)
  • docs/plan/ARCHITECTURE.md
  • docs/plan/changes/archive/2026-08-28-dlopen-audio-backend-and-audio-blocks.md
  • docs/plan/diagrams/system.mmd

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 8554f85 into main Aug 28, 2026
5 checks passed
@tato123
tato123 deleted the ship/dlopen-audio-backend-and-audio-blocks branch August 28, 2026 22:34
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.

1 participant