FA-61236 / Bond day-count conventions / Open access
30E+/360 end-of-month rollover: a start on the 31st is also rolled to the next month · case 01
Periods starting on the 31st are one day short.
ROOT CAUSE
The rollover rule is applied symmetrically to D1.
VERIFIED REPAIR
Clamp D1=31 to 30; only D2 rolls forward.
Unsuccessful approach: Clamping D1 only when the original end day is also 31 misses most periods.
Case contract
Inputs two dates [y,m,d]. If D1 is 31 it becomes 30. If D2 is 31 it becomes 1 and M2 increases by one (the formula absorbs a month 13). Return 360*(Y2-Y1)+30*(M2-M1)+(D2-D1).
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
N = 1
observations = []
def solve(a, b):
y1, m1, d1 = a
y2, m2, d2 = b
if d1 == 31:
d1 = 1
m1 += 1
if d2 == 31:
d2 = 1
m2 += 1
return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression start day treatment 1', [[2024, 12, 31], [2026, 3, 22]], 442], ['regression start day treatment 2', [[2042, 7, 31], [2042, 8, 31]], 31], ['partial repair probe 1', [[2042, 3, 31], [2042, 8, 5]], 125], ['partial repair probe 2', [[2023, 1, 31], [2024, 2, 29]], 389], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2030, 7, 9], [2031, 9, 20]], 431], ['normal control 2', [[2031, 10, 27], [2032, 6, 3]], 216]], [['regression start day treatment 1', [[2015, 1, 31], [2016, 8, 31]], 571], ['regression start day treatment 2', [[2022, 8, 31], [2022, 9, 30]], 30], ['partial repair probe 1', [[2028, 10, 31], [2030, 1, 13]], 433], ['partial repair probe 2', [[2030, 8, 31], [2031, 3, 13]], 193], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2027, 9, 27], [2029, 4, 30]], 573], ['normal control 2', [[2039, 11, 30], [2041, 12, 28]], 748]], [['regression start day treatment 1', [[2054, 7, 31], [2056, 1, 31]], 541], ['regression start day treatment 2', [[2007, 1, 31], [2008, 12, 31]], 691], ['partial repair probe 1', [[2017, 8, 31], [2019, 11, 2]], 782], ['partial repair probe 2', [[2028, 1, 31], [2030, 6, 30]], 870], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2000, 9, 30], [2002, 8, 1]], 661], ['normal control 2', [[2012, 1, 28], [2014, 11, 30]], 1022]], [['regression start day treatment 1', [[2059, 8, 31], [2059, 9, 29]], 29], ['regression start day treatment 2', [[2000, 10, 31], [2002, 3, 31]], 511], ['partial repair probe 1', [[2017, 12, 31], [2018, 1, 10]], 10], ['partial repair probe 2', [[2046, 12, 31], [2047, 12, 17]], 347], ['boundary control 1', [[2024, 1, 15], [2024, 1, 31]], 16], ['boundary control 2', [[2024, 2, 29], [2024, 3, 30]], 31], ['normal control 1', [[2042, 6, 30], [2043, 2, 7]], 217], ['normal control 2', [[2006, 5, 21], [2008, 1, 31]], 610]], [['regression start day treatment 1', [[2013, 7, 31], [2014, 12, 27]], 507], ['regression start day treatment 2', [[2004, 8, 31], [2006, 9, 1]], 721], ['partial repair probe 1', [[2047, 7, 31], [2049, 11, 23]], 833], ['partial repair probe 2', [[2023, 7, 31], [2025, 12, 19]], 859], ['boundary control 1', [[2024, 1, 15], [2024, 1, 31]], 16], ['boundary control 2', [[2024, 2, 29], [2024, 3, 30]], 31], ['normal control 1', [[2043, 3, 30], [2043, 9, 7]], 157], ['normal control 2', [[2055, 4, 30], [2057, 10, 1]], 871]]]
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 start day treatment 1 | 441 | 442 | Failed |
| regression start day treatment 2 | 30 | 31 | Failed |
| partial repair probe 1 | 124 | 125 | Failed |
| partial repair probe 2 | 388 | 389 | Failed |
| boundary control 1 | 31 | 31 | Passed |
| boundary control 2 | 16 | 16 | Passed |
| normal control 1 | 431 | 431 | Passed |
| normal control 2 | 216 | 216 | Passed |
SHA-256 / bf9e6b2dae8efbc75d3be26fd4681b6e1288c9e5afabbd856689cf0d9bbdf6cf
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(a, b):
y1, m1, d1 = a
y2, m2, d2 = b
if d1 == 31 and b[2] == 31:
d1 = 30
if d2 == 31:
d2 = 1
m2 += 1
return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression start day treatment 1', [[2024, 12, 31], [2026, 3, 22]], 442], ['regression start day treatment 2', [[2042, 7, 31], [2042, 8, 31]], 31], ['partial repair probe 1', [[2042, 3, 31], [2042, 8, 5]], 125], ['partial repair probe 2', [[2023, 1, 31], [2024, 2, 29]], 389], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2030, 7, 9], [2031, 9, 20]], 431], ['normal control 2', [[2031, 10, 27], [2032, 6, 3]], 216]], [['regression start day treatment 1', [[2015, 1, 31], [2016, 8, 31]], 571], ['regression start day treatment 2', [[2022, 8, 31], [2022, 9, 30]], 30], ['partial repair probe 1', [[2028, 10, 31], [2030, 1, 13]], 433], ['partial repair probe 2', [[2030, 8, 31], [2031, 3, 13]], 193], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2027, 9, 27], [2029, 4, 30]], 573], ['normal control 2', [[2039, 11, 30], [2041, 12, 28]], 748]], [['regression start day treatment 1', [[2054, 7, 31], [2056, 1, 31]], 541], ['regression start day treatment 2', [[2007, 1, 31], [2008, 12, 31]], 691], ['partial repair probe 1', [[2017, 8, 31], [2019, 11, 2]], 782], ['partial repair probe 2', [[2028, 1, 31], [2030, 6, 30]], 870], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2000, 9, 30], [2002, 8, 1]], 661], ['normal control 2', [[2012, 1, 28], [2014, 11, 30]], 1022]], [['regression start day treatment 1', [[2059, 8, 31], [2059, 9, 29]], 29], ['regression start day treatment 2', [[2000, 10, 31], [2002, 3, 31]], 511], ['partial repair probe 1', [[2017, 12, 31], [2018, 1, 10]], 10], ['partial repair probe 2', [[2046, 12, 31], [2047, 12, 17]], 347], ['boundary control 1', [[2024, 1, 15], [2024, 1, 31]], 16], ['boundary control 2', [[2024, 2, 29], [2024, 3, 30]], 31], ['normal control 1', [[2042, 6, 30], [2043, 2, 7]], 217], ['normal control 2', [[2006, 5, 21], [2008, 1, 31]], 610]], [['regression start day treatment 1', [[2013, 7, 31], [2014, 12, 27]], 507], ['regression start day treatment 2', [[2004, 8, 31], [2006, 9, 1]], 721], ['partial repair probe 1', [[2047, 7, 31], [2049, 11, 23]], 833], ['partial repair probe 2', [[2023, 7, 31], [2025, 12, 19]], 859], ['boundary control 1', [[2024, 1, 15], [2024, 1, 31]], 16], ['boundary control 2', [[2024, 2, 29], [2024, 3, 30]], 31], ['normal control 1', [[2043, 3, 30], [2043, 9, 7]], 157], ['normal control 2', [[2055, 4, 30], [2057, 10, 1]], 871]]]
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 start day treatment 1 | 441 | 442 | Failed |
| regression start day treatment 2 | 31 | 31 | Passed |
| partial repair probe 1 | 124 | 125 | Failed |
| partial repair probe 2 | 388 | 389 | Failed |
| boundary control 1 | 31 | 31 | Passed |
| boundary control 2 | 16 | 16 | Passed |
| normal control 1 | 431 | 431 | Passed |
| normal control 2 | 216 | 216 | Passed |
SHA-256 / af60ea8dac34c41337364240c4609bc39945e4319e50ed0e785c1ccaa6ac887c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(a, b):
y1, m1, d1 = a
y2, m2, d2 = b
if d1 == 31:
d1 = 30
if d2 == 31:
d2 = 1
m2 += 1
return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression start day treatment 1', [[2024, 12, 31], [2026, 3, 22]], 442], ['regression start day treatment 2', [[2042, 7, 31], [2042, 8, 31]], 31], ['partial repair probe 1', [[2042, 3, 31], [2042, 8, 5]], 125], ['partial repair probe 2', [[2023, 1, 31], [2024, 2, 29]], 389], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2030, 7, 9], [2031, 9, 20]], 431], ['normal control 2', [[2031, 10, 27], [2032, 6, 3]], 216]], [['regression start day treatment 1', [[2015, 1, 31], [2016, 8, 31]], 571], ['regression start day treatment 2', [[2022, 8, 31], [2022, 9, 30]], 30], ['partial repair probe 1', [[2028, 10, 31], [2030, 1, 13]], 433], ['partial repair probe 2', [[2030, 8, 31], [2031, 3, 13]], 193], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2027, 9, 27], [2029, 4, 30]], 573], ['normal control 2', [[2039, 11, 30], [2041, 12, 28]], 748]], [['regression start day treatment 1', [[2054, 7, 31], [2056, 1, 31]], 541], ['regression start day treatment 2', [[2007, 1, 31], [2008, 12, 31]], 691], ['partial repair probe 1', [[2017, 8, 31], [2019, 11, 2]], 782], ['partial repair probe 2', [[2028, 1, 31], [2030, 6, 30]], 870], ['boundary control 1', [[2024, 2, 29], [2024, 3, 30]], 31], ['boundary control 2', [[2024, 1, 15], [2024, 1, 31]], 16], ['normal control 1', [[2000, 9, 30], [2002, 8, 1]], 661], ['normal control 2', [[2012, 1, 28], [2014, 11, 30]], 1022]], [['regression start day treatment 1', [[2059, 8, 31], [2059, 9, 29]], 29], ['regression start day treatment 2', [[2000, 10, 31], [2002, 3, 31]], 511], ['partial repair probe 1', [[2017, 12, 31], [2018, 1, 10]], 10], ['partial repair probe 2', [[2046, 12, 31], [2047, 12, 17]], 347], ['boundary control 1', [[2024, 1, 15], [2024, 1, 31]], 16], ['boundary control 2', [[2024, 2, 29], [2024, 3, 30]], 31], ['normal control 1', [[2042, 6, 30], [2043, 2, 7]], 217], ['normal control 2', [[2006, 5, 21], [2008, 1, 31]], 610]], [['regression start day treatment 1', [[2013, 7, 31], [2014, 12, 27]], 507], ['regression start day treatment 2', [[2004, 8, 31], [2006, 9, 1]], 721], ['partial repair probe 1', [[2047, 7, 31], [2049, 11, 23]], 833], ['partial repair probe 2', [[2023, 7, 31], [2025, 12, 19]], 859], ['boundary control 1', [[2024, 1, 15], [2024, 1, 31]], 16], ['boundary control 2', [[2024, 2, 29], [2024, 3, 30]], 31], ['normal control 1', [[2043, 3, 30], [2043, 9, 7]], 157], ['normal control 2', [[2055, 4, 30], [2057, 10, 1]], 871]]]
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 start day treatment 1 | 442 | 442 | Passed |
| regression start day treatment 2 | 31 | 31 | Passed |
| partial repair probe 1 | 125 | 125 | Passed |
| partial repair probe 2 | 389 | 389 | Passed |
| boundary control 1 | 31 | 31 | Passed |
| boundary control 2 | 16 | 16 | Passed |
| normal control 1 | 431 | 431 | Passed |
| normal control 2 | 216 | 216 | Passed |
SHA-256 / 782f8753ee8b8bb67ac7f403110458fc6c7cddb7cf04644f4b68441ae214088f
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.483941+00:00.
Case digest / e562c6efee5b6f5963a0d896c1680b80d82b865033aeaa0a91239f5552b24b39