Hybrid routing: Grok Worker for full Coach chat; Foundation Models (Apple Intelligence) or the 0.5B Metal polish sidecar for private on-device polish and light assist.
stream: true; Worker pipes xAI SSE into the chat UI.TargetFeasibility gates.HKObserverQuery + enableBackgroundDelivery (and BG refresh/processing backups) refresh digests and fire Watch-wear / pre-sleep / trend pings without opening the app. iOS still throttles.app.thescale.ios.plus.monthly / app.thescale.ios.pro.monthly. Local testing: Config/Products.storekit. Live model: grok-4.20-non-reasoning.cd workers/grok-proxy
npx wrangler secret put XAI_API_KEY
# Same random value as GROK_APP_SECRET in Secrets.xcconfig:
npx wrangler secret put APP_SHARED_SECRET
npx wrangler deploy
Tracked non-secret URL in TheScale/Config/TheScale.xcconfig:
GROK_PROXY_URL = https:/$()/the-scale-grok.alexhuther.workers.dev
GROK_API_KEY =
GROK_APP_SECRET =
Put GROK_APP_SECRET only in gitignored Secrets.xcconfig (copy from Secrets.example.xcconfig). Empty secret → fail closed (offline Coach) even when the proxy URL is set. Never put XAI_API_KEY in xcconfig.
Xcode .xcconfig treats // as a comment. A literal https://… silently becomes https: and breaks with NSURLErrorDomain -1000. Always use https:/$()/host.
iOS sends X-Scale-App-Secret, X-Scale-Device-Id (ScaleAnonymousIdentity), X-Scale-Plan, and X-Scale-Credit on every proxy POST. Worker rate-limits IP/device and enforces weekly caps server-side.
Worker notes: workers/grok-proxy/README.md.
Requires eligible device + Apple Intelligence enabled + model ready.
| Job | FM | Grok |
|---|---|---|
| Notification title/body polish | Prefer | Light assist only when FM + Metal off (tier-capped) |
Ping noise filter (shouldSendPing) |
Prefer (allow if FM off) | No |
| Coach wake reminder copy | Prefer polish after schedule | Timing stays local notifications; polish never blocks |
| Private fitness digest summary when Grok offline | Prefer | Light home-line polish when FM off (1/day max) |
| Memory fact extraction | Optional @Generable pass |
Heuristic + Grok context when consented |
| Full multi-agent Coach chat | No | Prefer when consent + live config |
iPhone XR / iOS 18 cannot run Apple Intelligence. Those devices prefer the Metal 0.5B sidecar when installed; otherwise a light Grok rewrite may run for the home today-line or one banner polish. Soft weekly caps (Free 1 / Plus 4 / Pro 10) plus a chat-credit reserve (Free 2 / Plus 4 / Pro 8) keep Free’s 5 credits usable for real Coach turns. See LightGrokAssist.
Code: FoundationModelAvailability, FoundationModelCoach (LanguageModelSession). Settings status + Coach FM ready / FM off badge.
For iPhones that are not Apple Intelligence capable (including base iPhone 15). AI-capable phones never download it.
| Piece | Detail |
|---|---|
| Package | Packages/ScaleOnDevicePolish (consumer SPM + llama.cpp Metal XCFramework b5046) |
| Model | Qwen2.5 0.5B Instruct Q4_K_M (~470 MB), downloaded to Application Support (Wi-Fi preferred) |
| Gate | SystemLanguageModel deviceNotEligible → install; eligible hardware → skip |
| Jobs | Same polish surfaces as FM via FoundationModelCoach fallback |
| UX | Settings status, download progress, retry; Coach badge Polish ready |
Host bridge: OnDevicePolishBootstrap. Auto-install after onboarding.
Exact copy lives in CoachCopySanitize.medicalDisclaimer. Shown only:
Never appended to chat, Progress roast, or notifications. Client sanitizer strips model-injected disclaimer / AI-tell boilerplate.
main, Clean Build, Run on iPhone 15.curl -s https://the-scale-grok.alexhuther.workers.dev → ok + stream: true.remind me in 2 minutes → exact local time in chat + Settings pending list → banner lands.See health-and-notifications.md for alert surfaces.
When profile sex is female, Keel uses a nurturing, praise-heavy, funny coach tone for Grok, Apple Intelligence, and the Metal polish sidecar. Daily energy and protein targets are phrased as visual plates (palm of protein, fist of carbs, handful of greens) instead of leading with bare calorie figures. Pace lines avoid jargon like ETA.
On iOS Simulator, Apple Intelligence is treated as unavailable so ModelManager does not spam promptTemplateNotFound / SensitiveContentAnalysis errors. On device, the first host/prompt-template failure disables FM for the process lifetime and callers fall back to algorithmic copy or the Metal polish sidecar.