Status & Roadmap¶
The single honest view of what is implemented today versus planned. Every maturity caveat elsewhere links here.
Implemented today¶
| Capability | State | Where it lives |
|---|---|---|
| SIDC / MIL-STD-2525E / APP-6E symbology | Implemented | common/src/sidc/ (parser) + mil-sym-android (Android) / mil-sym-ts (web) renderers |
| ADatP-3 formatted text (OPREP, INTREP, SALUTE) | Implemented | gateway/src/formats/adatp3.rs |
| CoT / TAK exchange | Implemented | gateway/src/formats/cot*.rs, tak_protobuf.rs |
| NFFI / STANAG 5527 blue-force tracking | Implemented (file export) | gateway/src/formats/nffi.rs |
| STANAG 4774/4778 classification labels | Implemented | common signed-cleartext labels and policy; first-party receive gates; server/src/storage_validator.rs for retained values |
| Zenoh transport routing (relay + federation) | Implemented | server (Zenoh router; private-CA TLS mesh, optional deployment-wide mTLS) |
| FIDO2 identity + token issuance | Implemented | directory (FIDO2 login, signs IdentityToken/ServerToken) |
| Capability-bound classification enforcement | Implemented | Directory-issued ceilings; first-party receive gates for LIVE values; server/src/storage_validator.rs for retained ingest/replay |
| Token-only identity (no client-cert PKI) | Implemented | directory (token-only enrollment), common proto (cert fields removed); only transport/federation TLS uses certs |
Force-tracking ingest API (/api/feed/*, Epic 14) |
Implemented | web (HS256 JWT API credentials, scopes, op-claims, revocation registry); see protocol/ingest-api.md |
| Targeting board + target state machine + effects/weaponeering | Implemented | web (detected→…→assessed, append-only target_transitions; effects offered→allocated→expended) |
| Detections / force observations | Implemented | web (op-scoped, kind detection | ew_emitter, source_kind provenance, CAT-1/TLE) |
| Client-side track fusion | Implemented | web (identity dedup + spatial gating + confidence + merge/split; server-side fused_tracks deferred) |
| EW zone / emitter authoring | Implemented | web (jamming / gps_denial / ao / fire-control zones; directional-lobe / 3D-volume emitters) |
| COP decision-support client | Implemented | web (fused COP, threat rings, TCM catalog) |
| Planning — orders over plan records, replay export | Implemented | web (orders editor over plan_records; seq versioning, all versions kept; NDJSON replay/ORK export schemaVersion: 1; estimate + plan versions + sync-task store retired — execution is the tasks[] table/timeline lenses) |
| Comms matrix | Implemented | web (ORBAT rows × nets, roles ★/●/◌, petra|radio carriage; read-side, not live transport) |
| Voice replay recorder | Implemented | web (server-side archive with exact relationship-derived subscription authority) |
| Original endpoint-signed voice authority | Implemented | common (LIVE_PUBLICATION composition + three opaque address domains), server (byte-transparent envelope/attachment relay), android / web (exact capability-derived subscriptions and original endpoint verification before audio decode) |
| Server-blind E2E content confidentiality | Implemented (live fleet-wide) | common (SealedContent + GroupKeyManager), server (payload-blind), android / web / node / gateway (seal+open, fail-closed); only heartbeats plaintext. No dual-read path — cutover complete. See security/model.md |
| Revocation typestate verify | Implemented | common (VerifiedEnvelope::authorize(&RevocationSnapshot) → AuthorizedIdentity), server (storage_validator for retained values) |
In progress / transitional¶
Authority and Server hard-cut candidate¶
The coordinated candidate removes the application auth handshake and every legacy reader,
address, token, and connection path. It adds automatic Web operation authority, Web's
closed all-cell publication/recording profile, automatic loss/capture group-key rotation,
generalized opaque addressing, endpoint-local ServerToken binding, authenticated
RetainedReplayReceiptV2 completion, and atomic three-file Server credentials.
This behavior is not live production. It remains release-gated until all component PRs are final and merged at one Common revision, Infrastructure stages all three Server credential files atomically, and the integrated rack deployment passes the hard-cut runout. No candidate component may be deployed into the current fleet alone.
Android WARP and owned-name cutover¶
The bearer-neutral connectivity decision records the
reproduced stale numeric-UID failure in Android per-app WARP and the bounded v1 remedy:
full-device WARP, an owned private namespace, explicit Android HTTP/Zenoh recovery, layered
diagnostics, one cloudflared connector on core-01, and ordinary LAN routing inside the
single rack. Cloudflare Mesh is deferred until physical rack-to-rack connectivity exists;
OpenWrt, HaLow and customer-radio configuration remain outside PETRA.
The blank tunneled_apps child and its Uids: <{}>/NXDOMAIN result remain the reproduced failed
canary, but they are no longer the handset's current state. On 2026-08-31 the canary-only
Cloudflare One App Configuration assignment was removed while the managed install and existing
organisation enrollment remained. ConnectivityService then reported a validated Cloudflare VPN
with exactly two coupled gaps: Google Play Store application UID 10145 and its Android-derived
SDK-sandbox companion UID 20145. Chrome and PETRA were covered without package selectors. Two
approved PETRA uninstall/reinstall canaries changed its UID from 10330 to 10331, then from
10331 to 10332, without restarting Cloudflare One. After the second reinstall the validated,
non-bypassable VPN still covered 0-10144, 10146-20144 and 20146-99999: only the approved
Play Store pair was outside it, while PETRA UID 10332 was inside. Private-name resolution,
Chrome WebAuthn, native Directory key/group-key/capability refresh and both configured Zenoh
router routes passed; the user reports being logged in. This closes the stale PETRA
numeric-UID failure and proves PETRA/Chrome route continuity under the approved exact-Play-Store
exception. The exception remains fail-closed: runtime evidence must prove the active user's
exclusive Cloudflare One and Play Store UIDs. On API 33 and later it must treat the Play Store
UID and its derived companion as one atomic pair; earlier supported releases have only the
application UID. One-sided, hard-coded or unrelated gaps and application allow-lists still fail.
It does not complete the release or DDIL gate. Android
#337 is merged with green CI and a signed
arm64 artifact. Infrastructure
#205 generates the complete Android
tile and overlay catalogues with their DDIL cache policy, and
#206 selects the new Android source
and signed artifact in the canonical schema-v4 release lock without changing the locked Common,
Directory, Server, Web, Node, Gateway or Zenoh bridge rows. The phone first ran the prior exact
locked signed candidate at version code 760, not a local diagnostic build. On 2026-09-01
Hexnode then delivered the newly locked version code 762 in place to canary
34131JEHN16560: PETRA retained UID 10332, the APK pulled from the device matched the locked
artifact byte for byte, and the repository's authoritative full-device WARP checker passed. The
preserved session refreshed the Directory key, group key and capability, then reported both rack
routers live. This proves the reviewed candidate can replace the prior signed build without an
uninstall or application UID change while the existing Cloudflare VPN remains connected.
Android #338 then corrected the live
position and heartbeat publication keys to use Directory-authorized opaque principals rather
than the raw signing key. Android
#339 fixed the separate receive-side
failure: valid Common/Prost capabilities use packed repeated-enum fields, while re-encoding them
with Wire may use an equivalent unpacked form, so application-side byte comparison had wrongly
sent position and heartbeat through the voice-only verifier. The fix preserves the original
capability bytes for Common verification and exposes stable rejection reason codes rather than
R8-obfuscated class names. On 2026-09-01 the exact signed version-code 764 artifact was installed
on two attached Pixel 7a handsets. Each reported 2 connected / 2 total, accepted the peer's live
position, and produced a clean trace with zero verification failures or verification drops.
Infrastructure #207 selects that
artifact and Directory's merged USB-first WebAuthn recovery build in the canonical release lock;
offline validation, the full Infrastructure suite, authenticated publication provenance and an
independent release-readiness review all pass. This is two-handset application evidence on the
current working network profile, not a managed rollout, owned-name cutover, WAN-mobility,
router/connector failure, transport-fallback or DDIL runout result.
Android #343 then separated structural
network changes from Android's frequent capability telemetry. The old log suffix 109 was the
Android network identifier, not a capability or error code. Repeated RSSI/bandwidth-only callbacks
remain inputs to the bounded recovery scheduler but no longer evict healthy HTTP pools or emit
INFO-level change events. Android #342
removes the compiled-in public MapLibre glyph endpoint: deployments may supply one managed HTTPS
glyph template, while an omitted template issues no glyph request. MapLibre also uses a
redirect-disabled client, so a configured HTTPS glyph request cannot be redirected to another
target or cleartext transport.
On 2026-09-02 the exact signed version-code 767 artifact was installed in place on both Pixel 7a
handsets without clearing application data; their original first-install timestamps and logged-in
sessions were preserved. Both resumed the live map, reported 2 connected / 2 total, and showed
SNAPSHOT READY • HEAD 0s. In an extended post-install sample the two handsets recorded 104
netId=109 and 17 netId=112 callbacks, all as VERBOSE telemetry; after the one-time network
registrations, no repeat was logged at INFO. Across both handsets there were no transport-restart
lines, AndroidRuntime/MapLibre errors or native fatals. Infrastructure
#209 selected this then-current exact
signed artifact; the 149-test Infrastructure suite, offline lock validator and authenticated
publication-provenance check pass.
Android #345 subsequently suppresses the
remaining VERBOSE capability-telemetry log while retaining those callbacks as bounded recovery
inputs. Its signed version-code 769 artifact is now the authoritative candidate selected by
Infrastructure #215 in the canonical
schema-v4 release lock, superseding #209's v767 selection. Consistent with the single-source rule
below, exact source, publication and artifact identities remain in that lock. No v769 live mutation
or validation has occurred: both connected Pixel 7a handsets still run the exact signed v767 build
and await a separately approved install/cutover.
The new petra.json catalogue is deliberately not applied through Hexnode yet. The canary still
reports the working .lan Directory/Web/router profile with zero managed tile or overlay sources.
All five owned names required by the staged petra.json profile returned unknown host from the
same validated WARP device, the GCS Terraform state was empty, and the reviewed saved plan still
contained nine creates with no change or destroy. Applying the MDM payload before the separately
approved Cloudflare/rack cutover would therefore replace a working canary with unreachable
endpoints. Infrastructure
#200 makes Ansible address the rack
through its authoritative inventory IPs without depending on the .lan path it may need to
repair. On 2026-09-01 a no-op SSH probe reached core-01, core-02 and media-01 through those
addresses; this proves the current controller layer-3/SSH path, not rack converge or service
health. The separately approved v769 install/cutover, the owned-name/CA cutover and managed-profile
verification, epoch rotation, cached-DDIL loss/recovery, Wi-Fi/WAN movement, router/fallback
exercises, archived evidence, deviations and sign-offs all remain open.
PETRA 1.0 DDIL data plane¶
The Android/infrastructure runout contract is now explicit: first-party Android receives one ordered, device-scoped MDM locator list (primary QUIC, primary TLS, alternate QUIC, alternate TLS). ServerTokens validate configured identities and coverage but never add, reorder, or promote routes. Cold restart and same-cell primary loss therefore require no application reconfiguration; after both paths fail, cached authority remains bounded by the signed offline horizon. The Infrastructure #125 fixture is deliberately non-HA and does not provide election, state replication, physical fault isolation, or lossless failover. This is an operator contract; its remaining claim is the human-observed rack gate, not unfinished endpoint implementation. The fixed list is intentional: runtime token promotion is nondeterministic after same-cell failure, while a manual alternate-path edit violates the no-reconfiguration runout procedure. See docs #125 and Infrastructure #125.
The normative PETRA 1.0 contract and its component
implementation waves through Phase 4 are complete. Server uses the generic verified
Storage/Queryable boundary; Node, Gateway, Android, and Web consume authenticated
Directory-issued complete capability sets and opaque addressing; reconnect barriers
replace grants atomically before shared traffic or outbox drainage. Connected authority
uses the actor-signed mutation wire and Directory-owned Web core relationship from
Docs #145,
Common #202, and
Directory #150. Direct browser
traffic uses the FIDO-bound, one-hour, memory-only human capability contract from
docs #147 and
Directory #152; bearer-only
sessions and unsigned member liveliness remain ineligible. The
authoritative-snapshot contract
is defined and its eight-family implementation wave has landed. Common owns the closed
wire, hostile corpus, semantic scope binding, heads and authenticated catalog; Directory
issues exact snapshot publication/query authority; Server retains and replies through the
generic verifier; Web maintains one transactional class-2 ledger and produces complete
DRAWING, TARGET, CHANNEL, INVITE, PLAN, REPORT_REQUIREMENT, SITREP_CURRENT,
and ORBAT cuts; and Android performs exact-head/catalog discovery, atomic replacement,
revision-floor/tombstone merge, and visible beyond-horizon recovery. SITREP_CURRENT is a
durable Web-derived read model per operation, current requirement, expected unit and
period; it commits audit evidence and never reconstructs a submitted ReportRecord or
endpoint authorship. The implementation wave includes
Common #219,
Directory #162–#166,
Server #152,
Android #297 and
#300, and
Web #638–#643.
One final contained simplification was deliberately pulled into the 1.0 candidate before physical runout. Android #270, implemented by #314 with the self-describing state-update follow-up #315 and explicit-state readability hardening #316, replaces the parallel Chat and Voice channel-state implementations with one family-neutral ordering, tombstone, ownership, membership, classification, and exact-key algorithm. Chat/Voice wire codecs and Room table adapters remain explicit; local roles are represented as a named role set rather than a positional Boolean sequence. Delivery provenance, membership actions, sender authority, operation channel kinds, publish state, map command mode, and position upserts are also explicit, while independent named UI flags remain Boolean. The issue was moved into the PETRA 1.0 milestone and closed before staging rather than carrying the duplicate algorithms into runout.
Bounded-retention implementation and its reproducible pre-runout evidence are merged.
Server #160 enables the reviewed
per-family horizon table, bounded RocksDB retention, configuration guards, and
reproducible capacity/eviction/rejection tests; its 1,024-cycle physical RocksDB/RSS soak
drives about 2.4 GiB of churn while proving the retained set and process memory remain
bounded. The hard cut leaves only /health on the plaintext HTTP listener; retention
diagnostics stay in structured logs and tests rather than a plaintext metrics endpoint.
Common #220 supplies one
exact cross-language Directory/Web/endpoint-signed recovery fixture. Android
#302 drives that fixture through the
production capability cache, two independently nonce-bound catalog passes, exact head and
retained manifest/chunk verification, decryption, Room projection, tombstone precedence,
and the sticky incomplete-transient-history indication after the horizon. Web
#644 rebuilds a fresh cut through the
production repository, snapshot service, scheduler and outbox from the retained class-2
ledger while proving the audit bytes remain unchanged. Server
#162 physically destroys and recreates
two RocksDB-backed Relay + Storage caches, then republishes and queries the exact signed
manifest and chunk bytes through the production verification boundary. Together these
merged paths cover the remaining all-cache reprovision criterion. This completes
Server #139 and releases its
bounded-revocation dependent #141.
The flag-day candidate selection is recorded only in Infrastructure's
canonical schema-v4 release lock.
Common #221 established the Common 0.21
contract; subsequent contained maintenance waves preserve its wire and storage compatibility.
The lock selects the exact Common and component source revisions, successful publication runs,
OCI index/Linux-amd64 pairs, and signed Android asset. Docs deliberately does not duplicate
those deployable identities. The offline validator, release-lock tests, repository CI,
independently reproduced APK digest and signature, and separate read-only
publication-provenance gate all pass. Publication evidence also confirms the unchanged Zenoh
1.10 index remains in GCP Artifact Registry.
The Android WARP canaries recorded above do not broaden the approved narrow exception: it covers
only the Play Store application UID and Android's derived SDK-sandbox companion as one atomic
pair, not arbitrary uncovered UIDs. Read-only device-policy state rules out an MDM
always-on/lockdown exemption, and the installed Cloudflare One 2.5.5 APK itself calls Android's
addDisallowedApplication("com.android.vending") while constructing its full-device tunnel.
Archived evidence remains fail-closed unless it derives and verifies that exact pair at runtime
on API 33 and later, or the single application UID on an earlier supported release, and also
proves exclusive Cloudflare One and Play Store UID ownership. The installed v767 build's
two-handset presence exchange passes on the current working profile; the authoritative signed and
locked v769 candidate has not been installed or live-validated. The prior v762 candidate's in-place
installation, WARP scope, Directory refresh and two-router liveliness checks also pass on the
original canary. The separately approved v769 install/cutover, applying petra.json, the
owned-name/CA cutover, rack partition/DDIL scenarios and human sign-off remain unverified on
deployed hardware.
The longest representative integrated load and human-observed rack exercise remains
the demo-rig runout #125.
Cold recovery includes the authenticated Web partition catalog: Directory issues the
bounded purpose-3 query selectors, Web reports the complete exact classification inventory
inside those selectors, and Android remains visibly blocked until two catalog passes are
stable and every ready partition has passed its own fresh exact-head flow.
The exact recorder-relationship authority, durable PlanAcknowledgementV1,
drawing-derived sensor plane, Gateway (verified principal, origin_uid) track identity,
original endpoint-signed voice path, mandatory signed callsign, and framed opaque
addressing changes are all included in this one-Common candidate. PETRA 1.0 remains a
flag-day reset: operators stop traffic, stage every component from the lock, wipe
pre-cutover credentials and retained development/test state, and re-enrol subjects.
No legacy address, reader, token, or Common-revision compatibility path survives release
entry. Connected edge channel creation uses only the full ordered
Directory-authorized operation contexts and creatable channel kinds in the signed
complete capability refresh; Android keeps disconnected creation as an inert local
draft until Directory activation succeeds.
-
Docs #149: Stock-Zenoh live audience isolation has an accepted 1.0 residual. First-party subscribers must use the smallest relationship-derived exact opaque channel, cell, command-target, and acknowledgement selectors and must verify every original LIVE publication before decode. Durable
QUERYremains capability/proof/revocation-gated by Relay + Storage. Stock Zenoh does not expose a PETRA capability-aware subscriber admission boundary, however, so a transport-reachable endpoint that holds the current deployment group-key epoch can widen a live subscription and decrypt observed traffic, including after app-layer revocation but before rotation. Revocation plus group-key rotation denies the next epoch. PETRA 1.0 adds no lease wire, Relay plugin, broad ack/sensor selector, or Zenoh fork and makes no immediate-withdrawal claim. Docs #151 tracks audience-specific encryption as the preferred post-1.0 remedy; a narrow upstream admission hook may be explored only as optional defence in depth. -
Server-side
fused_tracksdeferred. Track fusion is client-side only today; a server-side fused-track table is not yet built. - Sync-task / comms-net realtime publication deferred. These are authored and read in
webbut have no live cross-repo publication path; the NDJSON replay/ORK export bundle is the only cross-repo surface for them today.
Planned¶
| Standard | Where it will live | Doc |
|---|---|---|
| Link 16 (MIL-STD-6016 / STANAG 5516) | gateway/src/formats/ (no adapter yet) |
link16-track-ingest |
| Link 11B (STANAG 5511) | gateway/src/formats/ (no adapter yet) |
link11b-serial-ingest |
| VMF (MIL-STD-6017) | gateway/src/formats/ (no adapter yet) |
vmf-binary-messaging |
| MIP / DEM | gateway/src/formats/ (no adapter yet) |
mip-dem-exchange |
| NVG (NATO vector graphics) | gateway/src/formats/ (no adapter yet) |
nvg-tactical-graphics |
| OTH-Gold maritime | gateway/src/formats/ (no adapter yet) |
oth-gold-maritime |
| HLA simulation | gateway/src/formats/ (no adapter yet) |
hla-simulation |
| WMS (OGC) map tile layers | Not started (MapLibre supports WMS natively) | wms-map-sources |
Known gaps¶
- Directory horizontal scaling (HA prerequisite). Making the data tier highly available
(Postgres replication + backup) is an infrastructure choice. But the Directory
application assumes a single replica today: its nonce store and per-device refresh
rate limiter hold state in process memory, which would have to move behind Postgres before
more than one Directory instance could run behind a load balancer
(
directory:app/domains/api/service_token_refresh_limiter.ts). Until that app change lands, Directory availability is bounded by a single instance regardless of database HA. (The signing key is already DB-backed and re-read per mint, so it is not a blocker.) The Directory is the system's only true SPOF — while it is down no new logins or tokens are issued, though already-issued tokens keep the live mesh running. Routers do not need HA — they are relays whose redundancy comes from running federated peers (see Deployment topology → What needs HA).
PETRA 1.0 candidate status refreshed on 2026-09-02 against the live roadmap and canonical schema-v4 Infrastructure release lock. That lock is the sole deployable candidate record; Docs does not duplicate its component revisions or publication identities. The mobile-rack code wave, immutable publications and Android v769 release-lock update are merged with green CI. v769 is the authoritative signed and locked candidate, but both attached Pixel 7a handsets still run v767; their bounded checks above do not validate v769. The separately approved v769 install/cutover, the new managed profile and remaining rack/owned-name changes remain undeployed. The controller addressing fix is merged and its no-op all-host SSH reachability proof passes; no converge or service-health claim follows from that probe. Physical staging, the human-observed rack matrix, archived running-state evidence, deviation disposition, and four-party sign-off remain explicitly open in Docs #125.