feat(cli): add an opt-in service probe layer to icloud doctor - #347
Open
MrJarnould wants to merge 1 commit into
Open
MrJarnould wants to merge 1 commit into
MrJarnould wants to merge 1 commit into
Conversation
The service map only shows what Apple advertises. A host can be advertised and reachable while the endpoint behind it has been withdrawn, which is exactly what happened in timlaing#316 -- so the map alone would not have caught it. `--probe` closes that gap by calling each service once with a read-only request. Every probe is a GET or the service's own documented refresh; none writes. Find My is refreshed with locate=False on purpose, because counting or iterating the manager pings the user's hardware, which a diagnostic must not do as a side effect. A test pins that. Outcomes are separated by whose problem they are. A withdrawn endpoint or an unexpected error fails the run; a service Apple reports unavailable for this account, or one asking for re-authentication, is shown but does not, because neither is a pyicloud defect. Services whose webservice key was already reported missing are skipped rather than called. The probe table is kept honest the same way the inventory is: a test asserts it covers exactly the services endpoints.py names, in both directions. Probing is gated on the session status, not just on the API being resolvable -- the same reason the map findings are. The two can disagree, and calling eleven services with a session that reports unauthenticated produces a page of failures that say nothing about the library. Listing reminder lists took 28s against a real account, so both zone-backed services read their sync cursor instead; the happy-path test asserts which read was chosen, because a MagicMock answers either. Live: all eleven services answer, `files` reports unavailable without failing the run (that account is migrated off Ubiquity), and `invites` now passes -- it was the failure this layer originally found, fixed in timlaing#339. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 59 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (5)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Sep 4, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed change
icloud doctorreads the service map Apple returned at login. That map only shows what Appleadvertises — a host can be advertised and perfectly reachable while the endpoint behind it
has been withdrawn, which is exactly what happened in #316. So the map alone would not have
caught the bug the command exists for.
--probecloses that gap by calling each service once with a read-only request:Four decisions worth reviewing
Opt-in, and read-only. Every probe is a GET or the service's own documented refresh; none
writes. It costs one request per service, roughly ten seconds in total, which is why it is
behind a flag rather than on by default.
Find My is refreshed with
locate=Falsedeliberately. Counting or iterating the managerrefreshes with
locate=True, which pings the user's hardware. A diagnostic must not causethat as a side effect. There is a test asserting the call.
Outcomes are separated by whose problem they are. A withdrawn endpoint or an unexpected
error fails the run. A service Apple reports unavailable for this account — a Ubiquity library
migrated to iCloud Drive, say — or one asking for re-authentication is shown but does not,
because neither is a pyicloud defect. A service whose webservice key was already reported
missing is marked
skippedrather than called, since doing so would only restate the map moreslowly.
The probe table cannot drift. A test asserts it covers exactly the services
pyicloud/endpoints.pynames, in both directions, so a service can neither go silentlyunchecked nor keep a probe after the inventory drops it. I verified it by introducing each
kind of drift rather than assuming it works.
What the live runs changed
Listing reminder lists took 28 seconds against a real account. Both zone-backed services
now read their sync cursor instead — 0.3s, and it proves the same reachability. The
happy-path test asserts which read was chosen, because a
MagicMockanswers either and thetest was otherwise passing for no reason.
The probe layer found a real bug on its first run.
inviteswas the only service to failon a healthy account, which turned out to be a zone-wide CloudKit query against the shared
database. That is #338, fixed in #339, and
invitesnow reportsok— the layer found it andnow confirms it.
Type of change
Example of code:
Additional information
Cut from
mainand independent of #345 and #346.Testing. 952 tests pass on Python 3.10, 3.11, 3.12, 3.13 and 3.14, run locally. Twelve are
new.
Verified live: all eleven services answer,
filesreports unavailable without failing therun, exit code 0 with
--probeand the honest "Nothing was called; add --probe" wordingwithout it.
One thing found while rebasing this onto the merged
doctorcommand and worth calling out,since it is the kind of thing a clean auto-merge hides: probing is gated on the session status,
not merely on the API being resolvable. Those two can disagree, and calling eleven services
with a session that reports unauthenticated produces a page of failures that say nothing about
the library — under a verdict stating nothing could be checked. Same gating the map findings
already have, with a test that fails without it.
Checklist
If user exposed functionality or configuration variables are added/changed:
🤖 Generated with Claude Code