chore(openspec): archive edge-host-enrollment
Tests / Test passed: 794

Sync delta specs into main specs before archiving: modified
cloud-control-plane, device-pool, and host-agent-protocol; created
new edge-host-enrollment capability spec. openspec validate --specs
reports 18/18 passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 21:01:47 +08:00
co-authored by Claude Opus 4.6
parent 30f09b6268
commit 989fdbf878
12 changed files with 159 additions and 20 deletions
+32 -9
View File
@@ -7,26 +7,38 @@ synchronize devices, claim leased work, execute it locally, and report results.
## Requirements
### Requirement: Host identity is authenticated and bound to one host id
The internal Host Agent API SHALL require a host-scoped bearer principal and SHALL reject any request that attempts to act for a `host_id` different from the authenticated principal's bound host.
Except for the bootstrap enrollment operation authenticated by a configured one-time enrollment credential, the internal Host Agent API SHALL require a host-scoped bearer principal and SHALL reject any request that attempts to act for a `host_id` different from the authenticated principal's bound host.
#### Scenario: Host authenticates as itself
- **WHEN** a Host Agent presents valid credentials bound to its requested `host_id`
- **THEN** the internal API authorizes permitted heartbeat, claim, renewal, and result operations
- **WHEN** a Host Agent presents valid static or dynamically enrolled credentials bound to its requested `host_id`
- **THEN** the internal API authorizes permitted device enrollment, heartbeat, claim, renewal, and result operations
#### Scenario: Host attempts to impersonate another host
- **WHEN** valid credentials bound to host A are used on a request for host B
- **THEN** the internal API rejects the request without reading or modifying host B's state
### Requirement: Host Agent synchronizes heartbeat and complete device snapshots
The Host Agent SHALL periodically submit its complete local device snapshot to the control plane, and the control plane SHALL atomically refresh the host heartbeat and replace only that host's pooled-device records.
#### Scenario: Unknown Host credential is presented
- **WHEN** a caller presents a bearer credential that is neither statically configured nor bound to a non-revoked enrolled Host
- **THEN** the internal API rejects the request without exposing whether a Host ID exists
#### Scenario: Host reports devices
- **WHEN** a Host Agent submits a valid heartbeat containing its current devices
### Requirement: Host Agent synchronizes heartbeat and complete device snapshots
The Host Agent SHALL periodically submit its complete local device snapshot to the control plane, and the control plane SHALL atomically refresh the host heartbeat and replace only that host's pooled-device records. Enrollment-managed Hosts SHALL report the cloud device IDs assigned through device enrollment.
#### Scenario: Managed Host reports enrolled devices
- **WHEN** an enrollment-managed Host Agent submits a valid heartbeat containing cloud device IDs enrolled to that Host
- **THEN** the control plane updates the host's last-seen time and exposes the submitted devices through the aggregated pool
#### Scenario: Managed Host reports an unknown device ID
- **WHEN** an enrollment-managed Host reports a device ID not enrolled to that Host or a driver type that conflicts with its enrollment
- **THEN** the control plane rejects the entire snapshot without changing the previous heartbeat or pooled-device state
#### Scenario: Legacy Host reports devices
- **WHEN** a statically configured legacy Host submits a valid device snapshot
- **THEN** the control plane retains the existing compatible snapshot and ownership-conflict behavior
#### Scenario: Host reports no devices
- **WHEN** a previously populated host submits an empty device snapshot
- **THEN** only that host's prior device records are removed while devices owned by other hosts remain unchanged
- **WHEN** a previously populated Host submits an empty device snapshot
- **THEN** only that Host's prior pooled-device records are removed while durable enrollment records and devices owned by other Hosts remain unchanged
### Requirement: Host Agent receives work through outbound long-polling
The Host Agent SHALL request assigned work for its own host through a configurable long-poll endpoint, and the control plane SHALL return at most one atomically claimable assignment per response or an empty timeout response.
@@ -82,3 +94,14 @@ The Host Agent SHALL perform synchronization, work retrieval, lease renewal, and
#### Scenario: Host is behind NAT
- **WHEN** the Host Agent can reach the control-plane URL but exposes no inbound listener
- **THEN** it can register devices and execute cloud assignments through the complete protocol
### Requirement: Managed Host startup enrolls before normal protocol loops
The Host Agent SHALL resolve its Host identity and cloud device mappings before starting heartbeat synchronization or assignment long-polling.
#### Scenario: New managed Host starts
- **WHEN** the Host Agent has an enrollment token but no completed local Host identity
- **THEN** it performs idempotent Host enrollment, enrolls configured local devices, constructs its `DeviceManager` with cloud device IDs, and only then starts heartbeat and claim loops
#### Scenario: Explicit legacy credentials are configured
- **WHEN** both `HOST_AGENT_HOST_ID` and `HOST_AGENT_TOKEN` are explicitly supplied
- **THEN** the Host Agent skips bootstrap enrollment and preserves existing local device ID behavior