Files
settled-reach/tooling/atlas-verify
T
jpmschweitzerandClaude Opus 4.6 8a3c5af842 data(atlas): update systems.db + add atlas tooling scripts
systems.db: 43 North Reach body catalogs (hops 4-12)
tooling: atlas-verify, atlas-names, atlas-systems-done, atlas-helpers.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:18:09 +01:00

94 lines
3.0 KiB
Bash
Executable File

#!/bin/bash
# Verify a proposal JSON against integrity checks
# Usage: tooling/atlas-verify docs/atlas/proposals/GJ273.json
cd "$(dirname "$0")/.."
python3 -c "
import json, sys
with open('$1') as f:
p = json.load(f)
errors = []
bodies = p.get('bodies', [])
stations = p.get('stations', [])
# 1. Inhabited bodies must have names
for b in bodies:
if b.get('inhabited') and not b.get('proper_name'):
errors.append(f\"Inhabited body {b['body_id']} has no proper_name\")
# 2. Uninhabited bodies should have null names
for b in bodies:
if not b.get('inhabited') and b.get('proper_name'):
errors.append(f\"Uninhabited body {b['body_id']} has proper_name '{b['proper_name']}' (should be null)\")
# 3. All stations must have names
for s in stations:
if not s.get('proper_name'):
errors.append(f\"Station {s['station_id']} has no proper_name\")
# 4. Body count check
planets = [b for b in bodies if b['body_type'] == 'planet']
star_type = p.get('spectral_class', 'M')
if star_type.startswith(('G', 'F')):
min_planets = 8
elif star_type.startswith('K'):
min_planets = 7
else:
min_planets = 6
if len(planets) < min_planets:
errors.append(f\"Only {len(planets)} planets, need {min_planets}+ for {star_type} star\")
# 5. Required structures
oort = [b for b in bodies if b['body_type'] == 'oort_cloud']
if not oort:
errors.append('No oort cloud')
horizon = [s for s in stations if s['station_type'] == 'horizon']
if not horizon:
errors.append('No horizon station')
elif not any(s.get('has_gate_infrastructure') for s in horizon):
errors.append('Horizon station missing has_gate_infrastructure: true')
belts = [b for b in bodies if b['body_type'] == 'asteroid_belt']
if not belts:
errors.append('No asteroid belt')
# 6. Orbit consistency
top_level = [b for b in bodies if not b.get('parent_body_id')]
orbits = [b['orbit_index'] for b in top_level]
if orbits != sorted(orbits):
errors.append(f\"Top-level orbit_index not monotonic: {orbits}\")
if len(orbits) != len(set(orbits)):
errors.append(f\"Duplicate orbit_index in top-level: {orbits}\")
# 7. Moon orbit consistency
parents = {}
for b in bodies:
pid = b.get('parent_body_id')
if pid:
parents.setdefault(pid, []).append(b['orbit_index'])
for pid, idxs in parents.items():
if idxs != sorted(idxs):
errors.append(f\"Moon orbits under {pid} not monotonic: {idxs}\")
if len(idxs) != len(set(idxs)):
errors.append(f\"Duplicate moon orbit_index under {pid}: {idxs}\")
# 8. Parent references valid
body_ids = set(b['body_id'] for b in bodies)
for b in bodies:
pid = b.get('parent_body_id')
if pid and pid not in body_ids:
errors.append(f\"Body {b['body_id']} references missing parent {pid}\")
for s in stations:
oid = s.get('orbits_body_id')
if oid and oid not in body_ids:
errors.append(f\"Station {s['station_id']} references missing body {oid}\")
if errors:
print('FAIL')
for e in errors:
print(f' - {e}')
sys.exit(1)
else:
print('PASS')
"