chore(openspec): add cloud-console proposal
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Operator authenticates with a bearer token
|
||||
The console SHALL require an operator-supplied bearer token before calling any Cloud Control Plane endpoint, SHALL hold that token only in browser session storage, and SHALL attach it as an `Authorization: Bearer` header on every request.
|
||||
|
||||
#### Scenario: No token present
|
||||
- **WHEN** an operator opens the console without a previously entered token
|
||||
- **THEN** the console shows a token-entry screen instead of any dashboard view
|
||||
|
||||
#### Scenario: Token rejected by the Cloud API
|
||||
- **WHEN** the Cloud Control Plane responds `401` or `403` to a request carrying the stored token
|
||||
- **THEN** the console clears the stored token and returns to the token-entry screen with a clear message
|
||||
|
||||
#### Scenario: Tab closed
|
||||
- **WHEN** an operator closes the browser tab running the console
|
||||
- **THEN** the stored bearer token is discarded and is not available on the next visit
|
||||
|
||||
### Requirement: Task dashboard
|
||||
The console SHALL render a task view listing tasks by status with pagination, and SHALL show a task's detail including its attempt history, using the platform SDK's task-listing and attempt-history endpoints.
|
||||
|
||||
#### Scenario: Browse the task queue
|
||||
- **WHEN** an operator with a `tasks:read`-scoped token opens the task view
|
||||
- **THEN** the console displays tasks with their status, goal or workflow reference, and assigned device/host, and lets the operator filter by status
|
||||
|
||||
#### Scenario: Inspect a task's attempt history
|
||||
- **WHEN** an operator selects a task from the list
|
||||
- **THEN** the console displays that task's recorded attempts in order, including each attempt's outcome
|
||||
|
||||
### Requirement: Device pool and host registry views
|
||||
The console SHALL render the current device pool and host registry, including stale/unreachable device status, using the platform SDK's device- and host-listing endpoints.
|
||||
|
||||
#### Scenario: View devices across hosts
|
||||
- **WHEN** an operator with a `pool:read`-scoped token opens the device view
|
||||
- **THEN** the console displays every pooled device with its owning host, driver type, and current status, including `unreachable` for devices owned by a stale host
|
||||
|
||||
#### Scenario: View registered hosts
|
||||
- **WHEN** an operator opens the host view
|
||||
- **THEN** the console displays every registered host with its last-seen timestamp
|
||||
|
||||
### Requirement: Plugin registry view with registration
|
||||
The console SHALL render the registered plugin list and SHALL let an operator submit a new plugin manifest for registration, using the platform SDK's plugin-listing and plugin-registration endpoints.
|
||||
|
||||
#### Scenario: View registered plugins
|
||||
- **WHEN** an operator with a `plugins:read`-scoped token opens the plugin view
|
||||
- **THEN** the console displays every registered plugin with its `entry_point_kind` and whether it is wired to an execution path
|
||||
|
||||
#### Scenario: Register a plugin from the console
|
||||
- **WHEN** an operator with a `plugins:admin`-scoped token submits a valid plugin manifest through the console's registration form
|
||||
- **THEN** the console calls the plugin-registration endpoint and displays the newly registered plugin on success, or the API's validation/conflict error on failure
|
||||
|
||||
#### Scenario: Registration attempted without admin scope
|
||||
- **WHEN** an operator whose token lacks `plugins:admin` submits the registration form
|
||||
- **THEN** the console surfaces the API's authorization error without retrying or silently discarding the submission
|
||||
@@ -0,0 +1,40 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Task listing via the SDK
|
||||
The system SHALL allow an external integrator to list tasks known to the `task-scheduler` capability across all statuses, through the platform SDK's API, with optional status filtering and bounded pagination.
|
||||
|
||||
#### Scenario: List tasks without a filter
|
||||
- **WHEN** an integrator with `tasks:read` calls the task-listing endpoint with no status filter
|
||||
- **THEN** the API returns tasks across all statuses, most recently created first, bounded to the requested (or default) page size
|
||||
|
||||
#### Scenario: List tasks filtered by status
|
||||
- **WHEN** an integrator calls the task-listing endpoint with a status filter (e.g. `failed`)
|
||||
- **THEN** the API returns only tasks currently in that status
|
||||
|
||||
#### Scenario: Page size exceeds the maximum
|
||||
- **WHEN** an integrator requests a page size above the API's configured maximum
|
||||
- **THEN** the API rejects the request rather than returning an unbounded result set
|
||||
|
||||
### Requirement: Task attempt history via the SDK
|
||||
The system SHALL allow an external integrator to retrieve the attempt history of a known task — each attempt's assignment, lease, and terminal outcome — through the platform SDK's API, backed by the `task-scheduler` capability's attempt records.
|
||||
|
||||
#### Scenario: Retrieve attempt history for a known task
|
||||
- **WHEN** an integrator with `tasks:read` requests the attempt history for a task id that exists
|
||||
- **THEN** the API returns every recorded attempt for that task in chronological order, including its outcome
|
||||
|
||||
#### Scenario: Retrieve attempt history for an unknown task
|
||||
- **WHEN** an integrator requests attempt history for a task id that does not exist
|
||||
- **THEN** the API returns a not-found response rather than an unhandled server error
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Python SDK client mirrors the REST API
|
||||
The system SHALL provide a Python client (`CloudClient`) exposing methods corresponding to each `/v1/...` route (submit task, get task status, list tasks, get task attempt history, list devices, list hosts, list plugins, register plugin), so integrators do not need to hand-construct HTTP requests.
|
||||
|
||||
#### Scenario: Client submits a task and retrieves status
|
||||
- **WHEN** a caller uses `CloudClient` to submit a task and then fetch its status by the returned id
|
||||
- **THEN** the client's methods produce the same result as calling the corresponding `/v1/...` endpoints directly over HTTP
|
||||
|
||||
#### Scenario: Client lists tasks and retrieves attempt history
|
||||
- **WHEN** a caller uses `CloudClient` to list tasks with a status filter and then fetch attempt history for one returned task id
|
||||
- **THEN** the client's methods produce the same result as calling the corresponding `/v1/...` endpoints directly over HTTP
|
||||
Reference in New Issue
Block a user