Skip to content

feat(core): create a new device identity for each lease under lease.identity fresh - #145

Merged
V3RON merged 2 commits into
mainfrom
task/75
Sep 14, 2026
Merged

V3RON merged 2 commits into
mainfrom
task/75

Conversation

@V3RON

@V3RON V3RON commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Closes #75

What changed

New config lease.identity.ios / lease.identity.android, default reusable. Each device records the policy it was created under.

A fresh device serves one lease. When the lease ends, Simlock shuts it down, commits shutdown, then deletes it. It is never erased. mayBeGranted (domain.ts) is the one check that stops a spent device from being granted; the planner, warm pool, quarantine and startup all call it. A failed shutdown or delete emits device.purge-failed with strategy delete and quarantines the device; quarantine then retries the delete and never reclaims it. At startup, Simlock deletes spent devices left reclaiming or shutdown.

Spec deviation (agreed in session): the spec says no new transitions, but a failed delete happens in shutdown, so this adds shutdown → quarantined. A quarantined device counts as running capacity until it is deleted.

If a delete fails at startup, the device stays shutdown. It remains ungrantable, and the next start or the idle delete rule retries it. doctor --fix never moves a spent device from shutdown to ready, so its delete still finds it.

Completion conditions

  • Two sequential fresh leases get different UDIDs: engine test.
  • Release, expiry and device-lost termination each delete the device: one engine test each. A spent device is never granted: planner test (ready and shutdown scans).
  • At most one lease per device, however it was created: the check reads the device record.
  • A spent device counts against capacity until deleted: planner test.
  • A failed delete leaves an ungrantable quarantine: engine, warm-pool and quarantine tests.
  • Restart tests: reclaiming, shutdown-before-delete, grant then config change then release. Expiry after restart reuses the existing timer-restore path; there is no fresh-specific test for it.
  • Reusable unchanged: existing suite plus a reclaim-and-reuse test.
  • Both EVENTS.md cuts updated.
  • CONFIGURATION.md documents the setting and the boot cost.

pnpm check passes. Each new path was broken on purpose and its tests failed.

Written by an agent.

…dentity fresh

Adds lease.identity.{ios,android} (default reusable). A device records the
policy it was created under. A fresh device serves one lease: its lease end
is a shutdown and a delete, never an erase; a failed delete quarantines it
and quarantine retries the delete. Startup finishes deleting spent devices
left reclaiming or shutdown. Adds the shutdown -> quarantined transition.

Closes #75
doctor --fix moved a shutdown device observed running to ready. For a spent
fresh device that stranded it: every delete path selects shutdown, so it sat
ungrantable in the warm pool until the idle rules removed it. The fix now
skips spent devices. Also folds startup convergence's three copies of the
actionable-device filter into one helper.

Refs #75
@V3RON
V3RON merged commit 74c09e6 into main Sep 14, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a new iOS simulator for each lease

1 participant