Skip to content

Show Muse Code allowance on iPhone from the user's own usage hub #526

Closed as not planned

Description

@HemSoft

Description

Muse Code can't be added on iPhone. #522 and #525 found that Meta offers no sign-in or allowance endpoint an iPhone app can use. Add Account shows the limit as a footer (current main, fc55494):

Current Add Account footer: Muse Code isn't available on iPhone

The desktop tools already read the allowance on the host with muse usage --json: CodexBar for Windows (codexbar#274) and hs-pi-dashboard (#70, #71). hs-pi-dashboard relays that reading as a muse-code usage card. Read-only probes on 2026-10-27 at 01:15 ET found:

  • Agent GET /usage returns {machine, generatedAt, cards} (4.6 KB). It has no authentication and is served over plain HTTP on a Tailscale IP.
  • Fleet server GET https://agents.hemsoft.net/api/fleet returns every machine's usage along with projects and session data (1.18 MB, not compressed). It has no authentication. It uses a valid certificate, and its DNS name resolves to a tailnet address.
  • The Muse card carries gauges (window, weekly: usedPercent, resetAt, windowSeconds), plan, allowanceSource, observedAt, freshForSeconds and error. After a failed read it keeps the last good gauges and sets error. It has no schema version and no Meta account identifier.

The iOS app has no remote, relayed or synced source today: no iCloud or CloudKit entitlement, no desktop sync, no custom endpoint and no ATS exception.

Task: let a user who runs such a hub show their real Muse Code 5-hour and weekly allowance on iPhone. No Meta credential goes on the phone. Users without a hub keep a truthful unavailable state.

Why

Franz (2026-10-27): "If CodexBar and Pi Dashboard can report the Muse Code metrics, so can the iPhone." The reading already exists on the user's own machines. The phone only needs a safe way to read it without credential transfer, token copying or estimates.

Goal

Add Account offers Muse Code through a clearly labelled "via your own usage hub" route. The prerequisite is stated before selection. The user enters an HTTPS hub address and connects. The account is created only after a machine reporting Muse Code is bound. The dashboard, widget and watch then show the hub's reading with the #525 validation, freshness and unavailable rules. It is labelled as coming from that machine, never as a verified Meta account.

Acceptance Criteria

  • Add Account shows Muse Code in a separate "via your own usage hub" section that states the prerequisite. It isn't hidden, Pro-only or flagged, and the Show Muse Code as unavailable on iPhone with a truthful schema-1 allowance reader #525 "isn't available on iPhone" footer is gone.
  • Choosing it opens hub setup without creating an account. Canceling or failing leaves no account and uses no account slot. Free and Pro limits apply when the account is created.
  • Only https is accepted, with no ATS exception. The full usage address is required (a bare host is rejected with an example). Userinfo, query and fragment are rejected, and URLs are canonicalised (case, default port, trailing dot).
  • Connect reads the hub once and lists only online machines that report a muse-code card. One machine binds automatically; several show a picker; none shows a clear message. Connect can't run twice at once, and a binding already used by another account is refused.
  • Requests send no cookies, credentials or auth headers and don't use a cache. Redirects and any non-200 status are failures. Request and resource timeouts are set, and a response-size cap applies (the fleet endpoint gets a larger separate cap).
  • DNS or unreachable, TLS, timeout, 401/403, 429, other HTTP errors and malformed or unsupported payloads each show a distinct message.
  • The card is read only when key is muse-code and kind is quota. window and weekly gauges are validated with the Show Muse Code as unavailable on iPhone with a truthful schema-1 allowance reader #525 rules (unique bucket IDs, finite values, strict ISO-8601 dates, windowSeconds that matches the window, reset rollover, future observation). Freshness uses min(freshForSeconds, 420).
  • A card with a non-empty error is a failure, never a current reading. Retained gauges may appear only as last known with their measured time, with no alerts, forecast or new history.
  • Card error text, label, projectedEnd, subscriptionPriceUsd and warning are never shown. There is no SUS or price.
  • Hub address and machine are refresh inputs and the cache identity. Rebinding drops in-flight responses and cached bars from the old binding. A reading older than the last accepted one for the same binding never replaces it, including across relaunches.
  • Setup states that anyone who can reach an unauthenticated hub can read its usage.
  • The widget and watch carry bars, plan and times only. Extensions do no networking.

Definition of Done

  • Implementation, unit tests for URL rules, transport mapping, the card adapter, the error and staleness policy, binding and the out-of-order guard, and a DEBUG simulator fixture that drives the real client through a URLProtocol.
  • MUSE-CODE.md, PRIVACY.md, SUPPORT.md and CHANGELOG.md (Unreleased) updated.
  • An hs-pi-dashboard issue requests a lean, versioned usage endpoint and a stable machine/account identifier. No change is made there or in project-manager.
  • Pinned SwiftLint has 0 violations. Relevant CodexBarIOSTests pass. Automatic CI is unchanged.
  • Clean current-head Codex review, and a Council line recorded on the PR.

Validation

  • DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer xcrun swift package plugin --allow-writing-to-package-directory swiftlint lint --reporter xcode . reports 0 violations.
  • The unit tests in CodexBarIOSTests for the new hub source pass on the iPhone 17 simulator.
  • The PR embeds current-head iPhone 17 simulator screenshots of: Add Account with the hub section; hub setup (empty, error, machine picker); a measured hub card; a hub card with a producer error (last known); unreachable hub. Add a short recording of the setup flow if practical.
  • Pending for Franz, not an agent gate: a phone comparison against agents.hemsoft.net with Tailscale on.

Activity

  1. HemSoft commented on Oct 27, 2026

    @HemSoft
    CollaboratorAuthor

    Council (design round, before implementation)

    Council: Muse Wonder Full 1.0 · missing: GPT 6.1 Sol (Codex seat pause, weekly 25% used, 182% projected, usage.py 2026-10-27 01:17 ET) · adopted: 13 · declined: 1 (partial)

    Adopted:

    1. A card error makes the result a failure, never a current reading.
    2. /api/fleet isn't an implicit default. The full address is required.
    3. Hub address and machine become refresh inputs and the cache identity.
    4. No account is created until a machine is bound.
    5. Setup warns that an unauthenticated hub is readable by anyone who can reach it.
    6. URLs are canonicalised.
    7. TLS errors are reported separately.
    8. The hub route gets its own labelled Add Account section.
    9. Stricter card checks: kind, unique buckets, windowSeconds, min(freshForSeconds, 420).
    10. The card is labelled "from ", never as a verified Meta account.
    11. Duplicate bindings are refused.
    12. The last accepted observedAt is persisted per binding, so older readings never replace it across relaunches.
    13. Stricter transport: separate size caps, request and resource timeouts, all non-200 statuses are failures, distinct 401/403/429 messages, and Connect can't run twice at once.

    Declined in part: hiding the retained gauges entirely when error is set. The producer keeps them as its last good reading, and the app's existing failure policy shows last-known bars with their measured time for every provider. They're shown greyed as last known, under the failure message, with no alerts, forecast or new history.

  2. HemSoft commented on Oct 27, 2026

    @HemSoft
    CollaboratorAuthor

    Parked by Franz (2026-10-27 01:29 ET): CodexBar iOS is a public consumer app, and its users can't reach a personal usage hub. Abandoning the hub route. Revisit only when Meta offers Muse Code usage through a supported API. Until then #525's honest "not available on iPhone" state stands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions