Skip to content

Commit 78c7219

Browse files
thebenternCopilot
andauthored
Add Apple TAK v2 protocol spec and docs (#1838)
* Add Apple TAK v2 protocol spec and docs Introduce a complete back-spec for the TAK v2 integration on Apple: adds wire protocol contract, data model, spec, quickstart, research, plan, tasks, and verification checklists. Documents port assignments (72/78/257), V2 zstd flags and MTU handling, V1 ATAK_PLUGIN/ATAK_FORWARDER behavior, TAK server lifecycle (NWListener/TLS/keepalive), offline-queue rules, filename/XML sanitization, and cross-platform interop caveats. Intended as a retroactive, cross-repo parity reference for reviewers and implementers. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 7a2b108 commit 78c7219

9 files changed

Lines changed: 2137 additions & 0 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Protocol Integration Checklist: TAK v2 Protocol Integration (Apple)
2+
3+
**Purpose**: Validate Apple-side TAK v2 requirements quality, completeness, and clarity across all spec dimensions — three wire formats, NWListener lifecycle, SwiftUI surface, platform constraints, and cross-platform interoperability with Android.
4+
**Created**: 2026-05-14
5+
**Feature**: `specs/010-tak-v2-protocol/spec.md`
6+
**Focus**: Full-breadth requirements quality | back-spec review gate | cross-platform parity coverage
7+
**Depth**: Standard
8+
**Audience**: Reviewer (cross-platform; Android maintainer in the loop)
9+
10+
---
11+
12+
## Constitution Compliance (Apple)
13+
14+
- [x] CHK001 — All TAK logic resides in `Meshtastic/Helpers/TAK/`, `AccessoryManager+TAK.swift`, and `Views/Settings/TAKServerConfig.swift` — no scattered TAK code outside these locations? [Consistency, Spec §Source-Set Impact]
15+
- [x] CHK002 — Zero-lint-tolerance verified — `xcodebuild test` commands documented in `plan.md` § Constitution Check? [Consistency, Spec §Design Standards]
16+
- [x] CHK003 — SwiftUI-only surface confirmed for the TAK config screen — no UIKit storyboards / AppKit imports? [Consistency, Spec §Architecture]
17+
- [x] CHK004 — Privacy assessment confirms CoT payload content is never logged at non-debug levels (debug-only `Logger.tak.debug` logs are gated)? [Clarity, Spec §Privacy Assessment]
18+
- [x] CHK005 — Design Standards review scoped to all TAK-surface views (`TAKServerConfig`, `TAKModuleConfig`, `TAKIdentitySection`, "Route Received" notification body)? [Completeness, Spec §Design Standards]
19+
- [x] CHK006 — Verification commands documented for the full Apple TAK scope (test files + scheme) not just generic `xcodebuild build`? [Completeness, Spec §Plan Constitution Check]
20+
21+
## Requirement Completeness — Wire Protocol (V2 + V1 ATAK_PLUGIN + V1 ATAK_FORWARDER)
22+
23+
- [x] CHK007 — Apple's THREE wire formats explicitly enumerated (V2 port 78, V1 ATAK_PLUGIN port 72, V1 ATAK_FORWARDER port 257)? [Clarity, Spec §Summary, wire-protocol.md]
24+
- [x] CHK008 — Wire byte budget (225 bytes after Meshtastic framing within 237-byte LoRa MTU) specified with the same arithmetic as Android? [Clarity, Spec §FR-001 NFR-001]
25+
- [x] CHK009 — zstd dictionary selection (aircraft vs non-aircraft) documented as SDK-internal (vs. Android documenting the selection in app code)? [Completeness, research.md §R1]
26+
- [x] CHK010 — `flags = 0xFF` (uncompressed TAK_TRACKER) handling documented for the receive path? [Coverage, wire-protocol.md §Flags Byte Encoding]
27+
- [x] CHK011 — Apple's V1 ATAK_FORWARDER format (zlib + LT codes) documented in wire-protocol.md with the Apple-only interop caveat? [Gap, research.md §R6, wire-protocol.md]
28+
- [x] CHK012 — V2 send "what happens when compression fails" specified — Apple throws `AccessoryError.ioFailed` from `sendCoTToMeshV2`; bridge logs and aborts? [Clarity, Spec §FR-004]
29+
- [x] CHK013 — Port numbers (72, 78, 257) referenced via `PortNum.atakPlugin / atakPluginV2 / atakForwarder` enum constants throughout the implementation? [Clarity, wire-protocol.md §Port Assignments]
30+
- [x] CHK014 — Behavior when V2 packet arrives on a v2-incapable firmware specified — Apple receives on all portnums regardless? [Coverage, Spec §FR-005]
31+
32+
## Requirement Completeness — Type Mapping
33+
34+
- [x] CHK015 — V2 CoT type coverage delegated to the SDK (vs. Android enumerating in app code) and Apple does not duplicate the type list? [Completeness, data-model.md §Enum Mappings]
35+
- [x] CHK016 — Behavior for unknown CoT types on V2 documented — SDK parser throws; bridge logs and aborts (no fallback to V1)? [Clarity, Spec §Edge Cases]
36+
- [x] CHK017 — V1 ATAK_FORWARDER classifier (`GenericCoTHandler.classifySendMethod`) outputs documented (`.takPacketPLI`, `.takPacketChat`, `.exiDirect`, `.exiFountain`)? [Completeness, data-model.md §V1 ATAK_FORWARDER Classification]
37+
- [x] CHK018 — Bidirectional CoT preservation (source XML → V2 → wire → V2 → CoT XML → TAK client) maintains shape geometry via `sourceEventXml` preference? [Coverage, Spec §FR-011, research.md §R12]
38+
39+
## Requirement Completeness — Server Lifecycle (NWListener)
40+
41+
- [x] CHK019 — Failure modes beyond "port in use" documented — cert load failure, NWListener .failed state, TLS setup failure surface in `TAKServerManager.lastError`? [Coverage, Spec §Edge Cases]
42+
- [x] CHK020 — Maximum concurrent client count specified — not bounded in `TAKServerManager` (practical limit set by `NWListener` defaults; document in tasks.md as a future hardening)? [Gap, tasks.md T100]
43+
- [x] CHK021 — Graceful shutdown documented — `stop()` cancels keepalive tasks, closes connections via `NWConnection.cancel()`, removes from `connectedClients`? [Coverage, data-model.md §State Machines]
44+
- [x] CHK022 — 10-second keepalive interval traceable to ATAK's 15-second `RX_STALE_SECONDS` with margin? [Clarity, Spec §FR-007, wire-protocol.md §Keepalive]
45+
- [x] CHK023 — Behavior during iOS interruptions (incoming phone call, screen lock, app backgrounding) documented as bounded by BLE-peripheral background mode? [Gap, Spec §NFR-002, research.md]
46+
- [x] CHK024 — Offline queue FIFO eviction at enqueue time (oldest evicted when 50-cap is hit) documented? [Clarity, Spec §FR-014, data-model.md §Offline Queue Entry]
47+
- [x] CHK025 — Multiple-client-reconnect behavior — each client's `onClientConnected` triggers `drainOfflineQueue` independently; documented? [Coverage, data-model.md]
48+
49+
## Requirement Clarity — Legacy Fallback (Apple-only V1 ATAK_FORWARDER)
50+
51+
- [x] CHK026 — V1 ATAK_FORWARDER's Apple-to-Apple-only nature explicitly stated? Android peers act as opaque relays? [Clarity, Spec §Summary, wire-protocol.md §Interop Caveat]
52+
- [x] CHK027 — `.exiDirect` vs `.exiFountain` decision rule documented — single fragment if zlib output fits one MTU; else LT-coded? [Completeness, data-model.md §V1 ATAK_FORWARDER Classification, contracts/wire-protocol.md]
53+
- [x] CHK028 — Fountain receive timeout behavior documented — receiver waits for enough LT fragments to decode; drops silently on timeout? [Coverage, Spec §Edge Cases]
54+
- [x] CHK029 — Why Apple keeps ATAK_FORWARDER while Android dropped it — documented with rationale in research.md §R6? [Completeness, research.md]
55+
56+
## Requirement Clarity — V1 ATAK_PLUGIN Interop with Android
57+
58+
- [x] CHK030 — Apple ↔ Android PLI / GeoChat interop on port 72 explicitly asserted in both `spec.md` and `wire-protocol.md`? [Clarity, Spec §Summary, wire-protocol.md §Port Assignments]
59+
- [x] CHK031 — Bridging loss for non-PLI / non-GeoChat from Android-on-2.7.x to Apple-on-2.7.x documented (Android drops, Apple-only ATAK_FORWARDER doesn't help)? [Coverage, Spec §FR-012, Spec §Summary]
60+
61+
## Requirement Clarity — UI Surface (SwiftUI)
62+
63+
- [x] CHK032 — Combined identity-and-server settings screen documented as an Apple-specific UX choice (vs. Android's two-screen split)? [Clarity, Spec §Summary, research.md §R7]
64+
- [x] CHK033 — `fileExporter` vs `fileImporter` use cases distinguished — exporter for data package, importer for custom `.p12`? [Clarity, quickstart.md, spec.md §FR-009]
65+
- [x] CHK034 — `ZipDocument: FileDocument` and its `UTType.zip` typing called out? [Coverage, data-model.md / quickstart.md]
66+
- [x] CHK035 — `TAKModuleConfig` (standalone) vs. `TAKIdentitySection` (embedded in `TAKServerConfig`) relationship documented — both backed by the same admin-message round-trips? [Coverage, Spec §Architecture]
67+
68+
## Requirement Clarity — Platform-Specific Behavior
69+
70+
- [x] CHK036 — No PARTIAL_WAKE_LOCK equivalent on iOS — reliability bounded by BLE-peripheral background mode? [Clarity, Spec §Apple-Specific UX Surface §Background Execution, research.md]
71+
- [x] CHK037 — iOS Local Network permission — auto-prompted, no pre-flight UI? [Coverage, research.md §R10, Spec §Edge Cases]
72+
- [x] CHK038 — `Documents/TAK Routes/` visibility in Files app under "On My iPhone → Meshtastic → TAK Routes" documented? [Clarity, Spec §Apple-Specific UX Surface §Files App Integration]
73+
- [x] CHK039 — Mac Catalyst behavior called out (TAK server runs same NWListener path; macOS Finder for file access; macOS Notification Center for "Route Received")? [Coverage, Spec §Apple-Specific UX Surface §macOS]
74+
- [x] CHK040 — Per-send V2 receive `Task.detached(priority: .utility)` justified — keeps `@MainActor` AccessoryManager dispatch loop responsive? [Clarity, Spec §FR-018, research.md §R8]
75+
76+
## Requirement Clarity — Route Receipt UX
77+
78+
- [x] CHK041 — "Route Received" notification body text — exact string documented for review? [Clarity, Spec §FR-008]
79+
- [x] CHK042 — Route UID sanitization (`sanitizeForFilename`) defends against path traversal — documented with the exact stripped characters? [Coverage, Spec §FR-010]
80+
- [x] CHK043 — KML manifest value escaping (`escapeXml`) prevents XML injection in route name — documented? [Coverage, Spec §FR-010]
81+
- [x] CHK044 — Notification suppression / coalescing for rapid-succession route receipts — explicitly NOT implemented; flagged for backlog? [Gap, tasks.md T091]
82+
83+
## Cross-Platform Parity Gates
84+
85+
- [x] CHK045 — Apple SDK pin (`Meshtastic.xcworkspace/.../Package.resolved 0.2.3`) matches Android `core/proto/build.gradle.kts` SDK coord? [Consistency, research.md §R13]
86+
- [x] CHK046 — Embedded `MeshtasticProtobufs/Package.resolved` pin discrepancy (currently `0.2.2`) called out as a known issue with a follow-up task? [Coverage, research.md §R13, tasks.md T080]
87+
- [x] CHK047 — Wire-format equivalence on V2 explicitly asserted (Apple V2 wire bytes = Android V2 wire bytes)? [Clarity, wire-protocol.md §Port Assignments]
88+
- [x] CHK048 — Cross-platform fixture suite work flagged for backlog (T082)? [Coverage, tasks.md]
89+
- [x] CHK049 — Coordination requirement when SDK bumps documented in research.md (R13) and tasks.md (T122)? [Coverage]
90+
91+
## Verification
92+
93+
- [x] CHK050 — Spec verified against actual merged code as of 2026-05-14 (`HEAD = 72590684` on `main`; back-spec written on `spec-tak` branch)? [Consistency, plan.md]
94+
- [x] CHK051 — Apple-specific test files enumerated (8 files, ~172 `@Test` methods) in plan.md and quickstart.md? [Completeness]
95+
- [x] CHK052 — All FRs and NFRs have an identified code path / file location in plan.md? [Completeness]
96+
97+
---
98+
99+
## Notes
100+
101+
- This checklist mirrors the Android `checklists/protocol.md` structure but the items are scoped to Apple's surface area.
102+
- Items marked complete reflect the back-spec status as of 2026-05-14; future SDK bumps or feature additions may unmark items for re-review.
103+
- Cross-platform items (CHK045-CHK049) are the most likely to drift; consider adding to PR templates so they're re-checked on any TAK-touching PR on either repo.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Specification Quality Checklist: TAK v2 Protocol Integration (Apple)
2+
3+
**Purpose**: Validate the back-spec is complete and faithful to the merged Apple TAK v2 implementation before tagging the spec done.
4+
**Created**: 2026-05-14
5+
**Feature**: [spec.md](../spec.md)
6+
7+
## Content Quality
8+
9+
- [x] No premature implementation details in the user-scenarios section (architecture is documented separately).
10+
- [x] Focused on user value and observable behavior in the User Stories section.
11+
- [x] Written so a non-iOS engineer (e.g., the Android maintainer) can review for parity.
12+
- [x] All mandatory sections completed (Summary, Goals, Non-Goals, User Scenarios, Edge Cases, Architecture, Requirements, Source-Set Impact, Design Standards, Privacy, Success Criteria, Assumptions).
13+
14+
## Requirement Completeness
15+
16+
- [x] No `[NEEDS CLARIFICATION]` markers remain.
17+
- [x] Requirements (FR-001 through FR-020) are testable and unambiguous.
18+
- [x] Non-functional requirements (NFR-001 through NFR-005) are measurable.
19+
- [x] Success criteria reference observable user-facing or wire-level outcomes (SC-001 through SC-007).
20+
- [x] Success criteria are technology-agnostic where possible (wire bytes, byte sizes, time windows) — Apple-specific framework choices live in `research.md`.
21+
- [x] All acceptance scenarios defined per user story.
22+
- [x] Edge cases enumerated (zstd decompression failures, port-in-use, malformed XML, unknown CoT types, offline-queue overflow, Local Network denial, mac Catalyst, missing firmware version, partial Fountain delivery, iTAK route-receive silent-ignore).
23+
- [x] Scope explicitly bounded (Non-Goals lists what we will NOT do).
24+
- [x] Dependencies and assumptions identified (SDK version, firmware version, Local Network entitlement, Files app access).
25+
26+
## Feature Readiness
27+
28+
- [x] All functional requirements map to a code location in `plan.md`'s structure.
29+
- [x] User scenarios cover the primary mesh-send, mesh-receive, mixed-firmware, lifecycle, identity-config, and dual-path flows.
30+
- [x] Feature meets the success criteria documented in `spec.md`.
31+
- [x] Architecture comparison with Android is explicit (table in `spec.md` § Architecture).
32+
33+
## Apple-Specific Coverage
34+
35+
- [x] iOS background-execution model documented (no PARTIAL_WAKE_LOCK equivalent; BLE-peripheral background mode noted).
36+
- [x] iOS Local Network permission flow documented (auto-prompted; loopback works without).
37+
- [x] iOS Files app integration documented (`Documents/TAK Routes/` user-visible).
38+
- [x] SwiftUI surface explicitly called out (`fileExporter`, `fileImporter`, `FileDocument`, `LocalNotificationManager`).
39+
- [x] Mac Catalyst support called out.
40+
- [x] Swift Testing framework usage documented (not XCTest).
41+
- [x] Network.framework usage documented (not JSSE).
42+
- [x] V1 ATAK_FORWARDER (Apple-only) called out in three separate places (spec § Goals, plan § Phase 0, research § R6).
43+
44+
## Cross-Repo Parity
45+
46+
- [x] Companion to Android `specs/005-tak-v2-protocol` linked from every doc.
47+
- [x] Wire-format equivalence with Android V2 explicitly asserted.
48+
- [x] Wire-format divergence (Apple's V1 ATAK_FORWARDER) explicitly called out as Apple-only.
49+
- [x] SDK pin version coordination requirement documented (FR-NFR-005, R13).
50+
- [x] Cross-platform fixture parity work flagged in `tasks.md` (T082).
51+
52+
## Notes
53+
54+
- Spec is retroactive: implementation is merged on `main`; back-spec written 2026-05-14.
55+
- All CoT types are owned by the SDK; this spec does not enumerate them inline. Cross-references to the SDK proto schema and Android `data-model.md` carry that information.
56+
- Apple's three-wire-format reality is the largest deviation from Android's two-format spec; called out in every doc.
57+
- Notification UX (route-received toast) is Apple-only with no Android equivalent — documented as such in `research.md` R11.
58+
- The combined identity-and-server settings screen is an Apple-specific UX decision (`research.md` R7); Android keeps the two surfaces separate.

0 commit comments

Comments
 (0)