# device-pool Specification ## Purpose TBD - created by archiving change cloud-runtime. Update Purpose after archive. ## Requirements ### Requirement: Host registration and heartbeat sync The system SHALL provide a `DevicePool` that tracks a `HostRegistration` (host id, address, last-seen timestamp) for each host process that registers itself, and SHALL update a host's last-seen timestamp whenever that host pushes a device snapshot via `sync_host_devices(host_id, snapshot)`. #### Scenario: New host registers and syncs devices - **WHEN** a previously-unknown `host_id` calls `sync_host_devices` with a list of devices - **THEN** the pool creates a new `HostRegistration` for that host, records the current time as its last-seen timestamp, and stores each synced device as a `PooledDevice` owned by that host #### Scenario: Known host re-syncs - **WHEN** an already-registered `host_id` calls `sync_host_devices` again with an updated device snapshot - **THEN** the pool updates that host's last-seen timestamp and replaces its previously-stored `PooledDevice` records with the new snapshot, without duplicating or losing devices from other hosts ### Requirement: Aggregated device listing across hosts The system SHALL provide a way to list all `PooledDevice` records across every registered host, including each device's owning `host_id`, `driver_type`, status, and capability tags. #### Scenario: Listing devices across multiple hosts - **WHEN** two hosts have each synced a non-empty device snapshot - **THEN** a caller listing pool devices sees devices from both hosts in one combined result, each tagged with its correct `host_id` #### Scenario: No hosts registered - **WHEN** a caller lists pool devices before any host has ever synced - **THEN** the pool returns an empty list rather than raising an error ### Requirement: Stale host devices degrade to unreachable The system SHALL mark all `PooledDevice`s belonging to a host `unreachable` once that host's last-seen timestamp exceeds a configured staleness threshold, computed at read time, without requiring any background process and without raising an error for the stale host's absence. #### Scenario: Host misses its sync interval - **WHEN** a host's last-seen timestamp is older than `config.stale_after_seconds` at the time of a `list_devices()`/`get_device()` call - **THEN** every `PooledDevice` owned by that host is reported with status `unreachable`, regardless of the status value in its last-synced snapshot #### Scenario: Host resumes syncing after being stale - **WHEN** a host previously marked stale calls `sync_host_devices` again - **THEN** its devices immediately stop being reported `unreachable` and reflect the statuses in the new snapshot ### Requirement: Device lookup by id across the pool The system SHALL allow looking up a single `PooledDevice` by `device_id` regardless of which host owns it, returning a clear not-found result when no host has ever reported that device id. #### Scenario: Lookup finds device on any host - **WHEN** a caller requests a device by id that exists in some host's synced snapshot - **THEN** the pool returns that `PooledDevice` including its owning `host_id` #### Scenario: Lookup for unknown device id - **WHEN** a caller requests a device by id that no host has ever synced - **THEN** the pool returns a not-found result (e.g. `None`) rather than raising an unhandled exception ### Requirement: Authenticated network synchronization feeds the device pool The system SHALL expose an authenticated Host Agent operation that validates a host device snapshot against its authentication mode and durable device enrollments before delegating it to the existing device-pool synchronization behavior. #### Scenario: Valid managed remote snapshot - **WHEN** an authenticated enrollment-managed Host submits a complete snapshot containing only non-revoked device IDs enrolled to that Host with matching driver types - **THEN** the device pool refreshes that Host and its devices with the same replacement and staleness semantics as an in-process synchronization call #### Scenario: Valid legacy remote snapshot - **WHEN** an authenticated statically configured Host submits a valid complete snapshot - **THEN** the device pool preserves the existing compatible synchronization and ownership-conflict behavior #### Scenario: Invalid snapshot is rejected atomically - **WHEN** a Host Agent snapshot contains invalid identifiers, unowned cloud device IDs, conflicting driver metadata, statuses, or capability tags - **THEN** the control plane rejects the snapshot without partially replacing the Host's previous pooled devices or heartbeat timestamp ### Requirement: Device identity ownership conflicts are explicit The device pool SHALL reject a snapshot that claims a `device_id` actively owned by a different non-stale host, rather than silently transferring ownership. #### Scenario: Two live hosts report the same device id - **WHEN** host B reports a device id currently owned by non-stale host A - **THEN** host B's conflicting snapshot is rejected with an ownership-conflict response and host A retains ownership #### Scenario: Previous owner is stale - **WHEN** a configured ownership-recovery policy permits takeover and the prior owning host is stale beyond the recovery threshold - **THEN** the new host may claim the device id and the ownership transition is recorded ### Requirement: Durable device enrollment identity is independent of pool presence The cloud repository SHALL retain a Host-scoped device enrollment and its assigned `device_id` independently of whether the device appears in the Host's latest heartbeat snapshot. #### Scenario: Enrolled device disconnects - **WHEN** a Host submits a heartbeat that no longer includes a previously enrolled device - **THEN** the pooled-device projection removes that device while its durable enrollment remains available for later idempotent re-enrollment #### Scenario: Enrolled device reconnects - **WHEN** the Host later enrolls or reports the same local device reference again - **THEN** the control plane reuses the existing cloud `device_id` ### Requirement: Managed device identity cannot be claimed by another Host The device pool SHALL derive managed device ownership from durable enrollment rather than accepting a caller-selected cloud device ID. #### Scenario: Host reports another Host's managed device - **WHEN** Host B includes a cloud device ID enrolled to Host A in its heartbeat - **THEN** the control plane rejects Host B's snapshot and Host A retains ownership #### Scenario: Prior Host becomes stale - **WHEN** Host A becomes stale and Host B presents Host A's cloud device ID - **THEN** the control plane still rejects implicit takeover because managed device transfer requires a future explicit operation