Concepts

Roll child windows up to parent state.

Roll-ups aggregate many child keys into a parent key, such as devices to zones or zones to regions. Parent windows can then be queried, compared, exported, or explained like any other window.

Problem

Parent state is often implied by child state.

A zone may be offline because any device in it is offline. A region may be impacted because any zone is impacted. If every parent state is recalculated later in a separate reporting query, the parent timeline can drift away from the child evidence that created it.

Roll-ups record the parent state at the same temporal level as the child state. That means parent windows can be queried, compared, exported, and explained with the same APIs.

Solution

Declare parent activity from child contribution windows.

A roll-up watches the child windows produced by the pipeline and opens a parent window when the child aggregate satisfies the rule. The rule can be simple, such as active count greater than zero, or it can represent quorum, threshold, or health logic.

var pipeline = Spanfold.Spanfold
    .For<DeviceStateChanged>()
    .RecordWindows()
    .Window("DeviceOffline", window => window
        .Key(update => update.DeviceId)
        .ActiveWhen(update => update.IsOffline)
        .Segment("lifecycle", segment => segment.Value(update => update.Lifecycle)))
    .RollUp(
        "ZoneOffline",
        update => update.ZoneId,
        children => children.ActiveCount > 0,
        segments => segments.Preserve("lifecycle"))
    .RollUp(
        "RegionOffline",
        update => update.RegionId,
        children => children.ActiveCount > 0)
    .Build();

Mechanics

A roll-up is still a normal window.

Once created, the parent window is not a special report-only object. It has a window name, key, source, partition, temporal range, and segment context. That is what lets later concept layers reuse it.

Child contribution

Each child window contributes active or inactive evidence inside the parent key selected by the roll-up key expression.

Parent predicate

The roll-up rule evaluates the child aggregate, such as active count, required count, or another domain-specific threshold.

Parent window

When the predicate is true, Spanfold records a parent window that can be compared just like a directly recorded child window.

Chained roll-ups

A parent window can feed another parent level, such as device to zone to region, without changing how downstream comparisons work.

Segment projection

Choose which child context survives at parent level.

Segment projection is the important design choice. Preserving every child segment can make parent windows too fragmented. Dropping all segments can make the parent impossible to explain. Project only the context that still changes the parent-level question.

Preserve Keep a child segment dimension when it still defines meaningful parent boundaries.
Drop Ignore a child detail when it would create noise or over-split the parent window.
Rename Project child terminology into a parent-level vocabulary.
Transform Normalize segment values before they are emitted on the parent roll-up.