Skip to content

Fix connection lifetime, pin the build, gate on real OBS - #39

Merged
Agash merged 5 commits into
masterfrom
fix/audit-remediation
Sep 22, 2026
Merged

Agash merged 5 commits into
masterfrom
fix/audit-remediation

Conversation

@Agash

@Agash Agash commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Connection lifetime

The socket, serializer, receive cancellation, receive task and handshake state were separate fields
that could disagree. They are now one ObsConnectionContext, built per attempt from an immutable
settings snapshot and replaced whole. The serializer is selected from that snapshot, so changing
Format at runtime switches the wire format instead of reconnecting on the old one, and named
clients read the options monitor rather than a snapshot taken at registration.

  • ReidentifyAsync is single flight; Identified carries no request id, so concurrent operations
    cannot be matched to their replies.
  • MaxIncomingMessageBytes (64 MiB) is checked before each fragment is appended.
  • The hosted service coalesces configuration changes through a capacity-one channel and awaits the
    transition in StopAsync.
  • ConnectAsync no longer writes back onto shared monitored options.
  • A named-only container resolves; that path never registered ObsWebSocketMetrics.
  • New counters: obsws.events.dropped, obsws.messages.dropped.
  • MessagePack decodes from the transport buffer instead of a stream round trip.

Breaking: ObsWebSocketClient takes an ObsSerializerFactory instead of a serializer. Pass
_ => serializer to fix one. Keeping both constructors made AddSingleton<ObsWebSocketClient>()
ambiguous.

Build

protocol.json was gitignored and fetched from upstream master when absent, so a clean checkout
generated the public API from whatever upstream said that day. It is checked in, pinned by commit
and SHA-256 in protocol.lock.json, and verified on every build; only RefreshObsProtocol reaches
the network. The vendored file is byte-identical to the revision already in use, so no generated
source changed.

Toolchain moves to .NET 11 RC1 and C# 15, off LangVersion=latest and off preview roll-forward.

Verification

run-transport-tests rendered failures into a table and exited zero, so it could not gate anything.
It now reports a verdict and exits non-zero, and resolves input and filter kinds from the connected
OBS rather than assuming Windows-only ones. A new workflow installs OBS, runs it under Xvfb and
validates both transports.

The suite ships its fixtures rather than depending on the machine: a scene collection with a group
and a configurable transition for the CI runner, and a 17 KB clip so the media cursor requests have
something to seek. Outputs are enumerated once per cycle, since asking again after a state change
reads a freed encoder and takes OBS down (#25). Profiles are created, switched away from, then
removed, waiting for OBS to apply each step (#42).

The AOT gate dropped WarningsNotAsErrors=IL2104;IL3053, which excused exactly the aggregates that
hide trimming problems. It now itemises warnings, covers win-x64 as well as linux-x64, and fails
on any warning raised outside MessagePack. All 10 actions across 5 workflows are pinned to SHAs.

Testing

180 tests per TFM, green on net10 and net11, zero warnings. The regression tests for
re-identification and the size limit were each confirmed to fail with their fix reverted, and the
protocol hash gate to fail the build on a one-byte edit. Validated live against OBS on Windows over
both transports.

@Agash
Agash force-pushed the fix/audit-remediation branch from 0ace2a3 to df331d9 Compare September 17, 2026 07:03
@Agash Agash changed the title Address the independent audit findings Fix connection lifetime, pin the build, gate on real OBS Sep 17, 2026
@Agash
Agash force-pushed the fix/audit-remediation branch from df331d9 to 66399d5 Compare September 22, 2026 07:49
@Agash
Agash force-pushed the fix/audit-remediation branch 3 times, most recently from e4b3131 to 5784d45 Compare September 22, 2026 08:43
@Agash
Agash force-pushed the fix/audit-remediation branch from 5784d45 to 36576e6 Compare September 22, 2026 09:10
@Agash
Agash merged commit 99c19fe into master Sep 22, 2026
10 checks passed
@Agash
Agash deleted the fix/audit-remediation branch September 22, 2026 09:19
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