StreamState Class
Everything the transmitter holds about one stream: the configuration document the receiver sees (SSF 1.0 Section 8.1.1), the status (Section 8.1.2), and the subject bookkeeping the receiver drives through the subject endpoints (Section 8.1.3). An immutable snapshot - the store replaces whole states, so a half-applied update is unrepresentable.
public sealed record StreamState : System.IEquatable<Abblix.SharedSignals.Transmitter.StreamState>Inheritance System.Object → StreamState
Implements System.IEquatable<StreamState>
Remarks
The JSON member names are pinned rather than left to the property names, because a durable IStreamStore persists this type: without them a C# rename - a refactor with no wire consequence anywhere else - either breaks reading every stored registration or, for the optional members, silently resets it, so a stream a receiver had paused would come back enabled. The names are storage, not protocol: the document a receiver reads back is Configuration, which carries its own.
Properties
StreamState.AddedSubjects Property
The subjects the receiver added (SSF 1.0 Section 8.1.3.2). Under None these are the coverage; under All they undo earlier removals.
public System.Collections.Generic.IReadOnlyList<Abblix.SharedSignals.Transmitter.StreamSubject> AddedSubjects { get; init; }Property Value
System.Collections.Generic.IReadOnlyList<StreamSubject>
StreamState.Configuration Property
The stream's configuration document, exactly as the receiver reads it back.
public Abblix.SharedSignals.Model.StreamConfiguration Configuration { get; init; }Property Value
StreamState.LastVerificationRequestAt Property
When the receiver last triggered a verification event, the fact the "min_verification_interval" throttle is measured against (SSF 1.0 Sections 8.1.1, 8.1.4.2); null before the first trigger.
public System.Nullable<System.DateTimeOffset> LastVerificationRequestAt { get; init; }Property Value
System.Nullable<System.DateTimeOffset>
StreamState.ReceiverId Property
The identity of the receiver the stream belongs to, as the host's authentication established it. The transmitter may serve every receiver from the same endpoints and tell them apart by credentials (SSF 1.0 Section 8.1) - this is where that identity lands, and every management operation is scoped by it.
public string ReceiverId { get; init; }Property Value
StreamState.RemovedSubjects Property
The subjects the receiver removed (SSF 1.0 Section 8.1.3.3) - meaningful under All, where they carve subjects out of the default coverage.
public System.Collections.Generic.IReadOnlyList<Abblix.SecurityEvents.Subjects.SubjectIdentifier> RemovedSubjects { get; init; }Property Value
System.Collections.Generic.IReadOnlyList<Abblix.SecurityEvents.Subjects.SubjectIdentifier>
StreamState.Status Property
The stream's status value, one of StreamStatuses. A stream starts enabled: creating one is the receiver asking for events, and a default that needed a second call to start the flow would read as a broken stream.
public string Status { get; init; }Property Value
StreamState.StatusReason Property
Why the status is what it is, when anyone said (SSF 1.0 Section 8.1.2).
public string? StatusReason { get; init; }Property Value
StreamState.StreamId Property
The stream's identifier, read off the configuration - one value, one owner.
public string StreamId { get; }Property Value
StreamState.SubjectsMode Property
Which subjects the stream covers by default, fixed at creation from the transmitter's advertisement (SSF 1.0 Section 7.1).
public Abblix.SharedSignals.Transmitter.StreamSubjectsMode SubjectsMode { get; init; }Property Value
StreamState.Version Property
What the store's copy looked like when this one was read, so a write can tell whether anything happened in between.
public string? Version { get; init; }Property Value
Remarks
Every mutation of a stream is a read, a change in memory and a write back, and without this the write is unconditional: two calls adding a subject at once both read the same list, both write, both are answered 200, and one addition is gone. SSF 1.0 Section 9.1 tells a receiver that a success says nothing about what the transmitter did, so it never retries and never learns.
Opaque, and the store's to mint: a caller passes back what it was given, and UpdateAsync(StreamState, CancellationToken) refuses a write carrying anything else. Null belongs to a state that was built rather than read, which is why creation has its own method.