# platform-sdk Specification ## Purpose TBD - created by archiving change cloud-runtime. Update Purpose after archive. ## Requirements ### Requirement: Versioned public API surface The system SHALL expose the platform SDK's REST endpoints under a versioned URL prefix (`/v1/...`), distinct from the `mcp-tool-server` and `console-status-api`/`console-config-api` surfaces, so external integrators have a stable base path that will not silently change shape. #### Scenario: Routes are mounted under the version prefix - **WHEN** the platform SDK's router is mounted into an application - **THEN** every route it exposes (task submission, status queries, device/host listing, plugin listing/registration) is reachable only under the `/v1/` prefix ### Requirement: Task submission and status via the SDK The system SHALL allow an external integrator to submit a task (goal or workflow reference plus constraints) through the platform SDK's API, and to query that task's current status by id, backed by the `task-scheduler` capability. #### Scenario: Submit a task via the API - **WHEN** an integrator calls the task-submission endpoint with a valid goal and optional constraints - **THEN** the API returns a task id that can be used to poll status, and the underlying `task-scheduler` records a new `queued` `ScheduledTask` #### Scenario: Query status of a known task - **WHEN** an integrator requests status for a task id that exists - **THEN** the API returns that task's current status (`queued`, `assigned`, `dispatched`, `done`, or `failed`) #### Scenario: Query status of an unknown task - **WHEN** an integrator requests status for a task id that does not exist - **THEN** the API returns a not-found response rather than an unhandled server error ### Requirement: Device and host visibility via the SDK The system SHALL allow an external integrator to list devices and hosts known to the `device-pool` capability through the platform SDK's API. #### Scenario: List devices across the pool - **WHEN** an integrator calls the device-listing endpoint - **THEN** the API returns every `PooledDevice` known to the pool, including owning host id and current (possibly `unreachable`) status #### Scenario: List registered hosts - **WHEN** an integrator calls the host-listing endpoint - **THEN** the API returns every `HostRegistration` known to the pool, including last-seen timestamp ### Requirement: Plugin listing and registration via the SDK The system SHALL allow an external integrator to list registered plugins and submit a new plugin manifest for registration through the platform SDK's API, backed by the `plugin-system` capability. #### Scenario: List registered plugins - **WHEN** an integrator calls the plugin-listing endpoint - **THEN** the API returns every registered `PluginManifest`, including its `entry_point_kind` and whether it is wired to an execution path #### Scenario: Register a new plugin manifest - **WHEN** an integrator submits a valid plugin manifest to the plugin-registration endpoint - **THEN** the API registers it via `plugin-system`'s `PluginRegistry` and returns the stored manifest, or a clear validation/conflict error if registration fails ### Requirement: Pluggable authentication hook with a safe default The system SHALL evaluate every platform SDK route through a configurable `AuthProvider` hook, defaulting to a no-op provider that treats every caller as an anonymous, authenticated principal, so real authentication can be added later without changing route signatures. #### Scenario: Default configuration allows anonymous access - **WHEN** no `AuthProvider` is explicitly configured - **THEN** every route accepts requests without rejecting them for lack of credentials #### Scenario: Custom AuthProvider is honored - **WHEN** a caller configures a custom `AuthProvider` that rejects a request - **THEN** the platform SDK's routes return an authorization error for that request instead of proceeding, without any route's own handler code needing to change ### 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 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