Partition
Isolates runtime state. It decides which state machine receives an event and prevents unrelated entities or lanes from mutating the same active window.
Concepts
Segments are boundary context: when a segment value changes, the active window is split. Tags are descriptive context: they travel with the window without creating a new interval.
Problem
Operational state often changes context while staying active. A device can remain offline while an incident moves from triage to escalated. If that context matters analytically, one long window is too coarse. If it does not create a boundary, splitting the window creates noise.
Solution
Partition isolates runtime state. Segment changes split an active window and can be used in comparison scope. Tags attach descriptive metadata without creating a boundary.
.Window("DeviceOffline", window => window
.Key(update => update.DeviceId)
.ActiveWhen(update => update.IsOffline)
.Segment("lifecycle", lifecycle => lifecycle
.Value(update => update.Lifecycle)
.Child("stage", stage => stage.Value(update => update.Stage)))
.Tag("fleet", update => update.FleetId))
How it works
A segment is not just a label. It participates in the window boundary. If the active predicate stays true but the segment value changes, Spanfold closes the old active window and opens a new one with the new segment value. Tags do not do that; they describe the window without changing the interval shape.
Definitions
Isolates runtime state. It decides which state machine receives an event and prevents unrelated entities or lanes from mutating the same active window.
Splits windows when context changes. Use it for phases, lifecycle, market, deployment, or period boundaries that must be compared independently.
Describes a window without splitting it. Use it for fleet, customer, region, build number, or other metadata that should travel into exports and filters.
Example
Once segments and tags are recorded, they can be used in history queries, comparison scope, roll-up projection, and exports. Use segments when the answer should be measured inside a phase. Use tags when the same window should be discoverable by descriptive metadata.
var escalatedCritical = pipeline.History
.Compare("Escalated critical fleet QA")
.Target("primary", s => s.Source("primary"))
.Against("backup", s => s.Source("backup"))
.Within(scope => scope
.Window("DeviceOffline")
.Segment("lifecycle", "Incident")
.Segment("stage", "Escalated")
.Tag("fleet", "critical"))
.Using(c => c.Overlap().Residual().Missing())
.Run();