Archived 2026-07-02 — active milestone tracking moved to Linear (Reflective team). This file is kept for historical context only. Do not add new items here.
- Date: 2026-06-22
- Roadmap source:
EPIC.md - Architecture source:
docs/adr/0002-mobile-platform-boundary.md - Reference report:
docs/architecture/quorum-ios-native-ai-collaboration-report.md
This file is the execution backlog. Keep strategic direction in EPIC.md; keep
this file concrete, testable, and task-oriented.
[x]done[ ]openBlocked:cannot start until the named dependency existsAcceptance:the concrete condition that makes the task done
- Mobile captures, drafts, asks consent, queues, syncs, and renders receipts.
- Marquee mobile never promotes facts, mutates Lamport/Merkle chains, evaluates rulebooks as authority, owns billing, or stores Mosaic credentials.
- Swift/Kotlin own native UX and platform services.
- Rust owns shared workflow contracts, deterministic validation, queue/sync state, replay fixtures, capability policy, and FFI facades.
- Product domain logic comes from canonical product repos or generated server contracts, not from mobile-specific forks.
- M0.1 Root mobile architecture documented in
README.md. - M0.2 Native Swift/Kotlin + shared Rust decision accepted in ADR 0001.
- M0.3 Device/server authority boundary accepted in ADR 0002.
- M0.4 Quorum boundary responsibilities documented in
docs/architecture/quorum-sense-boundaries.md. - M0.5 Quorum fixture exists at
apps/marquee/quorum-sense/fixtures/field-signal-capture.v1.json. - M0.6 Canonical UniFFI schema exists at
schemas/quorum-mobile.udl. - M0.7 Quorum product FFI crate exists at
apps/marquee/quorum-sense/ffi/. - M0.8 iOS Quorum app target exists under
apps/marquee/quorum-sense/ios/. - M0.9 Android Quorum Compose shell exists under
apps/marquee/quorum-sense/android/. - M0.10 Local verification passed on 2026-06-22:
cargo test --workspace --locked. - M0.11 Local scaffold verification passed on 2026-06-22:
bash scripts/check-mobile-scaffold.sh.
Goal: make the current repo state honest and keep future mobile work inside the accepted boundaries.
Status: Done — 2026-06-24. CI is the live ground truth (separate Quorum
product jobs for iOS/Android plus distinct template smoke-shell jobs), the
release preflight mirrors it, and three guardrails are now enforced in CI/scripts
rather than asserted: the dependency boundary (cargo deny check bans, EPIC 4),
the security-advisory gate (cargo deny check advisories), and the authority
leakage scan (M1.6, below). Also folded in v0.1.0 were the supply-chain and
PII-boundary hardening tracked as QF-2026-06-24-01..05.
- M1.1 Remove stale iOS SwiftPM CI jobs that reference
apps/marquee/quorum-sense/ios/QuorumMobileIOS. Acceptance:rg "QuorumMobileIOS" .github MILESTONES.mdonly finds this task until the task is removed or marked done. Verified: only this task matches. - M1.2 Add a real Quorum product iOS CI job.
Acceptance: CI runs
just quorum-ios-genandjust quorum-ios-buildon macOS forapps/marquee/quorum-sense/ios/. Done: job "Quorum iOS Product App". - M1.3 Keep generic template smoke-shell CI separate from Quorum product CI. Acceptance: CI has distinct job names for template smoke shells and the Quorum product app. Done: "iOS/Android Smoke Shell" vs "Quorum iOS/Android" jobs.
- M1.4 Update release preflight to match CI. Acceptance: release preflight validates Rust gates, scaffold checks, and the current native product path without stale SwiftPM references.
- M1.5 Add a forbidden mobile dependency drift check.
Acceptance: CI fails if mobile FFI/product crates depend on server-only
crates such as
converge-kernel, Manifold adapters, Embassy live ports, or Mosaic credential-bearing crates without an ADR exception. Done:deny.toml[bans]+ CI "Dependency boundary" step. - M1.6 Add a scaffold check for Quorum authority leakage.
Acceptance: mobile Quorum source cannot introduce round-close, rulebook,
Lamport, Merkle, Stripe, or entitlement-authority code without updating the
boundary docs and an ADR. Done:
scripts/check-mobile-scaffold.shscans mobile source for those tokens and fails CI; relaxing it requires an ADR. - M1.7 Document generated artifact expectations.
Acceptance: iOS XCFramework/Swift bindings and Android JNI/Kotlin bindings
are clearly documented as generated and gitignored. Done: nested
.gitignoreinios/andandroid/;apps/marquee/quorum-sense/README.mddocuments them. - M1.8 Re-run local gates after CI changes.
Acceptance:
cargo test --workspace --lockedandbash scripts/check-mobile-scaffold.shpass.
Goal: stop treating fixture behavior as product logic and define the real mobile seam to canonical Quorum.
- M2.1 Rename or isolate fixture-only Rust behavior.
Done 2026-06-27:
refine.rsConverge formation replaces hardcoded stub indraft_field_signal; fixture ideals remain in JSON for structural contract only. - M2.2 Define the product capture submission DTO.
Done:
CapturePacket+CaptureSubmitRequestincapture.rs/sync.rs(see ADR 0006). - M2.3 Define typed Quorum mobile errors.
Done:
QuorumErrorin UDL; modality/consent/event/sync are wire enums. - M2.4 Productize the
spikes/quorum-domain-mobile/learning. Done 2026-06-27: v1 uses Converge refinement + portfolio types; incrementalquorum-domainadoption tracked in ADR 0006 and spike doc. - M2.5 Decide product crate distribution.
Done 2026-06-27: workspace path deps +
checkout-helms-depsCI action (ADR 0006). - M2.6 Add full fixture replay tests at the FFI boundary.
Done 2026-06-27:
ffi/tests/fixture_replay.rsloadsfield-signal-capture.v1.json. - M2.7 Add generated-binding smoke tests where practical.
Done:
ffi/tests/ffi_tests.rspublic surface + AndroidCapturePipelineFlowSpec.
Goal: ship the first real iOS-native Quorum workflow: speech/text capture → editable draft → explicit consent.
- M3.1 Create iOS feature folders for
Consent/,OfflineQueue/, andRealtime/. Done 2026-06-30:ios/Consent/,ios/OfflineQueue/(renamed fromQueue/),ios/Speech/,ios/Realtime/. - M3.2 Replace hardcoded inquiry id with an injected session/context value.
Done 2026-06-30:
CaptureSessionContext.inquiryThreadId()fromQUORUM_INQUIRY_THREAD_IDenv;SignalCaptureViewaccepts injected id. - M3.3 Add speech permission request flow.
Done 2026-06-30:
Speech/SpeechCaptureService.swiftrequests Speech + mic; denied/restricted states surfaced in capture UI. - M3.4 Add speech transcript capture.
Done 2026-06-30: live transcript via
SFSpeechRecognizer+AVAudioEngine. - M3.5 Add text capture as a first-class path. Done 2026-06-30: unified capture form; text and voice share draft → review → consent flow.
- M3.6 Add local draft normalization hook.
Done 2026-06-30:
PlatformSignalExtractor.normalizeCapturewith typed trim fallback. - M3.7 Add draft review screen.
Done 2026-06-30:
Consent/ConsentReviewView.swift— editable summary, raw capture, latent need, contradiction, confidence. - M3.8 Add typed consent decisions in Swift.
Done 2026-06-30: UniFFI
ConsentDecision+ConsentReviewViewactions. - M3.9 Add save-private and discard actions. Done 2026-06-30: save-private keeps session-local draft; reject/discard skip sync.
- M3.10 Add consented packet creation through the bridge.
Done 2026-06-30: only
Accepted/EditedAndAcceptedcall append + durable queue persist.
Goal: make Quorum mobile feel like an AI Director, not a dashboard. This milestone
rides alongside M3: start with preview data if needed, then align the canonical
director contract with Helms (director-contracts / helm-client) and expose it
through the Quorum FFI. mobile-core consumes/re-exports the contract and owns
mobile snapshot envelopes and replay fixtures; it does not define a parallel
DirectorFrame.
Architecture source:
../KB/04-architecture/2026-06-27-ai-director-mobile-ux-architecture.md
and root epic ../KB/08-roadmap/2026-06-27-ai-director-ux-epic.md.
- M3A.1 Add Quorum DirectorFrame fixture.
Acceptance:
apps/marquee/quorum-sense/fixtures/contains a canonical spine input event fixture (SessionPush / gate / session context shape) and a derived DirectorFrame JSON fixture for a decision checkpoint. The DirectorFrame is treated as a projection, not hand-authored standalone truth. - M3A.2 Add Swift value types for Director snapshots.
Acceptance: iOS models
DirectorFrame,DirectorPrompt,Choice,BlockingState,ContextLevel, and action intent tokens as typed Swift values mirroring the Helms contract; no raw strings in view logic beyond boundary mapping. - M3A.3 Add
DirectorNowViewin SwiftUI. Acceptance: iOS can render the Morning Director / Single Task state from the fixture or preview bridge with one primary action and no dashboard navigation. - M3A.4 Add
JudgmentPromptViewin SwiftUI. Acceptance: iOS renders a focused question with at most three choices and a single submit action. - M3A.5 Add
GatePromptViewin SwiftUI. Acceptance: iOS renders an explicit blocking gate with consequence, deadline, and bounded choices derived fromGatedDecision/GateCondition. No UI-only "later" verdict is allowed; defer must exist in the Helms contract before the UI can send it. - M3A.6 Add context escape affordance. Acceptance: task-level UI exposes local context/session/formation levels as an explicit escape hatch, but the default screen starts at the task.
- M3A.7 Route director actions as intents, not direct mutation. Acceptance: UI sends typed intents such as open task, submit judgment, approve gate, reject gate, request context; each intent maps to Helms/client action vocabulary, and view state updates only through a snapshot.
- M3A.8 Align DirectorFrame with Helms
director-contracts. Done 2026-06-30: UniFFI interface-enum pass forFfiWaitingFor,FfiDirectorPrompt, andFfiDirectorIntentinschemas/quorum-mobile.udl; Swift/Kotlin bridge mapping updated for tagged wire enums; domain mirrors remain inDirectorModelsat the view boundary. - M3A.9 Add mobile-core snapshot envelope and replay harness.
Done 2026-06-30:
crates/mobile-core/src/director/replay.rsexposesMobileDirectorSnapshot(version = upstream SSE sequence) and golden spine replay tests (SessionPush+GateCondition→helm-client→DirectorSnapshot). - M3A.10 Expose director snapshot through Quorum FFI.
Acceptance:
apps/marquee/quorum-sense/ffiemits the fixture-backedDirectorSnapshotthrough UniFFI (quorum_current_director_snapshot,quorum_submit_director_intent); Swift/Kotlin production bridges map wire DTOs atDirectorBridgeMapping. - M3A.11 Draft Android Compose parity screen. Acceptance: Android renders the same fixture as a Compose Now screen with semantic parity, not necessarily pixel parity.
- M3A.12 Wire live Director snapshot fetch against Quorum HTTP.
Acceptance:
quorum_configure_director_api+GET /api/director/snapshotresolve throughmobile-coreusing canonicalDirectorSnapshot; Client Helm SSE projection viaquorum_wait_director_update; intent submit POSTs toPOST /api/director/dev/intentwhen configured (LOCAL_DEV); fixture fallback when unreachable; DEBUG defaults tohttp://127.0.0.1:5161/quorum-senseBearerdev.
Goal: make offline operation durable and reusable across the portfolio.
- M4.1 Define Rust
ConsentDecision. Acceptance: consent states are explicit typed variants, not booleans or strings. Done:crates/mobile-core/src/consent.rswithAccepted/EditedAndAccepted/Rejected/SavedPrivate/Expired;quorum::append_after_consentgates queue onpermits_queue(). - M4.2 Define Rust
CapturePacket. Acceptance: packet captures modality, source metadata, draft payload, consent record, idempotency key, and app/workflow version. Done:crates/mobile-core/src/capture.rs; Quorum builders inquorum::capture_packet_from_draft/append_from_capture_packet. - M4.3 Define Rust
QueueState. Acceptance: state machine covers draft-local, pending-consent, queued, submitting, admitted, rejected, needs-review, and abandoned. Done:crates/mobile-core/src/queue.rswithQueueState,QueuedCapture, andquorum::queue_capture_from_draft. - M4.4 Define allowed queue transitions.
Acceptance: tests reject illegal transitions such as pending-consent →
submitting or rejected → admitted without explicit retry/review. Done:
queue/transitions.rswithallows_transition_to/transition_toandQueuedCapture::transition_to. - M4.5 Define local persistence contract.
Acceptance: Rust exposes stable records; native code can store them without
learning product internals. Done:
persistence.rswith versionedPersistedQueueRecordJSON encode/decode andpersistence_round_trip. Durability engine: native (ADR 0005); JSON is record encoding only. - M4.6 Implement iOS durable queue adapter.
Acceptance: queued packets survive app termination and relaunch. Store
PersistedQueueRecord::to_json()byrecord_id; reload viafrom_json; call Rust for transitions before write (ADR 0005). Done: UniFFI persistence helpers,FileQueueStore+QuorumQueuePersistence, bridge wiring, and relaunch tests inQueuePersistenceTests. - M4.7 Add BGTaskScheduler submission hook.
Done 2026-06-30:
OfflineQueue/QueueBackgroundSubmit.swiftregistersse.reflective.quorum.queue-submit; schedules after consent queue persist; bridgesubmitEligibleQueueRecords()drives Rust HTTP submit. - M4.8 Define HTTP submission client boundary.
Done 2026-06-30:
mobile-core/src/sync.rsdefinesPOST /api/capture/submit,CaptureSubmitRequest, UniFFIquorum_configure_capture_api+quorum_submit_persisted_queue_record. Server handler shipped 2026-06-27 inmarquee-apps/quorum-sense(capture_submit.rs,runway.app.json); E2E submit path is live when the Quorum server is running. - M4.9 Add admission receipt reconciliation.
Done 2026-06-30:
AdmissionReceipt+reconcile_admission_receipt/quorum_reconcile_capture_admission; local state advances only after receipt. - M4.10 Add replay tests for queue behavior.
Done 2026-06-30:
crates/mobile-core/tests/queue_replay_tests.rscovers offline persist, submit/admit, rollback, duplicate idempotency, rejection→review→retry.
Goal: make Android equal in architecture, even if individual native APIs differ.
- M5.1 Add Kotlin value/domain wrappers.
Done: typed
Confidence, UniFFI enums at boundary, domain wrappers incapture/. - M5.2 Add Android
QuorumCoreBridgeFFI. Done: production bridge maps FFI DTOs inQuorumCoreBridgeFFI.kt. - M5.3 Add Android product FFI build command.
Done:
just quorum-android-uniffi/just quorum-android-build. - M5.4 Add Android product build CI.
Done 2026-06-30:
android-productjob runsjust quorum-android-build. - M5.5 Add Compose consent review screen.
Done 2026-06-30:
consent/ConsentReviewScreen.ktmirrors iOS consent actions. - M5.6 Add WorkManager queue submission hook.
Done 2026-06-27:
QueueSubmitWorker+QueueBackgroundSubmitenqueue on consent persist and app startup; network-constrained unique work with exponential backoff. - M5.7 Add native capture path selection.
Done 2026-06-30:
PlatformSignalExtractor.normalizeCapture+ modality picker; text/voice/OCR share one bridge contract.
Epic: M6
Goal: make local/server AI placement explicit, inspectable, and policy-driven.
Status: In progress — 2026-06-27. Refinement backend seam (M6.7–M6.10) is on
main; capability snapshot, placement policy, probes, and user-facing fallback
copy (M6.1–M6.6) remain open.
- M6.1 Define Rust
CapabilitySnapshot. Acceptance: snapshot includes platform, OS version, local model availability, permissions, network, battery, thermal state, storage, privacy mode, plan, and workspace policy inputs. - M6.2 Define Rust
ComputePlacement. Acceptance: placement variants cover local-required, local-preferred, server-required, server-preferred, unavailable, and ask-user. - M6.3 Replace static
mobile-airouting. Acceptance: routing considers task, capability snapshot, privacy, and plan instead of only platform/task. - M6.4 Add iOS capability probes. Acceptance: Swift probes platform AI availability, permissions, network, battery/thermal state where available, and passes typed values to Rust.
- M6.5 Add Android capability probes. Acceptance: Kotlin probes Gemini/ML Kit availability, permissions, network, battery/thermal state where available, and passes typed values to Rust.
- M6.6 Add user-visible fallback copy. Acceptance: UI explains when local AI, server AI, or manual-only mode is being used.
- M6.7 Add
RefineBackend+ heuristic fallback in mobile-core. Done 2026-06-27:refine.rs— Converge formation withHeuristicBackend;draft_field_signal_with_backendfor pluggable language work. - M6.8 Expose UniFFI
LlmBackendcallback for draft refinement. Done 2026-06-27:schemas/quorum-mobile.udlcallback interface;quorum_draft_field_signal_with_llminquorum-ffi;LlmRefineBackendper-field fallback to heuristic when the model returns nothing. - M6.9 Add local
quorum-refine-servicedev tool. Done 2026-06-27:tools/quorum-refine-service/— HTTPPOST /completecloud-fallback tier for simulator/emulator when no on-device model is available. - M6.10 Wire native cloud-fallback LLM on iOS and Android.
Done 2026-06-27:
RefineServiceLlm.swift/RefineServiceLlm.ktimplementLlmBackend; production bridges pass intoquorum_draft_field_signal_with_llm. Androidnetwork_security_config.xmlpermits localhost in debug.
Epic: M6
Goal: render collective intelligence state without simulating server authority.
- M7.1 Define local vs server state labels. Acceptance: UI has distinct visual states for local draft, queued, submitting, server-admitted, rejected, and receipt-rendered.
- M7.2 Add Quorum live event model. Blocked: canonical SSE event contract must be available. Acceptance: mobile models server events such as round started, signal received, hypothesis formed, receipt updated, and outcome ready.
- M7.3 Add iOS live inquiry renderer. Acceptance: iOS can render server-computed status without local promotion.
- M7.4 Add facilitator field mode. Acceptance: facilitator can see missing evidence, unresolved tensions, queued participant signals, and mobile-safe review actions.
- M7.5 Preserve minority/ambiguous signals in UI. Acceptance: UX does not collapse or hide unresolved contradictions after draft creation or server sync.
- M7.6 Add notification/app intent plan. Acceptance: document and scaffold quick capture, review reminders, and queued submission status without bypassing consent.
Epic: M8
Goal: make the Quorum pattern reusable for every Reflective mobile app.
- M8.1 Add app classification worksheet template. Acceptance: new apps must declare marquee governed, studio local-first, or studio hybrid before implementation.
- M8.2 Add app README template. Acceptance: template includes mobile job, authority, domain source, transport, native platform APIs, Rust crates, fixtures, and non-goals.
- M8.3 Standardize fixture naming.
Acceptance: fixtures use
<workflow>.v<version>.jsonand include input, native AI expectations, Rust behavior, consent, queue, sync, and forbidden behavior. - M8.4 Align
apps/registry.txtwith Rust portfolio metadata. Acceptance: app registry andreflective-mobile-corecannot drift silently. - M8.5 Add new-app bootstrap checklist. Acceptance: checklist covers source repo instructions, domain footprint audit, FFI crate, native shells, fixtures, CI, and boundary review.
- M8.6 Add first non-Quorum worksheet. Acceptance: Inkling Notes or Wolfgang Chat has a filled mobile classification and dependency-footprint note before product code is added.
Epic: M10
Goal: prepare mobile apps for real users and app-store distribution.
- M9.1 Add token storage plan. Acceptance: iOS uses Keychain; Android uses EncryptedSharedPreferences or an equivalent platform-backed secure store.
- M9.2 Add capture data retention policy. Acceptance: docs say what remains local, what syncs, what is deleted, and how rejected/private drafts are handled.
- M9.3 Add privacy manifest and permission copy review. Acceptance: iOS permission strings and privacy metadata match actual capture behavior.
- M9.4 Add crash/diagnostics policy. Acceptance: telemetry cannot include raw captures, transcripts, photos, or private drafts by default.
- M9.5 Add TestFlight release checklist. Acceptance: signing, bundle id, archive, upload, tester notes, and rollback steps are documented.
- M9.6 Add Play internal testing checklist. Acceptance: signing, application id, release build, upload, tester notes, and rollback steps are documented.
- M9.7 Add billing/entitlement boundary note for mobile. Acceptance: docs state mobile consumes server-accepted entitlements and does not implement direct Stripe semantics; any Apple/Google IAP work requires server reconciliation.
Epic: M1
- Add PhotosUI + Vision OCR path on iOS after speech/text path works.
- Add CameraX + ML Kit OCR path on Android after FFI parity works.
- Add App Intents quick capture after consent model is implemented.
- Add cross-platform fixture replay in Swift and Kotlin test targets.
- Add local vector/search memory only after a real workflow requires it.
- Evaluate portable embeddings only after model size, privacy, and device support are specified.
- Add Studio local-first queue/sync variant after Inkling/Wolfgang worksheet is accepted.