Purpose and decision
fold on an iPhone Duo in --ios-simulator-device-set <set> fails before HID dispatch: CoreDevice's display inventory cannot resolve a simulator outside the default set. Hinge readback has the same dependency. Refuse scoped-set fold at runtime admission, before any display probe or HID effect. Full support requires a verified set-aware source for both the display table and hinge angle; none is available in the selected toolchain.
simctl accepts --set <path> and the HID send already uses it. devicectl device info displays and devicectl device motion hinge-angle accept --device but expose no set selector in Xcode 26.2 help. #2818's live scoped-set run found The specified device was not found. ADR 0025 requires hinge readback after motion, so successful HID alone cannot count as support. #2878 addresses simctl scope enforcement and does not solve CoreDevice scope.
Implementation contract
- In
packages/platform-apple/src/foldable/runtime.ts, make appleFoldFact(DeviceInfo) unavailable when device.simulatorSetPath is present. This is the owning fact for capability reporting and admission. Use a truthful typed reason, unsupported-device-scope; add it to the RuntimeOperationUnavailability union and its parser in packages/contracts/src/platform-runtime.ts. The resulting command failure is UNSUPPORTED_OPERATION with details.reason: 'unsupported-device-scope' and a hint naming the scoped simulator set. Do not add a second guard in pose.ts or match CoreDevice error text.
- Preserve the existing kind/OS refusals and default-set behavior. Scope refusal must occur before any
devicectl, simctl spawn, or helper build. Keep the capability result and command response consistent by deriving both from the fact.
- Update
agent-device help foldable and the fold command description to state the scoped-set limitation. Leave screenshot's separate unresolved-inventory behavior and ADR 0025 capture policy alone.
Proof and completion
- Plant a failing admission test on a scoped
DeviceInfo: both the fact/capability and routed fold response must be unavailable with the typed reason, and tool spies must record zero devicectl/simctl calls. Remove the planted failure only after the production change.
- Existing default-set fold and runtime fact tests pass without argv changes. Run
pnpm check:affected --run; report focused tests and help tests.
- On a throwaway foldable simulator in a temporary set, record
agent-device fold half-open --ios-simulator-device-set <set> --udid <verified-udid> --json returning the typed refusal before motion. Verify the hinge/panel was not changed by this request. Do not use a simulator belonging to another task.
Future support criterion
Revisit this refusal only when a set-aware source can supply both display inventory and verified hinge readback on a scoped Duo. Preserve the same admission fact and ADR 0025 post-dispatch proof.
Purpose and decision
foldon an iPhone Duo in--ios-simulator-device-set <set>fails before HID dispatch: CoreDevice's display inventory cannot resolve a simulator outside the default set. Hinge readback has the same dependency. Refuse scoped-set fold at runtime admission, before any display probe or HID effect. Full support requires a verified set-aware source for both the display table and hinge angle; none is available in the selected toolchain.simctlaccepts--set <path>and the HID send already uses it.devicectl device info displaysanddevicectl device motion hinge-angleaccept--devicebut expose no set selector in Xcode 26.2 help. #2818's live scoped-set run foundThe specified device was not found. ADR 0025 requires hinge readback after motion, so successful HID alone cannot count as support. #2878 addresses simctl scope enforcement and does not solve CoreDevice scope.Implementation contract
packages/platform-apple/src/foldable/runtime.ts, makeappleFoldFact(DeviceInfo)unavailable whendevice.simulatorSetPathis present. This is the owning fact for capability reporting and admission. Use a truthful typed reason,unsupported-device-scope; add it to theRuntimeOperationUnavailabilityunion and its parser inpackages/contracts/src/platform-runtime.ts. The resulting command failure isUNSUPPORTED_OPERATIONwithdetails.reason: 'unsupported-device-scope'and a hint naming the scoped simulator set. Do not add a second guard inpose.tsor match CoreDevice error text.devicectl,simctl spawn, or helper build. Keep the capability result and command response consistent by deriving both from the fact.agent-device help foldableand the fold command description to state the scoped-set limitation. Leave screenshot's separate unresolved-inventory behavior and ADR 0025 capture policy alone.Proof and completion
DeviceInfo: both the fact/capability and routedfoldresponse must be unavailable with the typed reason, and tool spies must record zerodevicectl/simctlcalls. Remove the planted failure only after the production change.pnpm check:affected --run; report focused tests and help tests.agent-device fold half-open --ios-simulator-device-set <set> --udid <verified-udid> --jsonreturning the typed refusal before motion. Verify the hinge/panel was not changed by this request. Do not use a simulator belonging to another task.Future support criterion
Revisit this refusal only when a set-aware source can supply both display inventory and verified hinge readback on a scoped Duo. Preserve the same admission fact and ADR 0025 post-dispatch proof.