Type: feature. Companion to Raven-Scout/Scout#56 (Mac app) and the Android companion.
Request
Give the iPhone app direct budget control — show the real spend cap and let the user set/change it from the app — consistent with the Mac and Android apps. Today iOS can read budget signals but offers no way to view a coherent budget or change it.
Current state (iOS)
The data is already here, but it's never assembled into a budget the user can see or edit:
ScoutMobile/Models/UsageEntry.swift already parses budget_cap and budget_spent from .scout-logs/usage-tracker.jsonl.
ScoutMobile/Views/Schedule/ScheduleScreen.swift renders a per-slot slot.budgetUsd ($X) — read-only.
ScoutMobile/Models/Run.swift + SessionLogParser.swift recognize the skippedBudget outcome ("Skipped (budget)"); NotificationService says "Skipped — budget cap reached."
There's no "spent vs cap today" surface, and no editing path. That's not an oversight to paper over — per the README/CLAUDE.md, the iOS app is read-mostly with no backend and no scoutctl, and schedule editing is deliberately read-only ("atomic header-preserving rewrites stay scoutctl's job"). The budget's source of truth lives engine-side.
The hard part: writing the budget without a backend
Reading is easy; control (write) is the real design question on iOS. Options to weigh:
- A. Display-only for v1 — assemble
budget_cap / budget_spent into a clear "today's spend vs cap" view (Sessions or a small Budget surface) and surface per-slot caps from the schedule. No write. Lowest risk; closes the visibility gap immediately.
- B. Vault-file override — have the app write a small, well-defined budget config/override file into the vault via the existing
NSFileCoordinator writer, which the engine reads on its next run. Reuses the app's proven coordinated-write + iCloud-materialization path; needs an engine-side contract for that file.
- C. Defer write to a backend — if Android's bridge (or a future shared service) becomes the canonical write path, iOS calls that instead of touching the vault. Keeps one writer of engine config.
Recommend shipping A now and gating B/C on the shared contract from Scout#56 (see below).
Scope to design
- Read the real cap (
budget_cap) and spend (budget_spent) and present spent-vs-remaining; surface per-slot caps coherently with the daily cap.
- Decide the write story (A/B/C) and, if writing, the file/endpoint contract + validation (min/max, currency/locale, confirm-on-raise).
- Make the
skippedBudget state actionable (explain the cap; offer the appropriate next step) rather than just a passive label.
Shared contract
The budget's source of truth is engine/vault config, not a per-app local value. Whatever Scout#56 settles on for where the cap lives and how it's written should be the contract this app consumes — so Mac, iOS, and Android read/write the same thing. Cross-ref: parent Scout#56, Android companion (linked below).
Captured from session notes 2026-06-23.
Type: feature. Companion to Raven-Scout/Scout#56 (Mac app) and the Android companion.
Request
Give the iPhone app direct budget control — show the real spend cap and let the user set/change it from the app — consistent with the Mac and Android apps. Today iOS can read budget signals but offers no way to view a coherent budget or change it.
Current state (iOS)
The data is already here, but it's never assembled into a budget the user can see or edit:
ScoutMobile/Models/UsageEntry.swiftalready parsesbudget_capandbudget_spentfrom.scout-logs/usage-tracker.jsonl.ScoutMobile/Views/Schedule/ScheduleScreen.swiftrenders a per-slotslot.budgetUsd($X) — read-only.ScoutMobile/Models/Run.swift+SessionLogParser.swiftrecognize theskippedBudgetoutcome ("Skipped (budget)");NotificationServicesays "Skipped — budget cap reached."There's no "spent vs cap today" surface, and no editing path. That's not an oversight to paper over — per the README/CLAUDE.md, the iOS app is read-mostly with no backend and no
scoutctl, and schedule editing is deliberately read-only ("atomic header-preserving rewrites stayscoutctl's job"). The budget's source of truth lives engine-side.The hard part: writing the budget without a backend
Reading is easy; control (write) is the real design question on iOS. Options to weigh:
budget_cap/budget_spentinto a clear "today's spend vs cap" view (Sessions or a small Budget surface) and surface per-slot caps from the schedule. No write. Lowest risk; closes the visibility gap immediately.NSFileCoordinatorwriter, which the engine reads on its next run. Reuses the app's proven coordinated-write + iCloud-materialization path; needs an engine-side contract for that file.Recommend shipping A now and gating B/C on the shared contract from Scout#56 (see below).
Scope to design
budget_cap) and spend (budget_spent) and present spent-vs-remaining; surface per-slot caps coherently with the daily cap.skippedBudgetstate actionable (explain the cap; offer the appropriate next step) rather than just a passive label.Shared contract
The budget's source of truth is engine/vault config, not a per-app local value. Whatever Scout#56 settles on for where the cap lives and how it's written should be the contract this app consumes — so Mac, iOS, and Android read/write the same thing. Cross-ref: parent Scout#56, Android companion (linked below).
Captured from session notes 2026-06-23.