docs(openspec): sync cloud control plane specs

This commit is contained in:
2026-07-13 08:58:04 +08:00
parent ea9b15fce7
commit 70d15f8f0b
5 changed files with 265 additions and 11 deletions
@@ -0,0 +1,77 @@
# cloud-control-plane Specification
## Purpose
Provide a runnable, authenticated Cloud Control Plane with durable scheduling,
lease maintenance, health reporting, and restart recovery.
## Requirements
### Requirement: Runnable Cloud Control Plane application
The system SHALL provide an independently runnable Cloud Control Plane application that composes the cloud repository, device pool, task scheduler, plugin registry, authentication providers, public platform router, internal Host Agent router, and lifecycle services without modifying the local Runtime API application.
#### Scenario: Start the cloud application
- **WHEN** an operator starts the Cloud Control Plane with valid configuration and an available database
- **THEN** the application exposes its versioned public, internal, and health routes and starts its configured lifecycle workers
#### Scenario: Local Runtime remains separately runnable
- **WHEN** an operator starts the existing local Runtime API without the cloud application
- **THEN** local Runtime routes operate without initializing cloud persistence, scheduling, or Host Agent services
### Requirement: Scheduler and lease maintenance run through application lifecycle
The Cloud Control Plane SHALL run configurable scheduler and expired-lease maintenance loops after application startup and SHALL stop them cleanly during shutdown.
#### Scenario: Queued work becomes assigned
- **WHEN** a queued task has an eligible device and the scheduler loop runs
- **THEN** the task receives an atomic assignment and becomes available to the owning Host Agent
#### Scenario: Lifecycle iteration fails transiently
- **WHEN** one scheduler or lease-maintenance iteration raises an operational error
- **THEN** the error is recorded and subsequent configured iterations continue rather than permanently terminating the worker
#### Scenario: Application shuts down
- **WHEN** the Cloud Control Plane receives a graceful shutdown signal
- **THEN** its lifecycle workers stop accepting new iterations and terminate without abandoning an in-process database transaction
### Requirement: Deployment and local persistence modes share one contract
The cloud repository SHALL support PostgreSQL for deployed operation and SQLite for local development and tests through the same behavioral contract, including hosts, devices, tasks, leases, attempts, and plugins.
#### Scenario: Start with PostgreSQL
- **WHEN** the configured database URL selects PostgreSQL and the schema is current
- **THEN** the control plane uses PostgreSQL for all cloud state and transactional assignment operations
#### Scenario: Start in local SQLite mode
- **WHEN** the configured database URL selects SQLite in a local or test environment
- **THEN** the same repository contract is available with the documented single-control-plane concurrency limitation
### Requirement: Cloud schema is versioned with migrations
The system SHALL provide versioned forward and downgrade database migrations and SHALL refuse readiness when the database schema is incompatible with the running application.
#### Scenario: Upgrade an existing cloud database
- **WHEN** an operator applies the release's migrations to a supported previous schema
- **THEN** existing hosts, devices, tasks, and plugins are retained and the new lease fields become available
#### Scenario: Schema is behind at startup
- **WHEN** the application connects to a database whose schema version is not accepted by the running release
- **THEN** readiness fails with a diagnostic that does not expose credentials
### Requirement: Restart recovery preserves durable work
The Cloud Control Plane SHALL recover persisted queued tasks and SHALL requeue or fail expired assigned/dispatched attempts according to retry policy after process restart.
#### Scenario: Restart with queued tasks
- **WHEN** the control plane restarts while tasks are queued
- **THEN** those tasks remain queued and are considered by later scheduler iterations
#### Scenario: Restart after a lease expires
- **WHEN** the control plane restarts and finds an assigned or dispatched task with an expired lease
- **THEN** lease maintenance requeues it when attempts remain or marks it failed when the retry limit is exhausted
### Requirement: Liveness, readiness, and safe operational logging
The application SHALL expose separate liveness and readiness endpoints and SHALL emit structured lifecycle logs with correlation identifiers while excluding credentials and sensitive device payloads.
#### Scenario: Database is unavailable
- **WHEN** the process is running but cannot reach its configured database
- **THEN** liveness succeeds and readiness fails
#### Scenario: Task lifecycle is logged
- **WHEN** a task is assigned, claimed, renewed, completed, retried, or failed
- **THEN** the log event includes available task, host, device, attempt, lease, and correlation identifiers but excludes bearer tokens, screenshots, UI trees, and typed text