feat: adaptive export lanes and classification (0.5.0)
Partition a batch into local vs. iCloud work and let the caller throttle
the iCloud lane when Photos/iCloud pushes back. LadderKit supplies the
mechanism; the caller owns the policy.
- PhotosDatabase.localAvailableUUIDs(dbPath:) surfaces
ZINTERNALRESOURCE.ZLOCALAVAILABILITY = 1 so callers can partition work
before export.
- LocalAvailabilityProviding + PhotosDatabaseLocalAvailability for the
partitioning seam.
- AdaptiveConcurrencyControlling protocol (observation-only:
currentLimit / record) + ExportOutcome. No concrete controller ships
here — the policy lives with the consumer.
- ExportError.classification: other | transientCloud | permanentlyUnavailable,
with backward-compatible decoding of the legacy unavailable flag.
- PhotoExporter.export gains optional localAvailability and
adaptiveController. Local and iCloud lanes run in parallel; the iCloud
lane polls currentLimit between dispatches and reports each outcome.
AppleScript fallback now runs parallel under the same gate. Cancellation
triggers group.cancelAll() so child tasks wind down promptly.
Fully backward compatible with 0.4.x.