FA-61271 / Bond day-count conventions / Open access
Adjusted versus unadjusted accrual periods: the accrual end always equals the payment date · case 01
Unadjusted accrual periods gain or lose days whenever the payment date moves.
ROOT CAUSE
After computing the payment date the code overwrites the accrual end with it.
VERIFIED REPAIR
Keep the unadjusted end for accrual unless the flag requests adjustment.
Unsuccessful approach: Tying only the final period end to the payment date still distorts that period.
Case contract
Inputs an unadjusted schedule (first element is the accrual start), holidays and a flag. Business days are weekdays not in holidays; adjustment is modified following. For each period the payment date is the adjusted end date; accrual days use adjusted start and end if the flag is set, otherwise the unadjusted dates. Return [[payment date, accrual days], ...].
Why this case matters
Bond accrual and pricing systems depend on exact day-count arithmetic; a single-day error changes settlement cash.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime
N = 1
observations = []
def solve(dates, holidays, adjust_accrual):
H = {datetime.date(*h) for h in holidays}
def biz(x):
return x.weekday() < 5 and x not in H
def fwd(x):
while not biz(x):
x += datetime.timedelta(days=1)
return x
def bwd(x):
while not biz(x):
x -= datetime.timedelta(days=1)
return x
def mf(x):
f = fwd(x)
return f if f.month == x.month else bwd(x)
out = []
for i in range(1, len(dates)):
s = datetime.date(*dates[i - 1])
e = datetime.date(*dates[i])
pay = mf(e)
e = pay
if adjust_accrual:
s, e = mf(s), mf(e)
out.append([[pay.year, pay.month, pay.day], (e - s).days])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression accrual end source 1', [[[2020, 4, 30], [2020, 10, 30], [2021, 4, 30], [2021, 10, 30], [2022, 4, 30]], [[2020, 5, 2]], False], [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 182]]], ['regression accrual end source 2', [[[2026, 3, 28], [2026, 6, 28], [2026, 9, 28], [2026, 12, 28], [2027, 3, 28]], [[2027, 3, 28]], False], [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 90]]], ['partial repair probe 1', [[[2021, 4, 29], [2021, 5, 29]], [], False], [[[2021, 5, 31], 30]]], ['partial repair probe 2', [[[2022, 12, 31], [2023, 1, 31], [2023, 2, 28], [2023, 3, 31], [2023, 4, 30]], [[2023, 4, 2]], False], [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 30]]], ['normal control 1', [[[2023, 8, 30], [2023, 9, 30], [2023, 10, 30]], [], True], [[[2023, 9, 29], 30], [[2023, 10, 30], 31]]], ['normal control 2', [[[2023, 4, 8], [2023, 5, 8], [2023, 6, 8]], [], False], [[[2023, 5, 8], 30], [[2023, 6, 8], 31]]], ['normal control 3', [[[2023, 2, 28], [2023, 3, 28], [2023, 4, 28], [2023, 5, 28]], [[2023, 3, 2], [2023, 3, 29], [2023, 4, 29]], True], [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]]], ['normal control 4', [[[2022, 11, 26], [2023, 2, 26], [2023, 5, 26], [2023, 8, 26], [2023, 11, 26]], [], True], [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]]]], [['regression accrual end source 1', [[[2022, 10, 31], [2023, 1, 31], [2023, 4, 30]], [], False], [[[2023, 1, 31], 92], [[2023, 4, 28], 89]]], ['regression accrual end source 2', [[[2019, 7, 31], [2019, 8, 31], [2019, 9, 30], [2019, 10, 31], [2019, 11, 30]], [[2019, 9, 1], [2019, 10, 2]], False], [[[2019, 8, 30], 31], [[2019, 9, 30], 30], [[2019, 10, 31], 31], [[2019, 11, 29], 30]]], ['partial repair probe 1', [[[2025, 3, 8], [2025, 6, 8], [2025, 9, 8], [2025, 12, 8], [2026, 3, 8]], [[2025, 9, 9]], False], [[[2025, 6, 9], 92], [[2025, 9, 8], 92], [[2025, 12, 8], 91], [[2026, 3, 9], 90]]], ['partial repair probe 2', [[[2025, 8, 21], [2025, 9, 21], [2025, 10, 21], [2025, 11, 21], [2025, 12, 21]], [[2025, 10, 23], [2025, 11, 22], [2025, 12, 23]], False], [[[2025, 9, 22], 31], [[2025, 10, 21], 30], [[2025, 11, 21], 31], [[2025, 12, 22], 30]]], ['normal control 1', [[[2024, 3, 29], [2024, 4, 29], [2024, 5, 29]], [[2024, 3, 31]], False], [[[2024, 4, 29], 31], [[2024, 5, 29], 30]]], ['normal control 2', [[[2028, 10, 31], [2029, 4, 30], [2029, 10, 31]], [[2028, 10, 31]], True], [[[2029, 4, 30], 182], [[2029, 10, 31], 184]]], ['normal control 3', [[[2024, 2, 27], [2024, 3, 27]], [], False], [[[2024, 3, 27], 29]]], ['normal control 4', [[[2022, 11, 30], [2023, 2, 28], [2023, 5, 30], [2023, 8, 30]], [[2023, 3, 2]], False], [[[2023, 2, 28], 90], [[2023, 5, 30], 91], [[2023, 8, 30], 92]]]], [['regression accrual end source 1', [[[2029, 5, 31], [2029, 11, 30], [2030, 5, 31], [2030, 11, 30]], [[2030, 6, 1]], False], [[[2029, 11, 30], 183], [[2030, 5, 31], 182], [[2030, 11, 29], 183]]], ['regression accrual end source 2', [[[2024, 6, 29], [2024, 9, 29], [2024, 12, 29], [2025, 3, 29], [2025, 6, 29]], [[2024, 10, 1], [2025, 6, 30]], False], [[[2024, 9, 30], 92], [[2024, 12, 30], 91], [[2025, 3, 31], 90], [[2025, 6, 27], 92]]], ['partial repair probe 1', [[[2027, 5, 28], [2027, 11, 28]], [], False], [[[2027, 11, 29], 184]]], ['partial repair probe 2', [[[2026, 8, 15], [2026, 9, 15], [2026, 10, 15], [2026, 11, 15]], [], False], [[[2026, 9, 15], 31], [[2026, 10, 15], 30], [[2026, 11, 16], 31]]], ['normal control 1', [[[2029, 12, 12], [2030, 6, 12]], [[2029, 12, 13]], True], [[[2030, 6, 12], 182]]], ['normal control 2', [[[2025, 4, 30], [2025, 5, 30]], [], True], [[[2025, 5, 30], 30]]], ['normal control 3', [[[2030, 6, 29], [2030, 7, 29], [2030, 8, 29]], [[2030, 6, 30], [2030, 7, 31], [2030, 8, 31]], True], [[[2030, 7, 29], 31], [[2030, 8, 29], 31]]], ['normal control 4', [[[2027, 9, 11], [2028, 3, 11], [2028, 9, 11], [2029, 3, 11], [2029, 9, 11]], [[2028, 3, 11], [2028, 9, 12]], True], [[[2028, 3, 13], 182], [[2028, 9, 11], 182], [[2029, 3, 12], 182], [[2029, 9, 11], 183]]]], [['regression accrual end source 1', [[[2030, 8, 30], [2030, 11, 30], [2031, 2, 28], [2031, 5, 30], [2031, 8, 30]], [[2030, 9, 1], [2031, 5, 30], [2031, 9, 1]], False], [[[2030, 11, 29], 92], [[2031, 2, 28], 90], [[2031, 5, 29], 91], [[2031, 8, 29], 92]]], ['regression accrual end source 2', [[[2030, 5, 31], [2030, 6, 30], [2030, 7, 31], [2030, 8, 31], [2030, 9, 30]], [[2030, 7, 1]], False], [[[2030, 6, 28], 30], [[2030, 7, 31], 31], [[2030, 8, 30], 31], [[2030, 9, 30], 30]]], ['partial repair probe 1', [[[2024, 5, 14], [2024, 6, 14], [2024, 7, 14]], [[2024, 7, 14]], False], [[[2024, 6, 14], 31], [[2024, 7, 15], 30]]], ['partial repair probe 2', [[[2022, 7, 31], [2023, 1, 31], [2023, 7, 31]], [[2022, 8, 2], [2023, 7, 31]], False], [[[2023, 1, 31], 184], [[2023, 7, 28], 181]]], ['normal control 1', [[[2030, 10, 31], [2031, 1, 31], [2031, 4, 30]], [[2030, 11, 1]], False], [[[2031, 1, 31], 92], [[2031, 4, 30], 89]]], ['normal control 2', [[[2027, 5, 2], [2027, 8, 2], [2027, 11, 2]], [], False], [[[2027, 8, 2], 92], [[2027, 11, 2], 92]]], ['normal control 3', [[[2025, 9, 19], [2026, 3, 19], [2026, 9, 19], [2027, 3, 19]], [[2026, 9, 19]], True], [[[2026, 3, 19], 181], [[2026, 9, 21], 186], [[2027, 3, 19], 179]]], ['normal control 4', [[[2023, 3, 29], [2023, 9, 29], [2024, 3, 29], [2024, 9, 29], [2025, 3, 29]], [[2023, 3, 30]], True], [[[2023, 9, 29], 184], [[2024, 3, 29], 182], [[2024, 9, 30], 185], [[2025, 3, 31], 182]]]], [['regression accrual end source 1', [[[2024, 9, 30], [2024, 10, 30], [2024, 11, 30], [2024, 12, 30], [2025, 1, 30]], [[2024, 12, 30]], False], [[[2024, 10, 30], 30], [[2024, 11, 29], 31], [[2024, 12, 31], 30], [[2025, 1, 30], 31]]], ['regression accrual end source 2', [[[2026, 4, 3], [2026, 7, 3], [2026, 10, 3], [2027, 1, 3], [2027, 4, 3]], [[2026, 7, 5], [2027, 1, 4]], False], [[[2026, 7, 3], 91], [[2026, 10, 5], 92], [[2027, 1, 5], 92], [[2027, 4, 5], 90]]], ['partial repair probe 1', [[[2022, 4, 30], [2022, 7, 30], [2022, 10, 30]], [], False], [[[2022, 7, 29], 91], [[2022, 10, 31], 92]]], ['partial repair probe 2', [[[2019, 8, 1], [2020, 2, 1], [2020, 8, 1]], [[2020, 8, 1]], False], [[[2020, 2, 3], 184], [[2020, 8, 3], 182]]], ['normal control 1', [[[2028, 4, 29], [2028, 5, 29], [2028, 6, 29]], [[2028, 6, 30]], True], [[[2028, 5, 29], 31], [[2028, 6, 29], 31]]], ['normal control 2', [[[2024, 2, 28], [2024, 8, 28], [2025, 2, 28]], [[2024, 2, 28]], True], [[[2024, 8, 28], 181], [[2025, 2, 28], 184]]], ['normal control 3', [[[2023, 4, 29], [2023, 5, 29]], [], True], [[[2023, 5, 29], 31]]], ['normal control 4', [[[2021, 9, 7], [2021, 12, 7], [2022, 3, 7], [2022, 6, 7]], [[2021, 9, 7], [2022, 3, 9]], True], [[[2021, 12, 7], 90], [[2022, 3, 7], 90], [[2022, 6, 7], 92]]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
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 |
|---|---|---|---|
| regression accrual end source 1 | [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 182], [[2022, 4, 29], 181]] | [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 182]] | Failed |
| regression accrual end source 2 | [[[2026, 6, 29], 93], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 91]] | [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 90]] | Failed |
| partial repair probe 1 | [[[2021, 5, 31], 32]] | [[[2021, 5, 31], 30]] | Failed |
| partial repair probe 2 | [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 28]] | [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 30]] | Failed |
| normal control 1 | [[[2023, 9, 29], 30], [[2023, 10, 30], 31]] | [[[2023, 9, 29], 30], [[2023, 10, 30], 31]] | Passed |
| normal control 2 | [[[2023, 5, 8], 30], [[2023, 6, 8], 31]] | [[[2023, 5, 8], 30], [[2023, 6, 8], 31]] | Passed |
| normal control 3 | [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]] | [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]] | Passed |
| normal control 4 | [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]] | [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]] | Passed |
SHA-256 / 224e6d8ad156f5c1261166fce141d824bf000c5e04ed12b2c2782d4e8db97af4
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime
N = 1
observations = []
def solve(dates, holidays, adjust_accrual):
H = {datetime.date(*h) for h in holidays}
def biz(x):
return x.weekday() < 5 and x not in H
def fwd(x):
while not biz(x):
x += datetime.timedelta(days=1)
return x
def bwd(x):
while not biz(x):
x -= datetime.timedelta(days=1)
return x
def mf(x):
f = fwd(x)
return f if f.month == x.month else bwd(x)
out = []
for i in range(1, len(dates)):
s = datetime.date(*dates[i - 1])
e = datetime.date(*dates[i])
pay = mf(e)
e = pay if i == len(dates) - 1 else e
if adjust_accrual:
s, e = mf(s), mf(e)
out.append([[pay.year, pay.month, pay.day], (e - s).days])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression accrual end source 1', [[[2020, 4, 30], [2020, 10, 30], [2021, 4, 30], [2021, 10, 30], [2022, 4, 30]], [[2020, 5, 2]], False], [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 182]]], ['regression accrual end source 2', [[[2026, 3, 28], [2026, 6, 28], [2026, 9, 28], [2026, 12, 28], [2027, 3, 28]], [[2027, 3, 28]], False], [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 90]]], ['partial repair probe 1', [[[2021, 4, 29], [2021, 5, 29]], [], False], [[[2021, 5, 31], 30]]], ['partial repair probe 2', [[[2022, 12, 31], [2023, 1, 31], [2023, 2, 28], [2023, 3, 31], [2023, 4, 30]], [[2023, 4, 2]], False], [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 30]]], ['normal control 1', [[[2023, 8, 30], [2023, 9, 30], [2023, 10, 30]], [], True], [[[2023, 9, 29], 30], [[2023, 10, 30], 31]]], ['normal control 2', [[[2023, 4, 8], [2023, 5, 8], [2023, 6, 8]], [], False], [[[2023, 5, 8], 30], [[2023, 6, 8], 31]]], ['normal control 3', [[[2023, 2, 28], [2023, 3, 28], [2023, 4, 28], [2023, 5, 28]], [[2023, 3, 2], [2023, 3, 29], [2023, 4, 29]], True], [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]]], ['normal control 4', [[[2022, 11, 26], [2023, 2, 26], [2023, 5, 26], [2023, 8, 26], [2023, 11, 26]], [], True], [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]]]], [['regression accrual end source 1', [[[2022, 10, 31], [2023, 1, 31], [2023, 4, 30]], [], False], [[[2023, 1, 31], 92], [[2023, 4, 28], 89]]], ['regression accrual end source 2', [[[2019, 7, 31], [2019, 8, 31], [2019, 9, 30], [2019, 10, 31], [2019, 11, 30]], [[2019, 9, 1], [2019, 10, 2]], False], [[[2019, 8, 30], 31], [[2019, 9, 30], 30], [[2019, 10, 31], 31], [[2019, 11, 29], 30]]], ['partial repair probe 1', [[[2025, 3, 8], [2025, 6, 8], [2025, 9, 8], [2025, 12, 8], [2026, 3, 8]], [[2025, 9, 9]], False], [[[2025, 6, 9], 92], [[2025, 9, 8], 92], [[2025, 12, 8], 91], [[2026, 3, 9], 90]]], ['partial repair probe 2', [[[2025, 8, 21], [2025, 9, 21], [2025, 10, 21], [2025, 11, 21], [2025, 12, 21]], [[2025, 10, 23], [2025, 11, 22], [2025, 12, 23]], False], [[[2025, 9, 22], 31], [[2025, 10, 21], 30], [[2025, 11, 21], 31], [[2025, 12, 22], 30]]], ['normal control 1', [[[2024, 3, 29], [2024, 4, 29], [2024, 5, 29]], [[2024, 3, 31]], False], [[[2024, 4, 29], 31], [[2024, 5, 29], 30]]], ['normal control 2', [[[2028, 10, 31], [2029, 4, 30], [2029, 10, 31]], [[2028, 10, 31]], True], [[[2029, 4, 30], 182], [[2029, 10, 31], 184]]], ['normal control 3', [[[2024, 2, 27], [2024, 3, 27]], [], False], [[[2024, 3, 27], 29]]], ['normal control 4', [[[2022, 11, 30], [2023, 2, 28], [2023, 5, 30], [2023, 8, 30]], [[2023, 3, 2]], False], [[[2023, 2, 28], 90], [[2023, 5, 30], 91], [[2023, 8, 30], 92]]]], [['regression accrual end source 1', [[[2029, 5, 31], [2029, 11, 30], [2030, 5, 31], [2030, 11, 30]], [[2030, 6, 1]], False], [[[2029, 11, 30], 183], [[2030, 5, 31], 182], [[2030, 11, 29], 183]]], ['regression accrual end source 2', [[[2024, 6, 29], [2024, 9, 29], [2024, 12, 29], [2025, 3, 29], [2025, 6, 29]], [[2024, 10, 1], [2025, 6, 30]], False], [[[2024, 9, 30], 92], [[2024, 12, 30], 91], [[2025, 3, 31], 90], [[2025, 6, 27], 92]]], ['partial repair probe 1', [[[2027, 5, 28], [2027, 11, 28]], [], False], [[[2027, 11, 29], 184]]], ['partial repair probe 2', [[[2026, 8, 15], [2026, 9, 15], [2026, 10, 15], [2026, 11, 15]], [], False], [[[2026, 9, 15], 31], [[2026, 10, 15], 30], [[2026, 11, 16], 31]]], ['normal control 1', [[[2029, 12, 12], [2030, 6, 12]], [[2029, 12, 13]], True], [[[2030, 6, 12], 182]]], ['normal control 2', [[[2025, 4, 30], [2025, 5, 30]], [], True], [[[2025, 5, 30], 30]]], ['normal control 3', [[[2030, 6, 29], [2030, 7, 29], [2030, 8, 29]], [[2030, 6, 30], [2030, 7, 31], [2030, 8, 31]], True], [[[2030, 7, 29], 31], [[2030, 8, 29], 31]]], ['normal control 4', [[[2027, 9, 11], [2028, 3, 11], [2028, 9, 11], [2029, 3, 11], [2029, 9, 11]], [[2028, 3, 11], [2028, 9, 12]], True], [[[2028, 3, 13], 182], [[2028, 9, 11], 182], [[2029, 3, 12], 182], [[2029, 9, 11], 183]]]], [['regression accrual end source 1', [[[2030, 8, 30], [2030, 11, 30], [2031, 2, 28], [2031, 5, 30], [2031, 8, 30]], [[2030, 9, 1], [2031, 5, 30], [2031, 9, 1]], False], [[[2030, 11, 29], 92], [[2031, 2, 28], 90], [[2031, 5, 29], 91], [[2031, 8, 29], 92]]], ['regression accrual end source 2', [[[2030, 5, 31], [2030, 6, 30], [2030, 7, 31], [2030, 8, 31], [2030, 9, 30]], [[2030, 7, 1]], False], [[[2030, 6, 28], 30], [[2030, 7, 31], 31], [[2030, 8, 30], 31], [[2030, 9, 30], 30]]], ['partial repair probe 1', [[[2024, 5, 14], [2024, 6, 14], [2024, 7, 14]], [[2024, 7, 14]], False], [[[2024, 6, 14], 31], [[2024, 7, 15], 30]]], ['partial repair probe 2', [[[2022, 7, 31], [2023, 1, 31], [2023, 7, 31]], [[2022, 8, 2], [2023, 7, 31]], False], [[[2023, 1, 31], 184], [[2023, 7, 28], 181]]], ['normal control 1', [[[2030, 10, 31], [2031, 1, 31], [2031, 4, 30]], [[2030, 11, 1]], False], [[[2031, 1, 31], 92], [[2031, 4, 30], 89]]], ['normal control 2', [[[2027, 5, 2], [2027, 8, 2], [2027, 11, 2]], [], False], [[[2027, 8, 2], 92], [[2027, 11, 2], 92]]], ['normal control 3', [[[2025, 9, 19], [2026, 3, 19], [2026, 9, 19], [2027, 3, 19]], [[2026, 9, 19]], True], [[[2026, 3, 19], 181], [[2026, 9, 21], 186], [[2027, 3, 19], 179]]], ['normal control 4', [[[2023, 3, 29], [2023, 9, 29], [2024, 3, 29], [2024, 9, 29], [2025, 3, 29]], [[2023, 3, 30]], True], [[[2023, 9, 29], 184], [[2024, 3, 29], 182], [[2024, 9, 30], 185], [[2025, 3, 31], 182]]]], [['regression accrual end source 1', [[[2024, 9, 30], [2024, 10, 30], [2024, 11, 30], [2024, 12, 30], [2025, 1, 30]], [[2024, 12, 30]], False], [[[2024, 10, 30], 30], [[2024, 11, 29], 31], [[2024, 12, 31], 30], [[2025, 1, 30], 31]]], ['regression accrual end source 2', [[[2026, 4, 3], [2026, 7, 3], [2026, 10, 3], [2027, 1, 3], [2027, 4, 3]], [[2026, 7, 5], [2027, 1, 4]], False], [[[2026, 7, 3], 91], [[2026, 10, 5], 92], [[2027, 1, 5], 92], [[2027, 4, 5], 90]]], ['partial repair probe 1', [[[2022, 4, 30], [2022, 7, 30], [2022, 10, 30]], [], False], [[[2022, 7, 29], 91], [[2022, 10, 31], 92]]], ['partial repair probe 2', [[[2019, 8, 1], [2020, 2, 1], [2020, 8, 1]], [[2020, 8, 1]], False], [[[2020, 2, 3], 184], [[2020, 8, 3], 182]]], ['normal control 1', [[[2028, 4, 29], [2028, 5, 29], [2028, 6, 29]], [[2028, 6, 30]], True], [[[2028, 5, 29], 31], [[2028, 6, 29], 31]]], ['normal control 2', [[[2024, 2, 28], [2024, 8, 28], [2025, 2, 28]], [[2024, 2, 28]], True], [[[2024, 8, 28], 181], [[2025, 2, 28], 184]]], ['normal control 3', [[[2023, 4, 29], [2023, 5, 29]], [], True], [[[2023, 5, 29], 31]]], ['normal control 4', [[[2021, 9, 7], [2021, 12, 7], [2022, 3, 7], [2022, 6, 7]], [[2021, 9, 7], [2022, 3, 9]], True], [[[2021, 12, 7], 90], [[2022, 3, 7], 90], [[2022, 6, 7], 92]]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
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 |
|---|---|---|---|
| regression accrual end source 1 | [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 181]] | [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 182]] | Failed |
| regression accrual end source 2 | [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 91]] | [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 90]] | Failed |
| partial repair probe 1 | [[[2021, 5, 31], 32]] | [[[2021, 5, 31], 30]] | Failed |
| partial repair probe 2 | [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 28]] | [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 30]] | Failed |
| normal control 1 | [[[2023, 9, 29], 30], [[2023, 10, 30], 31]] | [[[2023, 9, 29], 30], [[2023, 10, 30], 31]] | Passed |
| normal control 2 | [[[2023, 5, 8], 30], [[2023, 6, 8], 31]] | [[[2023, 5, 8], 30], [[2023, 6, 8], 31]] | Passed |
| normal control 3 | [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]] | [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]] | Passed |
| normal control 4 | [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]] | [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]] | Passed |
SHA-256 / f9a1d367f1db061df3aa119c6c8b9d51a113b7f10eecc8d685fd16b7c6498244
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import datetime
N = 1
observations = []
def solve(dates, holidays, adjust_accrual):
H = {datetime.date(*h) for h in holidays}
def biz(x):
return x.weekday() < 5 and x not in H
def fwd(x):
while not biz(x):
x += datetime.timedelta(days=1)
return x
def bwd(x):
while not biz(x):
x -= datetime.timedelta(days=1)
return x
def mf(x):
f = fwd(x)
return f if f.month == x.month else bwd(x)
out = []
for i in range(1, len(dates)):
s = datetime.date(*dates[i - 1])
e = datetime.date(*dates[i])
pay = mf(e)
if adjust_accrual:
s, e = mf(s), mf(e)
out.append([[pay.year, pay.month, pay.day], (e - s).days])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression accrual end source 1', [[[2020, 4, 30], [2020, 10, 30], [2021, 4, 30], [2021, 10, 30], [2022, 4, 30]], [[2020, 5, 2]], False], [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 182]]], ['regression accrual end source 2', [[[2026, 3, 28], [2026, 6, 28], [2026, 9, 28], [2026, 12, 28], [2027, 3, 28]], [[2027, 3, 28]], False], [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 90]]], ['partial repair probe 1', [[[2021, 4, 29], [2021, 5, 29]], [], False], [[[2021, 5, 31], 30]]], ['partial repair probe 2', [[[2022, 12, 31], [2023, 1, 31], [2023, 2, 28], [2023, 3, 31], [2023, 4, 30]], [[2023, 4, 2]], False], [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 30]]], ['normal control 1', [[[2023, 8, 30], [2023, 9, 30], [2023, 10, 30]], [], True], [[[2023, 9, 29], 30], [[2023, 10, 30], 31]]], ['normal control 2', [[[2023, 4, 8], [2023, 5, 8], [2023, 6, 8]], [], False], [[[2023, 5, 8], 30], [[2023, 6, 8], 31]]], ['normal control 3', [[[2023, 2, 28], [2023, 3, 28], [2023, 4, 28], [2023, 5, 28]], [[2023, 3, 2], [2023, 3, 29], [2023, 4, 29]], True], [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]]], ['normal control 4', [[[2022, 11, 26], [2023, 2, 26], [2023, 5, 26], [2023, 8, 26], [2023, 11, 26]], [], True], [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]]]], [['regression accrual end source 1', [[[2022, 10, 31], [2023, 1, 31], [2023, 4, 30]], [], False], [[[2023, 1, 31], 92], [[2023, 4, 28], 89]]], ['regression accrual end source 2', [[[2019, 7, 31], [2019, 8, 31], [2019, 9, 30], [2019, 10, 31], [2019, 11, 30]], [[2019, 9, 1], [2019, 10, 2]], False], [[[2019, 8, 30], 31], [[2019, 9, 30], 30], [[2019, 10, 31], 31], [[2019, 11, 29], 30]]], ['partial repair probe 1', [[[2025, 3, 8], [2025, 6, 8], [2025, 9, 8], [2025, 12, 8], [2026, 3, 8]], [[2025, 9, 9]], False], [[[2025, 6, 9], 92], [[2025, 9, 8], 92], [[2025, 12, 8], 91], [[2026, 3, 9], 90]]], ['partial repair probe 2', [[[2025, 8, 21], [2025, 9, 21], [2025, 10, 21], [2025, 11, 21], [2025, 12, 21]], [[2025, 10, 23], [2025, 11, 22], [2025, 12, 23]], False], [[[2025, 9, 22], 31], [[2025, 10, 21], 30], [[2025, 11, 21], 31], [[2025, 12, 22], 30]]], ['normal control 1', [[[2024, 3, 29], [2024, 4, 29], [2024, 5, 29]], [[2024, 3, 31]], False], [[[2024, 4, 29], 31], [[2024, 5, 29], 30]]], ['normal control 2', [[[2028, 10, 31], [2029, 4, 30], [2029, 10, 31]], [[2028, 10, 31]], True], [[[2029, 4, 30], 182], [[2029, 10, 31], 184]]], ['normal control 3', [[[2024, 2, 27], [2024, 3, 27]], [], False], [[[2024, 3, 27], 29]]], ['normal control 4', [[[2022, 11, 30], [2023, 2, 28], [2023, 5, 30], [2023, 8, 30]], [[2023, 3, 2]], False], [[[2023, 2, 28], 90], [[2023, 5, 30], 91], [[2023, 8, 30], 92]]]], [['regression accrual end source 1', [[[2029, 5, 31], [2029, 11, 30], [2030, 5, 31], [2030, 11, 30]], [[2030, 6, 1]], False], [[[2029, 11, 30], 183], [[2030, 5, 31], 182], [[2030, 11, 29], 183]]], ['regression accrual end source 2', [[[2024, 6, 29], [2024, 9, 29], [2024, 12, 29], [2025, 3, 29], [2025, 6, 29]], [[2024, 10, 1], [2025, 6, 30]], False], [[[2024, 9, 30], 92], [[2024, 12, 30], 91], [[2025, 3, 31], 90], [[2025, 6, 27], 92]]], ['partial repair probe 1', [[[2027, 5, 28], [2027, 11, 28]], [], False], [[[2027, 11, 29], 184]]], ['partial repair probe 2', [[[2026, 8, 15], [2026, 9, 15], [2026, 10, 15], [2026, 11, 15]], [], False], [[[2026, 9, 15], 31], [[2026, 10, 15], 30], [[2026, 11, 16], 31]]], ['normal control 1', [[[2029, 12, 12], [2030, 6, 12]], [[2029, 12, 13]], True], [[[2030, 6, 12], 182]]], ['normal control 2', [[[2025, 4, 30], [2025, 5, 30]], [], True], [[[2025, 5, 30], 30]]], ['normal control 3', [[[2030, 6, 29], [2030, 7, 29], [2030, 8, 29]], [[2030, 6, 30], [2030, 7, 31], [2030, 8, 31]], True], [[[2030, 7, 29], 31], [[2030, 8, 29], 31]]], ['normal control 4', [[[2027, 9, 11], [2028, 3, 11], [2028, 9, 11], [2029, 3, 11], [2029, 9, 11]], [[2028, 3, 11], [2028, 9, 12]], True], [[[2028, 3, 13], 182], [[2028, 9, 11], 182], [[2029, 3, 12], 182], [[2029, 9, 11], 183]]]], [['regression accrual end source 1', [[[2030, 8, 30], [2030, 11, 30], [2031, 2, 28], [2031, 5, 30], [2031, 8, 30]], [[2030, 9, 1], [2031, 5, 30], [2031, 9, 1]], False], [[[2030, 11, 29], 92], [[2031, 2, 28], 90], [[2031, 5, 29], 91], [[2031, 8, 29], 92]]], ['regression accrual end source 2', [[[2030, 5, 31], [2030, 6, 30], [2030, 7, 31], [2030, 8, 31], [2030, 9, 30]], [[2030, 7, 1]], False], [[[2030, 6, 28], 30], [[2030, 7, 31], 31], [[2030, 8, 30], 31], [[2030, 9, 30], 30]]], ['partial repair probe 1', [[[2024, 5, 14], [2024, 6, 14], [2024, 7, 14]], [[2024, 7, 14]], False], [[[2024, 6, 14], 31], [[2024, 7, 15], 30]]], ['partial repair probe 2', [[[2022, 7, 31], [2023, 1, 31], [2023, 7, 31]], [[2022, 8, 2], [2023, 7, 31]], False], [[[2023, 1, 31], 184], [[2023, 7, 28], 181]]], ['normal control 1', [[[2030, 10, 31], [2031, 1, 31], [2031, 4, 30]], [[2030, 11, 1]], False], [[[2031, 1, 31], 92], [[2031, 4, 30], 89]]], ['normal control 2', [[[2027, 5, 2], [2027, 8, 2], [2027, 11, 2]], [], False], [[[2027, 8, 2], 92], [[2027, 11, 2], 92]]], ['normal control 3', [[[2025, 9, 19], [2026, 3, 19], [2026, 9, 19], [2027, 3, 19]], [[2026, 9, 19]], True], [[[2026, 3, 19], 181], [[2026, 9, 21], 186], [[2027, 3, 19], 179]]], ['normal control 4', [[[2023, 3, 29], [2023, 9, 29], [2024, 3, 29], [2024, 9, 29], [2025, 3, 29]], [[2023, 3, 30]], True], [[[2023, 9, 29], 184], [[2024, 3, 29], 182], [[2024, 9, 30], 185], [[2025, 3, 31], 182]]]], [['regression accrual end source 1', [[[2024, 9, 30], [2024, 10, 30], [2024, 11, 30], [2024, 12, 30], [2025, 1, 30]], [[2024, 12, 30]], False], [[[2024, 10, 30], 30], [[2024, 11, 29], 31], [[2024, 12, 31], 30], [[2025, 1, 30], 31]]], ['regression accrual end source 2', [[[2026, 4, 3], [2026, 7, 3], [2026, 10, 3], [2027, 1, 3], [2027, 4, 3]], [[2026, 7, 5], [2027, 1, 4]], False], [[[2026, 7, 3], 91], [[2026, 10, 5], 92], [[2027, 1, 5], 92], [[2027, 4, 5], 90]]], ['partial repair probe 1', [[[2022, 4, 30], [2022, 7, 30], [2022, 10, 30]], [], False], [[[2022, 7, 29], 91], [[2022, 10, 31], 92]]], ['partial repair probe 2', [[[2019, 8, 1], [2020, 2, 1], [2020, 8, 1]], [[2020, 8, 1]], False], [[[2020, 2, 3], 184], [[2020, 8, 3], 182]]], ['normal control 1', [[[2028, 4, 29], [2028, 5, 29], [2028, 6, 29]], [[2028, 6, 30]], True], [[[2028, 5, 29], 31], [[2028, 6, 29], 31]]], ['normal control 2', [[[2024, 2, 28], [2024, 8, 28], [2025, 2, 28]], [[2024, 2, 28]], True], [[[2024, 8, 28], 181], [[2025, 2, 28], 184]]], ['normal control 3', [[[2023, 4, 29], [2023, 5, 29]], [], True], [[[2023, 5, 29], 31]]], ['normal control 4', [[[2021, 9, 7], [2021, 12, 7], [2022, 3, 7], [2022, 6, 7]], [[2021, 9, 7], [2022, 3, 9]], True], [[[2021, 12, 7], 90], [[2022, 3, 7], 90], [[2022, 6, 7], 92]]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
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 |
|---|---|---|---|
| regression accrual end source 1 | [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 182]] | [[[2020, 10, 30], 183], [[2021, 4, 30], 182], [[2021, 10, 29], 183], [[2022, 4, 29], 182]] | Passed |
| regression accrual end source 2 | [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 90]] | [[[2026, 6, 29], 92], [[2026, 9, 28], 92], [[2026, 12, 28], 91], [[2027, 3, 29], 90]] | Passed |
| partial repair probe 1 | [[[2021, 5, 31], 30]] | [[[2021, 5, 31], 30]] | Passed |
| partial repair probe 2 | [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 30]] | [[[2023, 1, 31], 31], [[2023, 2, 28], 28], [[2023, 3, 31], 31], [[2023, 4, 28], 30]] | Passed |
| normal control 1 | [[[2023, 9, 29], 30], [[2023, 10, 30], 31]] | [[[2023, 9, 29], 30], [[2023, 10, 30], 31]] | Passed |
| normal control 2 | [[[2023, 5, 8], 30], [[2023, 6, 8], 31]] | [[[2023, 5, 8], 30], [[2023, 6, 8], 31]] | Passed |
| normal control 3 | [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]] | [[[2023, 3, 28], 28], [[2023, 4, 28], 31], [[2023, 5, 29], 31]] | Passed |
| normal control 4 | [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]] | [[[2023, 2, 27], 91], [[2023, 5, 26], 88], [[2023, 8, 28], 94], [[2023, 11, 27], 91]] | Passed |
SHA-256 / c285319975890a9beb8c2475622726a846f1c9d903699739ddd8007419ac94a5
Verification & scope
A deterministic toy contract stated explicitly in the contract field; no claim of conformance to any published convention text. 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:46:53.663012+00:00.
Case digest / c3ab05588cca0c913e46ff0a2110bba94ab29c438ba0379b74f088a73e16418b