FAILURE MAP
← Case archive

FA-61126 / Bond day-count conventions / Open access

Inflation-linked reference index interpolation: the first of the month is already interpolated one day · case 01

Reference CPI on the first of a month is not equal to the lagged monthly index.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The interpolation weight uses d instead of d-1.

VERIFIED REPAIR

Weight by (d-1)/days_in_month so the first of the month uses CPI(m-3) exactly.

Unsuccessful approach: Using (d-1)/(days-1) makes the last day of the month reach CPI(m-2) too early.

Case contract

Inputs a date [y,m,d], a map "YYYY-MM" to CPI level and a base index. RefCPI = CPI(m-3) + (d-1)/days_in_month(m) * (CPI(m-2) - CPI(m-3)), computed in Decimal and rounded half-up to 5 decimals; the index ratio is RefCPI/base rounded half-up to 5 decimals. Return both as strings.

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
from decimal import Decimal, ROUND_HALF_UP, ROUND_DOWN
N = 1
observations = []
def solve(date, cpi, base):
    y, m, d = date
    def key(k):
        t = y * 12 + (m - 1) - k
        return '%04d-%02d' % (t // 12, t % 12 + 1)
    def mlen(yy, mm):
        if mm == 2:
            return 29 if (yy % 4 == 0 and yy % 100 != 0) or yy % 400 == 0 else 28
        return 30 if mm in (4, 6, 9, 11) else 31
    c3 = Decimal(str(cpi[key(3)]))
    c2 = Decimal(str(cpi[key(2)]))
    ref = c3 + Decimal(d) / Decimal(mlen(y, m)) * (c2 - c3)
    q = Decimal('0.00001')
    ref = ref.quantize(q, rounding=ROUND_HALF_UP)
    ratio = (ref / Decimal(str(base))).quantize(q, rounding=ROUND_HALF_UP)
    return [str(ref), str(ratio)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression interpolation day offset 1', [[2015, 7, 31], {'2015-02': 247.653, '2015-03': 248.694, '2015-04': 248.565, '2015-05': 247.879, '2015-06': 249.358}, 257.82243], ['247.90113', '0.96152']], ['regression interpolation day offset 2', [[2018, 4, 15], {'2017-11': 220.4, '2017-12': 220.485, '2018-01': 220.937, '2018-02': 220.601, '2018-03': 222.044}, 252.59477], ['220.78020', '0.87405']], ['partial repair probe 1', [[2026, 10, 15], {'2026-05': 232.276, '2026-06': 231.882, '2026-07': 232.689, '2026-08': 234.192, '2026-09': 235.747}, 247.93617], ['233.36777', '0.94124']], ['partial repair probe 2', [[2025, 7, 15], {'2025-02': 301.192, '2025-03': 302.573, '2025-04': 302.224, '2025-05': 302.214, '2025-06': 302.044}, 196.43824], ['302.21948', '1.53850']], ['normal control 1', [[2015, 7, 15], {'2015-02': 299.377, '2015-03': 300.048, '2015-04': 300.855, '2015-05': 301.702, '2015-06': 303.261}, 231.82612], ['301.23752', '1.29941']], ['normal control 2', [[2013, 1, 31], {'2012-08': 313.376, '2012-09': 313.359, '2012-10': 313.818, '2012-11': 314.75, '2012-12': 315.575}, 275.01141], ['314.71994', '1.14439']], ['normal control 3', [[2016, 11, 30], {'2016-06': 296.587, '2016-07': 295.932, '2016-08': 297.411, '2016-09': 297.179, '2016-10': 297.192}, 217.28455], ['297.18673', '1.36773']], ['normal control 4', [[2017, 12, 18], {'2017-07': 275.904, '2017-08': 277.101, '2017-09': 276.38, '2017-10': 275.708, '2017-11': 276.439}, 214.76861], ['276.01148', '1.28516']]], [['regression interpolation day offset 1', [[2030, 3, 15], {'2029-10': 224.591, '2029-11': 224.062, '2029-12': 224.85, '2030-01': 224.538, '2030-02': 224.323}, 183.17393], ['224.70910', '1.22675']], ['regression interpolation day offset 2', [[2019, 12, 1], {'2019-07': 274.442, '2019-08': 275.065, '2019-09': 276.33, '2019-10': 277.714, '2019-11': 277.701}, 232.84007], ['276.33000', '1.18678']], ['partial repair probe 1', [[2028, 6, 30], {'2028-01': 300.533, '2028-02': 299.739, '2028-03': 299.033, '2028-04': 298.273, '2028-05': 297.802}, 244.41776], ['298.29833', '1.22044']], ['partial repair probe 2', [[2029, 10, 15], {'2029-05': 254.036, '2029-06': 255.363, '2029-07': 254.905, '2029-08': 254.154, '2029-09': 253.538}, 190.14839], ['254.56584', '1.33877']], ['normal control 1', [[2030, 1, 31], {'2029-08': 258.182, '2029-09': 259.038, '2029-10': 260.528, '2029-11': 261.089, '2029-12': 260.528}, 239.9153], ['261.07090', '1.08818']], ['normal control 2', [[2025, 6, 2], {'2025-01': 234.405, '2025-02': 234.265, '2025-03': 233.979, '2025-04': 233.989, '2025-05': 235.1}, 191.02195], ['233.97933', '1.22488']], ['normal control 3', [[2027, 4, 12], {'2026-11': 251.107, '2026-12': 251.901, '2027-01': 251.899, '2027-02': 251.326, '2027-03': 250.898}, 281.48739], ['251.68890', '0.89414']], ['normal control 4', [[2017, 2, 1], {'2016-09': 309.163, '2016-10': 310.317, '2016-11': 310.08, '2016-12': 310.547, '2017-01': 311.286}, 258.21573], ['310.08000', '1.20086']]], [['regression interpolation day offset 1', [[2019, 12, 15], {'2019-07': 311.195, '2019-08': 311.486, '2019-09': 311.589, '2019-10': 312.364, '2019-11': 312.338}, 239.56499], ['311.93900', '1.30211']], ['regression interpolation day offset 2', [[2027, 6, 30], {'2027-01': 311.935, '2027-02': 311.81, '2027-03': 311.473, '2027-04': 311.272, '2027-05': 310.565}, 225.11473], ['311.27870', '1.38276']], ['partial repair probe 1', [[2020, 5, 15], {'2019-12': 260.644, '2020-01': 260.047, '2020-02': 260.119, '2020-03': 259.74, '2020-04': 259.666}, 263.8179], ['259.94784', '0.98533']], ['partial repair probe 2', [[2019, 2, 13], {'2018-09': 245.604, '2018-10': 247.024, '2018-11': 247.211, '2018-12': 248.387, '2019-01': 248.701}, 195.73715], ['247.71500', '1.26555']], ['normal control 1', [[2017, 9, 15], {'2017-04': 301.564, '2017-05': 301.466, '2017-06': 303.013, '2017-07': 303.006, '2017-08': 302.924}, 267.09526], ['303.00973', '1.13446']], ['normal control 2', [[2015, 7, 31], {'2015-02': 250.431, '2015-03': 250.107, '2015-04': 250.764, '2015-05': 250.87, '2015-06': 251.196}, 257.20943], ['250.86658', '0.97534']], ['normal control 3', [[2018, 4, 1], {'2017-11': 249.424, '2017-12': 250.548, '2018-01': 250.083, '2018-02': 250.39, '2018-03': 250.521}, 290.7034], ['250.08300', '0.86027']], ['normal control 4', [[2017, 6, 1], {'2017-01': 253.846, '2017-02': 254.082, '2017-03': 254.63, '2017-04': 255.282, '2017-05': 255.199}, 224.26428], ['254.63000', '1.13540']]], [['regression interpolation day offset 1', [[2013, 5, 1], {'2012-12': 287.816, '2013-01': 289.172, '2013-02': 288.577, '2013-03': 289.409, '2013-04': 290.766}, 191.02402], ['288.57700', '1.51068']], ['regression interpolation day offset 2', [[2031, 8, 1], {'2031-03': 293.421, '2031-04': 293.712, '2031-05': 294.986, '2031-06': 296.543, '2031-07': 296.273}, 287.20407], ['294.98600', '1.02710']], ['partial repair probe 1', [[2014, 1, 15], {'2013-08': 296.218, '2013-09': 295.96, '2013-10': 296.22, '2013-11': 295.831, '2013-12': 295.299}, 248.00937], ['296.04432', '1.19368']], ['partial repair probe 2', [[2029, 5, 10], {'2028-12': 288.774, '2029-01': 288.334, '2029-02': 287.591, '2029-03': 288.258, '2029-04': 288.933}, 295.81162], ['287.78465', '0.97286']], ['normal control 1', [[2015, 9, 15], {'2015-04': 260.345, '2015-05': 259.934, '2015-06': 260.142, '2015-07': 260.521, '2015-08': 261.74}, 224.49854], ['260.31887', '1.15956']], ['normal control 2', [[2012, 7, 15], {'2012-02': 262.929, '2012-03': 262.405, '2012-04': 263.942, '2012-05': 263.254, '2012-06': 262.605}, 241.79755], ['263.63129', '1.09030']], ['normal control 3', [[2021, 5, 31], {'2020-12': 248.557, '2021-01': 248.801, '2021-02': 250.327, '2021-03': 251.728, '2021-04': 251.515}, 270.76185], ['251.68281', '0.92954']], ['normal control 4', [[2016, 3, 1], {'2015-10': 245.296, '2015-11': 246.265, '2015-12': 247.039, '2016-01': 247.869, '2016-02': 247.934}, 236.03855], ['247.03900', '1.04660']]], [['regression interpolation day offset 1', [[2029, 6, 1], {'2029-01': 271.912, '2029-02': 272.107, '2029-03': 271.484, '2029-04': 272.182, '2029-05': 273.543}, 214.97507], ['271.48400', '1.26286']], ['regression interpolation day offset 2', [[2029, 3, 1], {'2028-10': 320.154, '2028-11': 320.519, '2028-12': 321.052, '2029-01': 320.333, '2029-02': 319.876}, 202.02671], ['321.05200', '1.58916']], ['partial repair probe 1', [[2021, 10, 7], {'2021-05': 317.506, '2021-06': 318.632, '2021-07': 318.365, '2021-08': 319.67, '2021-09': 320.939}, 220.79376], ['318.61758', '1.44306']], ['partial repair probe 2', [[2029, 10, 31], {'2029-05': 244.749, '2029-06': 244.349, '2029-07': 245.206, '2029-08': 244.591, '2029-09': 245.093}, 263.99626], ['244.61084', '0.92657']], ['normal control 1', [[2025, 12, 15], {'2025-07': 254.829, '2025-08': 254.915, '2025-09': 255.609, '2025-10': 256.99, '2025-11': 257.355}, 191.978], ['256.23268', '1.33470']], ['normal control 2', [[2020, 5, 1], {'2019-12': 249.479, '2020-01': 249.403, '2020-02': 250.265, '2020-03': 250.188, '2020-04': 249.804}, 267.33985], ['250.26500', '0.93613']], ['normal control 3', [[2032, 8, 1], {'2032-03': 319.308, '2032-04': 319.144, '2032-05': 320.071, '2032-06': 320.854, '2032-07': 321.536}, 220.40726], ['320.07100', '1.45218']], ['normal control 4', [[2026, 6, 30], {'2026-01': 264.473, '2026-02': 264.165, '2026-03': 264.808, '2026-04': 265.488, '2026-05': 266.87}, 249.03984], ['265.46533', '1.06596']]]]
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 fixtureActualExpectedOutcome
regression interpolation day offset 1['247.87900', '0.96143']['247.90113', '0.96152']Failed
regression interpolation day offset 2['220.76900', '0.87400']['220.78020', '0.87405']Failed
partial repair probe 1['233.41626', '0.94144']['233.36777', '0.94124']Failed
partial repair probe 2['302.21916', '1.53849']['302.21948', '1.53850']Failed
normal control 1['301.26484', '1.29953']['301.23752', '1.29941']Failed
normal control 2['314.75000', '1.14450']['314.71994', '1.14439']Failed
normal control 3['297.17900', '1.36770']['297.18673', '1.36773']Failed
normal control 4['275.98981', '1.28506']['276.01148', '1.28516']Failed

SHA-256 / d2ac23ea36ceda59a6099226975dfb09826e181490f432083fc22fdbe64a0b5c

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_UP, ROUND_DOWN
N = 1
observations = []
def solve(date, cpi, base):
    y, m, d = date
    def key(k):
        t = y * 12 + (m - 1) - k
        return '%04d-%02d' % (t // 12, t % 12 + 1)
    def mlen(yy, mm):
        if mm == 2:
            return 29 if (yy % 4 == 0 and yy % 100 != 0) or yy % 400 == 0 else 28
        return 30 if mm in (4, 6, 9, 11) else 31
    c3 = Decimal(str(cpi[key(3)]))
    c2 = Decimal(str(cpi[key(2)]))
    ref = c3 + Decimal(d - 1) / Decimal(mlen(y, m) - 1) * (c2 - c3)
    q = Decimal('0.00001')
    ref = ref.quantize(q, rounding=ROUND_HALF_UP)
    ratio = (ref / Decimal(str(base))).quantize(q, rounding=ROUND_HALF_UP)
    return [str(ref), str(ratio)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression interpolation day offset 1', [[2015, 7, 31], {'2015-02': 247.653, '2015-03': 248.694, '2015-04': 248.565, '2015-05': 247.879, '2015-06': 249.358}, 257.82243], ['247.90113', '0.96152']], ['regression interpolation day offset 2', [[2018, 4, 15], {'2017-11': 220.4, '2017-12': 220.485, '2018-01': 220.937, '2018-02': 220.601, '2018-03': 222.044}, 252.59477], ['220.78020', '0.87405']], ['partial repair probe 1', [[2026, 10, 15], {'2026-05': 232.276, '2026-06': 231.882, '2026-07': 232.689, '2026-08': 234.192, '2026-09': 235.747}, 247.93617], ['233.36777', '0.94124']], ['partial repair probe 2', [[2025, 7, 15], {'2025-02': 301.192, '2025-03': 302.573, '2025-04': 302.224, '2025-05': 302.214, '2025-06': 302.044}, 196.43824], ['302.21948', '1.53850']], ['normal control 1', [[2015, 7, 15], {'2015-02': 299.377, '2015-03': 300.048, '2015-04': 300.855, '2015-05': 301.702, '2015-06': 303.261}, 231.82612], ['301.23752', '1.29941']], ['normal control 2', [[2013, 1, 31], {'2012-08': 313.376, '2012-09': 313.359, '2012-10': 313.818, '2012-11': 314.75, '2012-12': 315.575}, 275.01141], ['314.71994', '1.14439']], ['normal control 3', [[2016, 11, 30], {'2016-06': 296.587, '2016-07': 295.932, '2016-08': 297.411, '2016-09': 297.179, '2016-10': 297.192}, 217.28455], ['297.18673', '1.36773']], ['normal control 4', [[2017, 12, 18], {'2017-07': 275.904, '2017-08': 277.101, '2017-09': 276.38, '2017-10': 275.708, '2017-11': 276.439}, 214.76861], ['276.01148', '1.28516']]], [['regression interpolation day offset 1', [[2030, 3, 15], {'2029-10': 224.591, '2029-11': 224.062, '2029-12': 224.85, '2030-01': 224.538, '2030-02': 224.323}, 183.17393], ['224.70910', '1.22675']], ['regression interpolation day offset 2', [[2019, 12, 1], {'2019-07': 274.442, '2019-08': 275.065, '2019-09': 276.33, '2019-10': 277.714, '2019-11': 277.701}, 232.84007], ['276.33000', '1.18678']], ['partial repair probe 1', [[2028, 6, 30], {'2028-01': 300.533, '2028-02': 299.739, '2028-03': 299.033, '2028-04': 298.273, '2028-05': 297.802}, 244.41776], ['298.29833', '1.22044']], ['partial repair probe 2', [[2029, 10, 15], {'2029-05': 254.036, '2029-06': 255.363, '2029-07': 254.905, '2029-08': 254.154, '2029-09': 253.538}, 190.14839], ['254.56584', '1.33877']], ['normal control 1', [[2030, 1, 31], {'2029-08': 258.182, '2029-09': 259.038, '2029-10': 260.528, '2029-11': 261.089, '2029-12': 260.528}, 239.9153], ['261.07090', '1.08818']], ['normal control 2', [[2025, 6, 2], {'2025-01': 234.405, '2025-02': 234.265, '2025-03': 233.979, '2025-04': 233.989, '2025-05': 235.1}, 191.02195], ['233.97933', '1.22488']], ['normal control 3', [[2027, 4, 12], {'2026-11': 251.107, '2026-12': 251.901, '2027-01': 251.899, '2027-02': 251.326, '2027-03': 250.898}, 281.48739], ['251.68890', '0.89414']], ['normal control 4', [[2017, 2, 1], {'2016-09': 309.163, '2016-10': 310.317, '2016-11': 310.08, '2016-12': 310.547, '2017-01': 311.286}, 258.21573], ['310.08000', '1.20086']]], [['regression interpolation day offset 1', [[2019, 12, 15], {'2019-07': 311.195, '2019-08': 311.486, '2019-09': 311.589, '2019-10': 312.364, '2019-11': 312.338}, 239.56499], ['311.93900', '1.30211']], ['regression interpolation day offset 2', [[2027, 6, 30], {'2027-01': 311.935, '2027-02': 311.81, '2027-03': 311.473, '2027-04': 311.272, '2027-05': 310.565}, 225.11473], ['311.27870', '1.38276']], ['partial repair probe 1', [[2020, 5, 15], {'2019-12': 260.644, '2020-01': 260.047, '2020-02': 260.119, '2020-03': 259.74, '2020-04': 259.666}, 263.8179], ['259.94784', '0.98533']], ['partial repair probe 2', [[2019, 2, 13], {'2018-09': 245.604, '2018-10': 247.024, '2018-11': 247.211, '2018-12': 248.387, '2019-01': 248.701}, 195.73715], ['247.71500', '1.26555']], ['normal control 1', [[2017, 9, 15], {'2017-04': 301.564, '2017-05': 301.466, '2017-06': 303.013, '2017-07': 303.006, '2017-08': 302.924}, 267.09526], ['303.00973', '1.13446']], ['normal control 2', [[2015, 7, 31], {'2015-02': 250.431, '2015-03': 250.107, '2015-04': 250.764, '2015-05': 250.87, '2015-06': 251.196}, 257.20943], ['250.86658', '0.97534']], ['normal control 3', [[2018, 4, 1], {'2017-11': 249.424, '2017-12': 250.548, '2018-01': 250.083, '2018-02': 250.39, '2018-03': 250.521}, 290.7034], ['250.08300', '0.86027']], ['normal control 4', [[2017, 6, 1], {'2017-01': 253.846, '2017-02': 254.082, '2017-03': 254.63, '2017-04': 255.282, '2017-05': 255.199}, 224.26428], ['254.63000', '1.13540']]], [['regression interpolation day offset 1', [[2013, 5, 1], {'2012-12': 287.816, '2013-01': 289.172, '2013-02': 288.577, '2013-03': 289.409, '2013-04': 290.766}, 191.02402], ['288.57700', '1.51068']], ['regression interpolation day offset 2', [[2031, 8, 1], {'2031-03': 293.421, '2031-04': 293.712, '2031-05': 294.986, '2031-06': 296.543, '2031-07': 296.273}, 287.20407], ['294.98600', '1.02710']], ['partial repair probe 1', [[2014, 1, 15], {'2013-08': 296.218, '2013-09': 295.96, '2013-10': 296.22, '2013-11': 295.831, '2013-12': 295.299}, 248.00937], ['296.04432', '1.19368']], ['partial repair probe 2', [[2029, 5, 10], {'2028-12': 288.774, '2029-01': 288.334, '2029-02': 287.591, '2029-03': 288.258, '2029-04': 288.933}, 295.81162], ['287.78465', '0.97286']], ['normal control 1', [[2015, 9, 15], {'2015-04': 260.345, '2015-05': 259.934, '2015-06': 260.142, '2015-07': 260.521, '2015-08': 261.74}, 224.49854], ['260.31887', '1.15956']], ['normal control 2', [[2012, 7, 15], {'2012-02': 262.929, '2012-03': 262.405, '2012-04': 263.942, '2012-05': 263.254, '2012-06': 262.605}, 241.79755], ['263.63129', '1.09030']], ['normal control 3', [[2021, 5, 31], {'2020-12': 248.557, '2021-01': 248.801, '2021-02': 250.327, '2021-03': 251.728, '2021-04': 251.515}, 270.76185], ['251.68281', '0.92954']], ['normal control 4', [[2016, 3, 1], {'2015-10': 245.296, '2015-11': 246.265, '2015-12': 247.039, '2016-01': 247.869, '2016-02': 247.934}, 236.03855], ['247.03900', '1.04660']]], [['regression interpolation day offset 1', [[2029, 6, 1], {'2029-01': 271.912, '2029-02': 272.107, '2029-03': 271.484, '2029-04': 272.182, '2029-05': 273.543}, 214.97507], ['271.48400', '1.26286']], ['regression interpolation day offset 2', [[2029, 3, 1], {'2028-10': 320.154, '2028-11': 320.519, '2028-12': 321.052, '2029-01': 320.333, '2029-02': 319.876}, 202.02671], ['321.05200', '1.58916']], ['partial repair probe 1', [[2021, 10, 7], {'2021-05': 317.506, '2021-06': 318.632, '2021-07': 318.365, '2021-08': 319.67, '2021-09': 320.939}, 220.79376], ['318.61758', '1.44306']], ['partial repair probe 2', [[2029, 10, 31], {'2029-05': 244.749, '2029-06': 244.349, '2029-07': 245.206, '2029-08': 244.591, '2029-09': 245.093}, 263.99626], ['244.61084', '0.92657']], ['normal control 1', [[2025, 12, 15], {'2025-07': 254.829, '2025-08': 254.915, '2025-09': 255.609, '2025-10': 256.99, '2025-11': 257.355}, 191.978], ['256.23268', '1.33470']], ['normal control 2', [[2020, 5, 1], {'2019-12': 249.479, '2020-01': 249.403, '2020-02': 250.265, '2020-03': 250.188, '2020-04': 249.804}, 267.33985], ['250.26500', '0.93613']], ['normal control 3', [[2032, 8, 1], {'2032-03': 319.308, '2032-04': 319.144, '2032-05': 320.071, '2032-06': 320.854, '2032-07': 321.536}, 220.40726], ['320.07100', '1.45218']], ['normal control 4', [[2026, 6, 30], {'2026-01': 264.473, '2026-02': 264.165, '2026-03': 264.808, '2026-04': 265.488, '2026-05': 266.87}, 249.03984], ['265.46533', '1.06596']]]]
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 fixtureActualExpectedOutcome
regression interpolation day offset 1['247.87900', '0.96143']['247.90113', '0.96152']Failed
regression interpolation day offset 2['220.77479', '0.87403']['220.78020', '0.87405']Failed
partial repair probe 1['233.39040', '0.94133']['233.36777', '0.94124']Failed
partial repair probe 2['302.21933', '1.53850']['302.21948', '1.53850']Failed
normal control 1['301.25027', '1.29947']['301.23752', '1.29941']Failed
normal control 2['314.75000', '1.14450']['314.71994', '1.14439']Failed
normal control 3['297.17900', '1.36770']['297.18673', '1.36773']Failed
normal control 4['275.99920', '1.28510']['276.01148', '1.28516']Failed

SHA-256 / feab1e5027c206ed09494cc3fe20cb8bce4e2585c9460397688d51e72e61db7d

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_UP, ROUND_DOWN
N = 1
observations = []
def solve(date, cpi, base):
    y, m, d = date
    def key(k):
        t = y * 12 + (m - 1) - k
        return '%04d-%02d' % (t // 12, t % 12 + 1)
    def mlen(yy, mm):
        if mm == 2:
            return 29 if (yy % 4 == 0 and yy % 100 != 0) or yy % 400 == 0 else 28
        return 30 if mm in (4, 6, 9, 11) else 31
    c3 = Decimal(str(cpi[key(3)]))
    c2 = Decimal(str(cpi[key(2)]))
    ref = c3 + Decimal(d - 1) / Decimal(mlen(y, m)) * (c2 - c3)
    q = Decimal('0.00001')
    ref = ref.quantize(q, rounding=ROUND_HALF_UP)
    ratio = (ref / Decimal(str(base))).quantize(q, rounding=ROUND_HALF_UP)
    return [str(ref), str(ratio)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression interpolation day offset 1', [[2015, 7, 31], {'2015-02': 247.653, '2015-03': 248.694, '2015-04': 248.565, '2015-05': 247.879, '2015-06': 249.358}, 257.82243], ['247.90113', '0.96152']], ['regression interpolation day offset 2', [[2018, 4, 15], {'2017-11': 220.4, '2017-12': 220.485, '2018-01': 220.937, '2018-02': 220.601, '2018-03': 222.044}, 252.59477], ['220.78020', '0.87405']], ['partial repair probe 1', [[2026, 10, 15], {'2026-05': 232.276, '2026-06': 231.882, '2026-07': 232.689, '2026-08': 234.192, '2026-09': 235.747}, 247.93617], ['233.36777', '0.94124']], ['partial repair probe 2', [[2025, 7, 15], {'2025-02': 301.192, '2025-03': 302.573, '2025-04': 302.224, '2025-05': 302.214, '2025-06': 302.044}, 196.43824], ['302.21948', '1.53850']], ['normal control 1', [[2015, 7, 15], {'2015-02': 299.377, '2015-03': 300.048, '2015-04': 300.855, '2015-05': 301.702, '2015-06': 303.261}, 231.82612], ['301.23752', '1.29941']], ['normal control 2', [[2013, 1, 31], {'2012-08': 313.376, '2012-09': 313.359, '2012-10': 313.818, '2012-11': 314.75, '2012-12': 315.575}, 275.01141], ['314.71994', '1.14439']], ['normal control 3', [[2016, 11, 30], {'2016-06': 296.587, '2016-07': 295.932, '2016-08': 297.411, '2016-09': 297.179, '2016-10': 297.192}, 217.28455], ['297.18673', '1.36773']], ['normal control 4', [[2017, 12, 18], {'2017-07': 275.904, '2017-08': 277.101, '2017-09': 276.38, '2017-10': 275.708, '2017-11': 276.439}, 214.76861], ['276.01148', '1.28516']]], [['regression interpolation day offset 1', [[2030, 3, 15], {'2029-10': 224.591, '2029-11': 224.062, '2029-12': 224.85, '2030-01': 224.538, '2030-02': 224.323}, 183.17393], ['224.70910', '1.22675']], ['regression interpolation day offset 2', [[2019, 12, 1], {'2019-07': 274.442, '2019-08': 275.065, '2019-09': 276.33, '2019-10': 277.714, '2019-11': 277.701}, 232.84007], ['276.33000', '1.18678']], ['partial repair probe 1', [[2028, 6, 30], {'2028-01': 300.533, '2028-02': 299.739, '2028-03': 299.033, '2028-04': 298.273, '2028-05': 297.802}, 244.41776], ['298.29833', '1.22044']], ['partial repair probe 2', [[2029, 10, 15], {'2029-05': 254.036, '2029-06': 255.363, '2029-07': 254.905, '2029-08': 254.154, '2029-09': 253.538}, 190.14839], ['254.56584', '1.33877']], ['normal control 1', [[2030, 1, 31], {'2029-08': 258.182, '2029-09': 259.038, '2029-10': 260.528, '2029-11': 261.089, '2029-12': 260.528}, 239.9153], ['261.07090', '1.08818']], ['normal control 2', [[2025, 6, 2], {'2025-01': 234.405, '2025-02': 234.265, '2025-03': 233.979, '2025-04': 233.989, '2025-05': 235.1}, 191.02195], ['233.97933', '1.22488']], ['normal control 3', [[2027, 4, 12], {'2026-11': 251.107, '2026-12': 251.901, '2027-01': 251.899, '2027-02': 251.326, '2027-03': 250.898}, 281.48739], ['251.68890', '0.89414']], ['normal control 4', [[2017, 2, 1], {'2016-09': 309.163, '2016-10': 310.317, '2016-11': 310.08, '2016-12': 310.547, '2017-01': 311.286}, 258.21573], ['310.08000', '1.20086']]], [['regression interpolation day offset 1', [[2019, 12, 15], {'2019-07': 311.195, '2019-08': 311.486, '2019-09': 311.589, '2019-10': 312.364, '2019-11': 312.338}, 239.56499], ['311.93900', '1.30211']], ['regression interpolation day offset 2', [[2027, 6, 30], {'2027-01': 311.935, '2027-02': 311.81, '2027-03': 311.473, '2027-04': 311.272, '2027-05': 310.565}, 225.11473], ['311.27870', '1.38276']], ['partial repair probe 1', [[2020, 5, 15], {'2019-12': 260.644, '2020-01': 260.047, '2020-02': 260.119, '2020-03': 259.74, '2020-04': 259.666}, 263.8179], ['259.94784', '0.98533']], ['partial repair probe 2', [[2019, 2, 13], {'2018-09': 245.604, '2018-10': 247.024, '2018-11': 247.211, '2018-12': 248.387, '2019-01': 248.701}, 195.73715], ['247.71500', '1.26555']], ['normal control 1', [[2017, 9, 15], {'2017-04': 301.564, '2017-05': 301.466, '2017-06': 303.013, '2017-07': 303.006, '2017-08': 302.924}, 267.09526], ['303.00973', '1.13446']], ['normal control 2', [[2015, 7, 31], {'2015-02': 250.431, '2015-03': 250.107, '2015-04': 250.764, '2015-05': 250.87, '2015-06': 251.196}, 257.20943], ['250.86658', '0.97534']], ['normal control 3', [[2018, 4, 1], {'2017-11': 249.424, '2017-12': 250.548, '2018-01': 250.083, '2018-02': 250.39, '2018-03': 250.521}, 290.7034], ['250.08300', '0.86027']], ['normal control 4', [[2017, 6, 1], {'2017-01': 253.846, '2017-02': 254.082, '2017-03': 254.63, '2017-04': 255.282, '2017-05': 255.199}, 224.26428], ['254.63000', '1.13540']]], [['regression interpolation day offset 1', [[2013, 5, 1], {'2012-12': 287.816, '2013-01': 289.172, '2013-02': 288.577, '2013-03': 289.409, '2013-04': 290.766}, 191.02402], ['288.57700', '1.51068']], ['regression interpolation day offset 2', [[2031, 8, 1], {'2031-03': 293.421, '2031-04': 293.712, '2031-05': 294.986, '2031-06': 296.543, '2031-07': 296.273}, 287.20407], ['294.98600', '1.02710']], ['partial repair probe 1', [[2014, 1, 15], {'2013-08': 296.218, '2013-09': 295.96, '2013-10': 296.22, '2013-11': 295.831, '2013-12': 295.299}, 248.00937], ['296.04432', '1.19368']], ['partial repair probe 2', [[2029, 5, 10], {'2028-12': 288.774, '2029-01': 288.334, '2029-02': 287.591, '2029-03': 288.258, '2029-04': 288.933}, 295.81162], ['287.78465', '0.97286']], ['normal control 1', [[2015, 9, 15], {'2015-04': 260.345, '2015-05': 259.934, '2015-06': 260.142, '2015-07': 260.521, '2015-08': 261.74}, 224.49854], ['260.31887', '1.15956']], ['normal control 2', [[2012, 7, 15], {'2012-02': 262.929, '2012-03': 262.405, '2012-04': 263.942, '2012-05': 263.254, '2012-06': 262.605}, 241.79755], ['263.63129', '1.09030']], ['normal control 3', [[2021, 5, 31], {'2020-12': 248.557, '2021-01': 248.801, '2021-02': 250.327, '2021-03': 251.728, '2021-04': 251.515}, 270.76185], ['251.68281', '0.92954']], ['normal control 4', [[2016, 3, 1], {'2015-10': 245.296, '2015-11': 246.265, '2015-12': 247.039, '2016-01': 247.869, '2016-02': 247.934}, 236.03855], ['247.03900', '1.04660']]], [['regression interpolation day offset 1', [[2029, 6, 1], {'2029-01': 271.912, '2029-02': 272.107, '2029-03': 271.484, '2029-04': 272.182, '2029-05': 273.543}, 214.97507], ['271.48400', '1.26286']], ['regression interpolation day offset 2', [[2029, 3, 1], {'2028-10': 320.154, '2028-11': 320.519, '2028-12': 321.052, '2029-01': 320.333, '2029-02': 319.876}, 202.02671], ['321.05200', '1.58916']], ['partial repair probe 1', [[2021, 10, 7], {'2021-05': 317.506, '2021-06': 318.632, '2021-07': 318.365, '2021-08': 319.67, '2021-09': 320.939}, 220.79376], ['318.61758', '1.44306']], ['partial repair probe 2', [[2029, 10, 31], {'2029-05': 244.749, '2029-06': 244.349, '2029-07': 245.206, '2029-08': 244.591, '2029-09': 245.093}, 263.99626], ['244.61084', '0.92657']], ['normal control 1', [[2025, 12, 15], {'2025-07': 254.829, '2025-08': 254.915, '2025-09': 255.609, '2025-10': 256.99, '2025-11': 257.355}, 191.978], ['256.23268', '1.33470']], ['normal control 2', [[2020, 5, 1], {'2019-12': 249.479, '2020-01': 249.403, '2020-02': 250.265, '2020-03': 250.188, '2020-04': 249.804}, 267.33985], ['250.26500', '0.93613']], ['normal control 3', [[2032, 8, 1], {'2032-03': 319.308, '2032-04': 319.144, '2032-05': 320.071, '2032-06': 320.854, '2032-07': 321.536}, 220.40726], ['320.07100', '1.45218']], ['normal control 4', [[2026, 6, 30], {'2026-01': 264.473, '2026-02': 264.165, '2026-03': 264.808, '2026-04': 265.488, '2026-05': 266.87}, 249.03984], ['265.46533', '1.06596']]]]
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 fixtureActualExpectedOutcome
regression interpolation day offset 1['247.90113', '0.96152']['247.90113', '0.96152']Passed
regression interpolation day offset 2['220.78020', '0.87405']['220.78020', '0.87405']Passed
partial repair probe 1['233.36777', '0.94124']['233.36777', '0.94124']Passed
partial repair probe 2['302.21948', '1.53850']['302.21948', '1.53850']Passed
normal control 1['301.23752', '1.29941']['301.23752', '1.29941']Passed
normal control 2['314.71994', '1.14439']['314.71994', '1.14439']Passed
normal control 3['297.18673', '1.36773']['297.18673', '1.36773']Passed
normal control 4['276.01148', '1.28516']['276.01148', '1.28516']Passed

SHA-256 / f6d4f92e35098cd492047ab0d8087ffafdbdf66daed54ad5abc1bdad9c451197

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:52.160078+00:00.

Case digest / 582371c96bdf56a15bc8e608d6cc448d0d81b9ce8336feae3a37870bb97962f6