Summary
A live zones/changes call against a real container returned zone objects that carry deleted and zoneType, neither of which MistKit models. deleted is the significant one: a caller currently cannot tell a deleted zone from a live one.
Evidence
POST zones/changes on iCloud.com.brightdigit.MistDemo / development / private DB, no sync token:
{
"moreComing": false,
"metaSyncToken": "AQAAAaBJidqD",
"zones": [
{
"zoneID": {
"zoneName": "WebChangeTest",
"ownerRecordName": "_aca0fa3547ae9f9cd1f7e25fed948a20",
"zoneType": "REGULAR_CUSTOM_ZONE"
},
"deleted": true
}
]
}
Every zone in the response had "deleted": true and a zoneType inside zoneID.
Current state
After #427, the shared Zone schema in openapi.yaml models zoneID, syncToken, atomic. The domain ZoneInfo carries zoneName, ownerRecordName, capabilities, syncToken, atomic.
Neither deleted (zone level) nor zoneType (inside zoneID) is represented, so both are silently dropped on decode.
Note #427 deliberately implemented only the subset confirmed against Apple's archived reference and left unconfirmed fields out rather than guessing (see .claude/memory/reference_cloudkit_zone_dictionary.md). This issue supplies live confirmation for two more fields — the same standard of evidence, now from an actual response rather than the docs.
Why deleted matters
zones/changes is a change feed: a deleted zone is exactly the kind of change a sync client must observe. Returning it as an ordinary ZoneInfo indistinguishable from a live zone means a caller replaying changes will treat deletions as creations.
Worth checking whether changes/database (DatabaseChangedZone, the supported replacement per #401) carries the same field — it likely does, and that path is the one callers should be using.
What to do
- Confirm the field set against
changes/database as well as zones/changes before encoding — do not assume they match.
- Add
deleted: Bool? to the Zone schema (and DatabaseChangedZone if confirmed there), and zoneType to ZoneID, in openapi.yaml; regenerate via ./Scripts/generate-openapi.sh.
- Surface them on the domain types. Consider whether
deleted deserves better than Bool? on ZoneInfo — a change feed arguably wants a per-zone enum (changed vs deleted), which would be a larger design change.
zoneType observed value: REGULAR_CUSTOM_ZONE. Find the full set before modeling it as an enum rather than a string.
Found while verifying #430.
🤖 Generated with Claude Code
Summary
A live
zones/changescall against a real container returned zone objects that carrydeletedandzoneType, neither of which MistKit models.deletedis the significant one: a caller currently cannot tell a deleted zone from a live one.Evidence
POST zones/changesoniCloud.com.brightdigit.MistDemo/development/ private DB, no sync token:{ "moreComing": false, "metaSyncToken": "AQAAAaBJidqD", "zones": [ { "zoneID": { "zoneName": "WebChangeTest", "ownerRecordName": "_aca0fa3547ae9f9cd1f7e25fed948a20", "zoneType": "REGULAR_CUSTOM_ZONE" }, "deleted": true } ] }Every zone in the response had
"deleted": trueand azoneTypeinsidezoneID.Current state
After #427, the shared
Zoneschema inopenapi.yamlmodelszoneID,syncToken,atomic. The domainZoneInfocarrieszoneName,ownerRecordName,capabilities,syncToken,atomic.Neither
deleted(zone level) norzoneType(insidezoneID) is represented, so both are silently dropped on decode.Note #427 deliberately implemented only the subset confirmed against Apple's archived reference and left unconfirmed fields out rather than guessing (see
.claude/memory/reference_cloudkit_zone_dictionary.md). This issue supplies live confirmation for two more fields — the same standard of evidence, now from an actual response rather than the docs.Why
deletedmatterszones/changesis a change feed: a deleted zone is exactly the kind of change a sync client must observe. Returning it as an ordinaryZoneInfoindistinguishable from a live zone means a caller replaying changes will treat deletions as creations.Worth checking whether
changes/database(DatabaseChangedZone, the supported replacement per #401) carries the same field — it likely does, and that path is the one callers should be using.What to do
changes/databaseas well aszones/changesbefore encoding — do not assume they match.deleted: Bool?to theZoneschema (andDatabaseChangedZoneif confirmed there), andzoneTypetoZoneID, inopenapi.yaml; regenerate via./Scripts/generate-openapi.sh.deleteddeserves better thanBool?onZoneInfo— a change feed arguably wants a per-zone enum (changed vs deleted), which would be a larger design change.zoneTypeobserved value:REGULAR_CUSTOM_ZONE. Find the full set before modeling it as an enum rather than a string.Found while verifying #430.
🤖 Generated with Claude Code