FAILURE MAP
← Case archive

FA-69701 / Orbital propagation / Open access

Cylindrical Earth shadow test: The shadow boundary is treated as sunlit · case 01

A satellite exactly on the shadow cylinder is reported sunlit.

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

ROOT CAUSE

The umbra test is strict.

VERIFIED REPAIR

Treat the boundary as umbra.

Unsuccessful approach: Comparing the squared distance with R mixes units.

Case contract

Input [r, s, R]: satellite position, sun direction (any length) and body radius. With u=s/|s| and d=r.u, the satellite is sunlit when d>=0; otherwise it is in umbra when the distance of r from the shadow axis |r-d u| is <= R. Return "umbra" or "sunlit".

Why this case matters

Orbit determination and mission planning chain many small conversions; one wrong branch or unit silently moves a spacecraft by kilometres.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    r,s,R=x
    sn=math.sqrt(sum(c*c for c in s))
    u=[c/sn for c in s]
    d=sum(a*b for a,b in zip(r,u))
    if d>=0: return 'sunlit'
    perp=[a-d*b for a,b in zip(r,u)]
    return 'umbra' if math.sqrt(sum(c*c for c in perp))<R else 'sunlit'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')]]
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
cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitumbraFailed
cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]umbraumbraPassed

SHA-256 / dc03540ba8cd58eb73e35addd6081a6ceec8120065c6fa702fda1efd863ba96e

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    r,s,R=x
    sn=math.sqrt(sum(c*c for c in s))
    u=[c/sn for c in s]
    d=sum(a*b for a,b in zip(r,u))
    if d>=0: return 'sunlit'
    perp=[a-d*b for a,b in zip(r,u)]
    return 'umbra' if sum(c*c for c in perp)<=R else 'sunlit'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')]]
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
cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitumbraFailed
cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitumbraFailed
cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]sunlitumbraFailed
cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]sunlitumbraFailed

SHA-256 / 989f0dee1cf0fccc963a73b2a498d98e809d538053101ed8d434998020d5d807

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    r,s,R=x
    sn=math.sqrt(sum(c*c for c in s))
    u=[c/sn for c in s]
    d=sum(a*b for a,b in zip(r,u))
    if d>=0: return 'sunlit'
    perp=[a-d*b for a,b in zip(r,u)]
    return 'umbra' if math.sqrt(sum(c*c for c in perp))<=R else 'sunlit'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')]]
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
cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]umbraumbraPassed

SHA-256 / 5cc0d5d1b55b6034de1b2f280cbf424106e2ceb3f4aa4427a4efec3712372db6

Verification & scope

A deterministic toy two-body model with stipulated constants and conventions; not flight dynamics software or a validated SGP4 implementation. 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:48:13.862472+00:00.

Case digest / f60e8325cc2ed902ede84c5acb08c3e5118748dd5d524b4dff206a35cd2a5088