Skip to content

Direct budget control: surface the real cap + in-app editing (companion to Scout#56) #2

Description

@jordanrburger

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions