Scan-cycle observability¶
Gap capability: first-class statistics on cycle-time behaviour — percentiles, jitter, overrun counts — exposed without requiring users to build their own.
First-class statistics on cycle-time behaviour — percentiles, jitter, overrun counts — exposed without requiring users to build their own. |
The runtime shall report p50, p95, and p99 execute-duration percentiles
per registered task, computed over a sliding window whose size is
configurable at Percentile estimation uses a fixed, compile-time bucket histogram so the
per-sample update path is allocation-free (Allocation-free telemetry u... (REQ_0104),
Fixed-bucket histogram for ... (ADR_0060)). The reported percentile is the geometric midpoint
of the occupied bucket ( These percentiles are coarse telemetry for trend and shape, not threshold-grade figures. Any SLA, acceptance, commissioning, or regression decision shall instead use the exact windowed extremes of the exact-extreme SLO conformance gate (Exact-extreme SLO conforman... (REQ_0851)); the histogram is deliberately not authoritative for pass/fail. Tightening the percentile estimate itself to ≤ 1 % relative error is a separate, deferred concern tracked as Sub-octave percentile preci... (REQ_0852) (sub-octave buckets) — it is not on the production sign-off path. |
Any pass/fail decision on cycle-time behaviour — acceptance test,
commissioning sign-off, regression gate, or alarm threshold — shall be
evaluated against the exact windowed extremes the runtime retains,
never against the bucket-quantised percentiles of Per-task latency percentiles (REQ_0100). The
percentile histogram carries up to
The authoritative quantities, each an actual observed sample carrying no bucket-quantisation error and aged with the same sliding window as Per-task latency percentiles (REQ_0100), are:
All three are already exposed on both the pull snapshot and the push / NDJSON paths (Statistics query API (REQ_0103), Cyclictest-style benchmark ... (REQ_0111)). A jitter SLO of the form “max jitter ≤ X over the window” is therefore decidable exactly, today, with no dependency on the deferred histogram-precision work of Sub-octave percentile preci... (REQ_0852). This requirement records the policy that the exact path — not the estimate — is the gate. |
To make the percentile estimate of Per-task latency percentiles (REQ_0100) itself threshold-grade, the histogram shall bound percentile relative error at ≤ 1 % at bucket centroids across the range 100 ns … 10 s, while preserving the allocation-free, bounded-time per-sample update of Allocation-free telemetry u... (REQ_0104). This requires a sub-octave (log-linear / mantissa-subdivided) bucket layout in place of the shipped octave buckets. Verified by Sub-octave percentile accur... (TEST_0868). Until it lands, exact threshold decisions use the exact-extreme gate of Exact-extreme SLO conforman... (REQ_0851); this requirement only tightens the estimate and is not on the production sign-off path. Math note. The ≤ 1 % bound and “≥ 3 buckets per decade” are independent constraints, not equivalent ones. Three buckets per decade give ~factor-2 bucket width (≈ 40 % worst-case intra-bucket error); a ≤ 1 % centroid bound needs bucket edges in roughly a 1.02 ratio (~115 buckets per decade). The superseded wording of Per-task latency percentiles (REQ_0100) and the original Fixed-bucket histogram for ... (ADR_0060) consequence note conflated the two. |
The runtime shall report the maximum observed jitter — defined as the absolute difference between actual and declared scan period — per cyclic task, computed over the same sliding window as Per-task latency percentiles (REQ_0100). Lifetime maxima are out of scope; the reported value ages out with the window. |
The runtime shall expose a monotonic counter per task that increments
on each scan-cycle execution that exceeds the declared budget per
Per-task overrun fault tran... (REQ_0070). The counter shall not reset on
|
Cycle-cycle statistics shall be available via two distinct paths:
Both paths shall be allocation-free on the runtime side (see Allocation-free telemetry u... (REQ_0104)); allocations on the consumer side are out of scope. |
The runtime’s per-sample telemetry update path — the code that runs inside the dispatch loop’s timing hooks to update the histogram, max-jitter, and overrun counter — shall perform zero heap allocations and shall complete in bounded time. The update path’s worst-case runtime shall be dominated by the
histogram bucket-index computation (a |
In addition to the bucket-quantised percentiles of Per-task latency percentiles (REQ_0100), the runtime shall report the exact minimum and maximum execute-duration observed per registered task, over the same sliding window as Per-task latency percentiles (REQ_0100). “Exact” means the reported values are actual observed samples, not bucket centroids — the absolute worst-case sample is retained, not merely the top occupied bucket. The min/max shall age out with the window (lifetime extrema are out of
scope, consistent with Per-task maximum jitter (REQ_0101)). The implementation shall be
allocation-free per Allocation-free telemetry u... (REQ_0104); a fixed-capacity monotonic deque
(sized to the window at |
For each cyclic task, the runtime shall report deadline lateness —
the signed offset between the task’s actual task-logic start (the
Deadline lateness is distinct from the period jitter of
Per-task maximum jitter (REQ_0101): jitter captures the spread of the measured period
and is blind to a constant offset, whereas lateness captures steady
drift or constant offset from the grid. The reported aggregate shall
include at least the windowed maximum (most-late) lateness; the raw
per-cycle Grid anchoring. The nominal grid point for a cycle is
|
The runtime shall maintain, per cyclic task, a monotonic zero-indexed
This exists so the executor’s telemetry composes with a cyclic
connector’s (Connector cycle telemetry (FEAT_0038)): because the NC task fires exactly once
per bus cycle (one-network-one-process), the executor’s per-task
|
For each cyclic task, the runtime shall report per scan cycle the
number of nominal grid slots the dispatcher passed over unserved
between the slot served by the task’s previous dispatch and the slot
served by this dispatch (the skip-realign of Absolute-grid cyclic dispat... (REQ_0268)). The
count shall be The count shall be carried on the push observation of
Statistics query API (REQ_0103) (field |