{"disclaimer":"Honesty split: SHIELD/ATLAS provides the operator-usable methods listed under 'provided' plus the operator surfaces under 'relatedSurfaces' (live breadcrumb + drift-bound + REPLOT banner on /field, operator-driven offline tile pre-cache on /field /cop /gps-denied). The 'notIntegrated' list is reference material — those external PNT systems exist in the world but SHIELD/ATLAS does NOT integrate with them as of this build. The /gps-denied page references them as conceptual nav modes for the jammer-uncertainty simulator only.","provided":{"toolkitUrl":"/pnt-toolkit","count":7,"methods":{"sunAzimuth":{"name":"Sun Azimuth (NOAA SPA)","gives":"True heading","accuracy":"±1°","requires":"Visible sun + watch + rough lat/lon","offline":true},"shadowStick":{"name":"Shadow-Stick Method","gives":"East-west line","accuracy":"±2°","requires":"Visible sun + 15-30 min wait + stick","offline":true},"polarisFix":{"name":"Polaris Fix (N hemisphere)","gives":"True north","accuracy":"±1°","requires":"Visible Polaris (lat > ~5°N)","offline":true},"southernCrossFix":{"name":"Southern Cross Fix (S hemisphere)","gives":"True south","accuracy":"±1.5°","requires":"Visible Crux + Pointers (S hemisphere)","offline":true},"twoLandmarkResection":{"name":"Two-Landmark Resection","gives":"Self lat/lon","accuracy":"~50-100m at 5km","requires":"Two visible known landmarks + compass","offline":true},"deadReckoning":{"name":"Dead Reckoning / Pace Count","gives":"Projected position","accuracy":"±5-10% of distance traveled","requires":"Known start + heading + segment log","offline":true},"magneticDeclination":{"name":"Magnetic Declination Lookup (coarse 2025-2030 epoch)","gives":"Magnetic→true conversion","accuracy":"±2-3° (verify against map marginal data)","requires":"Lat/lon + date","offline":true}},"relatedSurfaces":{"/field":"Anchor + bearing + range projection (inverse of resection — known anchor, derive target lat/lon); live operator breadcrumb (TRACK ON/OFF, watchPosition, last 10 min / 200 pts, dashed cyan polyline); accumulated distance + drift bound (foot 5%, wheeled 2%) since last anchor; REPLOT REQUIRED red banner at >200m foot / >500m wheeled; OFFLINE TILES panel for AO pre-cache","/phone":"Photo intake with EXIF GPS auto-extract; fallback to anchor+bearing+range or map tap","/cop":"Multi-track breadcrumb trails (last ~60s, ~30 pts/track) + heading vectors; OFFLINE TILES panel for AO pre-cache","/gps-denied":"Jammer-awareness + uncertainty-growth simulator (R-330Zh, Pole-21, Iranian, DPRK profiles) with per-session trajectory (≤1000 waypoints) + APPLY TERRAIN FIX endpoint + GeoJSON LineString export; OFFLINE TILES panel for AO pre-cache"},"offlineTileCache":{"mechanism":"Service Worker (/sw.js) intercepts CartoDB / OSM tile fetches and serves cache-first from CacheStorage 'shield-atlas-tiles-v1'","uiSurfaces":["/field","/cop","/gps-denied"],"actions":["PRE-CACHE WORLD (z0–z5, ~6 MB)","PRE-CACHE THIS AO (z0–z14, operator-confirmed bbox)","CLEAR CACHE"],"honestyNote":"Operator-driven, AO-specific. We do NOT ship a pre-bundled global high-resolution basemap (would violate OSM/CartoDB ToS for bulk redistribution and is not the right scope for a brigade PWA). Pre-cache happens in-garrison before deployment; tiles persist in browser cache and the basemap then works offline within the cached scope."}},"notIntegrated":{"disclaimer":"These external PNT systems EXIST in the world but SHIELD/ATLAS does NOT integrate with them. Listed for situational awareness and to be honest about scope.","systems":{"eLoran":{"name":"Enhanced LORAN (eLoran)","accuracyM":20,"available":"CONUS coastal + Northern Europe","latencySec":0.1},"leoPNT":{"name":"LEO PNT Constellation","accuracyM":5,"available":"Global (emerging)","latencySec":0.05},"atomicClock":{"name":"Chip-Scale Atomic Clock (CSAC)","accuracyM":0,"driftPerHour":100,"latencySec":0,"note":"Timekeeping only — enables INS"},"inertialNav":{"name":"Inertial Navigation System (INS)","accuracyDriftPerKm":15,"available":"Always","latencySec":0},"terrainMatch":{"name":"Terrain Matching (TERCOM/DTED)","accuracyM":10,"requiresDTED":true,"available":"Pre-loaded terrain required"},"visualOdometry":{"name":"Visual Inertial Odometry (VIO)","accuracyDriftPerKm":5,"requiresCamera":true,"available":"Camera + SLAM algorithm required"}}},"peerTriangulation":{"toolkitUrl":"/peer-locate","method":"Operator-assisted resection from peer GPS broadcasts via Gauss-Newton least squares on a local tangent plane. Output is a 1σ confidence ellipse (major × minor × orientation) computed from cov = σ²·(JᵀJ)⁻¹ — not an isotropic circle.","ingestPaths":{"auto":"Peers who can see the GPS-denied target POST their range to that target's callsign. The /peer-locate page polls /api/nav/peer-observations/:target every 5 s; the moment 3+ observations are within ±60 s AND have fresh (≤60 s) observer beacons, the solver fires automatically and renders a green ellipse.","manual":"GPS-denied operator picks 3+ peers from the active beacon list and enters their own operator-estimated ranges. Same solver, amber ellipse to distinguish it from auto fixes.","fallback":"When fresh peers drop below 3 mid-session AND a previous AUTO fix exists, the page switches to dead-reckoning extrapolation from the last good fix using operator-set heading + speed × elapsed × 1.5 (worst-case multiplier matching gps-denied-nav.ts dead_reckoning case). Snaps back to AUTO the moment a 3rd fresh observation arrives — poll never stops.","fallbackPrecondition":"DR fallback REQUIRES a prior valid AUTO fix to anchor from. On a cold start with <3 fresh observations and no prior fix, the page does NOT extrapolate — it explicitly redirects the operator to /pnt-toolkit (map resection from terrain features) or /field (breadcrumb DR from a known last waypoint). This is intentional: extrapolating from no anchor would invent a position out of nothing."},"interoperability":{"schema":"JSON over HTTP only — fixed shape documented in `api` block above. We do NOT parse TAK Cursor-on-Target (CoT) XML messages, ATAK protobuf bundles, or USMTF NAV-track formats. A CoT-emitting client must wrap its outbound feed in a small adapter that POSTs the {observer_callsign, target_callsign, range_m, method} JSON.","rationale":"Strict CoT/ATAK parser compatibility is out of scope for this PWA — we have no CoT schema validator, no XML namespace handling, and no MIL-STD-2525 cot.event<->JSON mapping. Adding one is a non-trivial follow-up that should be a separate task with explicit acceptance tests against TAK Server pcap fixtures.","adapterShape":"Minimal client-side adapter: pull peer-callsign + own-callsign + range_m from any source, fetch('/api/nav/peer-observation', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ observer_callsign, target_callsign, range_m, method }) })."},"api":{"postBeacon":"POST /api/nav/peer-beacon  body: {callsign, lat, lon, accuracy_m?, source?}  — broadcaster reports own GPS","listBeacons":"GET /api/nav/peer-beacons  -> {count, ttl_s, beacons:[{callsign, lat, lon, accuracy_m, source, ts, age_s}]}","deleteBeacon":"DELETE /api/nav/peer-beacon/:callsign  (admin-secret gated when INTEL_ADMIN_SECRET set)","postObservation":"POST /api/nav/peer-observation  body: {observer_callsign, target_callsign, range_m, method}  — observer reports range to a teammate, used by AUTO solve","listObservations":"GET /api/nav/peer-observations/:target  -> {totalObservations, freshObservations, readyToSolve, solve_window_s, observations:[{...,fresh,observer_lat,observer_lon,observer_age_s}]}  — primary AUTO-MODE poll endpoint","deleteObservation":"DELETE /api/nav/peer-observation/:observer/:target  (admin-secret gated)","selftest":"GET /api/nav/peer-locate/selftest  — synthesizes 3 observers + observations, asserts readyToSolve=true and ellipse axes finite (HTTP 500 on regression)"},"store":{"backing":"in-memory Map<callsign, beacon> + Map<observer|target, observation>","ttl_s":300,"maxBeacons":200,"maxObservations":500,"solveWindow_s":60,"persistence":"none — lost on server restart"},"gives":"Self lat/lon estimate with 1σ confidence ellipse {major_m, minor_m, theta_deg} rendered as a 64-vertex Leaflet polygon. AUTO fixes in green, MANUAL fixes in amber, DR fallback in red.","accuracy":"Dominated by operator range-estimate error (typically 10-30%); geometric fit converges in <10 iterations for well-conditioned 3+ peer geometry. Ellipse anisotropy reveals geometry-dependent uncertainty (e.g. major:minor 1.65:1 for a triangle with one off-axis peer).","requires":"AUTO: 3+ peers with active GPS broadcasting AND each one POSTs an observation targeting this callsign within ±60 s. MANUAL: same minus the observation POSTs (operator enters ranges directly).","timeSync":"Server uses Date.now() at observation receipt; freshness = observation_age_s ≤ solve_window_s AND observer_beacon_age_s ≤ solve_window_s. No NTP requirement on peer clients — the server timestamp is authoritative.","offline":false,"honestyHardNots":["We do NOT do hardware ranging between phones — the web platform exposes no API for RSSI, time-of-flight, angle-of-arrival, or UWB. Real TAK/ATAK peer-trilateration plugins use radio-layer primitives a PWA cannot reach. Every range_m is operator-reported (eyeball, pace count, map measure, landmark, or a handheld rangefinder if equipped).","We do NOT provide an authoritative GPS substitute. The fix narrows your uncertainty; it does not replace a satellite fix.","We do NOT provide an encrypted, authenticated, or trust-verified beacon channel. POSTs are anonymous; any teammate can broadcast. The store is in-memory and brigade-internal demonstration only. Production deployment must add per-callsign trust and transport security.","We do NOT use AI for the position solve. It is browser-side Gauss-Newton on a local tangent plane with closed-form 2×2 eigenvalue decomposition for the ellipse.","DR fallback is honest extrapolation, not a sensor reading. The drift radius assumes the operator's stated heading and speed are correct; in reality DR error compounds with heading drift on a phone IMU. Cross-check with map resection or breadcrumb on /field whenever possible."]},"hardRules":["All seven provided methods are decision support — operator confirms before any fires-related action.","We do NOT auto-derive position from photo via visual landmark matching against an imagery library — that is a separately licensed product class (Pictometry-based) and we do not claim it.","We do NOT integrate with eLoran, LEO PNT constellations, CSAC chip-scale atomic clocks, military-grade INS, TERCOM, or VIO/SLAM systems.","Peer triangulation is operator-assisted only — no hardware ranging, no encrypted channel, no trust verification. See peerTriangulation.honestyHardNots for the full list.","AI does not author ballistic numbers or position fixes. The math on /pnt-toolkit and /peer-locate is astronomy and geometry, not fires."]}