FA-276 / Runtime and resources / Open access
Callback duration accumulates into periodic task drift · case 01
A task sleeps a full period after finishing, or the attempted correction schedules overlapping callbacks.
ROOT CAUSE
Release times are derived from completion without preserving the original phase and nonoverlap policy.
VERIFIED REPAIR
Choose the first original-phase deadline at or after completion, strictly later than the preceding start.
Unsuccessful approach: Incrementing by exactly one period preserves phase but ignores missed deadlines after an overrun.
Case contract
Period is a positive integer, start and durations are nonnegative integers. The first callback starts at start. Later starts are the earliest start+k*period >= preceding completion and strictly greater than preceding start. Missed slots are skipped, not caught up. Return one start per duration.
Why this case matters
Models a fixed-phase periodic scheduler with nonoverlapping callbacks; it separates arithmetic policy from OS scheduling, clock drift, and real-time execution guarantees.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(period, start, durations):
times, current = [], start
for duration in durations:
times.append(current)
current += duration+period
return times
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('short callbacks do not accumulate drift', solve(10*N, 0, [N]*3), [0, 10*N, 20*N])
check('overrun skips expired slots', solve(10*N, 0, [25*N, N, N]), [0, 30*N, 40*N])
check('completion exactly on deadline', solve(10*N, 0, [10*N, N]), [0, 10*N])
check('zero-duration still waits a period', solve(N, 0, [0, 0, 0]), [0, N, 2*N])
check('nonzero initial phase preserved', solve(10*N, 3*N, [25*N, N, N]), [3*N, 33*N, 43*N])
check('no callbacks', solve(N, N, []), [])
check('single callback uses initial start', solve(N, 7*N, [100*N]), [7*N])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| short callbacks do not accumulate drift | [0, 11, 22] | [0, 10, 20] | Failed |
| overrun skips expired slots | [0, 35, 46] | [0, 30, 40] | Failed |
| completion exactly on deadline | [0, 20] | [0, 10] | Failed |
| zero-duration still waits a period | [0, 1, 2] | [0, 1, 2] | Passed |
| nonzero initial phase preserved | [3, 38, 49] | [3, 33, 43] | Failed |
| no callbacks | [] | [] | Passed |
| single callback uses initial start | [7] | [7] | Passed |
SHA-256 / a63c369fb4af8e8aa2d2eba1aa0d231a174bbb31efa58fd76cb3037c64cad6c9
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(period, start, durations):
return [start+i*period for i in range(len(durations))]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('short callbacks do not accumulate drift', solve(10*N, 0, [N]*3), [0, 10*N, 20*N])
check('overrun skips expired slots', solve(10*N, 0, [25*N, N, N]), [0, 30*N, 40*N])
check('completion exactly on deadline', solve(10*N, 0, [10*N, N]), [0, 10*N])
check('zero-duration still waits a period', solve(N, 0, [0, 0, 0]), [0, N, 2*N])
check('nonzero initial phase preserved', solve(10*N, 3*N, [25*N, N, N]), [3*N, 33*N, 43*N])
check('no callbacks', solve(N, N, []), [])
check('single callback uses initial start', solve(N, 7*N, [100*N]), [7*N])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| short callbacks do not accumulate drift | [0, 10, 20] | [0, 10, 20] | Passed |
| overrun skips expired slots | [0, 10, 20] | [0, 30, 40] | Failed |
| completion exactly on deadline | [0, 10] | [0, 10] | Passed |
| zero-duration still waits a period | [0, 1, 2] | [0, 1, 2] | Passed |
| nonzero initial phase preserved | [3, 13, 23] | [3, 33, 43] | Failed |
| no callbacks | [] | [] | Passed |
| single callback uses initial start | [7] | [7] | Passed |
SHA-256 / 37f47245ca578d2ca39323b4c4f17d14fcbae07652801a422f0f1ea7d594d17c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(period, start, durations):
times, slot = [], 0
for duration in durations:
current = start+slot*period
times.append(current)
completed = current+duration
slot = max(slot+1, (completed-start+period-1)//period)
return times
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('short callbacks do not accumulate drift', solve(10*N, 0, [N]*3), [0, 10*N, 20*N])
check('overrun skips expired slots', solve(10*N, 0, [25*N, N, N]), [0, 30*N, 40*N])
check('completion exactly on deadline', solve(10*N, 0, [10*N, N]), [0, 10*N])
check('zero-duration still waits a period', solve(N, 0, [0, 0, 0]), [0, N, 2*N])
check('nonzero initial phase preserved', solve(10*N, 3*N, [25*N, N, N]), [3*N, 33*N, 43*N])
check('no callbacks', solve(N, N, []), [])
check('single callback uses initial start', solve(N, 7*N, [100*N]), [7*N])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| short callbacks do not accumulate drift | [0, 10, 20] | [0, 10, 20] | Passed |
| overrun skips expired slots | [0, 30, 40] | [0, 30, 40] | Passed |
| completion exactly on deadline | [0, 10] | [0, 10] | Passed |
| zero-duration still waits a period | [0, 1, 2] | [0, 1, 2] | Passed |
| nonzero initial phase preserved | [3, 33, 43] | [3, 33, 43] | Passed |
| no callbacks | [] | [] | Passed |
| single callback uses initial start | [7] | [7] | Passed |
SHA-256 / fe5d579cc2759bea5826660ad90da1b274e30b5810068420fb44c8106cc62878
Verification & scope
This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:36:51.597394+00:00.
Case digest / cc94d8179fca17076565de39d7ea1c1d7a60f38649ad9167280aa78828461da0