Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
67317dd
docs(adr): delete completed ADR 0019 checkpoint history
thymikee Oct 16, 2026
4b903b6
docs(adr): write ADR 0019 in ASD-STE100
thymikee Oct 16, 2026
1bf28cb
docs(adr): write ADR 0021 in ASD-STE100
thymikee Oct 16, 2026
0dd561b
docs(adr): delete retired ADR 0022 classification procedure
thymikee Oct 16, 2026
07e5369
docs(adr): write ADR 0022 in ASD-STE100
thymikee Oct 16, 2026
595ec2a
docs(adr): delete completed ADR 0023 revision history
thymikee Oct 16, 2026
7698c0e
docs(adr): write ADR 0023 in ASD-STE100
thymikee Oct 16, 2026
293ed37
docs(adr): delete superseded ADR 0025 Device Hub process
thymikee Oct 16, 2026
4a1fdfe
docs(adr): write ADR 0025 in ASD-STE100
thymikee Oct 16, 2026
4a3c5f6
docs(adr): write ADR 0026 in ASD-STE100
thymikee Oct 16, 2026
62a37f3
docs(adr): write ADR 0027 in ASD-STE100
thymikee Oct 16, 2026
2a2b2b6
docs(adr): write ADR 0029 in ASD-STE100
thymikee Oct 16, 2026
debcf4d
docs(adr): write ADR 0030 in ASD-STE100
thymikee Oct 16, 2026
03c2c28
docs(adr): write ADR 0031 in ASD-STE100
thymikee Oct 16, 2026
4e4cf72
docs(adr): write ADR 0032 in ASD-STE100
thymikee Oct 16, 2026
c25a463
docs(adr): delete completed ADR 0033 move batches
thymikee Oct 16, 2026
ac3f84b
docs(adr): write ADR 0033 in ASD-STE100
thymikee Oct 16, 2026
d9e6a67
docs(adr): delete completed ADR 0019 substrate adoption instructions
thymikee Oct 16, 2026
d20256e
docs(adr): restore the ADR 0019 move-unit size rule
thymikee Oct 16, 2026
5954079
docs(adr): restore the frozen meaning in ADR 0021
thymikee Oct 16, 2026
04229ef
docs(adr): restore the frozen meaning in ADR 0022
thymikee Oct 16, 2026
3b47cb8
docs(adr): restore the frozen meaning in ADR 0023
thymikee Oct 16, 2026
d610c50
docs(adr): restore the frozen meaning in ADR 0025
thymikee Oct 16, 2026
f3d21f0
docs(adr): restore the frozen meaning in ADR 0026
thymikee Oct 16, 2026
0b59119
docs(adr): restore the frozen meaning in ADR 0027
thymikee Oct 16, 2026
3ede287
docs(adr): restore the frozen meaning in ADR 0029
thymikee Oct 16, 2026
a3f7e94
docs(adr): restore the frozen meaning in ADR 0030
thymikee Oct 16, 2026
60ce913
docs(adr): restore the frozen meaning in ADR 0031
thymikee Oct 16, 2026
43f7f5c
docs(adr): restore the frozen meaning in ADR 0032
thymikee Oct 16, 2026
18b09ef
docs(adr): restore the frozen meaning in ADR 0033
thymikee Oct 16, 2026
22868ce
docs(adr): restore the frozen meaning in ADR 0019
thymikee Oct 16, 2026
519a8aa
docs(adr): restore three conditions dropped by sentence splits
thymikee Oct 16, 2026
c88282d
docs(adr): keep translation hops in the ADR 0022 route-depth rule
thymikee Oct 17, 2026
effb311
docs(adr): restore that the ADR 0033 managed-allocation move landed
thymikee Oct 17, 2026
b090043
docs(adr): restore the ADR 0025 rule that the fold press is not evidence
thymikee Oct 17, 2026
36a5996
docs(adr): state the ADR 0022 route-depth rule with its base scope
thymikee Oct 17, 2026
0943c2f
docs(adr): cite R76's path-family ban in ADR 0033
thymikee Oct 17, 2026
86a2530
docs(adr): mark the ADR 0033 managed-allocation row as landed and rem…
thymikee Oct 17, 2026
1c931e3
docs(adr): restore scope words in ADR 0033 rows and prose
thymikee Oct 17, 2026
b38136f
docs(adr): restore scope words and a fixture ban in ADR 0019
thymikee Oct 17, 2026
6ce339f
docs(adr): restore scope words found by the 12-ADR drift pass
thymikee Oct 17, 2026
02caf40
docs(adr): restore ADR 0022 wording dropped by the rewrite
thymikee Oct 17, 2026
9b46544
docs(adr): restore ADR 0023 wording dropped by the rewrite
thymikee Oct 17, 2026
d7f3a5d
docs(adr): restore ADR 0031 wording dropped by the rewrite
thymikee Oct 17, 2026
63ea1e6
docs(adr): restore ADR 0032 wording dropped by the rewrite
thymikee Oct 17, 2026
44521bd
docs(adr): restore ADR 0033 wording dropped by the rewrite
thymikee Oct 17, 2026
d1ac2e2
docs(adr): restore ADR 0025 wording dropped by the rewrite
thymikee Oct 17, 2026
153cfdd
docs(adr): restore ADR 0026 wording dropped by the rewrite
thymikee Oct 17, 2026
11f98f7
docs(adr): restore ADR 0027 wording dropped by the rewrite
thymikee Oct 17, 2026
a9d05b0
docs(adr): restore ADR 0019 wording dropped by the rewrite
thymikee Oct 17, 2026
9a061e9
docs(adr): restore the ADR 0021 claim guard wording
thymikee Oct 17, 2026
17d2102
docs(adr): scope the ADR 0025 defensible-source claim to the recorded…
thymikee Oct 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,865 changes: 929 additions & 936 deletions docs/adr/0019-request-bound-platform-runtime.md

Large diffs are not rendered by default.

110 changes: 61 additions & 49 deletions docs/adr/0021-host-simlock-managed-device-allocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,87 @@

## Status

Accepted (2026-09-01). Decision replaced 2026-10-10: the in-process Host allocator integration is
withdrawn. Simlock closed its side ([simlock#70](https://github.com/callstackincubator/simlock/issues/70))
as superseded by a design in which agents lease devices themselves, and agent-device follows it.
Accepted (2026-09-01). The decision was replaced on 2026-10-10. The in-process Host allocator integration is withdrawn.
Simlock closed [simlock#70](https://github.com/callstackincubator/simlock/issues/70) in favor of direct device leases by agents.
agent-device follows that design.

## Rules at a glance

- Agents acquire booted devices from Simlock (`simlock lease`, its MCP tool, or its HTTP API) and
own renewal and release. agent-device does not call Simlock.
- Agents acquire booted devices from Simlock through `simlock lease`, the Simlock MCP tool, or the Simlock HTTP API.
Agents own renewal and release. agent-device does not call Simlock.
- Simlock owns allocation, capacity, provisioning, readiness, expiry, and device deletion.
- agent-device drives a leased device as an ordinary local device: the local platform runtime,
ordinary sessions, and process-owned device claims. There is no managed runtime owner, allocator
client, allocation journal, managed binding fence, or Host lease mapping.
- iOS: pass the grant's `SIMLOCK_IOS_DEVICE_SET` as `--ios-simulator-device-set` (or the
`iosSimulatorDeviceSet` config key). Discovery, `simctl`, and the XCTest runner then resolve the
leased simulator inside Simlock's set.
- Android: the grant's `ANDROID_ADB_SERVER_PORT` points `adb` at Simlock's server. The daemon's
`adb` invocations read it from the daemon's own environment, so the daemon must start inside the
lease environment (for example, a per-agent `--state-dir`).
- agent-device uses the ordinary local runtime, sessions, and process-owned device claims for a leased device.
It has no managed runtime owner, allocator client, allocation journal, managed binding fence, or Host lease mapping.
- For iOS, pass the grant's `SIMLOCK_IOS_DEVICE_SET` as `--ios-simulator-device-set` or the `iosSimulatorDeviceSet` config key.
Discovery, `simctl`, and the XCTest runner resolve the leased simulator inside Simlock's set.
- For Android, the grant's `ANDROID_ADB_SERVER_PORT` selects Simlock's adb server.
Daemon `adb` calls read the daemon's environment.
The daemon must start inside the lease environment, for example with a per-agent `--state-dir`.

## 1. Context

Simlock keeps parallel agents from fighting over the same simulator or emulator. Its simulators
live in a device set Xcode does not read, and its emulators register with Simlock's own adb server,
which is what stops another tool from erasing a leased device. A grant reports what reaching the
device needs as an `environment` object (`SIMLOCK_IOS_DEVICE_SET`, `ANDROID_ADB_SERVER_PORT`), and
`simlock lease --export-env` prints it for `eval`.
Simlock prevents parallel agents from competing for one simulator or emulator.
Its simulators reside in a device set that Xcode does not read, and its emulators register with Simlock's own adb server, which is what stops another tool from erasing a leased device.
A grant reports device access requirements in an `environment` object with `SIMLOCK_IOS_DEVICE_SET` and `ANDROID_ADB_SERVER_PORT`.
`simlock lease --export-env` prints this object for `eval`.

The first version of this ADR planned a Host inside agent-device that would allocate through
Simlock's typed client, journal allocation requests, fence every command with confirmed lease
authority, and run managed devices through a dedicated runtime owner. agent-device shipped those
foundations without ever activating them. Simlock then settled on agents leasing devices directly,
which needs nothing from agent-device beyond addressing a device in Simlock's roots, and both
already existed: simulator-set scoping and adb's own server-port environment.
The first design proposed a Host inside agent-device with these responsibilities:

- Allocate through Simlock's typed client.
- Journal allocation requests.
- Fence each command with confirmed lease authority.
- Use a dedicated runtime owner for managed devices.

agent-device shipped these foundations but never activated them.
Simlock then selected direct device leases by agents.
This design needs nothing from agent-device beyond the ability to address a device in Simlock's roots.
agent-device already supported simulator-set scope and adb's server-port environment.

## 2. Decision

agent-device has no Simlock-specific code. An agent leases a device, points agent-device at it with
the scope Simlock reports, and releases the lease when done:
agent-device has no Simlock-specific code.
An agent leases a device and configures agent-device with Simlock's reported scope.
After use, the agent releases the lease.

```sh
eval "$(simlock lease --platform ios --device 'iPhone 16' --detach --export-env)"
agent-device open MyApp --platform ios --ios-simulator-device-set "$SIMLOCK_IOS_DEVICE_SET"
```

The lease is the exclusion between agents; agent-device's process-owned device claims still guard
against two sessions of one installation driving the same device. Simlock's "advisory, not a
sandbox" model applies: agent-device does not verify that a device is leased.
The lease provides exclusion between agents.
Process-owned device claims still guard against two sessions of one installation that drive the same device.
Simlock's "advisory, not a sandbox" model applies.
agent-device does not verify that a device is leased.

## 3. Consequences

- The `managed-allocation` package, managed request admission and reachability, the `managed-local`
runtime owner kind, allocator-held device claims, and the managed device scope in platform
readiness and deployment are removed. A persisted durable-resource envelope naming a
`managed-local` owner decodes as unreattachable, and a schema-3 device-claim record as
inconsistent; no shipped production path ever wrote either.
- `device status` and `device release --stale` no longer report an `owner.kind: "allocator"` shape
or the `allocator-held` classification. Released v0.21.24 could print them but never produced them.
- Remote access to a leased device uses Simlock's own gateway or HTTP API, or agent-device's
existing `proxy` and remote daemon; neither depends on the other.
- The CLI and daemon take no per-request Android adb server port: one daemon talks to one adb
server, so agents holding leases from different Simlock daemons use separate state dirs. The Node
SDK's `agent-device/android-adb` functions run the caller's own adb executor, so the caller points
that executor at Simlock's server; the per-call `serverPort` in `AndroidAdbExecutorOptions` takes
effect only when that executor honors it.
- These components are removed:
- The `managed-allocation` package.
- Managed request admission and reachability.
- The `managed-local` runtime owner kind.
- Allocator-held device claims.
- Managed device scope in platform readiness and deployment.
A persisted durable-resource envelope with a `managed-local` owner decodes as unreattachable.
A schema-3 device-claim record decodes as inconsistent.
No shipped production path wrote either representation.
- `device status` and `device release --stale` no longer report `owner.kind: "allocator"` or `allocator-held`.
Released v0.21.24 could print these values but never produced them.
- Remote access to a leased device uses Simlock's own gateway or HTTP API, or the existing agent-device `proxy` and remote daemon.
Neither system depends on the other.
- The CLI and daemon accept no per-request Android adb server port.
One daemon uses one adb server.
Therefore, agents with leases from different Simlock daemons use separate state directories.
Node SDK `agent-device/android-adb` functions run the caller's own adb executor.
Therefore, the caller points that executor at Simlock's server.
Per-call `AndroidAdbExecutorOptions.serverPort` takes effect only if the executor honors it.

## 4. Withdrawn design

The replaced design required a durable allocation journal reconciled through Simlock after crashes,
fenced lease admission with renewal covering each command deadline plus teardown, a managed runtime
owner delegating to the local family, and allocator-held device claims whose principal was an
installation rather than a process. Recover it from git history (ADR text before 2026-10-10,
#2284, #2308, #2312) if an in-process allocator returns.
The replaced design required these components:

- A durable allocation journal reconciled through Simlock after crashes.
- Fenced lease admission with renewal across each command deadline and teardown.
- A managed runtime owner that delegates to the local family.
- Allocator-held device claims with an installation principal instead of a process principal.

If an in-process allocator returns, recover that design from git history: the ADR text before 2026-10-10, #2284, #2308, and #2312.
Loading
Loading