Add an input endpoint to a channel's head in addition to any it already feeds — the crosspoint patchbay's multi-in (the sources sum natively at the head). Idempotent: re-adding an endpoint already in the set is a no-op. The inverse of StructuralDsp.removeChannelSource; distinct from the replace-semantics StructuralDsp.setChannelSource.
Open a direct source→output route (no channel consumed).
OptionaladoptAdopt the engine strip as the ONE store behind the MAIN master reads — wired by the
server on a console whose entity rows own MAIN's strip state, so busFaderOf /
busPanOf / busMuteOf on MAIN answer that record instead of a per-bus copy.
Optional: a surface without the seam keeps its own store for MAIN, exactly as for
every other bus.
OptionalallocationThe allocation this console was declared at, for the session capture to record — the desk
the show was mixed on. Optional: a surface with no allocation concept simply has none, and
the session then carries no allocation block (absence is a fact).
Allocations refused for want of native bus slots (#112) — empty when everything fit.
Every managed summing bus (aux / group / mix / main) with its live state — the
real BusState the mixer returns ({ id, master, inputCount, sends, mixMinus? }),
NOT a bare id. Matrix buses are excluded; read those with StructuralDsp.matrices.
OptionalbusThe current group→main send level of a bus (1 if never set).
Whether a bus is muted (its whole summed output silenced).
OptionalbusWhether the CURRENT destination entered the row by observation rather than a write (§4).
OptionalbusWhether this bus's per-destination DELAY REACHES AUDIO, or is stored only.
Two native stages carry it and a bus is in exactly one: MAIN's destination rides the
per-route output stage, every other native bus rides its OWN bus-lane output stage
(2026-08-31-smart-alignment.md §9c). A bus with neither — and an output patched NOWHERE,
whatever stage it owns, since a per-destination delay with no destination has nothing to
reach — stores the value while no RT cycle consults it. A reader that OFFERS one of those
numbers as a correction is offering a write that changes a value and moves no loudspeaker,
which is why loudspeaker alignment (§9b) asks this before it offers an APPLY.
Optional: a surface that draws no such line does not answer, and a reader treats the silence as "it does" rather than refusing every console that never had the distinction.
OptionalbusThe destination this bus held before the healer last moved it (§2), volatile.
OptionalbusWhether the OPERATOR has locked this bus's destination — a gig protection, desk state, persisted with the session (ruling 2026-09-01). Optional: an engine that cannot say locks nothing, and every refusal built on it then simply does not fire.
The sink a managed bus output currently routes to, or undefined when it is unpatched.
OptionalbusWhether this bus DECLARES that it must always have a destination (the operator's "do not allow self-erasing"). A per-bus property, never a rule about a kind. Optional: an engine that cannot say declares nothing required.
Where that sink lands PHYSICALLY — the model endpoint resolved onto the device's ACTIVE
profile (#181) — or undefined when the bus is unpatched.
Distinct from busOutputOf, which stays the operator's INTENT and the per-destination
trim's identity. Anything that describes what the audio DOES — the leg row's monoFold and
the native fold route — reads this one, so a saved endpoint whose profile moved cannot make
the desk report a sum the graph is not performing.
OptionalbusA routable bus's OWN output ports, role-keyed — the SOURCE side of its route edges, and the only sources an adoption may fire from (§4). Optional: absence bounds adoption to nothing, which is the honest answer for a surface that publishes no tail.
The stored per-destination trim on a bus's route to out, or undefined (unity default).
OptionalbusWhether the OPERATOR unpatched this bus, as against every other reason it holds no destination (spec 2026-09-15 §2). Optional, absence-is-a-fact: an engine that cannot say remembers no decision, and the healer then treats every absence as a gap.
The current bus master L/R balance (0 = centre if never set).
OptionalchannelThe channel HEAD node's input port(s) — the DESTINATION every one of this channel's
source legs links into. Read by the outbound patchbay seam to scope the #168 deferral
ledger to one channel (issue #194): a deferred edge is this channel's business only when
its to is one of these ports, so a source patched into several channels is judged per
channel instead of everywhere it is listed. Optional — an engine that cannot answer leaves
the seam on its port-liveness-only read. undefined for an unknown channel.
A channel's live post-fader insert slots ({ uri, enabled, instanceId }), in order.
Every channel currently in the mix.
The resolved input endpoint feeding a channel's head (its current source / raw
input), or undefined when the channel is unpatched (its last source was removed).
The full set of input endpoints feeding a channel's head ([primary, ...extras]).
The channel's semantic source width — true when its patch made it stereo (a
stereo pair assigned / promoted as primary, or any stereo crosspoint extra). Rides
every patchbay.links broadcast so surfaces render the S tag + split meter.
The strip's EFFECTIVE audio WIDTH — true when this channel is a stereo strip right now.
SoftwareMixer.stripStereo exposed: the SAME expression the native leg count is built from,
and WIDER than StructuralDsp.channelSourceStereo by the linked-pair arm (a linked
primary IS a stereo strip — operator ruling 2026-08-06). /channel/{kind}/{index}/width and
the capability row's width word both read this and nothing else.
Apply a per-gig console allocation (create the buses sized to the channel count).
The current DCA operator label (undefined if unnamed).
Every DCA group (DcaState: { id, master, members, parents }, parents as keys).
OptionaldeclaredThe bus half of StructuralDsp.declaredChannelChain.
OptionaldeclaredOptionaldeskThe links into sinkPorts that come FROM the desk's own ports and that the desired graph
does NOT carry — a hand-made pw-link the operator laid (spec 2026-09-15 §4). The exact
mirror of foreignSinkLinks, off the same graph read and the same two classifiers.
Optional for the same reason that one is.
OptionaldetectThe routing loops in the running mix right now — rings in the desired audio graph, each annotated with the channels whose faders lie on it. Empty when the routing is acyclic. Pure read: no graph I/O, so it is safe to call after every structural mutation.
Optional, like StructuralDsp.reconcile: a hardware-adapter surface owns no routing graph to search, and simply never reports a loop.
The open direct source→output paths.
OptionalensureEnsure a single summing bus EXISTS: create it when absent, no-op when present — the
session-restore seam. A bus created at runtime (allocation.apply) is captured into
the session snapshot, but a fresh boot's console does not carry it; the console-state
provider calls this before re-applying the bus snapshot so a saved show round-trips
across a restart. Optional (like StructuralDsp.reconcile): a surface that
cannot create buses live omits it, and the provider then skips the missing bus
instead of failing the whole load.
Optionalopts: { mixMinus?: boolean; stereo?: boolean }OptionalexcludedEvery live link from an EXCLUDED app that touches the desk (spec 2026-09-15b) — the console INPUT side as well as the routed output side, because an excluded app is the one policy value refused BOTH ways. Optional for the same reason the sweep's own doors are.
OptionalforeignThe live links into sinkPorts a sever WOULD cut right now — takeoverExclusive's own
classification, exposed read-only so /patchbay/disconnect (rest-entity-map §2 hidden
entity #10) can preview the target set without severing anything. Optional for the same
reason takeoverExclusive is.
Optionalspare: (sourceNode: string) => booleanWhether a managed bus CAN be mix-minus — every summing bus but a matrix.
OptionallinkWire a raw endpoint hop outside the desired graph — the unpatch hand-back that re-links a released app stream to the default sink so it stays audible. Optional.
The stereo-link state of a channel (role + partner), or undefined if unlinked.
OptionalmarkMark how the destination the bus holds RIGHT NOW got there — called by the healer and the adopter straight after their own StructuralDsp.setBusOutput, which drops both marks.
The matrix outputs with their live state (MatrixState: { id, master, points }).
Whether a mute group is currently active (false if never set).
The current mute-group operator label (undefined if unnamed).
Every mute group (MuteGroupState: { id, active, members }).
OptionalnativeNative bus slots and what this console's buses already claim — the pair the past-the-roof
refusal decides on, so /console/allocation can publish the ceiling instead of a client
compiling one in (#112's other half). Optional for the same reason as allocation:
a surface with no native array bounding it has no roof, which is an absence and not a zero.
The currently-engaged panic scope, or null when no panic is held.
OptionalreconcileConverge the live graph onto the desired routing now. The server pokes this when the PipeWire graph changes so a respawned app stream (same node name, fresh node) is re-linked to its patched channel without operator action. Optional: hardware-adapter surfaces have no graph to reconcile.
Remove one input endpoint from a channel's head, leaving its other sources intact.
Remove a DCA entirely (release its members from the coupling).
Tear a direct source→output route down.
Remove a mute group entirely (release its members).
Move a bus master's processor at index from to index to.
Move a channel's processor at index from to index to (a reorder).
Every channel that HAS an output patch — the ONE list of routable outputs: the summing buses, the matrix outputs, and the cue/monitor bus, which is routable without being a summing bus and so appears in neither of the two lists above. Every caller that needs "which channels can be routed to a sink" asks THIS, never a hand-composed union.
Whether a channel is assigned to the main mix (true if never toggled).
The rich tap spec of a channel's send into a bus ('post' when no send is set).
OptionalsetDeclare the live instance picture behind the patched app streams (numeric node/port ids + live links, one entry per concurrent same-name node). Each reconcile then links EVERY instance to its patched channel by id (they sum) and cuts every instance's non-desk route — where a port NAME can only ever address the first matching node. Replaced whole from each fresh graph read; ids are never persisted. Optional.
The bus half of StructuralDsp.setChannelChain.
OptionalsetWrite this bus's format — MAIN only in this increment (SoftwareMixer.setBusFormat's own
gate). Returns whether the native call actually changed (or already held) the requested
port set. Optional for the same reason as setBusOutputLocked.
Set a bus's group→main send level (linear; scales the fold-back atop the master).
Mute / un-mute a whole bus (the group master's MUTE; the master fader survives).
State where a managed bus (incl. main/1) sends its output — the ONE door. undefined
UNPATCHES it. A bus has AT MOST ONE destination (operator ruling 2026-08-06); choosing
another replaces this one, links and all, in a single operation. Throws when the bus
DECLARES busOutputRequired and out is undefined.
OptionalsetLock or unlock this bus's destination — the ONE door. Optional for the same reason.
Enforcement is NOT here. The engine holds the fact so one store answers everyone and the session can persist it; the refusal lives on the REST row, because a restore, a boot and the route healer must all still be able to lay the patch the lock is protecting.
Set (merge) the per-destination output trim on a bus's route to out — the output-gain
floor (issue #158): a gain/mute for ONE physical destination, POST bus-master, independent
of the master and of every other destination the bus feeds. Persisted + captured so a
controlled level survives a reload; the native engine's per-route stage applies it.
OptionalsetRemember (or forget) the operator's own unpatch — the ONE door, written by the row.
Set a bus master L/R balance (−1 hard-L … 0 centre … +1 hard-R).
Enable / bypass a bus master's processor by id.
Set an lv2:Parameter (Patch ext) on the curated plugin hosted by a bus master's processor.
Toggle a bus's fold-back into the main mix (the group → main routing toggle).
OptionalsetDeclare the source ports the desk exclusively captures (patched application streams). Each reconcile then cuts their live links that are not desk routing — the session manager's default-sink auto-route that would double the audio. Optional.
Replace a channel's WHOLE processor chain — the door a session LOAD needs.
The per-node writes above each move one thing about a chain that already exists; a load
has no such chain to move, because the strip it is restoring onto was assembled from the
console default. Reconstructing a saved arrangement out of reorders would be a second
spelling of the same fact, and one that has to guess a path between two orders. The
engine already owns this door (SoftwareMixer.setChannelChain); it was simply not
reachable from the persistence provider, which is why chain order did not survive a save.
Assign a source to a channel live — the source → channel crosspoint. source is a
registered source id (its head-amp follows) or a raw StereoEndpoint.
Restore a channel's source width from captured provenance (snapshot/patch load). May re-apply the live pan/balance distribution, hence possibly async.
Set (or clear) a DCA's operator label.
Set a control-port value on a channel's live insert instance at slot.
Load an LV2 preset into a channel's live insert instance at slot.
Replace a channel's post-fader insert chain (the plugin.* insert slots) — wires the
plugins into the channel's live head → fader → [inserts] → bus pw-link path, so a
UI-added plugin actually processes (Bug G), unlike a parallel system:capture/playback
insert.
Turn a bus's N−1 behaviour on or off — the flag's ONE writer (ruling 2026-08-15).
Activate / release a mute group (mute or restore its members together).
Set (or clear) a mute group's operator label.
Replace a bus / matrix / main output's insert chain.
Engage / release the PANIC latch: a third OR term over effective mute, composed exactly
like an active mute group (packages/core/src/mute-group.ts's panicEngaged). Never
writes a channel's individual mute, so releasing it (panic.scope: null) restores
exactly the pre-panic state — nothing to snapshot, nothing to restore.
Enable / bypass a channel's processor by id.
Set an lv2:Parameter (Patch ext) on the curated plugin hosted by a channel's processor.
Assign / un-assign a channel to the main mix (the console MAIN routing toggle).
Set a channel's send into a bus (linear level + a tap). tap is a
SendTapSpec: the legacy 'pre'/'post', a named feed-point preset, or an
explicit { position } in the channel chain (the engine's 4-arg setSend).
Move an existing send's tap (position in the chain) without changing its level.
Register / replace a source (also re-gain / rename — it follows the source).
OptionalseverCut a classified link set, through the console's ONE severing primitive.
The registered sources, in registration order.
Swap a bus master's EQ and dynamics stages (Roland DYN↔EQ).
OptionaltakeoverExclusive takeover (operator #80): sever every live link into the given device- sink ports that is not the desk's own routing — the app / EasyEffects / Dummy-Driver hops the session manager wired straight to the sound card. Deliberate (the server's takeover act only, never an ordinary reconcile) and idempotent. Optional: hardware- adapter surfaces have no host graph to take over.
spare names the source NODES the sweep leaves alone (a leave-alone app, coexistence
spec amendment 2026-08-28); absent, nothing is spared.
Optionalspare: (sourceNode: string) => booleanhow many links were released, from how many distinct source nodes
Unlink a linked pair (given either half) back into two independent channels.
OptionalwouldWould adding the edge from → to close a routing loop that does not exist yet? Pure —
it does not mutate the desired graph. Asked BEFORE a patch lands so the resulting
warning can name the edge that closed the ring (which is also the edge a break may
safely cut). Optional, for the same reason as StructuralDsp.detectFeedbackLoops.
The structural-DSP capability the server drives — exactly the structural surface of import('@freemixer/audio-engine').SoftwareMixer. Declared here (not imported from the engine) so the server compiles against the contract before the engine merge lands, and so tests can supply a fake. The live
SoftwareMixersatisfies it structurally once it carries the 4-argsetSend+ thebuses()/dcas()/matrices()enumerators.