FA-12146 / Astronomical coordinate conventions / Open access
A right-ascension adapter ignores the declared hours unit · case 01
A right-ascension adapter ignores the declared hours unit.
ROOT CAUSE
A field name is treated as a sufficient unit specification.
VERIFIED REPAIR
Convert explicitly tagged hours to degrees and preserve degrees.
Unsuccessful approach: Converting all right ascensions multiplies values already in degrees.
Case contract
Return toy RA in degrees modulo 360; unit is hours or degrees; one hour is stipulated as 15 degrees.
Why this case matters
Astronomical catalog and observation adapters must preserve the declared coordinate convention across software boundaries.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(value, unit):
return value % 360
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hour input', solve(N, "hours"), 15*N)
check('degree input', solve(N, "degrees"), N)
check('one full day', solve(24, "hours"), 0)
check('negative hour', solve(-N, "hours"), 360-15*N)
check('degree wrap', solve(360+N, "degrees"), N)
check('zero', solve(0, "hours"), 0)
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 |
|---|---|---|---|
| hour input | 1 | 15 | Failed |
| degree input | 1 | 1 | Passed |
| one full day | 24 | 0 | Failed |
| negative hour | 359 | 345 | Failed |
| degree wrap | 1 | 1 | Passed |
| zero | 0 | 0 | Passed |
SHA-256 / c9d8a8d2c5292029ab9f6be0efbb83e62c2921392ad76361f9c1d7c58ed23e81
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(value, unit):
return value * 15 % 360
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hour input', solve(N, "hours"), 15*N)
check('degree input', solve(N, "degrees"), N)
check('one full day', solve(24, "hours"), 0)
check('negative hour', solve(-N, "hours"), 360-15*N)
check('degree wrap', solve(360+N, "degrees"), N)
check('zero', solve(0, "hours"), 0)
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 |
|---|---|---|---|
| hour input | 15 | 15 | Passed |
| degree input | 15 | 1 | Failed |
| one full day | 0 | 0 | Passed |
| negative hour | 345 | 345 | Passed |
| degree wrap | 15 | 1 | Failed |
| zero | 0 | 0 | Passed |
SHA-256 / 6048bb2fd7ffbfaae31505ef1e6fe6be0f471eca6880766317fa0d5d45e25a9e
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(value, unit):
return (value * 15 if unit == 'hours' else value) % 360
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hour input', solve(N, "hours"), 15*N)
check('degree input', solve(N, "degrees"), N)
check('one full day', solve(24, "hours"), 0)
check('negative hour', solve(-N, "hours"), 360-15*N)
check('degree wrap', solve(360+N, "degrees"), N)
check('zero', solve(0, "hours"), 0)
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 |
|---|---|---|---|
| hour input | 15 | 15 | Passed |
| degree input | 1 | 1 | Passed |
| one full day | 0 | 0 | Passed |
| negative hour | 345 | 345 | Passed |
| degree wrap | 1 | 1 | Passed |
| zero | 0 | 0 | Passed |
SHA-256 / 9e2f1df7c38e0bc021655abfd150b2711d3ef5144ad0eb2142cfed48862615e5
Verification & scope
Deterministic stipulated adapter model; no ephemeris, physical accuracy, or production astronomy library claims. 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:38:54.282499+00:00.
Case digest / 52cb4dae1615df4ce8d1a49d188d3468e92afe0abec510e34b85387d1f0042be