Skip to content

webrtc framer transport crate on predev (row 132, piece 1; carries #721) - #795

Merged
MattJackson merged 33 commits into
predevfrom
lane-webrtc-framer
Oct 13, 2026
Merged

MattJackson merged 33 commits into
predevfrom
lane-webrtc-framer

Conversation

@MattJackson

Copy link
Copy Markdown
Collaborator

Status row 132, piece 1 of 6: the webrtc framer. This carries #721 (D2, CONFLICTING) onto predev 62fdbdf and replaces it; #721's commits are kept as they were, with one merge of predev on top.

What it is

busbar-transport-webrtc, a datagram framer on the transport kind's table: ICE, SRTP and SCTP over str0m 0.24.1 on ring. The framer holds no DTLS state. Every name from the media stack's DTLS interface sits in src/shim.rs, and the shim refuses any keying profile other than AEAD-AES-GCM. The SRTP keys arrive through the contract's keying-material item (#706). The dropped-in door is this crate's own cdylib behind a dropped-in feature, the same way busbar-transport-stdio does it. The root registers the wire in [package.metadata.busbar.linked] behind the transport-webrtc feature.

Merge with predev

  • The only conflict was xtask/src/gates/population.rs. Predev's floor is 947 after mcp: the MCP-FIX stack (plane-mcp findings 1-18, 24) #703. The framer adds six non-test files (crypto, door, framing, lib, shim, stun), so the floor is now 953. I counted 947 on origin/predev and 953 on this head, using the gate's own filter.
  • Cargo.lock merged cleanly, and cargo metadata --locked passes.

Tests (each with a RED arm), cargo test -p busbar-transport-webrtc

  • AES_CM is refused by the cipher in both directions and at the keying item. RED arm: the GCM ciphers seal and open.
  • tests/dependency_closure.rs: aes, cipher and inout are confined to the SRTP key derivation, in both Cargo.lock and the source. RED arms: a second crate depending on aes is refused, and so is the framing naming aes.
  • A spoofed ICE path is not rebound, and application data that arrives before the peer is verified is dropped.
  • tests/zeroise.rs, using a watching allocator: keys are zeroised on drop. RED arm: the same key held in a plain Vec is seen freed without being zeroed.
  • tests/no_dtls.rs: the framer source names no DTLS type. RED arms: an engine inside the shim is refused, and so is the DTLS interface used outside the shim.
  • tests/conformance.rs: both doors go through the loader's transport table, state the same Statement and give equal transcripts. RED arm: the cdylib admitted against a different Statement is refused.

Rest of row 132 (one PR each, in this order)

keying-material presentation by the host (connector datagram driver), then the udp claim door (datagram listener from the root listen config), then busbar-minted tickets, then deleting broker.rs, then the browser cell.

…dropped-in door into the crate, add its tests

The framer builds against str0m 0.24.1 (media data is an Arc<[u8]>). Every name of the media
stack's DTLS interface moves into src/shim.rs (provider, certificate, profile mapping); the
shim refuses any keying profile but AEAD-AES-GCM. The drain routes what the stack queued for
sealing on every poll, the last one included, so SCTP reaches the far end. Address types come
from core::net. The dropped-in door is this crate's cdylib under a dropped-in feature, as
stdio's is, so the crate's closure stays busbar-contract plus its framing libraries.

Tests: AES_CM refused (cipher and keying item), the aes/cipher/inout dependency closure, no
DTLS type outside the shim, keys zeroised on drop (a watching allocator), and both doors
through the loader's transport table, each with its RED arm.
… drain its name from core

Clippy (-D warnings): the stun-success arms in framing.rs and the audio MediaAdded arm fold their
`if` into the match guard (collapsible_match); read_remote's return type is a `Remote` alias
(type_complexity); door.rs's piece loop is a `while let` (while_let_loop).

kind-isolation:transport-registration: the webrtc wire was composed in no place. The root links
it as a `transport-webrtc` row on the transport and transport-door axes, behind an optional,
off-by-default feature of the same name (the crate edge and the row together, as transport-ws).
Its linked entry gains COMPOSES_OVER (none) and SESSION (true, its claim row's session) beside
KEY and door. The shipped fold and session fixtures carry its row (both count rows a build
leaves off); qa/kind-isolation.toml names the busbar -> busbar-transport-webrtc edge.

kind-isolation:law0 (18 -> 20): the new crate made `webrtc` transport-instance vocabulary, so
core's existing mentions became hits (busbar-core-connector 68 -> 76, busbar-contract 226 -> 230).
Drained, not re-ceilinged: the connector's docs say "media association", the contract's
composition tests use a made-up `dgram` wire over `udp`.

Proved on Latchkey: clippy -p busbar-transport-webrtc --all-targets -D warnings; check -p busbar
--features transport-webrtc --tests; test -p busbar body_chunk_bounds and
transport_composed_over_consistency; gate kind-isolation and kind-isolation-ship
(transport-registration PASS, law0 back to 18 findings, the rest at base); selftest
kind-isolation and kind-isolation-ship; xtask plant_tests a_wire_composed_in_no_place_is_red_and_the_real_tree_has_none
and a_manifest_row_is_the_wires_one_registration. The per-crate clippy rows (core-duplex-ws,
loader-pack, ...) and the workspace selftest_runs_every_registered_gates_red_proof row share these
causes and are left to CI.
…rtc census id added

Landing busbar-transport-webrtc teaches the census the transport id `webrtc`,
so every `webrtc` in the composition root (a core-neutral crate) became a
busbar x transport hit: 12 in tests/plane_transport_neutrality.rs's own
source and 3 fixture rows (transport_fold.txt, transport_sessions.txt,
session_transport_nouns.txt), figure 11 -> 26. The [[law0]] ceiling does not
rise, so the cell is drained back to it:

- plane_transport_neutrality.rs no longer spells the noun in its own source
  (its fixture already holds the list "so the scanner's own source spells no
  word it bans"): the self-test plants `mulaw` / `dtmf_digit_count` for the
  bare-word and snake_case cases instead, which proves the same two rules;
  the noun list and the detector are unchanged (-12).
- The three fixture rows stay: the fold and session rows are read by the
  all-features build that links the wire, and the noun row mirrors the xtask
  twin's NOUNS. They are offset by three prose-only names of the line
  carrier's transport in the root's docs (serve_lines.rs x2, serve.rs x1),
  reworded to "line carrier"/"line transport" (-3).

Not run locally: the Latchkey run budget (RUN_CAP) is spent; the count is
reasoned from the matrix scanner (every non-Cargo.toml file under the crate,
occurrences per line, `webrtc`/`stdio` unmasked) and the PR's CI is the proof
for gate:kind-isolation and gate:kind-isolation-ship.
The red row (nextest busbar-kernel-egress::swrr_allocation::
a_warm_pools_selection_allocates_nothing) was a first-try FAIL that passed on
retry: the run reported failed 0, and the turnstile reads a TRY 1 FAIL as a red
row. Nothing in this PR touches the egress unit (src and test are byte-identical
to predev). The witness was racy: its counting flag was process-global, so
libtest's main thread, still filing the test it had just spawned, could
allocate inside the measuring window on a loaded shard.

Ruling: the witness measures the op, not the process. THE DESIGN A.8
(docs/design/BUSBAR-1.6.0.md l.3561: "A counting-allocator witness is 0 for
each request-path op"; l.1285 "no allocation and no blocking on the hot
path"). The flag is now thread-local. select_weighted runs wholly on the
calling thread, so every allocation it makes is still counted and the
assertion (== 0) is unchanged.
…plane edges

The webrtc framer adds six non-test .rs files under crates/, so the
population (941 at base) is 947 and the one-file-short selftest plant no
longer goes red: blocking-ffi, response-header and settings-leak selftests
failed on it. population::FLOOR is a ratchet pinned at the measured count,
so it moves to 947. The tracing selftest is fixed by merging predev
(13a9ecb, the SCAN_FLOOR plant cuts with Overlay::below_floor).

This branch touches qa/kind-isolation.toml, which arms kind-isolation:deps.
That row was red for two standing edges with no rows: busbar-llm ->
busbar-plane-llm (no [[dep]] row and no [[transitional]] drain row) and
busbar-voice -> busbar-plane-streaming (no [[dep]] row). Both are legacy ->
plane drain edges at count 1; they get not-allowed [[dep]] rows and the llm
edge gets its [[transitional]] row, on the same terms as busbar-a2a ->
busbar-plane-a2a.

Not proved on Latchkey: busbar-release dev refused every row (run budget
spent, RUN_CAP 4000/4000). Reasoned from the CI log of run 38094908998;
the PR's CI is the proof.
Conflict in xtask/src/gates/population.rs (FLOOR): keep both sides.
predev's computed one_file_short plant and its note stay; FLOOR stays
at 947, the census measured with this branch's six
busbar-transport-webrtc/src files, because a census floor "pins its
ceiling at TODAY'S MEASURED VALUE" (BUSBAR-1.6.0.md:2090-2092).
Predev's own floor guarantees >= 941 files there, so the merged tree
holds >= 947.
…door, chosen by rank

busbar-transport-webrtc's conformance (2 tests) failed at `stated()`: "the cdylib exports
busbar_plugin_door". `choose_cdylib` took `target/debug/libbusbar_transport_webrtc.*`, uplifted by
an earlier plain build without the `dropped-in` feature, so that image has no door. The test
build's own image, `deps/libbusbar_transport_webrtc.*`, does export it but was never a candidate:
cargo names a workspace cdylib with no metadata hash, and a `cargo test` never uplifts a lib's
cdylib (the lib is not a root unit), so the uplifted file is only ever another build's.

The choice now ranks: the image CDYLIB_ENV names; the lib unit's own unhashed `deps/<lib>`; the
uplifted image; the one hashed image. At every rank an image that does not load or exports no
`busbar_plugin_door` is passed over, and only doorless images built is a failure naming them.

Why this over a dedicated target dir: the suite is published to every plugin repo and runs inside
their test binaries; building the image into a dir of its own would mean a nested cargo build from
a test (a second cold build of the closure, a lock on the target dir), and `plugin-ci.yml` already
names its image in CDYLIB_ENV. Probing the symbol decides by what an image IS, the door the
dropped-in leg needs, never by which build ran last; the existing refusal of two different images
at one rank stays.

Tests: a doorless uplifted image is passed over for the deps image with the door, before and after
a later plain build; doorless images only are refused naming them; the real probe tells the example
cdylib from a file with no door. Fixed forward with the root cause (BUSBAR-1.6.0 §11.4, Part 2 #2:
one table, compiled in or dropped in; Part 6: nothing waived).
# Conflicts:
#	xtask/src/gates/population.rs
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

promote into predev: DENY @b6f9dda6d: 0 failing test row(s), 0 DENY row(s)

Denied because (1)
  • shard 3/4: gate:test:xtask-selftest row xtask: selftest structure-lint: red now, not red at base

Judged against base 75f438bb0: 1 new red, 0 worse, 6 standing (excused).

New reds: gate:test:xtask-selftest row xtask: selftest structure-lint: red now, not red at base

Already red on predev, not this PR's: 15
gate row detail
test:xtask-selftest ::xtask selftest kind-isolation
test:xtask-selftest ::xtask selftest plane-purity
test:xtask-selftest ::xtask selftest no-deferral-strict-done
test:xtask-selftest ::xtask selftest plane-purity-strict
test:xtask-selftest ::xtask selftest unconstructed
test:xtask-selftest ::xtask selftest structure-lint
test:xtask-selftest ::xtask selftest plane-transport-neutrality
construction one-pick-site 3 production call site(s) of 'pick_among(' (ceiling 2): crates/busbar-kernel-egress/src/walk.rs:358; crates/busbar-llm/src/engine/exhaustion/fallback.rs:120; crates/busbar-llm/src/engine/pipeline.rs:8
kind-isolation kind-isolation:deps 3 finding(s), 95 shipped edge instance(s) over 30 class(es), 95 declaration(s); 57 '[[dep]]' row(s), 0 question(s): unlisted-dep-edge legacy -> plane busbar-llm -> busbar-plane-llm is a shipped edge w
kind-isolation-ship kind-isolation:deps 9 finding(s) over 95 shipped edge(s): ship-edge kernel -> hooks busbar-kernel -> busbar-hook-ranking is 'not-allowed': the architecture grants no kernel -> hooks edge, and the ship criterion is the ar
kind-isolation-ship kind-isolation:test-deps 5 finding(s) over 31 test edge(s): ship-edge cleanliness -> export busbar-core-admin -> busbar-export-prometheus is 'not-allowed': the architecture grants no cleanliness -> export edge, and the ship c
kind-isolation-ship kind-isolation:faces 2 finding(s) over 41 crate(s): foreign-entry crates/busbar busbar is kind 'root' and implements 'Transport' 1 time(s) in shipped source — the entry face of kind 'transport'. A trait implementation is
kind-isolation-ship kind-isolation:legacy-drain 3 finding(s): transitional-live qa/kind-isolation.toml 'busbar-a2a -> busbar-core-admin' (legacy drain: the retiring A2A engine's tests drive the admin surface that drained into the cleanliness tier)
ship-ready ship-ready:ship-twin 'kind-isolation-ship' is not green: kind-isolation:deps (a dependency the architecture does not grant is still in the graph); kind-isolation:test-deps (a dependency the architecture does not grant is
structure-lint structure-lint:plane-dup:unledgered 22 finding(s): PLANE-DUPLICATE (module): 'config.rs' — a2a:crates/busbar-a2a/src/a2a/config.rs decisions:crates/busbar-plane-decisions/src/config.rs voice:crates/busbar-voice/src/config.rs (the ledger

tests passed: 24811, failed: 0. Run: https://github.com/GetBusbar/busbar/actions/runs/38345986614 . Artifact verdict-b6f9dda6da7d58dd1f3b7800907270719c498d62 (failures.json, junit.xml, raw.log; 90 days).

…ows #721 carried; they are not this crate's edges, and the transitional row armed legacy-drain red
xtask/src/gates/population.rs: predev's floor is 949 after FLIP-LLM (#464); the framer's six
non-test files make 955 on this head (measured with the gate's filter: 949 on predev, 955 here).

busbar-core-connector/tests/no_io_outside_hostio.rs: the one comment that named the webrtc
instance now names the spec paragraph by its kind ("Datagram media"), so connector x transport
holds at 68 once the framer's crate is in the tree.
xtask/src/gates/population.rs: predev's floor is 948 after #686; the framer's six non-test files
make 954 on this head (measured with the gate's filter: 948 on predev, 954 here).
xtask/src/gates/population.rs: predev's side whole. #810 deleted the hand-kept scan floor; the gate
reconciles its scan against git ls-files, and the framer's six source files are tracked.
@MattJackson
MattJackson merged commit ca0c338 into predev Oct 13, 2026
10 of 12 checks passed
@MattJackson
MattJackson deleted the lane-webrtc-framer branch October 13, 2026 13:38
MattJackson added a commit that referenced this pull request Oct 13, 2026
Brings predev 235e1a3 (#795, #783). Conflicts: qa/DESIGN-BINDINGS.md and qa/design-bindings.json, the generated design-bindings ledger: predev's files taken, then only this branch's own rows re-applied in the generator's format: PB-35 cites every_request_is_verified_by_the_door_and_the_kernel_caches_no_verdict; PB-100 drops the three deleted hop tests (execute_hop_refuses_non_allowlisted_host, vet_hop_url_enforces_https_allowlist_and_blocks_metadata, execute_hop_does_not_follow_redirect); mapped test checks 430 -> 428 (+1 -3). The .md and .json agree row for row (104 bindings, 428 test checks).
MattJackson added a commit that referenced this pull request Oct 13, 2026
Brings predev 235e1a3 (#795 webrtc framer, #783 store-memory extracted). Conflict: Cargo.toml, both sides kept: predev's busbar-transport-webrtc member and media pins, busbar-store-memory pinned with its fixture-store role; this branch's own deletion of the a2a-lf / a2a-pb pins with busbar-a2a stands. cargo metadata --locked reads the merged lock.
MattJackson added a commit that referenced this pull request Oct 13, 2026
…es with no reading

#795 (on predev) wrote busbar-transport-webrtc against the transport ABI before row 66 (#561/#778), which appended TransportTail::fault_rows / fault_rows_len and gave FramePiece's spare byte to fault. The door's TAIL states no status rows, so it states the empty fault table (null, 0), as busbar-transport-stdio's carrier does; its pieces and the conformance test's host piece carry fault: 0 (FAULT_NONE) where _reserved was. No transport ABI version constant is declared in the crate.
MattJackson added a commit that referenced this pull request Oct 13, 2026
…D, never an empty piece

Row 66's contract (#561, busbar-contract abi/transport/mod.rs:58-64, PIECE_END at :451-456, check_framer at check.rs:256-265): a stream's frames end with their own empty piece carrying PIECE_END and PIECE_END_OF_FRAME; an EMPTY piece without it is an empty message. #795's door turned Event::ChannelClose (framing.rs) into an empty piece with PIECE_END_OF_FRAME, which the host now reads as an empty binary message, never the channel's end.
- framing::Piece states end; ChannelClose's piece sets it, every other piece does not;
- door::piece_flags states an end as PIECE_END | PIECE_END_OF_FRAME and nothing else; every other piece keeps its bits;
- src/tests/door_tests.rs: a closed channel's piece is the end by flag (never text, fields, failed or continued, which check_framer refuses beside an end), an empty binary or text message is a frame and not the end, and messages and field blocks keep their bits.
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