PLAN.org
450 lines · 23259 bytes
36 symbols in this file
nameApple identifiersconceptdesignscreens1. Sky (home)2. System3. Sun4. Launches5. Librarywidgets, Live Activities, notificationsdata sourcesarchitecturebackendCloudflare productsAPNs from Workersjobsdata (D1)APIalertsprivacy and abuseoperationscontentmilestonesM0 results (2026-10-17)M1 status (2026-10-17)M2 status (2026-10-17)M3 status (2026-10-17)M4 status (2026-10-17)Deployment (2026-10-18)roadmapv1: nowv2: plan, track, more devicesv3: across time and culturesrisksopen questions
1#+title: Moonrise
2#+subtitle: concept and plan
3
4* name
5*Moonrise.* App Store name with a descriptor, e.g. "Moonrise: Sky and
6Space", since the bare name is shared and reads as moon-only.
7
8Existing apps (Oct 2026 search), all moon-times utilities: AVIA Moonrise
9(id390606204, last updated 2021), Moonrise Moment (id6788237210),
10Mooncaster. The descriptor and screenshots need to show the app covers
11far more than the moon.
12
13Reserved in App Store Connect 2026-10-17. USPTO search not done.
14
15* Apple identifiers
16| Item | Value |
17|-
18| Team ID | =ZCNAX3VL9D= |
19| Bundle ID | =sh.krz.moonrise= |
20| APNs key | "Moonrise APNs", key ID =644XS4F2RG=, Sandbox and Production. The .p8 is held outside the repo. |
21
22* concept
23An iPhone app for everything in space: what is overhead tonight, what the
24sun is doing, what is launching, where our spacecraft are, and a
25reference library for the planets, stars, galaxies and missions.
26
27The lead on every tab is a picture computed from real data or a real
28image: the sky above you, the solar system today, the sun this hour, a
29rocket on its pad. Text sits underneath, a swipe or tap away.
30
31Free of accounts. Works offline for anything that can be computed;
32fetches only live feeds.
33
34* design
35After NASA's 1975 Graphics Standards Manual.
36
37- Helvetica Neue (ships with iOS). Tabular figures for all numbers.
38- Strict grid, flush left, black hairlines, numbered modules.
39- Off-white and ink by day. Near-black with white line work at night.
40- One red accent for alerts and emphasis. Not NASA's exact red, no NASA
41 insignia or worm logotype, nothing that reads as an official NASA app.
42- Drawings are technical: orbits as orbits, dimension lines, to-scale
43 comparisons, Gantt-style mission timelines.
44- Night mode: red-on-black for dark-adapted eyes, switched on
45 automatically after astronomical dusk while the Sky tab is open.
46- Motion only where it carries data: planets moving at true relative
47 speeds, the moon's phase easing while scrubbing time.
48
49Avoid: neon on black, glow, scan lines, hexagons, crosshairs,
50monospaced readouts as decoration.
51
52* screens
53Five tabs.
54
55** 1. Sky (home)
56- Full-screen sky for your location and time: horizon, stars to about
57 magnitude 6, constellation lines, planets, the moon at its true phase,
58 the sun below the horizon as a glow at the edge.
59- Pans with the device (compass and gyroscope) or by drag. Pinch to zoom.
60- Tap any object for a card: name, magnitude, rise and set, distance,
61 link to its Library page.
62- Time scrubber: drag hours forward or back; tap to return to now.
63- Alert chips across the top when relevant: aurora (Kp threshold for
64 your latitude), ISS pass within the hour, launch within the hour,
65 eclipse or conjunction today.
66- Today sheet, pulled up from the bottom:
67 - Moon: phase, illumination, next quarter.
68 - Visible tonight: planets with direction, altitude, rise and set.
69 - ISS passes over the next 3 days.
70 - Next launch with countdown.
71 - Space weather: Kp now and forecast.
72 - Deep space: Voyager 1 distance and light time.
73
74** 2. System
75- Top-down orrery of the solar system for today. Log-scaled distances by
76 default; toggle to true scale.
77- Time slider from 1957 to 2050. Planets and spacecraft move together.
78- Spacecraft drawn with their trajectories: Voyager 1 and 2, New
79 Horizons, Juno, Europa Clipper, JUICE, Psyche, Parker Solar Probe,
80 Lucy, and missions at Mars.
81- Tap a planet or spacecraft for its Library page.
82- Inset for Earth–Moon space: ISS, JWST at L2, lunar missions.
83
84** 3. Sun
85- Latest SDO full-disk image, full width. Swipe between wavelengths:
86 171 Å (corona), 304 Å (chromosphere), 193 Å, HMI visible light.
87- Kp index: bar chart for the last 3 days and the 3-day forecast.
88- Aurora oval for your hemisphere (OVATION model) with your location
89 marked.
90- Solar flares: GOES X-ray flux for the last 24 hours, flare classes
91 marked.
92- Plain-language summary in one line: "Quiet", "Minor storm likely
93 tonight", and similar.
94
95** 4. Launches
96- Upcoming launches, each led by the rocket's silhouette drawn to a
97 common scale.
98- Detail: vehicle, mission, payload, orbit, pad on a map, countdown,
99 launch window, webcast link.
100- Live Activity from T−1 hour through orbit insertion.
101- Past launches with outcome.
102
103** 5. Library
104Every page leads with a drawing or image; facts follow as a spec sheet.
105
106- Solar system: the sun, 8 planets, dwarf planets, major moons. Each has
107 a dimensioned drawing, a to-scale comparison with Earth, a facts grid,
108 the missions that visited on a timeline, and a short essay.
109- Constellations: all 88. Modern line figure, the plate from a
110 historical atlas (Bayer, Hevelius, Bode), bright stars, best season,
111 where it is tonight.
112- Stars: bright named stars with type, distance, colour and the origin
113 of the name.
114- Deep sky: the 110 Messier objects, then well-known NGC objects, with
115 Hubble, Webb or ground images and a scale bar.
116- Spacecraft and missions: active and historic. Status, location,
117 instruments, findings, timeline.
118- Later sections: exoplanets, rockets side by side to scale, the history
119 of exploration as a browsable timeline, a scale view from Earth to the
120 observable universe.
121
122Search across all of it from the Library tab.
123
124* widgets, Live Activities, notifications
125- Lock Screen: moon phase; Kp; next launch countdown.
126- Home Screen: tonight's planets; Voyager 1 distance; today's sun image.
127- Live Activity: launch countdown through orbit.
128- Notifications, each off by default and opt-in: aurora possible at your
129 latitude; launch in one hour; ISS visible pass in 15 minutes.
130
131* data sources
132Checked 2026-10-17 against primary sources unless marked unconfirmed.
133
134| Source | Use | Terms and limits |
135|-
136| Astronomy Engine v2.1.19 (Don Cross) | Sun, moon, planet positions; rise, set, phases, eclipses, conjunctions | MIT, keep notice. No Swift package; C source vendored as an SPM target. Last release 2023-12. |
137| Yale Bright Star Catalogue (VizieR V/50) | 9,096 stars with V mag, bundled | No licence in ReadMe; VizieR says "free in a scientific context", check per catalogue. US-government origin (NSSDC); public domain unconfirmed. |
138| HYG database | Star names, distances | CC BY-SA 4.0; use only if BSC5 is not enough |
139| IAU boundaries (VizieR VI/49) | Boundaries | Same VizieR ambiguity as BSC5 |
140| Constellation lines: van der Sluys ConstellationLines v1.4 | Stick figures by HR number, bundled | CC BY 4.0. Credit: "Constellation lines: Marc van der Sluys, ConstellationLines (doi:10.5281/zenodo.10397192), CC BY 4.0." Stellarium (CC BY-SA, AGPL repo) and d3-celestial (no data licence) rejected. |
141| OpenNGC | Messier and NGC object data | CC BY-SA 4.0; ShareAlike on the data file. Decide before M5. |
142| NOAA SWPC JSON | Kp (=json/planetary_k_index_1m.json=), Kp forecast (=products/noaa-planetary-k-index-forecast.json=, array of objects), OVATION (=json/ovation_aurora_latest.json=, ~900 KB), GOES X-ray (=json/goes/primary/xrays-6-hour.json=), alerts (=products/alerts.json=) | No terms page; US government. =cache-control: max-age=60=: poll at most once a minute. |
143| NASA SDO | =assets/img/latest/latest_{512,1024,...}_{0171,0193,0304,HMIIC}.jpg= | Not copyrighted unless noted. Credit: "Courtesy of NASA/SDO and the AIA, EVE, and HMI science teams." |
144| JPL Horizons API | Spacecraft positions (Voyager 1 = -31) | No published limit; errors come back as HTTP 200, check payload. Cache server-side. |
145| CelesTrak GP | =celestrak.org/NORAD/elements/gp.php?CATNR=25544&FORMAT=JSON= | Updates every 2 h; one download per update. >50 HTTP errors in 2 h blocks the IP. Fetch only from the Worker; stop on any non-200. |
146| Launch Library 2 v2.3.0 | =ll.thespacedevs.com/2.3.0/= | 15 requests/hour anonymous (confirmed). Higher tiers via Patreon; price, commercial and attribution terms unpublished. Ask The Space Devs before launch. |
147| NASA Image and Video Library | Planet, mission and spacecraft images | Generally not copyrighted; acknowledge NASA. Insignia and logotype protected; no implied endorsement; no current astronauts in promotion. |
148| ESA/Hubble, ESA/Webb, ESO | Deep-sky images | CC BY 4.0; full credit line visible next to each image; note modifications. ESO: no commercial use of identifiable people. |
149| USGS Astrogeology | Planet and moon maps | Public domain |
150| NASA Exoplanet Archive | Exoplanets (later) | Public; bundle a snapshot, refresh periodically |
151| Historical star atlases (LoC, Linda Hall Library, Wikimedia scans) | Constellation plates | Works public domain; check each scan's terms |
152
153Track source and licence per image in the content bundle from day one.
154
155* architecture
156- iOS 26+, SwiftUI, Swift 6 language mode. iPhone first; iPad layout in
157 v1.1.
158- Packages:
159 - =SkyEngine=: Swift wrapper over Astronomy Engine's C library.
160 Coordinates, rise and set, phases, events, kō-style solar longitude
161 (shared with the parked seventy-two app).
162 - =SkyRenderer=: SwiftUI Canvas first; move to Metal if 9,000 stars
163 plus lines cannot hold 60 fps while panning.
164 - =Feeds=: typed clients for SWPC, SDO, CelesTrak, the backend. Cached
165 on disk with per-feed lifetimes.
166 - =Library=: bundled content (JSON plus images), versioned, updatable
167 from the backend without an app release.
168- Backend on Cloudflare; see [[*backend][backend]].
169- No accounts. Device registers an APNs token and a coarse latitude band
170 for aurora alerts, nothing else.
171
172* backend
173Only what the app cannot do alone: cache rate-limited feeds (Launch
174Library 2, Horizons), send pushes (aurora, launches), drive launch Live
175Activities, ship Library content updates. Positions, phases and ISS passes
176are computed on device; ISS pass alerts are local notifications. SWPC and
177SDO are public, so the app can fetch them directly if the backend is down.
178
179** Cloudflare products
180| Product | Role |
181|-
182| Workers (TypeScript) | JSON API; APNs sender |
183| Cron Triggers | Feed polling |
184| D1 | Devices, launches, alert dedupe, Live Activity tokens, ephemeris, content versions |
185| Workers Cache | Cache GET responses (=/v1/today= etc.) |
186| Queues | Push fan-out with retries, decoupled from polling |
187| R2 | Library content packs, widget-sized SDO thumbnails |
188| Workers secrets | APNs .p8 key, key ID, team ID; Launch Library 2 key |
189| Workers Rate Limiting | Per-IP limits on device registration |
190
191** APNs from Workers
192APNs requires HTTP/2. A Cloudflare engineer stated in workerd issue #4841
193(2025-08-20) that production requests pass through Cloudflare's proxy,
194which upgrades them to HTTP/2; workerd itself, and so =wrangler dev=, does
195not support HTTP/2 and there are no plans to add it. Cloudflare's docs do
196not state this. Open-source senders rely on it (e.g.
197FiveSheepCo/cloudflare-apns2). Containers (Workers Paid) can run an HTTP/2
198sender as a fallback. Spike: =spikes/apns-worker=.
199
200- Sign the ES256 provider JWT with WebCrypto; reuse it for 20–60 minutes
201 as Apple requires.
202- Test pushes against a deployed staging Worker using the sandbox APNs
203 host, never from local dev.
204- Keep the sender behind the push Queue so it can move to Cloudflare
205 Containers (a small Go or Python sender) if Workers' HTTP/2 stops
206 working, without touching the rest.
207- Delete tokens on HTTP 410.
208
209** jobs
210| Cron | Job |
211|-
212| =*/5 * * * *= | SWPC: 1-minute Kp, Kp forecast, OVATION aurora, alerts; run aurora engine |
213| =*/10 * * * *= | Launch Library 2 upcoming list |
214| =* * * * *= | If a launch is within 1 h: poll it (needs paid LL2 key); push Live Activity updates on status change |
215| =0 */4 * * *= | CelesTrak ISS and bright satellites |
216| =15 3 * * *= | JPL Horizons daily positions for ~20 spacecraft |
217
218The anonymous Launch Library 2 tier is 15 requests/hour; the 1-minute job
219needs a key. CelesTrak: never more than once per 2-hour update.
220
221** data (D1)
222- =devices=: APNs token, environment (sandbox/production), 5°
223 geomagnetic latitude band, UTC offset, preferences (aurora threshold,
224 launch alerts, quiet hours), last seen.
225- =launches=: normalized LL2 cache plus raw JSON.
226- =feed_snapshots=: latest result per feed with fetch time and status.
227- =alerts_sent=: dedupe key (type, band, storm event).
228- =live_activity_tokens=: launch, update token, device; push-to-start
229 tokens separately.
230- =spacecraft_ephemeris=: spacecraft, date, position.
231- =content_versions=: pack, version, hash, R2 key.
232
233** API
234| Method and path | Purpose |
235|-
236| =GET /v1/today= | One small payload: next launches, space weather summary, active alerts, spacecraft positions, content version. ETag. |
237| =GET /v1/launches=, =GET /v1/launches/{id}= | List, detail |
238| =GET /v1/spacecraft?ids=&from=&to== | Recent positions; full history ships in the app |
239| =GET /v1/content/manifest=, =GET /v1/content/{pack}= | Library updates from R2 |
240| =POST/PATCH/DELETE /v1/devices[/{token}]= | Register, preferences, unregister |
241| =POST /v1/live-activities= | Register an update token for a launch |
242| =GET /healthz= | Liveness and per-feed staleness |
243
244** alerts
245- Aurora: from Kp forecast and OVATION, find the latitude bands that can
246 see aurora; notify devices in those bands where it is dark, outside
247 quiet hours; at most one per band per storm.
248- Launches: "launch in one hour" to opted-in devices; push-to-start the
249 Live Activity (iOS 17.2+); update on countdown, hold, liftoff, staging,
250 orbit or scrub; end 15 minutes after the outcome.
251
252** privacy and abuse
253- Stored per device: push token, 5° latitude band, UTC offset,
254 preferences. No location, no accounts.
255- v1: per-IP rate limits. Later: App Attest verification in the Worker.
256
257** operations
258- Lives in =server/= in this repo (a separate =moonrise-server= repo is
259 optional); deploy with Wrangler.
260- Staging and production Workers with separate D1 databases and APNs
261 environments.
262- Workers Logs for errors; feed staleness in =/healthz=.
263- Likely Workers Paid plan (about $5/month) plus an optional Launch
264 Library 2 key. Check current pricing for Queues and D1 before launch.
265
266* content
267The Library is the largest piece of work.
268
269- v1: sun, 8 planets, 5 dwarf planets, ~25 major moons, 88
270 constellations, ~50 named stars, 110 Messier objects, ~40 missions.
271 About 320 pages.
272- Write in one voice: short essay plus spec sheet per page. Start from
273 NASA public-domain text where useful, rewritten.
274- Drawings for every planet and moon in the house style, generated from
275 data (radius, oblateness, rings, axial tilt) rather than drawn by hand.
276
277* milestones
278- *M0, spike.* Confirm every source, licence and rate limit above.
279 Astronomy Engine building from Swift with tests against Horizons.
280 Static sky render for one place and time. Reserve the name.
281- *M1, Sky.* Live sky with device motion, object cards, time scrubber,
282 night mode, Today sheet. Moon and planets widgets.
283- *M2, Sun.* SDO images, Kp, aurora oval, flares. Backend up; aurora
284 push.
285- *M3, Launches.* List, detail, rocket silhouettes, Live Activity.
286- *M4, System.* Orrery with time slider and spacecraft trajectories.
287- *M5, Library v1.* Solar system, constellations, stars, Messier,
288 missions. Search.
289- *1.0* = M1–M5, TestFlight, App Store.
290
291** M0 results (2026-10-17)
292- Data sources: checked; see [[*data sources][data sources]]. Open: Launch Library 2
293 commercial terms, OpenNGC ShareAlike, BSC5 licence statement.
294- =Packages/MoonriseKit=:
295 - =CAstronomy=: Astronomy Engine v2.1.19 C source.
296 - =SkyEngine=: Swift wrapper. Tests against JPL Horizons (Chicago,
297 2026-10-17 02:00 UT): apparent RA/Dec and airless alt/az for the Moon,
298 Mars, Jupiter, Saturn within 1′; heliocentric Jupiter and Saturn within
299 1′ angular (Saturn 0.00045 AU, about 10″).
300 - =SkyRenderer=: stereographic projection, 8,404 stars to V 6.5, 88
301 constellations, planets to mag 6, moon with phase, horizon. Scene
302 build 0.03 s, Canvas render of a 1179×2556 frame 0.09 s on an Apple
303 silicon Mac via =ImageRenderer=. Not measured on a device; panning at
304 60 fps (16 ms per frame) is unproven and likely needs culling,
305 pre-rendered star layers or Metal.
306- =spikes/apns-worker=: ES256 provider token via WebCrypto (unit-tested),
307 =/push= and a credential-free =/probe=. Deployed as
308 =moonrise-apns-spike=; =/probe= got APNs JSON responses (403
309 =InvalidProviderToken= with an =apns-id=) on 3 of 3 calls, so the
310 deployed Worker reaches the APNs sandbox over HTTP/2. Worker deleted
311 after the test. A real push still needs an APNs key and a device token.
312- Name reserved in App Store Connect; APNs key created (key ID 644XS4F2RG).
313
314** M1 status (2026-10-17)
315Stacked MRs: !2 app shell, !3 interaction, !4 Today sheet, !5 widgets,
316!6 device pointing.
317
318Done and checked in the iOS 27 simulator: live sky with location, drag
319and pinch, object cards, time scrubber, night mode, Today sheet (moon,
320planets, sun, live SWPC Kp), sandbox APNs token.
321
322Built but not checked:
323- Widgets: build and embed; not viewed (simulator widget gallery could
324 not be driven by automation).
325- Device pointing: maths unit-tested; needs a real phone.
326
327Not done:
328- Draw time on a real iPhone (decides Canvas vs Metal).
329- ISS passes: need an SGP4 propagator and CelesTrak data via the backend.
330- Launches and Voyager in the Today sheet: backend (M2, M3).
331- Automatic night mode after astronomical dusk.
332
333** M2 status (2026-10-17)
334Stacked MRs: !7 Sun tab, !8 backend, !9 aurora map.
335
336- Sun tab: done, checked in the simulator with live data.
337- Backend (=server/=): SWPC polling, =/v1/today=, device registration,
338 aurora alert rules and APNs sending. Unit-tested; smoke-tested under
339 =wrangler dev= with a local D1. Not deployed.
340- Simplifications against the design above: aurora pushes are sent
341 in-line from the cron (no Queue yet); "dark" is 20:00–04:00 local time
342 rather than sun altitude; no rate limiting or App Attest on
343 registration yet.
344- Aurora map: OVATION probabilities on a polar map with Natural Earth
345 coastlines; checked in the simulator.
346- Not done: app registration with the backend (needs a deployed URL),
347 launch caching, Live Activities.
348
349** M3 status (2026-10-17)
350MR !10.
351
352- Backend: Launch Library 2 upcoming list every 10 minutes (separate cron,
353 6 of 15 anonymous requests per hour) into D1; =GET /v1/launches=.
354 Smoke-tested locally with live LL2 data. LL2 images are not used
355 (licence often "Unknown").
356- App: Launches tab (list with T− countdowns, detail sheet); Debug builds
357 read the API from =http://localhost:8787= (=MOONRISE_API_URL=).
358- Live Activity: "Follow on Lock Screen" starts a local countdown
359 activity; verified on the simulator Lock Screen. Updates by push
360 (holds, scrubs, liftoff) not done.
361- Not done: rocket silhouettes to scale, push-to-start and push updates,
362 "launch in one hour" notification.
363
364** M4 status (2026-10-17)
365MR !11.
366
367- System tab: orrery with planets from Astronomy Engine (ecliptic axes),
368 log radial scale beyond 1 AU, Voyager 1 and 2, Pioneer 10 and 11 and New
369 Horizons paths from bundled JPL Horizons vectors (30-day steps to 2050),
370 time slider 1958–2050 with play, distance and light-time table. Checked
371 in the simulator.
372- =SkyEngine= now holds one recursive lock around all Astronomy Engine
373 calls, so any thread can use it.
374- Not done: tap a planet or probe for its Library page, Earth–Moon inset,
375 active missions (Juno, Europa Clipper, JUICE, Psyche, Parker, Lucy).
376
377** Deployment (2026-10-18)
378- Worker =moonrise-server= at https://moonrise-server.audit-labs.workers.dev,
379 D1 =moonrise=, crons =*/5= (SWPC) and =*/10= (LL2), APNS_KEY set.
380- SWPC polling confirmed in production (=/v1/today= serving Kp).
381- LL2 from Cloudflare returned 429 on the first run: the anonymous limit
382 is per IP and Workers share egress IPs. Needs an LL2 API key
383 (=LL2_API_KEY= secret, supported). Launches stay empty until then.
384- App Debug and Release builds use the deployed URL.
385- The app does not register devices with the backend yet, so no aurora
386 pushes are sent.
387
388* roadmap
389** v1: now
390Sky, System, Sun, Launches, Library core (above).
391
392** v2: plan, track, more devices
393- Events: eclipses, meteor showers, conjunctions, oppositions, each with
394 an observing plan. Eclipse path maps with local timings; the 2 August
395 2027 total eclipse (Spain, North Africa, Egypt) is a launch target.
396 Path maps and local timings done for every total and annular eclipse.
397- Deep Space Network Now: which DSN dishes are talking to which
398 spacecraft.
399- More satellites: Tiangong, Hubble, Starlink trains, bright passes. Done:
400 CelesTrak visual group plus one element set per Starlink launch still
401 below about 400 km.
402- Observing log stored as plain text or Org.
403- Mars: latest rover raw images, local time at each rover.
404- Library: exoplanets, rockets to scale, exploration timeline, scale
405 view. Done.
406- iPad, Mac, Apple Watch complications. Done: Mac as "Designed for iPad";
407 Watch app (Moon, Sun, planets tonight) with Moon and Planets complications.
408
409** v3: across time and cultures
410- Sky cultures: Chinese, Polynesian, Arabic, Norse and other
411 constellations over the same stars. Done for the ten CC BY-SA cultures in
412 Stellarium's set; Arabic is not included (CC BY-ND, permission granted only
413 to Stellarium).
414- Historical sky for any date and place, with precession. Done: 3000 BCE
415 to 3000 CE, with BSC5 proper motions and the pole star of the year.
416- 3D planets from USGS maps; immersive sky and orrery on Vision Pro. Done:
417 globes for the Sun, planets, dwarf planets and moons (NASA/USGS maps for 13,
418 colour for the rest); visionOS app with globes, an orrery volume and an
419 immersive star field. visionOS is compiled but not yet run (no simulator
420 runtime installed).
421- Guided seasonal sky tours and mission stories. Tours done: four, by
422 months, 5 to 8 stops each, in Library/Resources/tours. Mission stories
423 done for Voyager 1 and 2, Pioneer 10 and 11 and New Horizons, on the orrery.
424- Live coverage of major events (e.g. an Artemis landing) on the orrery
425 with a Live Activity. Done: GET /v1/live with a Horizons trajectory, an
426 Earth–Moon map on the System tab and a Live Activity. Artemis I is configured
427 as a past event for replay; add Artemis II and later missions to
428 server/src/live.ts (Horizons ID, window, phases) once their Horizons IDs are
429 published.
430- Maybe: smart-telescope pointing (Seestar and similar).
431
432* risks
433- Library scope: 320 pages is most of the effort. Ship 1.0 with fewer
434 pages before adding more.
435- Sky render performance and compass accuracy; indoor and urban magnetic
436 interference makes device-motion panning unreliable, so drag must
437 always work.
438- Third-party feed limits (Launch Library 2) and feed outages: show the
439 last good data with its age.
440- NASA brand rules: the style is borrowed, the branding must not be.
441- A crowded category (SkySafari, Night Sky, Stellarium, Next Spaceflight,
442 SpaceWeatherLive). The case for this app is all of it in one place,
443 designed well, not depth in any one area.
444
445* open questions
446- Pricing: free, paid up front, or free with a one-time unlock for the
447 Library and alerts.
448- Fallback for APNs if Workers' HTTP/2 stops working: Containers sender
449 vs. a separate small VPS. The M0 probe worked, so this is a contingency.
450- Whether the Sky tab needs AR camera overlay at all (current lean: no).