Repository navigation
Grok gRPC fallback, xAI dedupe, iOS canonical cards, dedupe - #306
Conversation
…use dedupe - Grok: x-xai-token-auth header, subscription_tier_display plan enrichment, and a best-effort grok.com gRPC-web credits fallback (documented wire contract, protobuf scanner with bounds) used only when the proxy publishes no percentage. - xAI/Grok: the same subscription pool reported under both keys keeps only the fresher window. - Copilot windows carry the monthly cadence (1m caption). - iOS: source-scope toggle, source badges/banners, per-window Updated stamps gone from the main list; canonical resolution only, fixed meter columns; source detail stays in Settings. - Muse Assist artwork deduped onto the Muse base (byte-identical).
This comment has been minimized.
This comment has been minimized.
|
Task description is insufficient for business logic validation. 🤔 Insufficient Task ContextI found a task linked to this PR, but it only contains minimal information (title only, no description or acceptance criteria). To perform a meaningful business rules validation, I need more details. 🔍 What I need to validate:
💡 How to improve the task context:
|
|
Mac build is red on the merge ref with 4 test failures. Evidence per failure, all traced to the canonical-cards rewrite in db0cde1 (neither main nor the branch touched the test files since the merge-base, so the tests still encode the pre-redesign structure):
Leaving the calls to your lane since this is an active redesign - flagging so the failures don't sit. The #304-era owner tests are the contract being asserted. |
Resolve the CopilotQuotaReader.swift conflict by taking main's line wrapping. Both sides carry identical arguments (token streams match after whitespace is removed); main only rewrapped the resetAt/window and remainingUnknown/status lines. The branch's Grok xAI work is untouched.
Review threads: - GrokGrpcCredits pins period decoding to the documented field 6, keeps the first match, and accepts only a weekly or monthly span, so an unrelated submessage can no longer invent resetAt/periodStart. - A published percentage that is out of range or non-finite is tracked as seen-but-rejected, so it cannot reach the implicit-zero rule and report a spent pool as 100% remaining. - The gRPC fallback returns a typed outcome; HTTP 401/403 and gRPC status 16 report GROK_TOKEN with a masked first-8/last-4 preview instead of being swallowed as missing data. - readGrok issues both enrichments concurrently and only when they have something to contribute, instead of always paying 2s + 6s serially. - The fallback re-normalizes the window after filling the percentage, so status/isExhausted/skip describe the number just filled in. - The Grok subscription pool is matched by canonical identity rather than by id suffix, and the dedupe runs over the merged collection so a provider group cannot re-add the duplicate. - muse-assist leaves the bundle-file lists; the key still resolves through the PlatformLogo map to the shared muse mark. Test failures repaired: - PlatformLogoResourceTests no longer demands muse-assist artwork the PR removed. - The three CompanionModelTests that pinned the pre-redesign card (picker in the header, model.sourceScope gate, atCapSummary signature) now assert the canonical-card behaviour the PR actually ships, and testSourceScopePickerShowsTheDeviceAwareLabel moved its premise to the model, where the device-aware label still lives.
|
@kody start-review |
withUnsafeBytes(of: &nanBits) needs a var; nanBits was a let constant, so GrokGrpcCreditsTests did not compile.
The identity was built as providerKey + a hardcoded ":subscription", so every grok/xai window matched it and testOtherXaiWindowsAreUntouched lost its API-credits row. Match the last two id components in full instead: parts[-2] == canonicalProviderKey && parts[-1] == "subscription". That still catches the source-prefixed local-mac:grok:subscription and the fleet xai:subscription, while excluding grok:legacy:subscription and xai:api-monthly.
Resolved ios/CodeCapsCompanion/App/Models/CompanionQuotaModel.swift by keeping both sides: #307's shared QuotaCapRule.isAtCap decides the cap instead of the local (x ?? 100) <= 0 copy, while this branch keeps the suffix-free subtitle. sourceSuffix could not be restored because this branch removed its definition along with the multi-source chip.
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
|
[GB-Designer] UI pass: nit (non-blocking for UI; the red Mac build is the real blocker) Good to see
|
- The gRPC fallback fills the credits pool by its exact id (`local-mac:grok:subscription`), never by a `:subscription` suffix, and never overwrites a percentage the proxy published. - Only an HTTP 401 from grok.com is a refused credential. A 403 and gRPC status 16 are grok.com's documented answer to a bearer-only probe with no Web Key Exchange keypair, so they stay a plain fallback miss. The 401 message names the refusal with the masked preview and no longer tells the owner to sign in again, since the CLI proxy accepted the same token. - `isUnauthenticated` reads the header-style `grpc-status: 16` trailer as well as the unspaced form. - A provider whose only reading the Grok and xAI dedupe removed gets no section, so it cannot render an empty "Quota unavailable" card beside the row that carries the pool. - CI captures the main iOS quota list with the seeded windows (`codecaps-ios-quota.png`), with a second Claude window so one card shows both meter rows. - The Data Sources footer takes the designer's plainer copy and uses `sentenceGap` between every sentence. Tests cover the fallback fill, status 16, 403 and 401, both trailer spellings, and the emptied-group cases on the manifest and offline paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Sweep update for this PR (CLAUDE seat). Merged main (#309 through #313) into the branch with no conflicts in 25dcc98, then fixed the open findings in 5bc9844:
Declined as optional hardening, with no behaviour change today: pinning the percentage to field 4, moving |
|
@kody start-review |
One conflict, in the Antigravity pool row of `CompanionQuotaModel.swift`. Main now drives the headline and the exhausted state from the fresh windows; this branch dropped the "(N sources)" suffix from the subtitle. The resolution keeps main's fresh-window logic and the subtitle without the suffix. No conflict marker remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Kody's naming note on the grok.com fallback: the outcome case now means only that grok.com answered HTTP 401 to the credits fallback, so it is renamed from authRejected to refused, and the local flag in readGrok follows. The doc comment on GrokGrpcOutcome had been split across two indents with a stray copy of the method's comment above the enum. It now sits inside the struct at the member indent and says what the case means. No behaviour changes. GrokGrpcCredits.parse: the period comment now says "first valid match wins", since a malformed or off-cadence field-6 submessage is skipped and a valid one after it is still read, so nobody tightens it into "first field 6 only". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stale: every finding fixed or answered at 6dbe420 (the one finding this review lists, "Grok gRPC authentication failures are silently swallowed", r4346459074: a typed outcome since 5e5832a, narrowed by the revised finding r4352695042 in 5bc9844 so only an HTTP 401 from grok.com is reported, with a first 8 and last 4 masked GROK_TOKEN preview and no sign-in instruction, and the case renamed to refused in 6dbe420; the other eleven Kody threads on this PR are fixed or answered and resolved), CI green. Dismissed by CLAUDE per owner ruling 2026-10-17.
Popup/plan fixes are in PR #304 (auto-merge armed). Folder-structure standardization is SWU-22; load-bearing paths (SPM/Xcode/release) intentionally unmoved.
Summary
This PR improves Grok quota completeness and consistency across local and fleet readings, adds a secondary Grok billing source, and simplifies the iOS quota experience to show one canonical reading per allowance.
Functional changes
Grok quota fallback
Grok/xAI subscription deduplication
groksubscription reading and fleetxai:subscriptionreading into one dashboard entry.occurredAttimestamp and leaves unrelated xAI windows and single-sided subscription data unchanged.Canonical iOS quota cards
Other quota and branding updates
Test coverage
GrokGrpcCreditsTestscovering framed and raw replies, product-share exclusion, active-period implicit zero, malformed input, period extraction, and the exact request frame.GrokXaiDedupeTestscovering fresher local and fleet readings, preservation of unrelated xAI windows, and single-sided subscription data.Outstanding review items
providerGroups; this can select the wrong duplicate or allow a dropped duplicate to be reintroduced.Summary
Improves Grok quota accuracy and refresh speed, ensures the Grok / xAI credits pool stays as one row, brings iOS cap logic into parity with Mac, and adds Copilot provider artwork with faster, thread-safe logo loading.
What changed
Grok quota fallback and refresh:
UNAUTHENTICATEDtrailer status, reporting a distinct "token rejected, sign in again" message with masked token preview instead of generic "no readable percentage".Grok / xAI deduplication:
<providerKey>:subscriptioncomponents instead of suffix matching, so unrelated windows likegrok:legacy:subscriptionorxai:api-monthlyare untouched.providerGroupsfirst, then dedupes once, so the fleetxai:subscriptionreading does not re-add a duplicate after the merge.iOS companion parity:
QuotaCapRuledecisions everywhere - window rows, Antigravity pools, weekly rows, and exhaustion tracking - so a live reading outranks a stale providerisExhaustedflag.copilotprovider mapping and monochrome handling for consistent logos.Provider marks / logos:
github-copilot/copilotmappings to sharedcopilotartwork, adds Copilot color/dark/light generation targets, and consolidatesmuse-assistonto the sharedmusemark.Tests: