You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reject an ordinary client or invalid admin credential before either mutation starts.
Make removal acknowledgement idempotent for the exact identity and generation.
Start terminal retention only after settlement, and for an identity only after removal acknowledgement.
Share these durable records with all frontends.
For admission: "fail-fast", do not enter the lease queue. Store a terminal failed disposition with a typed capacity refusal and retryAfterMs. The same key always returns that refusal. A retry after the delay uses a new key.
Shape resolution
Simlock resolves { platform, deviceType, osVersion? } against its installed catalog.
An omitted OS selects the newest compatible installed runtime.
An explicit major selects the newest compatible installed minor.
An exact version must match an installed component.
A missing component returns a terminal result for that attempt. requestLease must not download it implicitly.
External fence
Android can reuse a local device identity. Host must own an execution claim before Simlock grants that identity.
For activation: "external-fence", Simlock returns awaiting-external-fence with the reserved deviceId.
Host installs its claim and uses the authenticated admin client to call confirmLeaseActivation. Simlock checks the clean baseline, then returns the active lease.
Disconnect and restart must keep the reservation recoverable. Simlock must not publish the lease before confirmation.
The execution claim lasts for the allocator identity's full pool lifetime. A terminal lease or request is not permission to clear it. Host clears the claim only after getManagedIdentityStatus returns removed for the exact generation, then acknowledges that proof through the authenticated admin client.
Existing HTTP work
#68 uses an in-memory request tracker. If #68 merges first, make that tracker use this durable core record.
This issue does not add another network interface.
Completion conditions
A lost response followed by a retry returns the first result.
The same key returns the same capacity, disk, validation, or provisioning failure after host conditions change.
A new key after a terminal capacity refusal can start the next generation without supersession.
A terminal prior generation can never publish a grant.
A daemon restart keeps pending and terminal requests available.
A cancel and grant race produces one durable disposition and no leaked lease.
A capacity-one supersession cannot grant the old generation after the new generation starts.
Concurrent supersession attempts accept one replacement and refuse the others without mutation.
Two requester IDs can hold concurrent leases on one connection.
An external-fence request cannot become active before authenticated confirmation.
An ordinary client cannot confirm a fence or acknowledge identity removal.
An invalid admin credential causes zero mutation.
A reusable Android identity is never unclaimed between leases or during reclaim.
A request timeout or abort does not cancel durable work.
Retention cannot remove identity-removal proof before Host acknowledges it.
Tests cover client restart, daemon restart, retention expiry, invalid stale generations, different replay payloads, unsettled cleanup, and removal acknowledgement.
Depends on #71 for the public client methods and admin authentication.
Part of #70. See ADR 0021.
Purpose
Store each lease request before Simlock queues or provisions work.
A client must recover the same result after a disconnect or process restart. A retry must not create a second lease.
Simlock must keep this state in the core registry. A frontend must not own a second request registry.
Proposed API
The status keeps the request result separate from device settlement:
canceled,superseded, orfaileddoes not mean that device cleanup is complete. A reserved or unsettled identity continues to use capacity.Required behavior
(requesterId, idempotencyKey)as the durable request key.IDEMPOTENCY_CONFLICTwhen the same key has different immutable input.requesterId.REQUESTER_BUSYwhen the prior generation is nonterminal and the new key does not include an authorized supersession.(requesterId, expectedGeneration, next idempotencyKey, immutable next input)as the same supersession.AbortSignalcancellation as abandonment of only that caller's wait.cancelLeaseRequest.For
admission: "fail-fast", do not enter the lease queue. Store a terminalfaileddisposition with a typed capacity refusal andretryAfterMs. The same key always returns that refusal. A retry after the delay uses a new key.Shape resolution
Simlock resolves
{ platform, deviceType, osVersion? }against its installed catalog.requestLeasemust not download it implicitly.External fence
Android can reuse a local device identity. Host must own an execution claim before Simlock grants that identity.
For
activation: "external-fence", Simlock returnsawaiting-external-fencewith the reserveddeviceId.Host installs its claim and uses the authenticated admin client to call
confirmLeaseActivation. Simlock checks the clean baseline, then returns the active lease.Disconnect and restart must keep the reservation recoverable. Simlock must not publish the lease before confirmation.
The execution claim lasts for the allocator identity's full pool lifetime. A terminal lease or request is not permission to clear it. Host clears the claim only after
getManagedIdentityStatusreturnsremovedfor the exact generation, then acknowledges that proof through the authenticated admin client.Existing HTTP work
#68 uses an in-memory request tracker. If #68 merges first, make that tracker use this durable core record.
This issue does not add another network interface.
Completion conditions
Depends on #71 for the public client methods and admin authentication.