feat(leasing): proxy CLI names each new lease, daemon keeps a caller-chosen lease id

Merged
V3
4d ago
+355-10

Summary

A host in front of the daemon (e.g. one embedding @agent-device/proxy) cannot know a lease ID before the daemon returns it: the CLI drops any lease ID on allocate and the daemon always mints its own.

  • In proxy mode the CLI makes a new 32-hex lease ID for every allocation and sends it with agent_device.lease.allocate. It still uses the ID in the reply, so an older daemon that ignores the field keeps working.
  • The daemon's allocate takes an optional leaseId, checked by the existing lease ID validation. An ID an active lease holds is refused with INVALID_ARGS, reason LEASE_ID_IN_USE. Without one, the daemon mints as before.
  • client.leases.allocate({ leaseId }) forwards an ID named on the call, never the client's configured leaseId.

Additive; no RPC protocol bump. 14 files, including remote-proxy.md and client-api.md.

Validation

Commit 8a54c788d: pnpm check:affected --run passed (format, lint, typecheck, layering, fallow, build, 3602 related tests, daemon-wire-compat, docs).

The 5 new tests fail without the change. The non-proxy test (daemon mints) passes before and after.

Live, built CLI and a local HTTP daemon:

  • RPC: allocate with a chosen ID returns it. Heartbeat and release by it work. The same ID for another tenant gets LEASE_ID_IN_USE, and not-hex! gets Invalid lease id.. Allocate without an ID mints one.
  • connect proxy + install through a logging proxy: the CLI sent 512e6489… and the reply carried it. Heartbeat and release used it. The next connection sent a new ID (813de5ab…).