Aerospace New Zealand Summit 2026
Geodesic Space Systems is at the Summit to find founding partners: people who hold real operational data and want an independent check of their own flight dynamics. Flight dynamics you can check. Test our engines with your data.
- EVENT
- Aerospace New Zealand Summit 2026
- DATES
- PENDING
- VENUE
- PENDING
- SESSION OR STAND
- PENDING
Details are added here once they are confirmed, not before: a provisional date on a public page reads as a commitment whether or not it was meant as one.
Our engines are checked against published references and against synthetic worlds where the truth is known exactly. Methods, results and limits are published, failures included. What comes next is proof in real operations, and that takes real data and independent eyes.
- Satellite operators bring ephemerides, covariances and manoeuvre histories
- Insurers bring the questions that decide cover, and the evidence they would need
- Mission designers bring the cases that matter to them, beyond LEO
Predictions are registered before every run. Tests are blind where possible. Results are reviewed with the partner first, and published only with their consent.
Founding partners receive early access to the full engine set, results on their own data first, and a say in our Flight Ops, Evidence and licensing services. Those three services are being shaped with founding partners and are not yet offered as available.
Test cases you run or check yourself. Each one gives you the script, what a pass looks like, and where to check the answer without relying on us. None asks you to take our word for anything, and each one can fail.
- RUN IT YOURSELF
- With a Burner key, against our API, while the GDS Physics engine is running. In this development phase it is not always running: a reply of HTTP 530 means it is off, not that a case failed.
- CHECK OUR SIGNED RUN
- No key, and no request to us. We publish the exact request, the result the engine signed and the outside reference; you check the signature and compare the numbers.
Named specifically, including where we are aligned rather than compliant. What each one covers is on the Developer's Portal.
- MESSAGE FORMATS
- CCSDS 502.0-B-3 Orbit Parameter Message · CCSDS 503.0-B-1 Orbit Ephemeris Message · CCSDS 508.0-B-1 Conjunction Data Message
- PHYSICAL MODELS
- IERS Conventions 2010, §10.3 eq. 10.12, relativistic corrections · EGM96 zonal J2–J8 · NRLMSISE-00 · the JPL DE Chebyshev layout for ephemerides
- METHODS
- Foster encounter-plane Pc, as used by NASA CARA · Battin §8.11 third-body formulation · Edelbaum low-thrust transfer · Walker 1984 constellation geometry
- SIGNED RESULTS
- Ed25519 signatures (RFC 8032) over SHA-256 digests (FIPS 180-4), by a key that AWS Nitro Enclaves attests, checked up to the AWS Nitro root
Six cases. Run cases 1 to 5 in order with a Burner key: later cases read files the earlier ones write. Case 6 is a signed run you check with no key at all. Cases 1 to 5 were run against the live engine on 22 September 2026 (UTC), and passed.
A Burner key: ask us for one at the Summit, or through Contact. It reaches the message validators and /v1/opm/propagate (RK4, with an optional J2 term), up to 6,000 steps a call, and lasts 48 hours. You also need curl and Python 3.9 or later.
Save this as request.json: a 7,000 km circular orbit with J2 on, 98 steps of 60 s, a little over one orbit. Every case from 1 to 5 uses this one file.
{
"opm": {
"header": { "ccsds_opm_vers": "3.0", "creation_date": "2026-09-22T00:00:00Z",
"originator": "SUMMIT-TEST" },
"metadata": { "object_name": "SUMMIT-TEST", "object_id": "2026-000A",
"center_name": "EARTH", "ref_frame": "EME2000", "time_system": "UTC" },
"data": { "state_vector": { "epoch": "2026-09-22T00:00:00Z",
"x": 7000.0, "y": 0.0, "z": 0.0,
"x_dot": 0.0, "y_dot": 7.5461, "z_dot": 0.0 } }
},
"gm": 398600.4418,
"include_j2": true, "j2": 0.00108262668, "body_radius_km": 6378.137,
"step_seconds": 60.0,
"steps": 98
}
# bash or zsh (on Windows, Git Bash or WSL) # or download the same file: curl -sSO https://geodesicspacesystems.com/test-cases/request.json # Git Bash on Windows has no python3 command; this makes python3 run python there command -v python3 >/dev/null || python3() { python "$@"; } export GDS_KEY='paste your Burner key here' API=https://api.geodesicspacesystems.com
The validator reads the same message the engine would, and costs nothing from your allowance: it never reaches an engine.
python3 -c "import json; json.dump(json.load(open('request.json'))['opm'], open('opm.json', 'w'))"
curl -sS "$API/v1/opm/validate" -H "x-api-key: $GDS_KEY" \
-H "Content-Type: application/json" --data-binary @opm.json
Passes when the answer reads "accepted":true, and its summary gives "radius_km":7000.0 and "speed_km_s":7.5461.
Check it without us: both are in your file, the length of (x, y, z) and of (x_dot, y_dot, z_dot). The circular speed at 7,000 km, √(GM/r) with GM = 398,600.4418 km³/s², is 7.54605 km/s: the file’s 7.5461 is that, rounded. The message format is CCSDS 502.0-B-3, free from ccsds.org.
Run the propagation twice and compare every state.
for n in 1 2; do
curl -sS "$API/v1/opm/propagate" -H "x-api-key: $GDS_KEY" \
-H "Content-Type: application/json" --data-binary @request.json -o run$n.json
done
python3 -c "
import json
a, b = (json.load(open(f))['states'] for f in ('run1.json', 'run2.json'))
print(len(a), 'states:', 'IDENTICAL' if a == b else 'DIFFERENT')"
Passes when it prints 98 states: IDENTICAL. It compares the states only: the timing in the engine block changes from run to run, and that is time spent, not the answer.
Check it without us: there is nothing to look up. Both answers are in your hands, and the comparison is Python’s own equality on every number.
Ask for the final state alone and compare it with the last state of the arc from case 2.
curl -sS "$API/v1/opm/propagate?want_trajectory=false" -H "x-api-key: $GDS_KEY" \
-H "Content-Type: application/json" --data-binary @request.json -o end.json
python3 -c "
import json
arc = json.load(open('run1.json'))['states']
end = json.load(open('end.json'))['states']
print('SAME TO THE LAST BIT' if end == arc[-1:] else 'DIFFERENT')"
Passes when it prints SAME TO THE LAST BIT, epoch included.
Check it without us: as in case 2, both answers are yours. The epoch is checkable by hand: 98 × 60 s after 2026-09-22T00:00:00Z is 01:38:00.
Ask the engine to sign the answer inside its enclave, then check the signature with our verifier: one short Python file that imports nothing of ours. Its SHA-256 is on the docs page.
curl -sS "$API/v1/opm/propagate?certify=true&want_trajectory=false" -H "x-api-key: $GDS_KEY" \
-H "Content-Type: application/json" --data-binary @request.json -o signed.json
python3 -c "import json; json.dump(json.load(open('signed.json'))['certificate'], open('cert.json', 'w'))"
python3 -m pip install cryptography
curl -sSO https://geodesicspacesystems.com/geodesic_verify.py
python3 geodesic_verify.py --certificate cert.json --request request.json
# now change one digit of the request and check again
sed 's/7000.0/7000.1/' request.json > tampered.json
python3 geodesic_verify.py --certificate cert.json --request tampered.json
Passes when the first check ends RESULT: VERIFIED and the second ends RESULT: FAILED, on the line about client_digest: the certificate names your exact request, and no other.
Check it without us: the verifier trusts one thing it did not get from the certificate: AWS’s Nitro Enclaves root, pinned in the file. Fetch the root from AWS and compare fingerprints:
curl -sSO https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip unzip -p AWS_NitroEnclaves_Root-G1.zip | openssl x509 -noout -fingerprint -sha256 grep '^NITRO_ROOT_SHA256' geodesic_verify.py
The two should show the same 64 hex digits, colons and case aside.
Twenty lines of Python and no libraries: two-body gravity plus J2 in its textbook form, stepped with classical fourth-order Runge–Kutta, the method this route uses. It reads your request.json and the engine’s arc from case 2.
python3 - <<'EOF'
import json, math
req = json.load(open('request.json'))
sv = req['opm']['data']['state_vector']
mu, j2, R = req['gm'], req['j2'], req['body_radius_km']
h, n = req['step_seconds'], req['steps']
def f(s): # two-body plus J2, the textbook form
x, y, z, vx, vy, vz = s
r = math.sqrt(x*x + y*y + z*z)
g = -mu / (r*r*r)
k = 1.5 * j2 * mu * (R*R) / r**4
q = (z/r) * (z/r)
return [vx, vy, vz, g*x - k*(x/r)*(1 - 5*q),
g*y - k*(y/r)*(1 - 5*q), g*z - k*(z/r)*(3 - 5*q)]
def rk4(s, h): # classical fourth-order Runge-Kutta
k1 = f(s)
k2 = f([a + 0.5*h*b for a, b in zip(s, k1)])
k3 = f([a + 0.5*h*b for a, b in zip(s, k2)])
k4 = f([a + h*b for a, b in zip(s, k3)])
return [a + (h/6)*(b + 2*c + 2*d + e) for a, b, c, d, e in zip(s, k1, k2, k3, k4)]
keys = ('x', 'y', 'z', 'x_dot', 'y_dot', 'z_dot')
mine = fine = [sv[k] for k in keys]
for _ in range(n):
mine = rk4(mine, h)
for _ in range(n * 60):
fine = rk4(fine, h / 60)
last = json.load(open('run1.json'))['states'][-1]
d = 1000 * math.dist([last[k] for k in ('X', 'Y', 'Z')], mine[:3]) # the answer's own names
print('engine vs your RK4, same step: %.3g m' % d, '-> SAME ORBIT' if d < 1e-6 else '-> DIFFERENT')
print('your RK4, 60 s vs 1 s steps: %.3g m' % (1000 * math.dist(mine[:3], fine[:3])))
EOF
Passes when the first line ends SAME ORBIT: your arithmetic and the engine’s agree to under a micrometre. The second line is RK4’s own step error at 60 s, 24.6 m after 98 minutes by this script: a property of the method and the step you chose, not of the engine. Ask for shorter steps when that matters.
Check it without us: your own code is the reference here. In a propagator you trust, set two-body plus J2 about the frame’s z-axis, with the same GM, J2 and radius and a tight tolerance: it gives the 1 s answer, and the engine’s 60 s arc differs from it by the step error on the second line.
On 18 September 2026 we asked the engine for halo orbits about the Earth–Moon L1, L2 and L3 points, using JPL’s own mass ratio, and had each answer signed. We publish the nine exact requests and signed results. The checker reads every number from the signed bytes, recomputes the Jacobi constant, integrates each orbit for one period with its own integrator, and compares period, stability index and state with JPL’s published families. The verifier then checks each signature and its AWS chain, with no network request.
# in a new shell, Git Bash on Windows needs the python3 line from Set up again
command -v python3 >/dev/null || python3() { python "$@"; }
curl -sSO https://geodesicspacesystems.com/test-cases/cr3bp-halo-jpl.json
curl -sSO https://geodesicspacesystems.com/test-cases/check_cr3bp_halo.py
curl -sSO https://geodesicspacesystems.com/geodesic_verify.py
python3 -m pip install cryptography
python3 check_cr3bp_halo.py
for n in 1 2 3 4 5 6 7 8 9; do
python3 geodesic_verify.py --offline run$n-bundle.json --request run$n-request.json | grep RESULT
done
Passes when the checker ends 9 of 9 runs pass every check and all nine verifier lines read RESULT: VERIFIED. Measured on 18 September 2026: period and stability index within 1e-9 of JPL’s (relative), each orbit closing to 1e-8 or better.
Check it without us: the reference is JPL’s. The checker downloads each family from JPL’s Three-Body Periodic Orbits API, for example https://ssd-api.jpl.nasa.gov/periodic_orbits.api?sys=earth-moon&family=halo&libr=2&branch=S, and you can look the same orbits up by Jacobi constant in JPL’s periodic orbits tool. The model is the circular restricted three-body problem; the Jacobi constant is C = x² + y² + 2(1−μ)/r1 + 2μ/r2 − v².
Not in this set, and listed in the file. At L1 the two a = 0.3 seeds returned exact JPL orbits of the opposite north/south class. Three larger seeds found no answer within the 30 s limit. And asked for planar Lyapunov orbits about L1 and L2, the route returned a different family: three of the four answers are exact members of JPL’s distant retrograde orbit family about the Moon (period and stability index within 1e-10), and the fourth is not in JPL’s catalogue. We traced it to how the route starts its search: it places the first guess further from the point than the request documents, keeps that starting point fixed, and accepts any closed orbit that starts near the point. A distant retrograde orbit through the same start passes, and nothing yet checks that a Lyapunov orbit comes back unstable, as every one about L1 and L2 is.
Send the request bytes exactly as saved: --data-binary keeps them intact, where curl’s -d would strip the line breaks and change the digest. If a case does not pass for you, tell us on Feedback, Bugs & Test Results.