Roadmap
Roadmap
The original phase order intentionally proved the riskiest Siri path before expanding the interface. Physical testing has now shown both the value and the limits of that path; beginning September 27, 2026, visual interaction is the primary product direction and voice is an optional secondary bridge.
Phase 1 — Skeleton and persistence
Status: Complete
- SwiftUI app and Xcode project
- SwiftData child and ledger models
- central ledger service
- child list and add-child flow
- derived balances and minimal manual action
- initial unit tests
- simulator build and test verification
Phase 2 — Siri proof of concept
Status: Complete
- exact USD
Decimal/IntentCurrencyAmountconversion with tests - lightweight
ChildEntityand case-insensitiveEntityStringQuery GiveMoneyIntentAppShortcutsProviderusing valid current phrase syntax- focused OSLog instrumentation
- Siri capability, usage description, and explicit missing-amount prompting in TestFlight build
0.1 (2) - end-to-end Siri execution through a user-created shortcut on the managed iPhone
- localized App Shortcut phrase resources in TestFlight build
0.1 (3) - automatic App Shortcut phrase routing failed on the managed physical device in builds
0.1 (1)through0.1 (3) - automatic App Shortcut routing and prompted parameters succeeded twice on an unmanaged iPhone SE with build
0.1 (3) - automatic routing later succeeded on the unchanged managed-phone installation and persisted a twenty-cent transaction
- terminated and locked execution succeeded without requiring an unlock; termination/relaunch persistence is verified
- amounts below ten cents were repeatedly rejected by Siri’s currency resolver before intent execution
- open and background execution succeeded; numeric “ten cents” and “twenty-five cents” resolved, while dime and quarter wording did not
Exit criterion: Rebecca begins at $0.00; a Siri utterance reasonably close to “Give Rebecca a dime in Kid Money” persists +10 cents, Siri reports the balance, and the relaunched app shows $0.10.
Pause for the physical-device matrix in SIRI_TEST_PLAN.md. Do not claim success based on compilation alone.
Direct development installation was attempted on a managed work iPhone, but the organization’s developer-trust policy prevented launch. The development app, Developer Mode, and pairing were removed. The owner chose TestFlight/App Store distribution as the compliant route to this checkpoint; release preparation is tracked in APP_STORE_RELEASE.md.
App Shortcut phrases can interpolate at most one intent parameter. The proof of concept interpolates the child; the amount remains required and may be extracted semantically or requested by Siri as a follow-up. Record the observed behavior rather than assuming one-shot routing.
Phase 3 — Complete voice actions
Status: Complete
- Take Money
- Get Balance
- auditable Undo Last Transaction
- natural-language and coin-name experiments
- voice-specific error handling
Physical testing showed that IntentCurrencyAmount does not understand dime or quarter wording reliably, so a supplemental denomination path is justified. Keep arbitrary currency amounts available.
The then-current 11 tests passed, device and simulator builds succeeded without warnings, and Xcode’s App Shortcuts Preview mapped the representative Phase 3 phrases to the intended actions. Build 4 physical testing verified upgrade migration, Take Money, Get Balance, Undo, the supplemental dime/quarter path, terminated execution, repeated undo, and relaunch persistence on the managed work phone. Coin utterances correctly supply the denomination but still require a child follow-up. One terminated “Give a dime” attempt routed to a web result before succeeding on retry; preserve this as a reliability finding.
Siri reliability experiment — build 5
Status: Complete
The user specifically requested one-shot forms such as “Give Rebecca ten cents in Kid Money” before beginning Phase 4. The installed SDK rejects IntentCurrencyAmount in an App Shortcut phrase and permits only AppEntity or AppEnum phrase parameters. Build 5 therefore combines an active child and a common amount into one dynamic LedgerAdjustmentEntity, which fits Apple’s one-parameter limit. It advertises app-name-first and app-name-last give/take forms, retains the arbitrary-amount follow-up intents, and removes the overlapping coin App Shortcuts that Xcode’s flexible matcher preferred over the full request. The underlying coin actions remain available in Shortcuts.
Build 5 physical testing verified one-shot ten-cent, twenty-cent, and one-dollar additions, ten cents from a locked screen, and one-shot twenty-cent subtraction when the child precedes the amount. The stable grammar is “Give/Take [child] [numeric amount] in Kid Money.” App-name-first forms can invoke Wallet disambiguation, amount-first take wording can fail, and coin language remains unreliable. Turning off Apple Cash and Wallet Siri suggestions did not remove Wallet disambiguation. The owner explicitly accepted numeric cent language instead of coin names.
Five-cent increment expansion — build 6
Status: Complete
Build 6 expands the combined entity from a few common values to every five-cent increment from $0.05 through $1.00. One cent remains supported, and arbitrary values remain available through the prompted intents. The locked-screen physical matrix passed for fifteen-cent give, twenty-five-cent take, and thirty-five-cent give adjustments, with exact balances and relaunch persistence. Siri requested Kid Money/Wallet disambiguation for each phrase but asked no child or amount follow-up. The routing experiment is complete; the app-specific grammar is reliable after the system-level app choice.
Phase 4 — Useful manual interface
Status: Complete
- transaction history and quick coin buttons
- arbitrary add/subtract input
- rename and archive children without deleting history
- stronger empty/error states and modest visual polish
- distribute the manual interface as TestFlight build
0.1 (7) - owner review of the manual interface on physical hardware
Phase 5 — Reliability
Status: Complete
- locale-aware manual-input conversion tests
- duplicate exact-name lookup coverage for Siri disambiguation
- reject transactions that would overflow an
Int64balance - verify an
Int64.mintransaction cannot create an invalid undo entry - expanded persistence and App Intent store-access stress coverage
- privacy-conscious logging and diagnostics
- focused VoiceOver descriptions for balance and transaction rows
- one process-wide production
ModelContainershared by the app and intents - explicitly disable SwiftData-managed CloudKit discovery before adding a direct CloudKit sync layer
Phase 5 also established the store boundary needed by the planned shared ledger. Cloud synchronization can attach to the one local replica without creating a second SwiftData or Core Data synchronization stack.
Phase 6 — Shared family ledger
Status: In progress — build 11 physically verified manual incremental sync in both directions, owner-Siri-originated delivery, two-phone relaunch persistence, and controlled offline/reconnect recovery
- approve the persistence, authentication, and migration design
- preserve SwiftData as the local-first working store
- add the CloudKit container and private zone-sharing capability
- implement a disposable counter-only invitation and two-way-write probe
- deploy the probe schema and distribute build 8 to internal testers
- generate and deploy CloudKit’s
cloudkit.shareproduction schema - recover an incomplete build 8 probe without touching ledger data
- distribute recovery build 9 to internal and family external testers
- accept the private share using a second iCloud Apple Account
- verify owner-to-participant and participant-to-owner writes on physical devices
- verify counter 2 persists after terminating and relaunching both apps
- confirm both phones’ local ledgers remain unchanged by the counter-only test
- define deterministic Household, Child, and LedgerTransaction record mappings
- add durable, coalescing pending changes at the ledger mutation boundary
- keep local-only and preparing households dormant with no queued uploads
- strictly decode and atomically merge remote CloudKit records
- durably defer transactions delivered before their referenced child
- enforce deterministic child conflicts and same-transaction undo convergence
- drain the pending-change queue through an injected transport with persisted retry/backoff and account-state handling
- resolve optimistic child conflicts and stop on immutable transaction conflicts
- adapt the durable queue and merge services to
CKSyncEnginesend/fetch events - serialize and restore the engine’s opaque state
- persist CloudKit system fields for change-tag-aware optimistic retries
- stage an existing ledger non-destructively with deterministic initial changes
- persist migration phases and repair interrupted staging after relaunch
- retain local edits made during setup and guard share/activation ordering
- refuse to silently merge an invitation into an unrelated local ledger
- validate owner iCloud status and idempotently provision a private zone through an injected, dormant setup runner
- drive the deterministic initial queue through one explicit
CKSyncEnginesend and block share creation until it drains - create or recover the zone-wide private
CKShareafter initial upload - preserve all local ledger rows across setup interruption and confirmed remote-zone cleanup
- validate and persist a private read-write invitation before acceptance
- refuse participant adoption when an unrelated local ledger exists
- recover an interrupted share acceptance and initial shared-zone fetch
- atomically import a scoped first snapshot and block edits until activation
- gate owner/participant activation on current iCloud identity and share access
- retain queued local edits through an offline restart; freeze on account switch or share revocation without deleting ledger rows
- distinguish missing zones, revocation, and managed-account restrictions from temporary CloudKit outages in the dormant access check
- design explicit owner upload consent and safe participant invitation routing
- add a dormant sync session that checks access before fetch and again before send, with durable retry and no upload from incomplete setup state
- require a separate owner consent sheet before any real-ledger upload
- route counter-probe and real-ledger invitations separately; reject unsupported shares and stage a valid invitation without accepting it
- provide explicit Join, Sync Now, and participant-management actions
- verify the owner sharing and consent screens on an iPhone simulator
- publish the private-sharing privacy policy and App Store privacy label
- validate and distribute real-ledger sharing build 10 to internal testers
- physically verify build 10 preserves the owner’s local ledger and that cancelling the upload consent leaves sharing disabled
- add build 10 to the external Family Test group for the spouse
- physically observe owner-side Sharing enabled after explicit upload consent and a private invitation sent through Apple’s sharing UI
- physically verify participant Join, Sharing enabled, and complete initial transaction history on a second iCloud Apple Account
- fix and physically verify ordinary owner-to-participant synchronization of the previously queued manual edit
- physically verify participant-to-owner synchronization after a manual edit
- validate, upload, and add candidate Sync Now fix build 11 to both TestFlight groups
- verify an unlocked prompted Siri addition creates an exact shared-ledger transaction and durable pending change in build 11
- verify the owner-Siri-originated transaction reaches the participant once and survives termination, relaunch, and another no-duplicate sync
- verify an offline owner edit remains queued across relaunch, stays absent from the participant until reconnect, then synchronizes exactly once
- add Xcode 27 out-of-process App Intents coverage for dynamic entity resolution and an exact fifteen-cent preset mutation
- compile, archive, upload, and add Xcode 27 build 12 to Internal Testing
- verify Xcode 27 build 12 can execute the one-shot fifteen-cent route from the locked screen without child or amount follow-up
- characterize intermittent iOS 27 one-shot routing; build 12’s first unlocked attempt returned unsupported, while the identical locked phrase immediately afterward succeeded, later unlocked retries succeeded, and the warmed route survived app termination
- test a fixed personal Shortcut and Vocal Shortcut from the locked screen
- stop the voice-routing experiment after a 36-phrase Vocal Shortcut matrix confused similar child names and amounts; retain voice as optional rather than adding an in-app training workflow
- retain one automatic CKSyncEngine runtime for an activated household
- coalesce local mutations into a debounced guarded send opportunity
- force a guarded fetch/send whenever the app returns to the foreground
- enable remote-notification background delivery without adding polling
- physically verify basic automatic owner-to-participant and participant-to-owner delivery, foreground catch-up, and relaunch without using Sync Now in build 14
- physically verify rapid consecutive edits and automatic offline/reconnect recovery in build 14
- enable one private custom record zone and zone-wide
CKShareper household - use each participant’s existing iCloud Apple Account for authentication
- invite a spouse with read-write access through Apple’s system sharing UI
- enable the tested existing-ledger upload through an explicit owner opt-in
- define deterministic conflict and same-transaction undo behavior
- verify two-way manual and Siri changes across two physical devices
- verify offline/reconnect, invite revocation, iCloud sign-out, and managed-device restrictions
- deploy the real-ledger CloudKit schema to Production before TestFlight
- update the privacy policy and App Store disclosures before distribution
See FAMILY_SHARING_DESIGN.md for the approved persistence, authentication,
migration, and validation design. The probe procedure and strict no-ledger-data
boundary are recorded in PHASE6_CONNECTION_TEST.md.
The real-ledger consent and invitation screens are distributed to internal and
family external testers in build 10, as specified in
PHASE6_ACTIVATION_FLOW.md. The Production CloudKit schema and privacy
disclosures passed their release gates September 26, 2026. The owner-only
no-upload physical preflight passed before external build 10 distribution.
The participant joined and saw the complete initial history. A subsequent
owner-side manual edit remained queued after Sync Now and did not appear on the
participant after their Sync Now. Build 11 repaired that path: the owner queue
drained and the participant received the edit once with the expected balance.
The participant then made a manual edit, cleared her queue with Sync Now, and
the owner received it exactly once with the expected balance. An
owner-Siri-originated fifteen-cent edit then reached the participant exactly
once, and both phones preserved the matching balance and history across
termination, relaunch, and another sync. A subsequent offline owner edit
remained queued across relaunch, stayed absent from the participant until
reconnect, then synchronized exactly once; both phones converged to $3.35.
Xcode 27’s App Intents testing framework also executes the dynamic
child-and-fifteen-cent preset path out of process and reads back exactly 15
cents on the iOS 27 simulator. This validates the app-side intent and entity
query boundary but not Siri’s natural-language or locked-screen routing. The
Xcode 27 build 12 then physically executed the one-shot fifteen-cent phrase
from the locked screen after Kid Money/Wallet disambiguation, without asking
for child or amount, and produced the correct $3.50 balance. However, the
identical unlocked attempt immediately beforehand returned unsupported. The
next unlocked retry succeeded too, asking only for Kid Money/Wallet
disambiguation and moving the balance to $3.80. The route exists and works;
the sequence is consistent with an initial post-update registration/cache
warm-up. A terminated-app attempt also succeeded and moved the balance to
$3.95. This closes the repeated automatic-routing experiment: application
execution is sound, while Siri’s initial phrase routing is outside the app’s
deterministic control. The next product experiment is a user-created Shortcut
whose fixed action and exact Siri name encode the child and amount.
Account-switch and share-revocation recovery remain intentionally deferred
until their non-destructive physical procedure is agreed.
Phase 7 — Visual-first quick actions
Status: Complete — build 15 passed the owner and two-phone release-candidate matrix
- replace compact home rows with large child cards showing balance and six direct amount buttons
- add a global Give/Take selector so the same layout handles both signs
- store one ordered, configurable set of up to six exact amounts per device
- keep quick actions on the home screen and arbitrary adjustments in child detail
- place a direct, no-confirmation All Children card after the child cards
- add a contextual, one-tap visual Undo Last action to the home screen
- apply all-children changes atomically while preserving one auditable transaction and queued CloudKit save per active child
- exclude archived children from family-wide changes
- upload build 13 and add it to Internal Testing
- physically verify build 14’s Undo Last, All Children placement and no-confirmation behavior, absence of detail-page quick actions, and automatic clearing of the owner’s pending sync queue
- add build 14 to the family external group for two-phone checks; App Store Connect shows Testing in both Internal Testing and Family Test
- physically verify individual give/take, group give/take, customization, relaunch persistence, and transaction history on the owner phone
- physically verify the polished layout on the owner phone and basic automatic synchronization in both directions on two phones; the receiving app needed a background/foreground cycle for one change
- physically verify rapid edits and automatic offline/reconnect recovery without Sync Now on two phones
- remove the home-screen Undo Last control at the owner’s request while retaining the underlying undo operation for Shortcuts
- hide the obsolete counter-only connection test from the sharing screen
- distribute build 15 to both TestFlight groups and verify upgrade safety, bidirectional exact-once automatic sync, and termination/relaunch persistence on two physical phones
Voice remains implemented, documented, and test-covered, but it is no longer a release gate for visual ledger improvements. Do not expand the Siri phrase matrix unless a future iOS release materially changes the routing or speech- recognition constraints observed on real devices.
After the basic two-way matrix is stable:
- Let the household owner choose a family-ledger display name (for example, “Jones Family”) and synchronize later renames safely as household metadata.
- Add pull-to-refresh on a child’s transaction-history screen, backed by the same guarded Sync Now path and an honest visible result.
Explicitly deferred
Application-managed accounts, a custom backend, Android, recurring allowances, notifications, payments, subscriptions, analytics, advertising, and gamification.
CloudKit-based private family sharing is in progress by explicit owner request. The original distributed prototype shared only a disposable counter. Deterministic real ledger mappings, durable queues, local remote-merge behavior, guarded queue processing, a dormant CKSyncEngine adapter, and the non-destructive migration state machine are implemented and tested. Dormant owner private-zone/share provisioning is also implemented behind an injected setup transport. Participant adoption is implemented behind an injected transport with local preflight and retryable initial import. A separate injected activation gate tests account and share failure recovery. The local build now wires these paths to explicit sharing setup and, after activation, one guarded automatic sync engine. Automatic behavior is distributed and physically verified in both directions, including foreground catch-up, rapid edits, and offline/reconnect recovery. App Store listing and submission preparation is now the active release work.