FAILURE MAP
← Case archive

FA-55391 / Astronomical coordinate conventions / Open access

Orbital phase labels: Mean anomaly retains full elapsed revolutions rather than folded angle · case 01

The adapter reports an incorrect mean anomaly while other fields remain valid.

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

ROOT CAUSE

Mean anomaly retains full elapsed revolutions rather than folded angle. Faulty expression: 360*(d['t']/d['P']+d['q'])

VERIFIED REPAIR

Preserve the declared model convention at this site: 360*((d['t']/d['P']+d['q'])%1)

Unsuccessful approach: A partial convention repair still uses 180*((d['t']/d['P']+d['q'])%1)

Case contract

A folded-orbit coordinate has period P>0, elapsed time t from periastron, and phase offset q in cycles. Phase is fractional cycle, cycle index is floor quotient, mean anomaly is phase times a full turn, and eclipse phase offsets are explicit. No orbital dynamics is solved. Output fields are defined by: phase = (d['t']/d['P']+d['q'])%1; cycle_index = int((d['t']/d['P']+d['q'])//1); mean_anomaly = 360*((d['t']/d['P']+d['q'])%1); phase_zero_epoch = d['epoch']-d['q']*d['P']; eclipse_phase = ((d['t']/d['P']+d['q'])-d['eclipse'])%1; phase_rate = 1/d['P']

Why this case matters

Catalog, detector, sky-coordinate, and spectroscopy adapters must preserve the association between numeric coordinates and their declared reference conventions.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'phase': (d['t']/d['P']+d['q'])%1, 'cycle_index': int((d['t']/d['P']+d['q'])//1), 'mean_anomaly': 360*(d['t']/d['P']+d['q']), 'phase_zero_epoch': d['epoch']-d['q']*d['P'], 'eclipse_phase': ((d['t']/d['P']+d['q'])-d['eclipse'])%1, 'phase_rate': 1/d['P']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'t': 17, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.95, 'cycle_index': 1, 'mean_anomaly': 342.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.44999999999999996, 'phase_rate': 0.1}), ({'t': 0, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 0, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': -21, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.1499999999999999, 'cycle_index': -2, 'mean_anomaly': 53.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.6499999999999999, 'phase_rate': 0.1}), ({'t': 17, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.7, 'cycle_index': 1, 'mean_anomaly': 251.99999999999997, 'phase_zero_epoch': 100, 'eclipse_phase': 0.19999999999999996, 'phase_rate': 0.1}), ({'t': 10, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 2, 'mean_anomaly': 270.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.25, 'phase_rate': 0.25}), ({'t': 17, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.44999999999999996, 'cycle_index': 1, 'mean_anomaly': 161.99999999999997, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.19999999999999996, 'phase_rate': 0.1})], 2: [({'t': 18, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.04999999999999982, 'cycle_index': 2, 'mean_anomaly': 17.999999999999936, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.5499999999999998, 'phase_rate': 0.1}), ({'t': 1, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.35, 'cycle_index': 0, 'mean_anomaly': 125.99999999999999, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.85, 'phase_rate': 0.1}), ({'t': -20, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': -2, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': 18, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.8, 'cycle_index': 1, 'mean_anomaly': 288.0, 'phase_zero_epoch': 100, 'eclipse_phase': 0.30000000000000004, 'phase_rate': 0.1}), ({'t': 11, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.0, 'cycle_index': 3, 'mean_anomaly': 0.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.5, 'phase_rate': 0.25}), ({'t': 18, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.55, 'cycle_index': 1, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.30000000000000004, 'phase_rate': 0.1})], 3: [({'t': 19, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.1499999999999999, 'cycle_index': 2, 'mean_anomaly': 53.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.6499999999999999, 'phase_rate': 0.1}), ({'t': 2, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.45, 'cycle_index': 0, 'mean_anomaly': 162.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.95, 'phase_rate': 0.1}), ({'t': -19, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.3500000000000001, 'cycle_index': -2, 'mean_anomaly': 126.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.8500000000000001, 'phase_rate': 0.1}), ({'t': 19, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.8999999999999999, 'cycle_index': 1, 'mean_anomaly': 323.99999999999994, 'phase_zero_epoch': 100, 'eclipse_phase': 0.3999999999999999, 'phase_rate': 0.1}), ({'t': 12, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 3, 'mean_anomaly': 90.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.75, 'phase_rate': 0.25}), ({'t': 19, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.6499999999999999, 'cycle_index': 1, 'mean_anomaly': 233.99999999999997, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.3999999999999999, 'phase_rate': 0.1})], 4: [({'t': 20, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 2, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': 3, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.55, 'cycle_index': 0, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.050000000000000044, 'phase_rate': 0.1}), ({'t': -18, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.44999999999999996, 'cycle_index': -2, 'mean_anomaly': 161.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.9500000000000002, 'phase_rate': 0.1}), ({'t': 20, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.0, 'cycle_index': 2, 'mean_anomaly': 0.0, 'phase_zero_epoch': 100, 'eclipse_phase': 0.5, 'phase_rate': 0.1}), ({'t': 13, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.5, 'cycle_index': 3, 'mean_anomaly': 180.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.0, 'phase_rate': 0.25}), ({'t': 20, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 1, 'mean_anomaly': 270.0, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.5, 'phase_rate': 0.1})], 5: [({'t': 21, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.3500000000000001, 'cycle_index': 2, 'mean_anomaly': 126.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.8500000000000001, 'phase_rate': 0.1}), ({'t': 4, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.65, 'cycle_index': 0, 'mean_anomaly': 234.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.15000000000000002, 'phase_rate': 0.1}), ({'t': -17, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.55, 'cycle_index': -2, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.050000000000000044, 'phase_rate': 0.1}), ({'t': 21, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.10000000000000009, 'cycle_index': 2, 'mean_anomaly': 36.00000000000003, 'phase_zero_epoch': 100, 'eclipse_phase': 0.6000000000000001, 'phase_rate': 0.1}), ({'t': 14, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 3, 'mean_anomaly': 270.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.25, 'phase_rate': 0.25}), ({'t': 21, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.8500000000000001, 'cycle_index': 1, 'mean_anomaly': 306.00000000000006, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.6000000000000001, 'phase_rate': 0.1})]}
for i, (record, expected) in enumerate(fixtures[N]):
    check('astronomical fixture %s' % i, solve(record), 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
astronomical fixture 0{'cycle_index': 1, 'eclipse_phase': 0.44999999999999996, 'mean_anomaly': 702.0, 'phase': 0.95, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': 1, 'eclipse_phase': 0.44999999999999996, 'mean_anomaly': 342.0, 'phase': 0.95, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Failed
astronomical fixture 1{'cycle_index': 0, 'eclipse_phase': 0.75, 'mean_anomaly': 90.0, 'phase': 0.25, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': 0, 'eclipse_phase': 0.75, 'mean_anomaly': 90.0, 'phase': 0.25, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Passed
astronomical fixture 2{'cycle_index': -2, 'eclipse_phase': 0.6499999999999999, 'mean_anomaly': -666.0, 'phase': 0.1499999999999999, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': -2, 'eclipse_phase': 0.6499999999999999, 'mean_anomaly': 53.99999999999997, 'phase': 0.1499999999999999, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Failed
astronomical fixture 3{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 612.0, 'phase': 0.7, 'phase_rate': 0.1, 'phase_zero_epoch': 100}{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 251.99999999999997, 'phase': 0.7, 'phase_rate': 0.1, 'phase_zero_epoch': 100}Failed
astronomical fixture 4{'cycle_index': 2, 'eclipse_phase': 0.25, 'mean_anomaly': 990.0, 'phase': 0.75, 'phase_rate': 0.25, 'phase_zero_epoch': 99.0}{'cycle_index': 2, 'eclipse_phase': 0.25, 'mean_anomaly': 270.0, 'phase': 0.75, 'phase_rate': 0.25, 'phase_zero_epoch': 99.0}Failed
astronomical fixture 5{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 522.0, 'phase': 0.44999999999999996, 'phase_rate': 0.1, 'phase_zero_epoch': 102.5}{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 161.99999999999997, 'phase': 0.44999999999999996, 'phase_rate': 0.1, 'phase_zero_epoch': 102.5}Failed

SHA-256 / ff3f97457254b55c7d1aa6719c71002fb287f1affbb3829cd93f1de55e20c30a

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'phase': (d['t']/d['P']+d['q'])%1, 'cycle_index': int((d['t']/d['P']+d['q'])//1), 'mean_anomaly': 180*((d['t']/d['P']+d['q'])%1), 'phase_zero_epoch': d['epoch']-d['q']*d['P'], 'eclipse_phase': ((d['t']/d['P']+d['q'])-d['eclipse'])%1, 'phase_rate': 1/d['P']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'t': 17, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.95, 'cycle_index': 1, 'mean_anomaly': 342.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.44999999999999996, 'phase_rate': 0.1}), ({'t': 0, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 0, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': -21, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.1499999999999999, 'cycle_index': -2, 'mean_anomaly': 53.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.6499999999999999, 'phase_rate': 0.1}), ({'t': 17, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.7, 'cycle_index': 1, 'mean_anomaly': 251.99999999999997, 'phase_zero_epoch': 100, 'eclipse_phase': 0.19999999999999996, 'phase_rate': 0.1}), ({'t': 10, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 2, 'mean_anomaly': 270.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.25, 'phase_rate': 0.25}), ({'t': 17, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.44999999999999996, 'cycle_index': 1, 'mean_anomaly': 161.99999999999997, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.19999999999999996, 'phase_rate': 0.1})], 2: [({'t': 18, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.04999999999999982, 'cycle_index': 2, 'mean_anomaly': 17.999999999999936, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.5499999999999998, 'phase_rate': 0.1}), ({'t': 1, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.35, 'cycle_index': 0, 'mean_anomaly': 125.99999999999999, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.85, 'phase_rate': 0.1}), ({'t': -20, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': -2, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': 18, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.8, 'cycle_index': 1, 'mean_anomaly': 288.0, 'phase_zero_epoch': 100, 'eclipse_phase': 0.30000000000000004, 'phase_rate': 0.1}), ({'t': 11, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.0, 'cycle_index': 3, 'mean_anomaly': 0.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.5, 'phase_rate': 0.25}), ({'t': 18, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.55, 'cycle_index': 1, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.30000000000000004, 'phase_rate': 0.1})], 3: [({'t': 19, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.1499999999999999, 'cycle_index': 2, 'mean_anomaly': 53.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.6499999999999999, 'phase_rate': 0.1}), ({'t': 2, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.45, 'cycle_index': 0, 'mean_anomaly': 162.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.95, 'phase_rate': 0.1}), ({'t': -19, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.3500000000000001, 'cycle_index': -2, 'mean_anomaly': 126.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.8500000000000001, 'phase_rate': 0.1}), ({'t': 19, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.8999999999999999, 'cycle_index': 1, 'mean_anomaly': 323.99999999999994, 'phase_zero_epoch': 100, 'eclipse_phase': 0.3999999999999999, 'phase_rate': 0.1}), ({'t': 12, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 3, 'mean_anomaly': 90.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.75, 'phase_rate': 0.25}), ({'t': 19, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.6499999999999999, 'cycle_index': 1, 'mean_anomaly': 233.99999999999997, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.3999999999999999, 'phase_rate': 0.1})], 4: [({'t': 20, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 2, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': 3, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.55, 'cycle_index': 0, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.050000000000000044, 'phase_rate': 0.1}), ({'t': -18, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.44999999999999996, 'cycle_index': -2, 'mean_anomaly': 161.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.9500000000000002, 'phase_rate': 0.1}), ({'t': 20, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.0, 'cycle_index': 2, 'mean_anomaly': 0.0, 'phase_zero_epoch': 100, 'eclipse_phase': 0.5, 'phase_rate': 0.1}), ({'t': 13, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.5, 'cycle_index': 3, 'mean_anomaly': 180.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.0, 'phase_rate': 0.25}), ({'t': 20, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 1, 'mean_anomaly': 270.0, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.5, 'phase_rate': 0.1})], 5: [({'t': 21, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.3500000000000001, 'cycle_index': 2, 'mean_anomaly': 126.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.8500000000000001, 'phase_rate': 0.1}), ({'t': 4, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.65, 'cycle_index': 0, 'mean_anomaly': 234.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.15000000000000002, 'phase_rate': 0.1}), ({'t': -17, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.55, 'cycle_index': -2, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.050000000000000044, 'phase_rate': 0.1}), ({'t': 21, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.10000000000000009, 'cycle_index': 2, 'mean_anomaly': 36.00000000000003, 'phase_zero_epoch': 100, 'eclipse_phase': 0.6000000000000001, 'phase_rate': 0.1}), ({'t': 14, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 3, 'mean_anomaly': 270.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.25, 'phase_rate': 0.25}), ({'t': 21, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.8500000000000001, 'cycle_index': 1, 'mean_anomaly': 306.00000000000006, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.6000000000000001, 'phase_rate': 0.1})]}
for i, (record, expected) in enumerate(fixtures[N]):
    check('astronomical fixture %s' % i, solve(record), 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
astronomical fixture 0{'cycle_index': 1, 'eclipse_phase': 0.44999999999999996, 'mean_anomaly': 171.0, 'phase': 0.95, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': 1, 'eclipse_phase': 0.44999999999999996, 'mean_anomaly': 342.0, 'phase': 0.95, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Failed
astronomical fixture 1{'cycle_index': 0, 'eclipse_phase': 0.75, 'mean_anomaly': 45.0, 'phase': 0.25, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': 0, 'eclipse_phase': 0.75, 'mean_anomaly': 90.0, 'phase': 0.25, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Failed
astronomical fixture 2{'cycle_index': -2, 'eclipse_phase': 0.6499999999999999, 'mean_anomaly': 26.999999999999986, 'phase': 0.1499999999999999, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': -2, 'eclipse_phase': 0.6499999999999999, 'mean_anomaly': 53.99999999999997, 'phase': 0.1499999999999999, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Failed
astronomical fixture 3{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 125.99999999999999, 'phase': 0.7, 'phase_rate': 0.1, 'phase_zero_epoch': 100}{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 251.99999999999997, 'phase': 0.7, 'phase_rate': 0.1, 'phase_zero_epoch': 100}Failed
astronomical fixture 4{'cycle_index': 2, 'eclipse_phase': 0.25, 'mean_anomaly': 135.0, 'phase': 0.75, 'phase_rate': 0.25, 'phase_zero_epoch': 99.0}{'cycle_index': 2, 'eclipse_phase': 0.25, 'mean_anomaly': 270.0, 'phase': 0.75, 'phase_rate': 0.25, 'phase_zero_epoch': 99.0}Failed
astronomical fixture 5{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 80.99999999999999, 'phase': 0.44999999999999996, 'phase_rate': 0.1, 'phase_zero_epoch': 102.5}{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 161.99999999999997, 'phase': 0.44999999999999996, 'phase_rate': 0.1, 'phase_zero_epoch': 102.5}Failed

SHA-256 / 0097093fd06e1186506783c04f81f4d5bdbdb48b6f463134a53ef3f563f334c7

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    return {'phase': (d['t']/d['P']+d['q'])%1, 'cycle_index': int((d['t']/d['P']+d['q'])//1), 'mean_anomaly': 360*((d['t']/d['P']+d['q'])%1), 'phase_zero_epoch': d['epoch']-d['q']*d['P'], 'eclipse_phase': ((d['t']/d['P']+d['q'])-d['eclipse'])%1, 'phase_rate': 1/d['P']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = {1: [({'t': 17, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.95, 'cycle_index': 1, 'mean_anomaly': 342.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.44999999999999996, 'phase_rate': 0.1}), ({'t': 0, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 0, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': -21, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.1499999999999999, 'cycle_index': -2, 'mean_anomaly': 53.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.6499999999999999, 'phase_rate': 0.1}), ({'t': 17, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.7, 'cycle_index': 1, 'mean_anomaly': 251.99999999999997, 'phase_zero_epoch': 100, 'eclipse_phase': 0.19999999999999996, 'phase_rate': 0.1}), ({'t': 10, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 2, 'mean_anomaly': 270.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.25, 'phase_rate': 0.25}), ({'t': 17, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.44999999999999996, 'cycle_index': 1, 'mean_anomaly': 161.99999999999997, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.19999999999999996, 'phase_rate': 0.1})], 2: [({'t': 18, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.04999999999999982, 'cycle_index': 2, 'mean_anomaly': 17.999999999999936, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.5499999999999998, 'phase_rate': 0.1}), ({'t': 1, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.35, 'cycle_index': 0, 'mean_anomaly': 125.99999999999999, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.85, 'phase_rate': 0.1}), ({'t': -20, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': -2, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': 18, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.8, 'cycle_index': 1, 'mean_anomaly': 288.0, 'phase_zero_epoch': 100, 'eclipse_phase': 0.30000000000000004, 'phase_rate': 0.1}), ({'t': 11, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.0, 'cycle_index': 3, 'mean_anomaly': 0.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.5, 'phase_rate': 0.25}), ({'t': 18, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.55, 'cycle_index': 1, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.30000000000000004, 'phase_rate': 0.1})], 3: [({'t': 19, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.1499999999999999, 'cycle_index': 2, 'mean_anomaly': 53.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.6499999999999999, 'phase_rate': 0.1}), ({'t': 2, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.45, 'cycle_index': 0, 'mean_anomaly': 162.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.95, 'phase_rate': 0.1}), ({'t': -19, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.3500000000000001, 'cycle_index': -2, 'mean_anomaly': 126.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.8500000000000001, 'phase_rate': 0.1}), ({'t': 19, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.8999999999999999, 'cycle_index': 1, 'mean_anomaly': 323.99999999999994, 'phase_zero_epoch': 100, 'eclipse_phase': 0.3999999999999999, 'phase_rate': 0.1}), ({'t': 12, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 3, 'mean_anomaly': 90.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.75, 'phase_rate': 0.25}), ({'t': 19, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.6499999999999999, 'cycle_index': 1, 'mean_anomaly': 233.99999999999997, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.3999999999999999, 'phase_rate': 0.1})], 4: [({'t': 20, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.25, 'cycle_index': 2, 'mean_anomaly': 90.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.75, 'phase_rate': 0.1}), ({'t': 3, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.55, 'cycle_index': 0, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.050000000000000044, 'phase_rate': 0.1}), ({'t': -18, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.44999999999999996, 'cycle_index': -2, 'mean_anomaly': 161.99999999999997, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.9500000000000002, 'phase_rate': 0.1}), ({'t': 20, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.0, 'cycle_index': 2, 'mean_anomaly': 0.0, 'phase_zero_epoch': 100, 'eclipse_phase': 0.5, 'phase_rate': 0.1}), ({'t': 13, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.5, 'cycle_index': 3, 'mean_anomaly': 180.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.0, 'phase_rate': 0.25}), ({'t': 20, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 1, 'mean_anomaly': 270.0, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.5, 'phase_rate': 0.1})], 5: [({'t': 21, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.3500000000000001, 'cycle_index': 2, 'mean_anomaly': 126.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.8500000000000001, 'phase_rate': 0.1}), ({'t': 4, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.65, 'cycle_index': 0, 'mean_anomaly': 234.0, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.15000000000000002, 'phase_rate': 0.1}), ({'t': -17, 'P': 10, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.55, 'cycle_index': -2, 'mean_anomaly': 198.00000000000003, 'phase_zero_epoch': 97.5, 'eclipse_phase': 0.050000000000000044, 'phase_rate': 0.1}), ({'t': 21, 'P': 10, 'q': 0, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.10000000000000009, 'cycle_index': 2, 'mean_anomaly': 36.00000000000003, 'phase_zero_epoch': 100, 'eclipse_phase': 0.6000000000000001, 'phase_rate': 0.1}), ({'t': 14, 'P': 4, 'q': 0.25, 'eclipse': 0.5, 'epoch': 100}, {'phase': 0.75, 'cycle_index': 3, 'mean_anomaly': 270.0, 'phase_zero_epoch': 99.0, 'eclipse_phase': 0.25, 'phase_rate': 0.25}), ({'t': 21, 'P': 10, 'q': -0.25, 'eclipse': 0.25, 'epoch': 100}, {'phase': 0.8500000000000001, 'cycle_index': 1, 'mean_anomaly': 306.00000000000006, 'phase_zero_epoch': 102.5, 'eclipse_phase': 0.6000000000000001, 'phase_rate': 0.1})]}
for i, (record, expected) in enumerate(fixtures[N]):
    check('astronomical fixture %s' % i, solve(record), 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
astronomical fixture 0{'cycle_index': 1, 'eclipse_phase': 0.44999999999999996, 'mean_anomaly': 342.0, 'phase': 0.95, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': 1, 'eclipse_phase': 0.44999999999999996, 'mean_anomaly': 342.0, 'phase': 0.95, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Passed
astronomical fixture 1{'cycle_index': 0, 'eclipse_phase': 0.75, 'mean_anomaly': 90.0, 'phase': 0.25, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': 0, 'eclipse_phase': 0.75, 'mean_anomaly': 90.0, 'phase': 0.25, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Passed
astronomical fixture 2{'cycle_index': -2, 'eclipse_phase': 0.6499999999999999, 'mean_anomaly': 53.99999999999997, 'phase': 0.1499999999999999, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}{'cycle_index': -2, 'eclipse_phase': 0.6499999999999999, 'mean_anomaly': 53.99999999999997, 'phase': 0.1499999999999999, 'phase_rate': 0.1, 'phase_zero_epoch': 97.5}Passed
astronomical fixture 3{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 251.99999999999997, 'phase': 0.7, 'phase_rate': 0.1, 'phase_zero_epoch': 100}{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 251.99999999999997, 'phase': 0.7, 'phase_rate': 0.1, 'phase_zero_epoch': 100}Passed
astronomical fixture 4{'cycle_index': 2, 'eclipse_phase': 0.25, 'mean_anomaly': 270.0, 'phase': 0.75, 'phase_rate': 0.25, 'phase_zero_epoch': 99.0}{'cycle_index': 2, 'eclipse_phase': 0.25, 'mean_anomaly': 270.0, 'phase': 0.75, 'phase_rate': 0.25, 'phase_zero_epoch': 99.0}Passed
astronomical fixture 5{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 161.99999999999997, 'phase': 0.44999999999999996, 'phase_rate': 0.1, 'phase_zero_epoch': 102.5}{'cycle_index': 1, 'eclipse_phase': 0.19999999999999996, 'mean_anomaly': 161.99999999999997, 'phase': 0.44999999999999996, 'phase_rate': 0.1, 'phase_zero_epoch': 102.5}Passed

SHA-256 / 2543cb1270eda2194fb4e4d51501afb6a5b47dfa9f4ef358d533afe4f8c81fad

Verification & scope

Explicitly stipulated finite algebraic adapter; no standards conformance, physical accuracy, or production-library claim. Inputs are the documented finite valid model domain. 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:45:57.422014+00:00.

Case digest / 26bd072207d876febea00f5ac6b323d1925329cba1db957f4ceeae56c1b74593