Skip to content

Commit 92129f2

Browse files
committed
docs: slim Apple platform consolidation ADR
1 parent e35d0d4 commit 92129f2

1 file changed

Lines changed: 29 additions & 112 deletions

File tree

Lines changed: 29 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,46 @@
1-
# ADR 0009: Apple Platform Consolidation (AppleOS leaf axis)
1+
# ADR 0009: Apple platform consolidation
22

33
## Status
44

5-
Accepted
6-
7-
Completed process history is in git history.
8-
9-
> **Amended by [ADR 0019](0019-request-bound-platform-runtime.md).** The Apple family and explicit `AppleOS` leaf axis remain accepted.
10-
> The lazy platform-module registry and private `@agent-device/platform-*` packages supersede the shallow `PlatformPlugin` shape and root `src/platforms/**` location.
11-
> Each command cuts over to the new execution path in one atomic step.
12-
> Shared physical mechanics move only through ADR 0019's legal injected substrate transition or after their last legacy user.
13-
14-
## Rules at a glance
15-
16-
- Use one `apple` Platform with an `AppleOS` discriminant, not six Platform literals.
17-
- Keep the OS-agnostic Apple engine in `packages/platform-apple/src/core/` and genuinely per-OS code in `packages/platform-apple/src/os/<os>/` leaves.
18-
- Express per-OS capability differences as data keyed by `AppleOS`.
19-
- Keep macOS as a distinct AppKit leaf.
20-
- Do not flatten the tvOS focus-only interaction contract across OSes.
21-
- Keep watchOS as an unsupported sentinel. Discovery never produces it.
22-
- Internal family ownership must not leak into the public `ios`/`macos` leaf projection.
23-
- As of 2026-08, no public-command coverage is claimed for visionOS or watchOS. Net-new visionOS spatial-input QA is deferred.
5+
Accepted. [ADR 0019](0019-request-bound-platform-runtime.md) supersedes the original platform-plugin shape and owns the package and request-bound runtime seam.
6+
Each command cuts over to the new execution path in one atomic step.
7+
Shared physical mechanics move only through ADR 0019's legal injected substrate transition or after their last legacy user.
248

259
## Context
2610

27-
Apple support uses an asymmetric model.
28-
Physically, Apple support is spread across an `ios` directory, and that directory is actually the shared Apple engine.
29-
`Platform` has separate `ios` and `macos` literals.
30-
However, tvOS is not a platform: it is `platform: 'ios' + target: 'tv'`.
31-
`resolveApplePlatformName` in `src/kernel/device.ts` reconstructs the OS name late and loses information.
32-
Approximately 697 LOC of macOS code resides in `src/platforms/ios/`.
33-
`src/platforms/macos/devices.ts` is a 19-line stub imported by iOS discovery, which reverses the intended dependency direction.
34-
The Apple interactor in `src/core/interactors/apple.ts` also imports from `platforms/ios`.
35-
36-
A survey by four investigators found approximately 85% of `platforms/ios` already OS-agnostic:
37-
38-
- Runner stack.
39-
- Tool-provider.
40-
- Discovery.
41-
- Snapshot.
42-
- Screenshot.
43-
- Perf.
44-
- Debug-symbols.
45-
46-
The XCTest runner already builds `ios | macos | tvos` from one Xcode project.
47-
Thus, distinguishing or adding an Apple OS costs more than its actual implementation requires.
48-
iPadOS, visionOS, and watchOS have no model.
11+
Apple support shared an engine while presenting asymmetric iOS, tvOS, and macOS models.
12+
Inferring the OS from the target lost information, and the structure did not model iPadOS, visionOS, or watchOS.
13+
The XCTest runner builds iOS, macOS, and tvOS from one project.
4914

5015
## Decision
5116

52-
Model Apple OSes with an **`AppleOS` discriminant** (`ios | ipados | tvos | watchos | visionos | macos`) under one `apple` Platform.
17+
Model Apple OSes with an `AppleOS` discriminant (`ios | ipados | tvos | watchos | visionos | macos`) under one `apple` Platform.
5318
Do not use six `Platform` literals.
54-
Consolidate the OS-agnostic Apple engine under `packages/platform-apple/src/core/`.
55-
Keep genuinely per-OS code in `packages/platform-apple/src/os/<os>/` leaves.
56-
The Apple plugin is the first instance of the platform-plugin registry.
57-
The registry and enforcement paths named below are authoritative.
58-
Per-OS capability differences become data keyed by `AppleOS`.
59-
60-
## Alternatives Considered
61-
62-
- **Give each Apple OS its own `Platform` literal.** Rejected.
63-
`DeviceTarget` (`mobile | tv | desktop`) already spans platforms.
64-
Android TV uses `target: 'tv'`, so a `tvos` literal would conflict with the form-factor axis.
65-
Approximately 15 `isApplePlatform` sites and approximately 52 `macos` branch sites would need to enumerate six literals.
66-
This would also break the working single-bucket `apple` capability/selector model.
67-
- **Keep the existing structure.** Rejected.
68-
It retains tvOS/macOS asymmetry, mislabeled macOS code, and lossy target→OS inference without a path to iPadOS/visionOS.
69-
- **Exclude macOS from consolidation.** Rejected.
70-
macOS is already entangled.
71-
It builds through the same XCUITest project, and approximately 697 LOC of its code resides in `platforms/ios`.
72-
Exclusion would retain the incorrect label.
73-
A distinct AppKit leaf normalizes macOS without making it the same as the other OSes.
74-
75-
## Consequences
19+
Keep the OS-agnostic Apple engine in the Apple platform package's core and genuinely per-OS code in its OS leaves.
20+
Express per-OS capability differences as data keyed by `AppleOS` in request-bound runtime facts.
21+
This design composes with the daemon facet and descriptor `platformExecution` declaration in ADR 0008.
7622

77-
Adding a first-class Apple OS becomes cheap: it needs a leaf module and a runner-profile row.
78-
iOS/iPadOS/tvOS/macOS mostly require moves and renames because the engine never needed to know which Apple OS it drives.
79-
visionOS is scoped net-new work.
80-
XCUITest supports visionOS.
81-
The work includes:
23+
Keep macOS as a distinct AppKit leaf with its helper binary and menubar and desktop surface model.
24+
Do not flatten the tvOS focus-only interaction contract, which has no coordinate `tap`, across OSes.
25+
Keep watchOS as an unsupported sentinel: the Apple interactor, gesture admission, and supported-deployment check reject it, and discovery never produces it.
26+
XCUITest cannot drive watchOS UI.
8227

83-
- A profile row.
84-
- A build case.
85-
- `#if os(visionOS)`.
86-
- A wider discovery filter.
87-
- Real spatial-input QA.
28+
The public wire continues to emit `ios` and `macos` leaves through `PUBLIC_PLATFORMS`.
29+
Internal family ownership must not leak into that compatibility projection.
8830

89-
watchOS is an explicit **unsupported sentinel** because XCUITest cannot drive watchOS UI.
90-
macOS remains a distinct AppKit leaf, and its helper binary and menubar/desktop surface model are preserved.
91-
The tvOS focus-only interaction contract, with no coordinate `tap`, must not be flattened across OSes.
92-
Snapshot fidelity is uneven.
93-
The deep-RN AX-server fallback is iOS-simulator-only.
94-
Public leaf output remains a separate compatibility projection.
31+
## Rejected alternatives
9532

96-
This design composes with the daemon facet and the descriptor `platformExecution` declaration in ADR 0008.
97-
Per-OS behavior is data in request-bound runtime facts.
33+
- One `Platform` literal per Apple OS: `DeviceTarget` already spans platforms, and a tvOS literal conflicts with the form-factor axis and the single Apple capability and selector model.
34+
- Keep the existing structure: it retains asymmetric and mislabeled support and lossy OS inference without a path to iPadOS or visionOS.
35+
- Exclude macOS: it shares the XCUITest project and was already entangled with the Apple engine. A distinct AppKit leaf preserves its differences.
9836

99-
Implementation status as of 2026-08:
37+
## Consequences and open gaps
10038

101-
- Shipped:
102-
- The internal `Platform` collapse to `apple`.
103-
- Additive `appleOs` groundwork.
104-
- The shared Apple engine under `packages/platform-apple/src/core`.
105-
- macOS leaf files under `packages/platform-apple/src/os/macos`.
106-
- A dedicated tvOS leaf under `packages/platform-apple/src/os/tvos`.
107-
- Direct internal imports to the Apple modules.
108-
- The per-`AppleOS` runtime facts, including `packages/platform-apple/src/gesture-facts.ts`.
109-
The former capability projection was retired after its predicates moved into request-bound facts.
110-
- The watchOS **unsupported sentinel**.
111-
The `AppleOS` type reserves watchOS, and the interactor rejects it.
112-
XCUITest cannot drive watchOS UI.
113-
`isSupportedAppleDeploymentLeaf`, the Apple interactor, and gesture admission reject it.
114-
Discovery never produces it.
115-
- visionOS profile/build/discovery, plus simulator-deployment evidence.
116-
- Decision-only support boundary:
117-
- visionOS discovery and simulator deployment are supported and unit-tested in `packages/platform-apple/src/inventory-classification.test.ts` and `packages/platform-apple/src/deployment/runtime.test.ts`.
118-
- App deployment is also admitted for CoreDevice-backed physical devices.
119-
- XCTest-backed physical deployment is unsupported.
120-
- Push remains simulator-only.
121-
- No public-command coverage is claimed for visionOS or watchOS.
122-
- This ADR records this boundary without a command-coverage manifest for either leaf.
123-
- Retained compatibility: the public wire still emits `ios`/`macos` leaves through `PUBLIC_PLATFORMS`.
124-
Internal family ownership must not leak into that projection.
125-
- Deferred: net-new visionOS spatial-input QA.
39+
Adding an Apple OS needs a leaf module and a runner-profile row.
40+
Snapshot fidelity is uneven, and the deep-RN AX-server fallback is iOS-simulator-only.
12641

127-
This ADR owns the Apple family/leaf decision.
128-
ADR 0019 now owns the staged package/runtime seam.
129-
Net-new visionOS spatial-input QA remains a separate follow-up outside the consolidation.
42+
visionOS discovery and simulator deployment are supported.
43+
App deployment is also admitted for CoreDevice-backed physical devices; XCTest-backed physical deployment is unsupported.
44+
Push remains simulator-only.
45+
No public-command coverage is claimed for visionOS or watchOS, and this record does not claim a command-coverage manifest for either leaf.
46+
Net-new visionOS spatial-input QA remains deferred.

0 commit comments

Comments
 (0)