From c5193ee1515d21688e40a298fcbd69e8593df935 Mon Sep 17 00:00:00 2001 From: "spin-stack-website-sync[bot]" <347572492+spin-stack-website-sync[bot]@users.noreply.github.com> Date: Wed, 11 Nov 2026 12:52:28 +0000 Subject: [PATCH 1/3] sources: spin v20261110.01 b7ba5206f1, brand main e5d547cff9 Written by sync.yml: versions.yaml bumped by task sources:bump, the reference by task reference. --- public/openapi.json | 3364 +++++++++++++---- src/assets/shots/snapshots.png | Bin 64820 -> 65276 bytes src/assets/shots/workspace.png | Bin 108445 -> 108458 bytes src/assets/shots/workspaces.png | Bin 47585 -> 47555 bytes .../docs/reference/api/adminservice.md | 147 + src/content/docs/reference/api/hostservice.md | 20 + src/content/docs/reference/api/index.md | 6 +- .../docs/reference/api/projectservice.md | 42 + .../docs/reference/api/settingsservice.md | 52 +- .../docs/reference/api/setupservice.md | 3 +- src/content/docs/reference/api/types.md | 192 +- .../docs/reference/api/workspaceservice.md | 8 +- src/content/docs/reference/cli/admin.md | 134 +- src/content/docs/reference/cli/agent.md | 16 +- src/content/docs/reference/cli/api-key.md | 10 +- src/content/docs/reference/cli/code.md | 22 +- src/content/docs/reference/cli/cp.md | 10 +- src/content/docs/reference/cli/exec.md | 20 +- src/content/docs/reference/cli/git.md | 18 +- src/content/docs/reference/cli/index.md | 2 +- src/content/docs/reference/cli/login.md | 8 +- src/content/docs/reference/cli/logout.md | 2 +- src/content/docs/reference/cli/mcp.md | 2 +- src/content/docs/reference/cli/open.md | 17 +- src/content/docs/reference/cli/port.md | 16 +- src/content/docs/reference/cli/project.md | 28 +- src/content/docs/reference/cli/settings.md | 24 +- src/content/docs/reference/cli/share.md | 20 +- src/content/docs/reference/cli/smoke.md | 2 +- src/content/docs/reference/cli/snapshot.md | 24 +- src/content/docs/reference/cli/ssh-config.md | 4 +- src/content/docs/reference/cli/ssh-key.md | 12 +- src/content/docs/reference/cli/ssh.md | 10 +- src/content/docs/reference/cli/team.md | 56 +- src/content/docs/reference/cli/update.md | 2 +- src/content/docs/reference/cli/version.md | 2 +- src/content/docs/reference/cli/vscode.md | 6 +- src/content/docs/reference/cli/whoami.md | 2 +- src/content/docs/reference/cli/workspace.md | 156 +- .../docs/reference/configuration/file.md | 14 +- .../docs/reference/security/known-gaps.md | 2 +- src/content/docs/reference/security/rules.md | 2 +- src/content/docs/reference/status/index.md | 173 +- src/content/docs/use/access.md | 2 +- src/content/docs/use/dashboard.md | 2 +- src/data/features.json | 23 +- src/data/figures.json | 8 +- src/data/pricing.json | 4 +- src/data/reference.json | 14 +- src/data/shots.json | 4 +- versions.yaml | 6 +- 51 files changed, 3580 insertions(+), 1133 deletions(-) diff --git a/public/openapi.json b/public/openapi.json index bbf1da6..39bf23d 100644 --- a/public/openapi.json +++ b/public/openapi.json @@ -6,6 +6,68 @@ "version": "v1" }, "paths": { + "/spin.v1.AdminService/AcceptThirdPartyTerms": { + "post": { + "tags": [ + "AdminService" + ], + "summary": "AcceptThirdPartyTerms", + "description": "Accept the terms, as the version shown, for the items named: this installation then\n downloads them - the releases this control plane pins at once, and the newest daily.", + "operationId": "spin.v1.AdminService.AcceptThirdPartyTerms", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.AcceptThirdPartyTermsRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.AcceptThirdPartyTermsResponse" + } + } + } + } + } + } + }, "/spin.v1.AdminService/AddAllowedEmail": { "post": { "tags": [ @@ -747,6 +809,68 @@ } } }, + "/spin.v1.AdminService/GetEmailSettings": { + "post": { + "tags": [ + "AdminService" + ], + "summary": "GetEmailSettings", + "description": "The SMTP server the installation tells people through. The password is never read back.", + "operationId": "spin.v1.AdminService.GetEmailSettings", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetEmailSettingsRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetEmailSettingsResponse" + } + } + } + } + } + } + }, "/spin.v1.AdminService/GetFleetVersions": { "post": { "tags": [ @@ -1119,14 +1243,14 @@ } } }, - "/spin.v1.AdminService/GetSecuritySettings": { + "/spin.v1.AdminService/GetRunbook": { "post": { "tags": [ "AdminService" ], - "summary": "GetSecuritySettings", - "description": "Get security settings", - "operationId": "spin.v1.AdminService.GetSecuritySettings", + "summary": "GetRunbook", + "description": "One runbook, its markdown and where its file is at the pinned commit. NOT_FOUND for an id\n this release's runbooks do not have.", + "operationId": "spin.v1.AdminService.GetRunbook", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1151,7 +1275,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetSecuritySettingsRequest" + "$ref": "#/components/schemas/spin.v1.GetRunbookRequest" } } }, @@ -1173,7 +1297,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetSecuritySettingsResponse" + "$ref": "#/components/schemas/spin.v1.GetRunbookResponse" } } } @@ -1181,14 +1305,14 @@ } } }, - "/spin.v1.AdminService/GetStorageSettings": { + "/spin.v1.AdminService/GetSecuritySettings": { "post": { "tags": [ "AdminService" ], - "summary": "GetStorageSettings", - "description": "Where the installation's object store is. The secret is never read back.", - "operationId": "spin.v1.AdminService.GetStorageSettings", + "summary": "GetSecuritySettings", + "description": "Get security settings", + "operationId": "spin.v1.AdminService.GetSecuritySettings", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1213,7 +1337,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetStorageSettingsRequest" + "$ref": "#/components/schemas/spin.v1.GetSecuritySettingsRequest" } } }, @@ -1235,7 +1359,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetStorageSettingsResponse" + "$ref": "#/components/schemas/spin.v1.GetSecuritySettingsResponse" } } } @@ -1243,14 +1367,14 @@ } } }, - "/spin.v1.AdminService/GetStorageUsage": { + "/spin.v1.AdminService/GetStorageSettings": { "post": { "tags": [ "AdminService" ], - "summary": "GetStorageUsage", - "description": "What the store holds, by what each object is for: every volume's objects and the layers its\n commits name, with the workspace, image or extension release it is. As the storage-gc job\n last read it - daily, or when an admin runs it - never the bucket itself.", - "operationId": "spin.v1.AdminService.GetStorageUsage", + "summary": "GetStorageSettings", + "description": "Where the installation's object store is. The secret is never read back.", + "operationId": "spin.v1.AdminService.GetStorageSettings", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1275,7 +1399,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetStorageUsageRequest" + "$ref": "#/components/schemas/spin.v1.GetStorageSettingsRequest" } } }, @@ -1297,7 +1421,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetStorageUsageResponse" + "$ref": "#/components/schemas/spin.v1.GetStorageSettingsResponse" } } } @@ -1305,14 +1429,14 @@ } } }, - "/spin.v1.AdminService/GetTelemetryStatus": { + "/spin.v1.AdminService/GetStorageUsage": { "post": { "tags": [ "AdminService" ], - "summary": "GetTelemetryStatus", - "description": "What the collector has sent and failed to send over its last minute, as the watch on its\n machine read it from the collector itself.", - "operationId": "spin.v1.AdminService.GetTelemetryStatus", + "summary": "GetStorageUsage", + "description": "What the store holds, by what each object is for: every volume's objects and the layers its\n commits name, with the workspace, image or extension release it is. As the storage-gc job\n last read it - daily, or when an admin runs it - never the bucket itself.", + "operationId": "spin.v1.AdminService.GetStorageUsage", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1337,7 +1461,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetTelemetryStatusRequest" + "$ref": "#/components/schemas/spin.v1.GetStorageUsageRequest" } } }, @@ -1359,7 +1483,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetTelemetryStatusResponse" + "$ref": "#/components/schemas/spin.v1.GetStorageUsageResponse" } } } @@ -1367,14 +1491,14 @@ } } }, - "/spin.v1.AdminService/GetVSCodeServers": { + "/spin.v1.AdminService/GetTelemetryStatus": { "post": { "tags": [ "AdminService" ], - "summary": "GetVSCodeServers", - "description": "The VS Code servers workspaces are given (the vscode-server extension): each release, and\n the publish this control plane ran since it started, if it ran one.", - "operationId": "spin.v1.AdminService.GetVSCodeServers", + "summary": "GetTelemetryStatus", + "description": "What the collector has sent and failed to send over its last minute, as the watch on its\n machine read it from the collector itself.", + "operationId": "spin.v1.AdminService.GetTelemetryStatus", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1399,7 +1523,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetVSCodeServersRequest" + "$ref": "#/components/schemas/spin.v1.GetTelemetryStatusRequest" } } }, @@ -1421,7 +1545,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetVSCodeServersResponse" + "$ref": "#/components/schemas/spin.v1.GetTelemetryStatusResponse" } } } @@ -1429,14 +1553,14 @@ } } }, - "/spin.v1.AdminService/ListAllowedEmails": { + "/spin.v1.AdminService/GetThirdPartyTerms": { "post": { "tags": [ "AdminService" ], - "summary": "ListAllowedEmails", - "description": "List allowed emails/domains", - "operationId": "spin.v1.AdminService.ListAllowedEmails", + "summary": "GetThirdPartyTerms", + "description": "The software this installation downloads from its makers, the terms it is used under, and\n which of it an administrator accepted the terms for: who, when, and which text. Nothing is\n downloaded of an item whose terms are not accepted (internal/controlplane/thirdparty).", + "operationId": "spin.v1.AdminService.GetThirdPartyTerms", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1461,7 +1585,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListAllowedEmailsRequest" + "$ref": "#/components/schemas/spin.v1.GetThirdPartyTermsRequest" } } }, @@ -1483,7 +1607,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListAllowedEmailsResponse" + "$ref": "#/components/schemas/spin.v1.GetThirdPartyTermsResponse" } } } @@ -1491,14 +1615,14 @@ } } }, - "/spin.v1.AdminService/ListAuditLog": { + "/spin.v1.AdminService/GetVSCodeServers": { "post": { "tags": [ "AdminService" ], - "summary": "ListAuditLog", - "description": "Read the audit log, newest first. There is no RPC that writes one: an entry is written\n by the operation it records, so a log an API could add to would be one an API could\n forge.", - "operationId": "spin.v1.AdminService.ListAuditLog", + "summary": "GetVSCodeServers", + "description": "The VS Code servers workspaces are given (the vscode-server extension): each release, and\n the publish this control plane ran since it started, if it ran one.", + "operationId": "spin.v1.AdminService.GetVSCodeServers", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1523,7 +1647,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListAuditLogRequest" + "$ref": "#/components/schemas/spin.v1.GetVSCodeServersRequest" } } }, @@ -1545,7 +1669,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListAuditLogResponse" + "$ref": "#/components/schemas/spin.v1.GetVSCodeServersResponse" } } } @@ -1553,14 +1677,14 @@ } } }, - "/spin.v1.AdminService/ListConfigChanges": { + "/spin.v1.AdminService/GetWorkspaceNames": { "post": { "tags": [ "AdminService" ], - "summary": "ListConfigChanges", - "description": "What the config file says now and the installation does not, for an administrator to\n decide: the file seeds an installation once, and after that its changes are proposals.", - "operationId": "spin.v1.AdminService.ListConfigChanges", + "summary": "GetWorkspaceNames", + "description": "The names of the workspaces ids are, whoever owns them and whatever state they are in, a\n deleted one among them: a record of the platform's logs names a workspace by its id, and\n ListWorkspaces is the caller's own. An id the installation no longer holds a row for is\n left out of the answer.", + "operationId": "spin.v1.AdminService.GetWorkspaceNames", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1585,7 +1709,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListConfigChangesRequest" + "$ref": "#/components/schemas/spin.v1.GetWorkspaceNamesRequest" } } }, @@ -1607,7 +1731,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListConfigChangesResponse" + "$ref": "#/components/schemas/spin.v1.GetWorkspaceNamesResponse" } } } @@ -1615,13 +1739,14 @@ } } }, - "/spin.v1.AdminService/ListHostClasses": { + "/spin.v1.AdminService/ListAllowedEmails": { "post": { "tags": [ "AdminService" ], - "summary": "ListHostClasses", - "operationId": "spin.v1.AdminService.ListHostClasses", + "summary": "ListAllowedEmails", + "description": "List allowed emails/domains", + "operationId": "spin.v1.AdminService.ListAllowedEmails", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1646,7 +1771,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListHostClassesRequest" + "$ref": "#/components/schemas/spin.v1.ListAllowedEmailsRequest" } } }, @@ -1668,7 +1793,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListHostClassesResponse" + "$ref": "#/components/schemas/spin.v1.ListAllowedEmailsResponse" } } } @@ -1676,14 +1801,14 @@ } } }, - "/spin.v1.AdminService/ListJobRuns": { + "/spin.v1.AdminService/ListAuditLog": { "post": { "tags": [ "AdminService" ], - "summary": "ListJobRuns", - "description": "One job's runs, newest first.", - "operationId": "spin.v1.AdminService.ListJobRuns", + "summary": "ListAuditLog", + "description": "Read the audit log, newest first. There is no RPC that writes one: an entry is written\n by the operation it records, so a log an API could add to would be one an API could\n forge.", + "operationId": "spin.v1.AdminService.ListAuditLog", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1708,7 +1833,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListJobRunsRequest" + "$ref": "#/components/schemas/spin.v1.ListAuditLogRequest" } } }, @@ -1730,7 +1855,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListJobRunsResponse" + "$ref": "#/components/schemas/spin.v1.ListAuditLogResponse" } } } @@ -1738,14 +1863,14 @@ } } }, - "/spin.v1.AdminService/ListJobs": { + "/spin.v1.AdminService/ListConfigChanges": { "post": { "tags": [ "AdminService" ], - "summary": "ListJobs", - "description": "The control plane's periodic work - backups, cleanups, the object store's garbage\n collection - with how often each runs and how its last run went.", - "operationId": "spin.v1.AdminService.ListJobs", + "summary": "ListConfigChanges", + "description": "What the config file says now and the installation does not, for an administrator to\n decide: the file seeds an installation once, and after that its changes are proposals.", + "operationId": "spin.v1.AdminService.ListConfigChanges", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1770,7 +1895,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListJobsRequest" + "$ref": "#/components/schemas/spin.v1.ListConfigChangesRequest" } } }, @@ -1792,7 +1917,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListJobsResponse" + "$ref": "#/components/schemas/spin.v1.ListConfigChangesResponse" } } } @@ -1800,14 +1925,13 @@ } } }, - "/spin.v1.AdminService/ListRekeys": { + "/spin.v1.AdminService/ListHostClasses": { "post": { "tags": [ "AdminService" ], - "summary": "ListRekeys", - "description": "The disks being re-keyed, and the ones a revoked host's keys marked for it.", - "operationId": "spin.v1.AdminService.ListRekeys", + "summary": "ListHostClasses", + "operationId": "spin.v1.AdminService.ListHostClasses", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1832,7 +1956,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListRekeysRequest" + "$ref": "#/components/schemas/spin.v1.ListHostClassesRequest" } } }, @@ -1854,7 +1978,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListRekeysResponse" + "$ref": "#/components/schemas/spin.v1.ListHostClassesResponse" } } } @@ -1862,14 +1986,14 @@ } } }, - "/spin.v1.AdminService/ListResourcePresets": { + "/spin.v1.AdminService/ListJobRuns": { "post": { "tags": [ "AdminService" ], - "summary": "ListResourcePresets", - "description": "List resource presets", - "operationId": "spin.v1.AdminService.ListResourcePresets", + "summary": "ListJobRuns", + "description": "One job's runs, newest first.", + "operationId": "spin.v1.AdminService.ListJobRuns", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1894,7 +2018,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListResourcePresetsRequest" + "$ref": "#/components/schemas/spin.v1.ListJobRunsRequest" } } }, @@ -1916,7 +2040,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListResourcePresetsResponse" + "$ref": "#/components/schemas/spin.v1.ListJobRunsResponse" } } } @@ -1924,14 +2048,14 @@ } } }, - "/spin.v1.AdminService/ListUserAPIKeys": { + "/spin.v1.AdminService/ListJobs": { "post": { "tags": [ "AdminService" ], - "summary": "ListUserAPIKeys", - "description": "List another user's API keys. The secret is never stored, so this is what an admin can\n know about a key: what it is called, when it was made, when it was last used.", - "operationId": "spin.v1.AdminService.ListUserAPIKeys", + "summary": "ListJobs", + "description": "The control plane's periodic work - backups, cleanups, the object store's garbage\n collection - with how often each runs and how its last run went.", + "operationId": "spin.v1.AdminService.ListJobs", "parameters": [ { "name": "Connect-Protocol-Version", @@ -1956,7 +2080,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListUserAPIKeysRequest" + "$ref": "#/components/schemas/spin.v1.ListJobsRequest" } } }, @@ -1978,7 +2102,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListUserAPIKeysResponse" + "$ref": "#/components/schemas/spin.v1.ListJobsResponse" } } } @@ -1986,14 +2110,14 @@ } } }, - "/spin.v1.AdminService/ListUsers": { + "/spin.v1.AdminService/ListRekeys": { "post": { "tags": [ "AdminService" ], - "summary": "ListUsers", - "description": "List all users", - "operationId": "spin.v1.AdminService.ListUsers", + "summary": "ListRekeys", + "description": "The disks being re-keyed, and the ones a revoked host's keys marked for it.", + "operationId": "spin.v1.AdminService.ListRekeys", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2018,7 +2142,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListUsersRequest" + "$ref": "#/components/schemas/spin.v1.ListRekeysRequest" } } }, @@ -2040,7 +2164,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListUsersResponse" + "$ref": "#/components/schemas/spin.v1.ListRekeysResponse" } } } @@ -2048,14 +2172,14 @@ } } }, - "/spin.v1.AdminService/PublishVSCodeServers": { + "/spin.v1.AdminService/ListResourcePresets": { "post": { "tags": [ "AdminService" ], - "summary": "PublishVSCodeServers", - "description": "Publish the servers of the newest stable VS Code releases, or of the commits named, as a\n new release. Answers once the publish has begun - it downloads a gigabyte - and\n GetVSCodeServers says how it goes.", - "operationId": "spin.v1.AdminService.PublishVSCodeServers", + "summary": "ListResourcePresets", + "description": "List resource presets", + "operationId": "spin.v1.AdminService.ListResourcePresets", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2080,7 +2204,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.PublishVSCodeServersRequest" + "$ref": "#/components/schemas/spin.v1.ListResourcePresetsRequest" } } }, @@ -2102,7 +2226,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.PublishVSCodeServersResponse" + "$ref": "#/components/schemas/spin.v1.ListResourcePresetsResponse" } } } @@ -2110,14 +2234,14 @@ } } }, - "/spin.v1.AdminService/RekeyVolume": { + "/spin.v1.AdminService/ListRunbooks": { "post": { "tags": [ "AdminService" ], - "summary": "RekeyVolume", - "description": "Re-key a workspace's disk: copy it whole under a key of its own, point the workspace at the\n copy, and delete the disk - which shreds the key assumed taken and every snapshot of the disk,\n since those are what that key opens. The workspace must be stopped or quarantined. Refused for\n a disk something descends from. Audited.", - "operationId": "spin.v1.AdminService.RekeyVolume", + "summary": "ListRunbooks", + "description": "What an operator does when an alert fires, a job fails or an owner is told something went\n wrong: spin-stack/runbooks at the commit this release pins, served so it is read in the app.", + "operationId": "spin.v1.AdminService.ListRunbooks", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2142,7 +2266,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RekeyVolumeRequest" + "$ref": "#/components/schemas/spin.v1.ListRunbooksRequest" } } }, @@ -2164,7 +2288,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RekeyVolumeResponse" + "$ref": "#/components/schemas/spin.v1.ListRunbooksResponse" } } } @@ -2172,14 +2296,14 @@ } } }, - "/spin.v1.AdminService/RemoveAllowedEmail": { + "/spin.v1.AdminService/ListUserAPIKeys": { "post": { "tags": [ "AdminService" ], - "summary": "RemoveAllowedEmail", - "description": "Remove allowed email/domain", - "operationId": "spin.v1.AdminService.RemoveAllowedEmail", + "summary": "ListUserAPIKeys", + "description": "List another user's API keys. The secret is never stored, so this is what an admin can\n know about a key: what it is called, when it was made, when it was last used.", + "operationId": "spin.v1.AdminService.ListUserAPIKeys", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2204,7 +2328,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RemoveAllowedEmailRequest" + "$ref": "#/components/schemas/spin.v1.ListUserAPIKeysRequest" } } }, @@ -2226,7 +2350,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RemoveAllowedEmailResponse" + "$ref": "#/components/schemas/spin.v1.ListUserAPIKeysResponse" } } } @@ -2234,14 +2358,14 @@ } } }, - "/spin.v1.AdminService/RemoveStoredVolume": { + "/spin.v1.AdminService/ListUsers": { "post": { "tags": [ "AdminService" ], - "summary": "RemoveStoredVolume", - "description": "Remove an image, an extension release, an unclaimed volume or an orphan from the store: its\n row, then its volume, whose key is shredded; storage-gc collects its layers on its next run.\n Refused for one that is kept (StoredVolume.kept_because), one placed on a host, and a\n workspace's disk. Audited.", - "operationId": "spin.v1.AdminService.RemoveStoredVolume", + "summary": "ListUsers", + "description": "List all users", + "operationId": "spin.v1.AdminService.ListUsers", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2266,7 +2390,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RemoveStoredVolumeRequest" + "$ref": "#/components/schemas/spin.v1.ListUsersRequest" } } }, @@ -2288,7 +2412,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RemoveStoredVolumeResponse" + "$ref": "#/components/schemas/spin.v1.ListUsersResponse" } } } @@ -2296,14 +2420,14 @@ } } }, - "/spin.v1.AdminService/RetryPlatformImages": { + "/spin.v1.AdminService/PublishVSCodeServers": { "post": { "tags": [ "AdminService" ], - "summary": "RetryPlatformImages", - "description": "Look again now rather than when the next retry is due.", - "operationId": "spin.v1.AdminService.RetryPlatformImages", + "summary": "PublishVSCodeServers", + "description": "Publish the servers of the newest stable VS Code releases, or of the commits named, as a\n new release. Answers once the publish has begun - it downloads a gigabyte - and\n GetVSCodeServers says how it goes.", + "operationId": "spin.v1.AdminService.PublishVSCodeServers", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2328,7 +2452,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RetryPlatformImagesRequest" + "$ref": "#/components/schemas/spin.v1.PublishVSCodeServersRequest" } } }, @@ -2350,7 +2474,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RetryPlatformImagesResponse" + "$ref": "#/components/schemas/spin.v1.PublishVSCodeServersResponse" } } } @@ -2358,14 +2482,14 @@ } } }, - "/spin.v1.AdminService/RevokeUserAPIKey": { + "/spin.v1.AdminService/RekeyVolume": { "post": { "tags": [ "AdminService" ], - "summary": "RevokeUserAPIKey", - "description": "Revoke another user's API key - the offboarding an admin cannot do by asking the user,\n who may already be gone. It is audited with the admin who did it.", - "operationId": "spin.v1.AdminService.RevokeUserAPIKey", + "summary": "RekeyVolume", + "description": "Re-key a workspace's disk: copy it whole under a key of its own, point the workspace at the\n copy, and delete the disk - which shreds the key assumed taken and every snapshot of the disk,\n since those are what that key opens. The workspace must be stopped or quarantined. Refused for\n a disk something descends from. Audited.", + "operationId": "spin.v1.AdminService.RekeyVolume", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2390,7 +2514,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeUserAPIKeyRequest" + "$ref": "#/components/schemas/spin.v1.RekeyVolumeRequest" } } }, @@ -2412,7 +2536,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeUserAPIKeyResponse" + "$ref": "#/components/schemas/spin.v1.RekeyVolumeResponse" } } } @@ -2420,14 +2544,14 @@ } } }, - "/spin.v1.AdminService/RunJobNow": { + "/spin.v1.AdminService/RemoveAllowedEmail": { "post": { "tags": [ "AdminService" ], - "summary": "RunJobNow", - "description": "Run a job now rather than when it is next due. Refused while it is running: a second run\n alongside the first would do the same work twice. Audited with the admin who asked.", - "operationId": "spin.v1.AdminService.RunJobNow", + "summary": "RemoveAllowedEmail", + "description": "Remove allowed email/domain", + "operationId": "spin.v1.AdminService.RemoveAllowedEmail", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2452,7 +2576,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RunJobNowRequest" + "$ref": "#/components/schemas/spin.v1.RemoveAllowedEmailRequest" } } }, @@ -2474,7 +2598,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RunJobNowResponse" + "$ref": "#/components/schemas/spin.v1.RemoveAllowedEmailResponse" } } } @@ -2482,14 +2606,14 @@ } } }, - "/spin.v1.AdminService/SetRegistrationMode": { + "/spin.v1.AdminService/RemoveStoredVolume": { "post": { "tags": [ "AdminService" ], - "summary": "SetRegistrationMode", - "description": "Set registration mode", - "operationId": "spin.v1.AdminService.SetRegistrationMode", + "summary": "RemoveStoredVolume", + "description": "Remove an image, an extension release, an unclaimed volume or an orphan from the store: its\n row, then its volume, whose key is shredded; storage-gc collects its layers on its next run.\n Refused for one that is kept (StoredVolume.kept_because), one placed on a host, and a\n workspace's disk. Audited.", + "operationId": "spin.v1.AdminService.RemoveStoredVolume", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2514,7 +2638,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SetRegistrationModeRequest" + "$ref": "#/components/schemas/spin.v1.RemoveStoredVolumeRequest" } } }, @@ -2536,7 +2660,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SetRegistrationModeResponse" + "$ref": "#/components/schemas/spin.v1.RemoveStoredVolumeResponse" } } } @@ -2544,14 +2668,14 @@ } } }, - "/spin.v1.AdminService/UntagImage": { + "/spin.v1.AdminService/RetryPlatformImages": { "post": { "tags": [ "AdminService" ], - "summary": "UntagImage", - "description": "Take a ref off what it names: no new workspace gets those bytes by it, the disks cloned from\n them go on reading them, and a later publish under the ref tags the new bytes. Audited.", - "operationId": "spin.v1.AdminService.UntagImage", + "summary": "RetryPlatformImages", + "description": "Look again now rather than when the next retry is due.", + "operationId": "spin.v1.AdminService.RetryPlatformImages", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2576,7 +2700,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UntagImageRequest" + "$ref": "#/components/schemas/spin.v1.RetryPlatformImagesRequest" } } }, @@ -2598,7 +2722,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UntagImageResponse" + "$ref": "#/components/schemas/spin.v1.RetryPlatformImagesResponse" } } } @@ -2606,13 +2730,14 @@ } } }, - "/spin.v1.AdminService/UpdateHostClass": { + "/spin.v1.AdminService/RevokeThirdPartyTerms": { "post": { "tags": [ "AdminService" ], - "summary": "UpdateHostClass", - "operationId": "spin.v1.AdminService.UpdateHostClass", + "summary": "RevokeThirdPartyTerms", + "description": "Take the acceptance back for the items named: nothing more of them is downloaded. What was\n downloaded already stays until an administrator removes it.", + "operationId": "spin.v1.AdminService.RevokeThirdPartyTerms", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2637,7 +2762,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateHostClassRequest" + "$ref": "#/components/schemas/spin.v1.RevokeThirdPartyTermsRequest" } } }, @@ -2659,7 +2784,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateHostClassResponse" + "$ref": "#/components/schemas/spin.v1.RevokeThirdPartyTermsResponse" } } } @@ -2667,14 +2792,14 @@ } } }, - "/spin.v1.AdminService/UpdateInstallationSettings": { + "/spin.v1.AdminService/RevokeUserAPIKey": { "post": { "tags": [ "AdminService" ], - "summary": "UpdateInstallationSettings", - "description": "Update installation settings", - "operationId": "spin.v1.AdminService.UpdateInstallationSettings", + "summary": "RevokeUserAPIKey", + "description": "Revoke another user's API key - the offboarding an admin cannot do by asking the user,\n who may already be gone. It is audited with the admin who did it.", + "operationId": "spin.v1.AdminService.RevokeUserAPIKey", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2699,7 +2824,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateInstallationSettingsRequest" + "$ref": "#/components/schemas/spin.v1.RevokeUserAPIKeyRequest" } } }, @@ -2721,7 +2846,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateInstallationSettingsResponse" + "$ref": "#/components/schemas/spin.v1.RevokeUserAPIKeyResponse" } } } @@ -2729,13 +2854,14 @@ } } }, - "/spin.v1.AdminService/UpdateNetworkPolicy": { + "/spin.v1.AdminService/RunJobNow": { "post": { "tags": [ "AdminService" ], - "summary": "UpdateNetworkPolicy", - "operationId": "spin.v1.AdminService.UpdateNetworkPolicy", + "summary": "RunJobNow", + "description": "Run a job now rather than when it is next due. Refused while it is running: a second run\n alongside the first would do the same work twice. Audited with the admin who asked.", + "operationId": "spin.v1.AdminService.RunJobNow", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2760,7 +2886,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateNetworkPolicyRequest" + "$ref": "#/components/schemas/spin.v1.RunJobNowRequest" } } }, @@ -2782,7 +2908,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateNetworkPolicyResponse" + "$ref": "#/components/schemas/spin.v1.RunJobNowResponse" } } } @@ -2790,14 +2916,14 @@ } } }, - "/spin.v1.AdminService/UpdateResourcePreset": { + "/spin.v1.AdminService/SetRegistrationMode": { "post": { "tags": [ "AdminService" ], - "summary": "UpdateResourcePreset", - "description": "Update a resource preset", - "operationId": "spin.v1.AdminService.UpdateResourcePreset", + "summary": "SetRegistrationMode", + "description": "Set registration mode", + "operationId": "spin.v1.AdminService.SetRegistrationMode", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2822,7 +2948,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateResourcePresetRequest" + "$ref": "#/components/schemas/spin.v1.SetRegistrationModeRequest" } } }, @@ -2844,7 +2970,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateResourcePresetResponse" + "$ref": "#/components/schemas/spin.v1.SetRegistrationModeResponse" } } } @@ -2852,14 +2978,14 @@ } } }, - "/spin.v1.AdminService/UpdateSecuritySettings": { + "/spin.v1.AdminService/UntagImage": { "post": { "tags": [ "AdminService" ], - "summary": "UpdateSecuritySettings", - "description": "Update security settings", - "operationId": "spin.v1.AdminService.UpdateSecuritySettings", + "summary": "UntagImage", + "description": "Take a ref off what it names: no new workspace gets those bytes by it, the disks cloned from\n them go on reading them, and a later publish under the ref tags the new bytes. Audited.", + "operationId": "spin.v1.AdminService.UntagImage", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2884,7 +3010,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateSecuritySettingsRequest" + "$ref": "#/components/schemas/spin.v1.UntagImageRequest" } } }, @@ -2906,7 +3032,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateSecuritySettingsResponse" + "$ref": "#/components/schemas/spin.v1.UntagImageResponse" } } } @@ -2914,14 +3040,14 @@ } } }, - "/spin.v1.AdminService/UpdateStorageSettings": { + "/spin.v1.AdminService/UpdateEmailSettings": { "post": { "tags": [ "AdminService" ], - "summary": "UpdateStorageSettings", - "description": "Set where the object store is, checked against it before it is written; every control\n plane restarts within seconds to open it. Another store while volumes exist is refused.", - "operationId": "spin.v1.AdminService.UpdateStorageSettings", + "summary": "UpdateEmailSettings", + "description": "Set the SMTP server, checked against it - connected to and signed in to - before it is\n written. An empty host turns email off.", + "operationId": "spin.v1.AdminService.UpdateEmailSettings", "parameters": [ { "name": "Connect-Protocol-Version", @@ -2946,7 +3072,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateStorageSettingsRequest" + "$ref": "#/components/schemas/spin.v1.UpdateEmailSettingsRequest" } } }, @@ -2968,7 +3094,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateStorageSettingsResponse" + "$ref": "#/components/schemas/spin.v1.UpdateEmailSettingsResponse" } } } @@ -2976,14 +3102,13 @@ } } }, - "/spin.v1.AdminService/UpdateUser": { + "/spin.v1.AdminService/UpdateHostClass": { "post": { "tags": [ "AdminService" ], - "summary": "UpdateUser", - "description": "Update user (can toggle is_instance_admin, disable user)", - "operationId": "spin.v1.AdminService.UpdateUser", + "summary": "UpdateHostClass", + "operationId": "spin.v1.AdminService.UpdateHostClass", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3008,7 +3133,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateUserRequest" + "$ref": "#/components/schemas/spin.v1.UpdateHostClassRequest" } } }, @@ -3030,7 +3155,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateUserResponse" + "$ref": "#/components/schemas/spin.v1.UpdateHostClassResponse" } } } @@ -3038,13 +3163,14 @@ } } }, - "/spin.v1.AuthService/ApproveWorkspaceSignIn": { + "/spin.v1.AdminService/UpdateInstallationSettings": { "post": { "tags": [ - "AuthService" + "AdminService" ], - "summary": "ApproveWorkspaceSignIn", - "operationId": "spin.v1.AuthService.ApproveWorkspaceSignIn", + "summary": "UpdateInstallationSettings", + "description": "Update installation settings", + "operationId": "spin.v1.AdminService.UpdateInstallationSettings", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3069,7 +3195,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ApproveWorkspaceSignInRequest" + "$ref": "#/components/schemas/spin.v1.UpdateInstallationSettingsRequest" } } }, @@ -3091,7 +3217,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ApproveWorkspaceSignInResponse" + "$ref": "#/components/schemas/spin.v1.UpdateInstallationSettingsResponse" } } } @@ -3099,14 +3225,13 @@ } } }, - "/spin.v1.AuthService/BeginWorkspaceSignIn": { + "/spin.v1.AdminService/UpdateNetworkPolicy": { "post": { "tags": [ - "AuthService" + "AdminService" ], - "summary": "BeginWorkspaceSignIn", - "description": "A sign-in on a workspace's host, done by the dashboard. The proxy begins it and sends the\n browser to the dashboard, which approves it for whoever is signed in there and sends the\n browser back with a one-time code; the proxy completes it with that code and the binding\n it gave the same browser. The identity provider is only ever told the dashboard's callback.", - "operationId": "spin.v1.AuthService.BeginWorkspaceSignIn", + "summary": "UpdateNetworkPolicy", + "operationId": "spin.v1.AdminService.UpdateNetworkPolicy", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3131,7 +3256,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.BeginWorkspaceSignInRequest" + "$ref": "#/components/schemas/spin.v1.UpdateNetworkPolicyRequest" } } }, @@ -3153,7 +3278,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.BeginWorkspaceSignInResponse" + "$ref": "#/components/schemas/spin.v1.UpdateNetworkPolicyResponse" } } } @@ -3161,14 +3286,14 @@ } } }, - "/spin.v1.AuthService/CheckDeviceLogin": { + "/spin.v1.AdminService/UpdateResourcePreset": { "post": { "tags": [ - "AuthService" + "AdminService" ], - "summary": "CheckDeviceLogin", - "description": "Check device login status (CLI polls this)\n Returns session token once user has completed login and entered the code", - "operationId": "spin.v1.AuthService.CheckDeviceLogin", + "summary": "UpdateResourcePreset", + "description": "Update a resource preset", + "operationId": "spin.v1.AdminService.UpdateResourcePreset", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3193,7 +3318,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CheckDeviceLoginRequest" + "$ref": "#/components/schemas/spin.v1.UpdateResourcePresetRequest" } } }, @@ -3215,7 +3340,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CheckDeviceLoginResponse" + "$ref": "#/components/schemas/spin.v1.UpdateResourcePresetResponse" } } } @@ -3223,14 +3348,14 @@ } } }, - "/spin.v1.AuthService/CompleteLogin": { + "/spin.v1.AdminService/UpdateSecuritySettings": { "post": { "tags": [ - "AuthService" + "AdminService" ], - "summary": "CompleteLogin", - "description": "Complete login (callback from IdP)", - "operationId": "spin.v1.AuthService.CompleteLogin", + "summary": "UpdateSecuritySettings", + "description": "Update security settings", + "operationId": "spin.v1.AdminService.UpdateSecuritySettings", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3255,7 +3380,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteLoginRequest" + "$ref": "#/components/schemas/spin.v1.UpdateSecuritySettingsRequest" } } }, @@ -3277,7 +3402,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteLoginResponse" + "$ref": "#/components/schemas/spin.v1.UpdateSecuritySettingsResponse" } } } @@ -3285,13 +3410,14 @@ } } }, - "/spin.v1.AuthService/CompleteWorkspaceSignIn": { + "/spin.v1.AdminService/UpdateStorageSettings": { "post": { "tags": [ - "AuthService" + "AdminService" ], - "summary": "CompleteWorkspaceSignIn", - "operationId": "spin.v1.AuthService.CompleteWorkspaceSignIn", + "summary": "UpdateStorageSettings", + "description": "Set where the object store is, checked against it before it is written; every control\n plane restarts within seconds to open it. Another store while volumes exist is refused.", + "operationId": "spin.v1.AdminService.UpdateStorageSettings", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3316,7 +3442,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteWorkspaceSignInRequest" + "$ref": "#/components/schemas/spin.v1.UpdateStorageSettingsRequest" } } }, @@ -3338,7 +3464,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteWorkspaceSignInResponse" + "$ref": "#/components/schemas/spin.v1.UpdateStorageSettingsResponse" } } } @@ -3346,14 +3472,14 @@ } } }, - "/spin.v1.AuthService/ConfirmDeviceLogin": { + "/spin.v1.AdminService/UpdateUser": { "post": { "tags": [ - "AuthService" + "AdminService" ], - "summary": "ConfirmDeviceLogin", - "description": "Complete device login (dashboard calls this after user enters code)\n Requires authentication - links the device code to the current user", - "operationId": "spin.v1.AuthService.ConfirmDeviceLogin", + "summary": "UpdateUser", + "description": "Update user (can toggle is_instance_admin, disable user)", + "operationId": "spin.v1.AdminService.UpdateUser", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3378,7 +3504,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ConfirmDeviceLoginRequest" + "$ref": "#/components/schemas/spin.v1.UpdateUserRequest" } } }, @@ -3400,7 +3526,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ConfirmDeviceLoginResponse" + "$ref": "#/components/schemas/spin.v1.UpdateUserResponse" } } } @@ -3408,14 +3534,13 @@ } } }, - "/spin.v1.AuthService/CreateAPIKey": { + "/spin.v1.AuthService/ApproveWorkspaceSignIn": { "post": { "tags": [ "AuthService" ], - "summary": "CreateAPIKey", - "description": "Create API key", - "operationId": "spin.v1.AuthService.CreateAPIKey", + "summary": "ApproveWorkspaceSignIn", + "operationId": "spin.v1.AuthService.ApproveWorkspaceSignIn", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3440,7 +3565,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CreateAPIKeyRequest" + "$ref": "#/components/schemas/spin.v1.ApproveWorkspaceSignInRequest" } } }, @@ -3462,7 +3587,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CreateAPIKeyResponse" + "$ref": "#/components/schemas/spin.v1.ApproveWorkspaceSignInResponse" } } } @@ -3470,14 +3595,14 @@ } } }, - "/spin.v1.AuthService/ExchangeWorkloadToken": { + "/spin.v1.AuthService/BeginWorkspaceSignIn": { "post": { "tags": [ "AuthService" ], - "summary": "ExchangeWorkloadToken", - "description": "Exchanges a workload's JWT-SVID, for the control plane's audience (identity.ControlPlaneAudience),\n for a key delegated from the key that made its workspace: what an agent in a workspace drives\n others with. Verified by go-spiffe against the trust domain's bundle; the key holds no more than\n its parent (delegation.Within), lasts no longer than the token's workload needs, and goes with the\n workspace.", - "operationId": "spin.v1.AuthService.ExchangeWorkloadToken", + "summary": "BeginWorkspaceSignIn", + "description": "A sign-in on a workspace's host, done by the dashboard. The proxy begins it and sends the\n browser to the dashboard, which approves it for whoever is signed in there and sends the\n browser back with a one-time code; the proxy completes it with that code and the binding\n it gave the same browser. The identity provider is only ever told the dashboard's callback.", + "operationId": "spin.v1.AuthService.BeginWorkspaceSignIn", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3502,7 +3627,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ExchangeWorkloadTokenRequest" + "$ref": "#/components/schemas/spin.v1.BeginWorkspaceSignInRequest" } } }, @@ -3524,7 +3649,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ExchangeWorkloadTokenResponse" + "$ref": "#/components/schemas/spin.v1.BeginWorkspaceSignInResponse" } } } @@ -3532,14 +3657,14 @@ } } }, - "/spin.v1.AuthService/GetCurrentUser": { + "/spin.v1.AuthService/CheckDeviceLogin": { "post": { "tags": [ "AuthService" ], - "summary": "GetCurrentUser", - "description": "Get current user info", - "operationId": "spin.v1.AuthService.GetCurrentUser", + "summary": "CheckDeviceLogin", + "description": "Check device login status (CLI polls this)\n Returns session token once user has completed login and entered the code", + "operationId": "spin.v1.AuthService.CheckDeviceLogin", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3564,7 +3689,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetCurrentUserRequest" + "$ref": "#/components/schemas/spin.v1.CheckDeviceLoginRequest" } } }, @@ -3586,7 +3711,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetCurrentUserResponse" + "$ref": "#/components/schemas/spin.v1.CheckDeviceLoginResponse" } } } @@ -3594,14 +3719,14 @@ } } }, - "/spin.v1.AuthService/ListAPIKeys": { + "/spin.v1.AuthService/CompleteLogin": { "post": { "tags": [ "AuthService" ], - "summary": "ListAPIKeys", - "description": "List API keys", - "operationId": "spin.v1.AuthService.ListAPIKeys", + "summary": "CompleteLogin", + "description": "Complete login (callback from IdP)", + "operationId": "spin.v1.AuthService.CompleteLogin", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3626,7 +3751,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListAPIKeysRequest" + "$ref": "#/components/schemas/spin.v1.CompleteLoginRequest" } } }, @@ -3648,7 +3773,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListAPIKeysResponse" + "$ref": "#/components/schemas/spin.v1.CompleteLoginResponse" } } } @@ -3656,14 +3781,13 @@ } } }, - "/spin.v1.AuthService/ListIdentityProviders": { + "/spin.v1.AuthService/CompleteWorkspaceSignIn": { "post": { "tags": [ "AuthService" ], - "summary": "ListIdentityProviders", - "description": "List available identity providers (for login page)\n Always includes built-in GitHub provider; additional OIDC providers from database", - "operationId": "spin.v1.AuthService.ListIdentityProviders", + "summary": "CompleteWorkspaceSignIn", + "operationId": "spin.v1.AuthService.CompleteWorkspaceSignIn", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3688,7 +3812,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListIdentityProvidersRequest" + "$ref": "#/components/schemas/spin.v1.CompleteWorkspaceSignInRequest" } } }, @@ -3710,7 +3834,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListIdentityProvidersResponse" + "$ref": "#/components/schemas/spin.v1.CompleteWorkspaceSignInResponse" } } } @@ -3718,14 +3842,14 @@ } } }, - "/spin.v1.AuthService/Logout": { + "/spin.v1.AuthService/ConfirmDeviceLogin": { "post": { "tags": [ "AuthService" ], - "summary": "Logout", - "description": "Logout (invalidate session)", - "operationId": "spin.v1.AuthService.Logout", + "summary": "ConfirmDeviceLogin", + "description": "Complete device login (dashboard calls this after user enters code)\n Requires authentication - links the device code to the current user", + "operationId": "spin.v1.AuthService.ConfirmDeviceLogin", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3750,7 +3874,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.LogoutRequest" + "$ref": "#/components/schemas/spin.v1.ConfirmDeviceLoginRequest" } } }, @@ -3772,7 +3896,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.LogoutResponse" + "$ref": "#/components/schemas/spin.v1.ConfirmDeviceLoginResponse" } } } @@ -3780,14 +3904,14 @@ } } }, - "/spin.v1.AuthService/RevokeAPIKey": { + "/spin.v1.AuthService/CreateAPIKey": { "post": { "tags": [ "AuthService" ], - "summary": "RevokeAPIKey", - "description": "Revoke API key", - "operationId": "spin.v1.AuthService.RevokeAPIKey", + "summary": "CreateAPIKey", + "description": "Create API key", + "operationId": "spin.v1.AuthService.CreateAPIKey", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3812,7 +3936,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeAPIKeyRequest" + "$ref": "#/components/schemas/spin.v1.CreateAPIKeyRequest" } } }, @@ -3834,7 +3958,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeAPIKeyResponse" + "$ref": "#/components/schemas/spin.v1.CreateAPIKeyResponse" } } } @@ -3842,14 +3966,14 @@ } } }, - "/spin.v1.AuthService/SearchUsers": { + "/spin.v1.AuthService/ExchangeWorkloadToken": { "post": { "tags": [ "AuthService" ], - "summary": "SearchUsers", - "description": "Search users by name or email (for team member selection, workspace sharing)", - "operationId": "spin.v1.AuthService.SearchUsers", + "summary": "ExchangeWorkloadToken", + "description": "Exchanges a workload's JWT-SVID, for the control plane's audience (identity.ControlPlaneAudience),\n for a key delegated from the key that made its workspace: what an agent in a workspace drives\n others with. Verified by go-spiffe against the trust domain's bundle; the key holds no more than\n its parent (delegation.Within), lasts no longer than the token's workload needs, and goes with the\n workspace.", + "operationId": "spin.v1.AuthService.ExchangeWorkloadToken", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3874,7 +3998,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchUsersRequest" + "$ref": "#/components/schemas/spin.v1.ExchangeWorkloadTokenRequest" } } }, @@ -3896,7 +4020,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchUsersResponse" + "$ref": "#/components/schemas/spin.v1.ExchangeWorkloadTokenResponse" } } } @@ -3904,14 +4028,14 @@ } } }, - "/spin.v1.AuthService/StartDeviceLogin": { + "/spin.v1.AuthService/GetCurrentUser": { "post": { "tags": [ "AuthService" ], - "summary": "StartDeviceLogin", - "description": "Start device login flow (for CLI when OAuth redirect is not available)\n Returns a user code and verification URL. User visits URL and enters code.", - "operationId": "spin.v1.AuthService.StartDeviceLogin", + "summary": "GetCurrentUser", + "description": "Get current user info", + "operationId": "spin.v1.AuthService.GetCurrentUser", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3936,7 +4060,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartDeviceLoginRequest" + "$ref": "#/components/schemas/spin.v1.GetCurrentUserRequest" } } }, @@ -3958,7 +4082,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartDeviceLoginResponse" + "$ref": "#/components/schemas/spin.v1.GetCurrentUserResponse" } } } @@ -3966,14 +4090,14 @@ } } }, - "/spin.v1.AuthService/StartLogin": { + "/spin.v1.AuthService/ListAPIKeys": { "post": { "tags": [ "AuthService" ], - "summary": "StartLogin", - "description": "Start login flow with a specific identity provider\n Use \"github\" for built-in GitHub auth, or IdP ID for dynamic providers", - "operationId": "spin.v1.AuthService.StartLogin", + "summary": "ListAPIKeys", + "description": "List API keys", + "operationId": "spin.v1.AuthService.ListAPIKeys", "parameters": [ { "name": "Connect-Protocol-Version", @@ -3998,7 +4122,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartLoginRequest" + "$ref": "#/components/schemas/spin.v1.ListAPIKeysRequest" } } }, @@ -4020,7 +4144,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartLoginResponse" + "$ref": "#/components/schemas/spin.v1.ListAPIKeysResponse" } } } @@ -4028,14 +4152,14 @@ } } }, - "/spin.v1.ExecService/Exec": { + "/spin.v1.AuthService/ListIdentityProviders": { "post": { "tags": [ - "ExecService" + "AuthService" ], - "summary": "Exec", - "description": "Runs command in the workspace's login shell and answers once it has exited, or once timeout\n has passed: stdin is all of it, given at once, and stdout and stderr are kept up to a bound\n each.", - "operationId": "spin.v1.ExecService.Exec", + "summary": "ListIdentityProviders", + "description": "List available identity providers (for login page)\n Always includes built-in GitHub provider; additional OIDC providers from database", + "operationId": "spin.v1.AuthService.ListIdentityProviders", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4060,7 +4184,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ExecRequest" + "$ref": "#/components/schemas/spin.v1.ListIdentityProvidersRequest" } } }, @@ -4082,7 +4206,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ExecResponse" + "$ref": "#/components/schemas/spin.v1.ListIdentityProvidersResponse" } } } @@ -4090,14 +4214,14 @@ } } }, - "/spin.v1.ExecService/ReadFile": { + "/spin.v1.AuthService/Logout": { "post": { "tags": [ - "ExecService" + "AuthService" ], - "summary": "ReadFile", - "description": "Reads a file of the workspace's, whole, up to a bound.", - "operationId": "spin.v1.ExecService.ReadFile", + "summary": "Logout", + "description": "Logout (invalidate session)", + "operationId": "spin.v1.AuthService.Logout", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4122,7 +4246,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ReadFileRequest" + "$ref": "#/components/schemas/spin.v1.LogoutRequest" } } }, @@ -4144,7 +4268,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ReadFileResponse" + "$ref": "#/components/schemas/spin.v1.LogoutResponse" } } } @@ -4152,14 +4276,14 @@ } } }, - "/spin.v1.ExecService/WriteFile": { + "/spin.v1.AuthService/RevokeAPIKey": { "post": { "tags": [ - "ExecService" + "AuthService" ], - "summary": "WriteFile", - "description": "Writes a file of the workspace's, whole, making the directories it is in.", - "operationId": "spin.v1.ExecService.WriteFile", + "summary": "RevokeAPIKey", + "description": "Revoke API key", + "operationId": "spin.v1.AuthService.RevokeAPIKey", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4184,7 +4308,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.WriteFileRequest" + "$ref": "#/components/schemas/spin.v1.RevokeAPIKeyRequest" } } }, @@ -4206,7 +4330,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.WriteFileResponse" + "$ref": "#/components/schemas/spin.v1.RevokeAPIKeyResponse" } } } @@ -4214,13 +4338,14 @@ } } }, - "/spin.v1.ForgeService/CompleteAppCreation": { + "/spin.v1.AuthService/SearchUsers": { "post": { "tags": [ - "ForgeService" + "AuthService" ], - "summary": "CompleteAppCreation", - "operationId": "spin.v1.ForgeService.CompleteAppCreation", + "summary": "SearchUsers", + "description": "Search users by name or email (for team member selection, workspace sharing)", + "operationId": "spin.v1.AuthService.SearchUsers", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4245,7 +4370,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteAppCreationRequest" + "$ref": "#/components/schemas/spin.v1.SearchUsersRequest" } } }, @@ -4267,7 +4392,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteAppCreationResponse" + "$ref": "#/components/schemas/spin.v1.SearchUsersResponse" } } } @@ -4275,13 +4400,14 @@ } } }, - "/spin.v1.ForgeService/CompleteConnect": { + "/spin.v1.AuthService/StartDeviceLogin": { "post": { "tags": [ - "ForgeService" + "AuthService" ], - "summary": "CompleteConnect", - "operationId": "spin.v1.ForgeService.CompleteConnect", + "summary": "StartDeviceLogin", + "description": "Start device login flow (for CLI when OAuth redirect is not available)\n Returns a user code and verification URL. User visits URL and enters code.", + "operationId": "spin.v1.AuthService.StartDeviceLogin", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4306,7 +4432,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteConnectRequest" + "$ref": "#/components/schemas/spin.v1.StartDeviceLoginRequest" } } }, @@ -4328,7 +4454,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CompleteConnectResponse" + "$ref": "#/components/schemas/spin.v1.StartDeviceLoginResponse" } } } @@ -4336,14 +4462,14 @@ } } }, - "/spin.v1.ForgeService/DeleteForgeApp": { + "/spin.v1.AuthService/StartLogin": { "post": { "tags": [ - "ForgeService" + "AuthService" ], - "summary": "DeleteForgeApp", - "description": "Takes the app out of use at once. Every connection through it is revoked at the forge, and the\n app is gone when that is done.", - "operationId": "spin.v1.ForgeService.DeleteForgeApp", + "summary": "StartLogin", + "description": "Start login flow with a specific identity provider\n Use \"github\" for built-in GitHub auth, or IdP ID for dynamic providers", + "operationId": "spin.v1.AuthService.StartLogin", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4368,7 +4494,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeleteForgeAppRequest" + "$ref": "#/components/schemas/spin.v1.StartLoginRequest" } } }, @@ -4390,7 +4516,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeleteForgeAppResponse" + "$ref": "#/components/schemas/spin.v1.StartLoginResponse" } } } @@ -4398,14 +4524,14 @@ } } }, - "/spin.v1.ForgeService/Disconnect": { + "/spin.v1.ExecService/Exec": { "post": { "tags": [ - "ForgeService" + "ExecService" ], - "summary": "Disconnect", - "description": "Forgets the token and revokes it at the forge.", - "operationId": "spin.v1.ForgeService.Disconnect", + "summary": "Exec", + "description": "Runs command in the workspace's login shell and answers once it has exited, or once timeout\n has passed: stdin is all of it, given at once, and stdout and stderr are kept up to a bound\n each.", + "operationId": "spin.v1.ExecService.Exec", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4430,7 +4556,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DisconnectRequest" + "$ref": "#/components/schemas/spin.v1.ExecRequest" } } }, @@ -4452,7 +4578,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DisconnectResponse" + "$ref": "#/components/schemas/spin.v1.ExecResponse" } } } @@ -4460,13 +4586,14 @@ } } }, - "/spin.v1.ForgeService/ListConnections": { + "/spin.v1.ExecService/ReadFile": { "post": { "tags": [ - "ForgeService" + "ExecService" ], - "summary": "ListConnections", - "operationId": "spin.v1.ForgeService.ListConnections", + "summary": "ReadFile", + "description": "Reads a file of the workspace's, whole, up to a bound.", + "operationId": "spin.v1.ExecService.ReadFile", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4491,7 +4618,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListConnectionsRequest" + "$ref": "#/components/schemas/spin.v1.ReadFileRequest" } } }, @@ -4513,7 +4640,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListConnectionsResponse" + "$ref": "#/components/schemas/spin.v1.ReadFileResponse" } } } @@ -4521,14 +4648,14 @@ } } }, - "/spin.v1.ForgeService/ListForgeApps": { + "/spin.v1.ExecService/WriteFile": { "post": { "tags": [ - "ForgeService" + "ExecService" ], - "summary": "ListForgeApps", - "description": "The installation's app on each forge: whether a person can connect, and where. Its secrets are\n never answered with.", - "operationId": "spin.v1.ForgeService.ListForgeApps", + "summary": "WriteFile", + "description": "Writes a file of the workspace's, whole, making the directories it is in.", + "operationId": "spin.v1.ExecService.WriteFile", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4553,7 +4680,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListForgeAppsRequest" + "$ref": "#/components/schemas/spin.v1.WriteFileRequest" } } }, @@ -4575,7 +4702,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListForgeAppsResponse" + "$ref": "#/components/schemas/spin.v1.WriteFileResponse" } } } @@ -4583,13 +4710,13 @@ } } }, - "/spin.v1.ForgeService/PollDeviceConnect": { + "/spin.v1.ForgeService/CompleteAppCreation": { "post": { "tags": [ "ForgeService" ], - "summary": "PollDeviceConnect", - "operationId": "spin.v1.ForgeService.PollDeviceConnect", + "summary": "CompleteAppCreation", + "operationId": "spin.v1.ForgeService.CompleteAppCreation", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4614,7 +4741,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.PollDeviceConnectRequest" + "$ref": "#/components/schemas/spin.v1.CompleteAppCreationRequest" } } }, @@ -4636,7 +4763,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.PollDeviceConnectResponse" + "$ref": "#/components/schemas/spin.v1.CompleteAppCreationResponse" } } } @@ -4644,14 +4771,13 @@ } } }, - "/spin.v1.ForgeService/SearchRepositories": { + "/spin.v1.ForgeService/CompleteConnect": { "post": { "tags": [ "ForgeService" ], - "summary": "SearchRepositories", - "description": "The repositories the person's account reaches that match query, as the forge searches them\n with the person's token: what they can see there is what they can pick here.", - "operationId": "spin.v1.ForgeService.SearchRepositories", + "summary": "CompleteConnect", + "operationId": "spin.v1.ForgeService.CompleteConnect", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4676,7 +4802,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchRepositoriesRequest" + "$ref": "#/components/schemas/spin.v1.CompleteConnectRequest" } } }, @@ -4698,7 +4824,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchRepositoriesResponse" + "$ref": "#/components/schemas/spin.v1.CompleteConnectResponse" } } } @@ -4706,14 +4832,14 @@ } } }, - "/spin.v1.ForgeService/SetForgeApp": { + "/spin.v1.ForgeService/DeleteForgeApp": { "post": { "tags": [ "ForgeService" ], - "summary": "SetForgeApp", - "description": "Keeping an app that was made elsewhere. Refused while the forge has one: an app is never\n edited, because another client id could not revoke what this one granted.", - "operationId": "spin.v1.ForgeService.SetForgeApp", + "summary": "DeleteForgeApp", + "description": "Takes the app out of use at once. Every connection through it is revoked at the forge, and the\n app is gone when that is done.", + "operationId": "spin.v1.ForgeService.DeleteForgeApp", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4738,7 +4864,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SetForgeAppRequest" + "$ref": "#/components/schemas/spin.v1.DeleteForgeAppRequest" } } }, @@ -4760,7 +4886,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SetForgeAppResponse" + "$ref": "#/components/schemas/spin.v1.DeleteForgeAppResponse" } } } @@ -4768,14 +4894,14 @@ } } }, - "/spin.v1.ForgeService/StartAppCreation": { + "/spin.v1.ForgeService/Disconnect": { "post": { "tags": [ "ForgeService" ], - "summary": "StartAppCreation", - "description": "Making the app, by an instance admin, through the forge's manifest flow: StartAppCreation\n answers the form the browser posts to the forge, which makes the app and sends the admin back\n with a code; CompleteAppCreation exchanges it for the app's credentials. Nobody copies a key.", - "operationId": "spin.v1.ForgeService.StartAppCreation", + "summary": "Disconnect", + "description": "Forgets the token and revokes it at the forge.", + "operationId": "spin.v1.ForgeService.Disconnect", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4800,7 +4926,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartAppCreationRequest" + "$ref": "#/components/schemas/spin.v1.DisconnectRequest" } } }, @@ -4822,7 +4948,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartAppCreationResponse" + "$ref": "#/components/schemas/spin.v1.DisconnectResponse" } } } @@ -4830,14 +4956,13 @@ } } }, - "/spin.v1.ForgeService/StartConnect": { + "/spin.v1.ForgeService/ListConnections": { "post": { "tags": [ "ForgeService" ], - "summary": "StartConnect", - "description": "Connecting: StartConnect answers where the person authorizes the app and a binding only this\n client keeps; the forge sends the browser back to redirect_uri with a code and the state, and\n CompleteConnect exchanges them, with the binding, for the person's token.", - "operationId": "spin.v1.ForgeService.StartConnect", + "summary": "ListConnections", + "operationId": "spin.v1.ForgeService.ListConnections", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4862,7 +4987,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartConnectRequest" + "$ref": "#/components/schemas/spin.v1.ListConnectionsRequest" } } }, @@ -4884,7 +5009,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartConnectResponse" + "$ref": "#/components/schemas/spin.v1.ListConnectionsResponse" } } } @@ -4892,14 +5017,14 @@ } } }, - "/spin.v1.ForgeService/StartDeviceConnect": { + "/spin.v1.ForgeService/ListForgeApps": { "post": { "tags": [ "ForgeService" ], - "summary": "StartDeviceConnect", - "description": "Connecting from somewhere with no browser to send back to, the CLI: the control plane asks the\n forge for a device code (RFC 8628) and keeps it, and answers with the code the person types on\n the forge's page and a handle only the caller can poll with. PollDeviceConnect asks the forge,\n at most once an interval, and on the person's approval keeps their token as CompleteConnect\n does: once, for the person who began it.", - "operationId": "spin.v1.ForgeService.StartDeviceConnect", + "summary": "ListForgeApps", + "description": "The installation's app on each forge: whether a person can connect, and where. Its secrets are\n never answered with.", + "operationId": "spin.v1.ForgeService.ListForgeApps", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4924,7 +5049,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartDeviceConnectRequest" + "$ref": "#/components/schemas/spin.v1.ListForgeAppsRequest" } } }, @@ -4946,7 +5071,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.StartDeviceConnectResponse" + "$ref": "#/components/schemas/spin.v1.ListForgeAppsResponse" } } } @@ -4954,14 +5079,13 @@ } } }, - "/spin.v1.HostService/ActivateHost": { + "/spin.v1.ForgeService/PollDeviceConnect": { "post": { "tags": [ - "HostService" + "ForgeService" ], - "summary": "ActivateHost", - "description": "Activate a drained host (set to healthy, admin only)", - "operationId": "spin.v1.HostService.ActivateHost", + "summary": "PollDeviceConnect", + "operationId": "spin.v1.ForgeService.PollDeviceConnect", "parameters": [ { "name": "Connect-Protocol-Version", @@ -4986,7 +5110,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ActivateHostRequest" + "$ref": "#/components/schemas/spin.v1.PollDeviceConnectRequest" } } }, @@ -5008,7 +5132,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ActivateHostResponse" + "$ref": "#/components/schemas/spin.v1.PollDeviceConnectResponse" } } } @@ -5016,14 +5140,14 @@ } } }, - "/spin.v1.HostService/DrainHost": { + "/spin.v1.ForgeService/SearchRepositories": { "post": { "tags": [ - "HostService" + "ForgeService" ], - "summary": "DrainHost", - "description": "Set host to draining (admin only)", - "operationId": "spin.v1.HostService.DrainHost", + "summary": "SearchRepositories", + "description": "The repositories the person's account reaches that match query, as the forge searches them\n with the person's token: what they can see there is what they can pick here.", + "operationId": "spin.v1.ForgeService.SearchRepositories", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5048,7 +5172,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DrainHostRequest" + "$ref": "#/components/schemas/spin.v1.SearchRepositoriesRequest" } } }, @@ -5070,7 +5194,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DrainHostResponse" + "$ref": "#/components/schemas/spin.v1.SearchRepositoriesResponse" } } } @@ -5078,14 +5202,14 @@ } } }, - "/spin.v1.HostService/GetFleet": { + "/spin.v1.ForgeService/SetForgeApp": { "post": { "tags": [ - "HostService" + "ForgeService" ], - "summary": "GetFleet", - "description": "The fleet as a whole (admin only): how many hosts there are against how many the\n installation has asked its cloud for, and what it is waiting for. A fleet that scales from\n none looks broken without this - no hosts, no explanation, and a workspace that waits\n minutes for a machine to boot with nothing saying so.", - "operationId": "spin.v1.HostService.GetFleet", + "summary": "SetForgeApp", + "description": "Keeping an app that was made elsewhere. Refused while the forge has one: an app is never\n edited, because another client id could not revoke what this one granted.", + "operationId": "spin.v1.ForgeService.SetForgeApp", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5110,7 +5234,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetFleetRequest" + "$ref": "#/components/schemas/spin.v1.SetForgeAppRequest" } } }, @@ -5132,7 +5256,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetFleetResponse" + "$ref": "#/components/schemas/spin.v1.SetForgeAppResponse" } } } @@ -5140,14 +5264,14 @@ } } }, - "/spin.v1.HostService/GetHost": { + "/spin.v1.ForgeService/StartAppCreation": { "post": { "tags": [ - "HostService" + "ForgeService" ], - "summary": "GetHost", - "description": "Get host details (admin only)", - "operationId": "spin.v1.HostService.GetHost", + "summary": "StartAppCreation", + "description": "Making the app, by an instance admin, through the forge's manifest flow: StartAppCreation\n answers the form the browser posts to the forge, which makes the app and sends the admin back\n with a code; CompleteAppCreation exchanges it for the app's credentials. Nobody copies a key.", + "operationId": "spin.v1.ForgeService.StartAppCreation", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5172,7 +5296,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetHostRequest" + "$ref": "#/components/schemas/spin.v1.StartAppCreationRequest" } } }, @@ -5194,7 +5318,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetHostResponse" + "$ref": "#/components/schemas/spin.v1.StartAppCreationResponse" } } } @@ -5202,14 +5326,14 @@ } } }, - "/spin.v1.HostService/GetHostPolicy": { + "/spin.v1.ForgeService/StartConnect": { "post": { "tags": [ - "HostService" + "ForgeService" ], - "summary": "GetHostPolicy", - "description": "What a host may do, as against what it is (admin only). A host reads what it *is* from\n its own environment, before it can reach this; everything else it is told, on its\n heartbeat, and it reports back the revision it is running under.", - "operationId": "spin.v1.HostService.GetHostPolicy", + "summary": "StartConnect", + "description": "Connecting: StartConnect answers where the person authorizes the app and a binding only this\n client keeps; the forge sends the browser back to redirect_uri with a code and the state, and\n CompleteConnect exchanges them, with the binding, for the person's token.", + "operationId": "spin.v1.ForgeService.StartConnect", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5234,7 +5358,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetHostPolicyRequest" + "$ref": "#/components/schemas/spin.v1.StartConnectRequest" } } }, @@ -5256,7 +5380,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetHostPolicyResponse" + "$ref": "#/components/schemas/spin.v1.StartConnectResponse" } } } @@ -5264,14 +5388,14 @@ } } }, - "/spin.v1.HostService/ListHosts": { + "/spin.v1.ForgeService/StartDeviceConnect": { "post": { "tags": [ - "HostService" + "ForgeService" ], - "summary": "ListHosts", - "description": "List all hosts (admin only)", - "operationId": "spin.v1.HostService.ListHosts", + "summary": "StartDeviceConnect", + "description": "Connecting from somewhere with no browser to send back to, the CLI: the control plane asks the\n forge for a device code (RFC 8628) and keeps it, and answers with the code the person types on\n the forge's page and a handle only the caller can poll with. PollDeviceConnect asks the forge,\n at most once an interval, and on the person's approval keeps their token as CompleteConnect\n does: once, for the person who began it.", + "operationId": "spin.v1.ForgeService.StartDeviceConnect", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5296,7 +5420,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListHostsRequest" + "$ref": "#/components/schemas/spin.v1.StartDeviceConnectRequest" } } }, @@ -5318,7 +5442,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListHostsResponse" + "$ref": "#/components/schemas/spin.v1.StartDeviceConnectResponse" } } } @@ -5326,13 +5450,14 @@ } } }, - "/spin.v1.HostService/SetHostPolicy": { + "/spin.v1.HostService/ActivateHost": { "post": { "tags": [ "HostService" ], - "summary": "SetHostPolicy", - "operationId": "spin.v1.HostService.SetHostPolicy", + "summary": "ActivateHost", + "description": "Activate a drained host (set to healthy, admin only)", + "operationId": "spin.v1.HostService.ActivateHost", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5357,7 +5482,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SetHostPolicyRequest" + "$ref": "#/components/schemas/spin.v1.ActivateHostRequest" } } }, @@ -5379,7 +5504,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SetHostPolicyResponse" + "$ref": "#/components/schemas/spin.v1.ActivateHostResponse" } } } @@ -5387,14 +5512,14 @@ } } }, - "/spin.v1.HostService/TestHostWriteback": { + "/spin.v1.HostService/DrainHost": { "post": { "tags": [ "HostService" ], - "summary": "TestHostWriteback", - "description": "Measures a host's disk under writeback thresholds no preset names, against the ones it holds\n (admin only). SetHostPolicy refuses such thresholds for a host until it has been tested with\n them; the test loads that host's disk for about forty seconds.", - "operationId": "spin.v1.HostService.TestHostWriteback", + "summary": "DrainHost", + "description": "Set host to draining (admin only)", + "operationId": "spin.v1.HostService.DrainHost", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5419,7 +5544,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.TestHostWritebackRequest" + "$ref": "#/components/schemas/spin.v1.DrainHostRequest" } } }, @@ -5441,7 +5566,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.TestHostWritebackResponse" + "$ref": "#/components/schemas/spin.v1.DrainHostResponse" } } } @@ -5449,14 +5574,14 @@ } } }, - "/spin.v1.HostShellService/ApproveHostShell": { + "/spin.v1.HostService/GetFleet": { "post": { "tags": [ - "HostShellService" + "HostService" ], - "summary": "ApproveHostShell", - "description": "Approves a shell another administrator asked for.", - "operationId": "spin.v1.HostShellService.ApproveHostShell", + "summary": "GetFleet", + "description": "The fleet as a whole (admin only): how many hosts there are against how many the\n installation has asked its cloud for, and what it is waiting for. A fleet that scales from\n none looks broken without this - no hosts, no explanation, and a workspace that waits\n minutes for a machine to boot with nothing saying so.", + "operationId": "spin.v1.HostService.GetFleet", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5481,7 +5606,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ApproveHostShellRequest" + "$ref": "#/components/schemas/spin.v1.GetFleetRequest" } } }, @@ -5503,7 +5628,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ApproveHostShellResponse" + "$ref": "#/components/schemas/spin.v1.GetFleetResponse" } } } @@ -5511,14 +5636,14 @@ } } }, - "/spin.v1.HostShellService/CloseHostShell": { + "/spin.v1.HostService/GetHost": { "post": { "tags": [ - "HostShellService" + "HostService" ], - "summary": "CloseHostShell", - "description": "Ends a shell: one not yet approved is refused, any other is ended and its host retired.", - "operationId": "spin.v1.HostShellService.CloseHostShell", + "summary": "GetHost", + "description": "Get host details (admin only)", + "operationId": "spin.v1.HostService.GetHost", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5543,7 +5668,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CloseHostShellRequest" + "$ref": "#/components/schemas/spin.v1.GetHostRequest" } } }, @@ -5565,7 +5690,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CloseHostShellResponse" + "$ref": "#/components/schemas/spin.v1.GetHostResponse" } } } @@ -5573,14 +5698,14 @@ } } }, - "/spin.v1.HostShellService/GetHostShellRecording": { + "/spin.v1.HostService/GetHostPolicy": { "post": { "tags": [ - "HostShellService" + "HostService" ], - "summary": "GetHostShellRecording", - "description": "What a shell's sessions recorded, asciicast v2, each session's in turn.", - "operationId": "spin.v1.HostShellService.GetHostShellRecording", + "summary": "GetHostPolicy", + "description": "What a host may do, as against what it is (admin only). A host reads what it *is* from\n its own environment, before it can reach this; everything else it is told, on its\n heartbeat, and it reports back the revision it is running under.", + "operationId": "spin.v1.HostService.GetHostPolicy", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5605,7 +5730,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetHostShellRecordingRequest" + "$ref": "#/components/schemas/spin.v1.GetHostPolicyRequest" } } }, @@ -5627,7 +5752,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetHostShellRecordingResponse" + "$ref": "#/components/schemas/spin.v1.GetHostPolicyResponse" } } } @@ -5635,14 +5760,14 @@ } } }, - "/spin.v1.HostShellService/ListHostShells": { + "/spin.v1.HostService/ListHosts": { "post": { "tags": [ - "HostShellService" + "HostService" ], - "summary": "ListHostShells", - "description": "The installation's host shells, newest first: all of them, or one host's.", - "operationId": "spin.v1.HostShellService.ListHostShells", + "summary": "ListHosts", + "description": "List all hosts (admin only)", + "operationId": "spin.v1.HostService.ListHosts", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5667,7 +5792,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListHostShellsRequest" + "$ref": "#/components/schemas/spin.v1.ListHostsRequest" } } }, @@ -5689,7 +5814,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListHostShellsResponse" + "$ref": "#/components/schemas/spin.v1.ListHostsResponse" } } } @@ -5697,14 +5822,14 @@ } } }, - "/spin.v1.HostShellService/RequestHostShell": { + "/spin.v1.HostService/RemoveHost": { "post": { "tags": [ - "HostShellService" + "HostService" ], - "summary": "RequestHostShell", - "description": "Asks for a shell on a host. Where the installation has a second administrator approve\n (host_shell_needs_approval), it waits for one; otherwise the host is emptied at once.", - "operationId": "spin.v1.HostShellService.RequestHostShell", + "summary": "RemoveHost", + "description": "Takes a machine of an autoscaling group out of the fleet (admin only), as Host.removal says:\n given back to its group (GIVE_BACK), or forgotten (FORGET). A host whose removal is REVOKE is\n refused: RevokeRunner is its removal.", + "operationId": "spin.v1.HostService.RemoveHost", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5729,7 +5854,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RequestHostShellRequest" + "$ref": "#/components/schemas/spin.v1.RemoveHostRequest" } } }, @@ -5751,7 +5876,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RequestHostShellResponse" + "$ref": "#/components/schemas/spin.v1.RemoveHostResponse" } } } @@ -5759,14 +5884,13 @@ } } }, - "/spin.v1.LogService/GetTrace": { + "/spin.v1.HostService/SetHostPolicy": { "post": { "tags": [ - "LogService" + "HostService" ], - "summary": "GetTrace", - "description": "GetTrace is every span of one trace, in the order they began.", - "operationId": "spin.v1.LogService.GetTrace", + "summary": "SetHostPolicy", + "operationId": "spin.v1.HostService.SetHostPolicy", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5791,7 +5915,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetTraceRequest" + "$ref": "#/components/schemas/spin.v1.SetHostPolicyRequest" } } }, @@ -5813,7 +5937,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetTraceResponse" + "$ref": "#/components/schemas/spin.v1.SetHostPolicyResponse" } } } @@ -5821,15 +5945,635 @@ } } }, - "/spin.v1.LogService/GetWorkspaceTrace": { + "/spin.v1.HostService/TestHostWriteback": { "post": { "tags": [ - "LogService" + "HostService" ], - "summary": "GetWorkspaceTrace", - "description": "GetWorkspaceTrace is the spans of one trace marked as about one workspace, in the order they\n began, for its owner: the rest of the trace is left out, as SearchWorkspaceTraces leaves it.", - "operationId": "spin.v1.LogService.GetWorkspaceTrace", - "parameters": [ + "summary": "TestHostWriteback", + "description": "Measures a host's disk under writeback thresholds no preset names, against the ones it holds\n (admin only). SetHostPolicy refuses such thresholds for a host until it has been tested with\n them; the test loads that host's disk for about forty seconds.", + "operationId": "spin.v1.HostService.TestHostWriteback", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.TestHostWritebackRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.TestHostWritebackResponse" + } + } + } + } + } + } + }, + "/spin.v1.HostShellService/ApproveHostShell": { + "post": { + "tags": [ + "HostShellService" + ], + "summary": "ApproveHostShell", + "description": "Approves a shell another administrator asked for.", + "operationId": "spin.v1.HostShellService.ApproveHostShell", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.ApproveHostShellRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.ApproveHostShellResponse" + } + } + } + } + } + } + }, + "/spin.v1.HostShellService/CloseHostShell": { + "post": { + "tags": [ + "HostShellService" + ], + "summary": "CloseHostShell", + "description": "Ends a shell: one not yet approved is refused, any other is ended and its host retired.", + "operationId": "spin.v1.HostShellService.CloseHostShell", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.CloseHostShellRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.CloseHostShellResponse" + } + } + } + } + } + } + }, + "/spin.v1.HostShellService/GetHostShellRecording": { + "post": { + "tags": [ + "HostShellService" + ], + "summary": "GetHostShellRecording", + "description": "What a shell's sessions recorded, asciicast v2, each session's in turn.", + "operationId": "spin.v1.HostShellService.GetHostShellRecording", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetHostShellRecordingRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetHostShellRecordingResponse" + } + } + } + } + } + } + }, + "/spin.v1.HostShellService/ListHostShells": { + "post": { + "tags": [ + "HostShellService" + ], + "summary": "ListHostShells", + "description": "The installation's host shells, newest first: all of them, or one host's.", + "operationId": "spin.v1.HostShellService.ListHostShells", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.ListHostShellsRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.ListHostShellsResponse" + } + } + } + } + } + } + }, + "/spin.v1.HostShellService/RequestHostShell": { + "post": { + "tags": [ + "HostShellService" + ], + "summary": "RequestHostShell", + "description": "Asks for a shell on a host. Where the installation has a second administrator approve\n (host_shell_needs_approval), it waits for one; otherwise the host is emptied at once.", + "operationId": "spin.v1.HostShellService.RequestHostShell", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.RequestHostShellRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.RequestHostShellResponse" + } + } + } + } + } + } + }, + "/spin.v1.LogService/GetTrace": { + "post": { + "tags": [ + "LogService" + ], + "summary": "GetTrace", + "description": "GetTrace is every span of one trace, in the order they began.", + "operationId": "spin.v1.LogService.GetTrace", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetTraceRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetTraceResponse" + } + } + } + } + } + } + }, + "/spin.v1.LogService/GetWorkspaceTrace": { + "post": { + "tags": [ + "LogService" + ], + "summary": "GetWorkspaceTrace", + "description": "GetWorkspaceTrace is the spans of one trace marked as about one workspace, in the order they\n began, for its owner: the rest of the trace is left out, as SearchWorkspaceTraces leaves it.", + "operationId": "spin.v1.LogService.GetWorkspaceTrace", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetWorkspaceTraceRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.GetWorkspaceTraceResponse" + } + } + } + } + } + } + }, + "/spin.v1.LogService/HistogramPlatformLogs": { + "post": { + "tags": [ + "LogService" + ], + "summary": "HistogramPlatformLogs", + "description": "HistogramPlatformLogs is how many of those records each interval of the window holds, by\n severity: the chart above them.", + "operationId": "spin.v1.LogService.HistogramPlatformLogs", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.HistogramPlatformLogsRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.HistogramLogsResponse" + } + } + } + } + } + } + }, + "/spin.v1.LogService/HistogramWorkspaceLogs": { + "post": { + "tags": [ + "LogService" + ], + "summary": "HistogramWorkspaceLogs", + "description": "HistogramWorkspaceLogs is how many of those records each interval of the window holds.", + "operationId": "spin.v1.LogService.HistogramWorkspaceLogs", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.HistogramWorkspaceLogsRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.HistogramWorkspaceLogsResponse" + } + } + } + } + } + } + }, + "/spin.v1.LogService/ListLogIndexes": { + "post": { + "tags": [ + "LogService" + ], + "summary": "ListLogIndexes", + "description": "ListLogIndexes is every index the store keeps, as the store itself reports it: its fields,\n how long it keeps what it holds and how much it holds. An administrator's: how much each\n index holds is how busy the installation and its workspaces are.", + "operationId": "spin.v1.LogService.ListLogIndexes", + "parameters": [ { "name": "Connect-Protocol-Version", "in": "header", @@ -5853,7 +6597,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetWorkspaceTraceRequest" + "$ref": "#/components/schemas/spin.v1.ListLogIndexesRequest" } } }, @@ -5875,7 +6619,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetWorkspaceTraceResponse" + "$ref": "#/components/schemas/spin.v1.ListLogIndexesResponse" } } } @@ -5883,14 +6627,14 @@ } } }, - "/spin.v1.LogService/HistogramPlatformLogs": { + "/spin.v1.LogService/PlatformLogFieldValues": { "post": { "tags": [ "LogService" ], - "summary": "HistogramPlatformLogs", - "description": "HistogramPlatformLogs is how many of those records each interval of the window holds, by\n severity: the chart above them.", - "operationId": "spin.v1.LogService.HistogramPlatformLogs", + "summary": "PlatformLogFieldValues", + "description": "PlatformLogFieldValues is what one field most often is in the records a search of the\n platform's logs finds: service_name, severity_text, attributes.* or resource_attributes.*.", + "operationId": "spin.v1.LogService.PlatformLogFieldValues", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5915,7 +6659,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.HistogramPlatformLogsRequest" + "$ref": "#/components/schemas/spin.v1.PlatformLogFieldValuesRequest" } } }, @@ -5937,7 +6681,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.HistogramLogsResponse" + "$ref": "#/components/schemas/spin.v1.PlatformLogFieldValuesResponse" } } } @@ -5945,14 +6689,14 @@ } } }, - "/spin.v1.LogService/HistogramWorkspaceLogs": { + "/spin.v1.LogService/SearchPlatformLogs": { "post": { "tags": [ "LogService" ], - "summary": "HistogramWorkspaceLogs", - "description": "HistogramWorkspaceLogs is how many of those records each interval of the window holds.", - "operationId": "spin.v1.LogService.HistogramWorkspaceLogs", + "summary": "SearchPlatformLogs", + "description": "SearchPlatformLogs is what the installation's own processes logged - the control plane, the\n proxy, the runners. An administrator's: a platform's log names every workspace it touched.", + "operationId": "spin.v1.LogService.SearchPlatformLogs", "parameters": [ { "name": "Connect-Protocol-Version", @@ -5977,7 +6721,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.HistogramWorkspaceLogsRequest" + "$ref": "#/components/schemas/spin.v1.SearchPlatformLogsRequest" } } }, @@ -5999,7 +6743,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.HistogramWorkspaceLogsResponse" + "$ref": "#/components/schemas/spin.v1.SearchLogsResponse" } } } @@ -6007,14 +6751,14 @@ } } }, - "/spin.v1.LogService/ListLogIndexes": { + "/spin.v1.LogService/SearchTraces": { "post": { "tags": [ "LogService" ], - "summary": "ListLogIndexes", - "description": "ListLogIndexes is every index the store keeps, as the store itself reports it: its fields,\n how long it keeps what it holds and how much it holds. An administrator's: how much each\n index holds is how busy the installation and its workspaces are.", - "operationId": "spin.v1.LogService.ListLogIndexes", + "summary": "SearchTraces", + "description": "SearchTraces is the installation's traces whose first span matches, newest first. An\n administrator's, as the platform's logs are.", + "operationId": "spin.v1.LogService.SearchTraces", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6039,7 +6783,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListLogIndexesRequest" + "$ref": "#/components/schemas/spin.v1.SearchTracesRequest" } } }, @@ -6061,7 +6805,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListLogIndexesResponse" + "$ref": "#/components/schemas/spin.v1.SearchTracesResponse" } } } @@ -6069,14 +6813,14 @@ } } }, - "/spin.v1.LogService/PlatformLogFieldValues": { + "/spin.v1.LogService/SearchWorkspaceLogs": { "post": { "tags": [ "LogService" ], - "summary": "PlatformLogFieldValues", - "description": "PlatformLogFieldValues is what one field most often is in the records a search of the\n platform's logs finds: service_name, severity_text, attributes.* or resource_attributes.*.", - "operationId": "spin.v1.LogService.PlatformLogFieldValues", + "summary": "SearchWorkspaceLogs", + "description": "SearchWorkspaceLogs is what one workspace's machine wrote to its console, where the\n installation collects it: whoever may read the workspace's console may search it.", + "operationId": "spin.v1.LogService.SearchWorkspaceLogs", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6101,7 +6845,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.PlatformLogFieldValuesRequest" + "$ref": "#/components/schemas/spin.v1.SearchWorkspaceLogsRequest" } } }, @@ -6123,7 +6867,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.PlatformLogFieldValuesResponse" + "$ref": "#/components/schemas/spin.v1.SearchWorkspaceLogsResponse" } } } @@ -6131,14 +6875,14 @@ } } }, - "/spin.v1.LogService/SearchPlatformLogs": { + "/spin.v1.LogService/SearchWorkspaceTraces": { "post": { "tags": [ "LogService" ], - "summary": "SearchPlatformLogs", - "description": "SearchPlatformLogs is what the installation's own processes logged - the control plane, the\n proxy, the runners. An administrator's: a platform's log names every workspace it touched.", - "operationId": "spin.v1.LogService.SearchPlatformLogs", + "summary": "SearchWorkspaceTraces", + "description": "SearchWorkspaceTraces is the spans marked as about one workspace - its creation, its starts\n and stops, what its host did for it - newest first, for its owner. A trace names every\n workspace it touched, so a span not marked as this one's is never answered, whichever trace\n it is in.", + "operationId": "spin.v1.LogService.SearchWorkspaceTraces", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6163,7 +6907,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchPlatformLogsRequest" + "$ref": "#/components/schemas/spin.v1.SearchWorkspaceTracesRequest" } } }, @@ -6185,7 +6929,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchLogsResponse" + "$ref": "#/components/schemas/spin.v1.SearchWorkspaceTracesResponse" } } } @@ -6193,14 +6937,14 @@ } } }, - "/spin.v1.LogService/SearchTraces": { + "/spin.v1.LogService/ServiceHealth": { "post": { "tags": [ "LogService" ], - "summary": "SearchTraces", - "description": "SearchTraces is the installation's traces whose first span matches, newest first. An\n administrator's, as the platform's logs are.", - "operationId": "spin.v1.LogService.SearchTraces", + "summary": "ServiceHealth", + "description": "ServiceHealth is how each of the installation's services did over a window, as its traces\n and logs say it. An administrator's, as the traces are.", + "operationId": "spin.v1.LogService.ServiceHealth", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6225,7 +6969,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchTracesRequest" + "$ref": "#/components/schemas/spin.v1.ServiceHealthRequest" } } }, @@ -6247,7 +6991,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchTracesResponse" + "$ref": "#/components/schemas/spin.v1.ServiceHealthResponse" } } } @@ -6255,14 +6999,138 @@ } } }, - "/spin.v1.LogService/SearchWorkspaceLogs": { + "/spin.v1.LogService/WorkspaceLogFieldValues": { "post": { "tags": [ "LogService" ], - "summary": "SearchWorkspaceLogs", - "description": "SearchWorkspaceLogs is what one workspace's machine wrote to its console, where the\n installation collects it: whoever may read the workspace's console may search it.", - "operationId": "spin.v1.LogService.SearchWorkspaceLogs", + "summary": "WorkspaceLogFieldValues", + "description": "WorkspaceLogFieldValues is the same of one workspace's, for whoever may read it.", + "operationId": "spin.v1.LogService.WorkspaceLogFieldValues", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.WorkspaceLogFieldValuesRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.WorkspaceLogFieldValuesResponse" + } + } + } + } + } + } + }, + "/spin.v1.PasskeyService/BeginPasskeyCeremony": { + "post": { + "tags": [ + "PasskeyService" + ], + "summary": "BeginPasskeyCeremony", + "description": "A challenge for one ceremony of the caller's, bound to what it is for: a passkey registered, a\n key added, a passkey deleted. Taken once, by the call it is answered in, within minutes.", + "operationId": "spin.v1.PasskeyService.BeginPasskeyCeremony", + "parameters": [ + { + "name": "Connect-Protocol-Version", + "in": "header", + "description": "Define the version of the Connect protocol", + "schema": { + "$ref": "#/components/schemas/connect-protocol-version" + }, + "example": 1 + }, + { + "name": "Connect-Timeout-Ms", + "in": "header", + "description": "Define the timeout, in ms", + "schema": { + "$ref": "#/components/schemas/connect-timeout-header" + }, + "example": 1000 + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.BeginPasskeyCeremonyRequest" + } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connect.error" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spin.v1.BeginPasskeyCeremonyResponse" + } + } + } + } + } + } + }, + "/spin.v1.PasskeyService/DeletePasskey": { + "post": { + "tags": [ + "PasskeyService" + ], + "summary": "DeletePasskey", + "description": "Deletes a passkey of the caller's, with an assertion of one of theirs.", + "operationId": "spin.v1.PasskeyService.DeletePasskey", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6287,7 +7155,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchWorkspaceLogsRequest" + "$ref": "#/components/schemas/spin.v1.DeletePasskeyRequest" } } }, @@ -6309,7 +7177,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchWorkspaceLogsResponse" + "$ref": "#/components/schemas/spin.v1.DeletePasskeyResponse" } } } @@ -6317,14 +7185,13 @@ } } }, - "/spin.v1.LogService/SearchWorkspaceTraces": { + "/spin.v1.PasskeyService/ListPasskeys": { "post": { "tags": [ - "LogService" + "PasskeyService" ], - "summary": "SearchWorkspaceTraces", - "description": "SearchWorkspaceTraces is the spans marked as about one workspace - its creation, its starts\n and stops, what its host did for it - newest first, for its owner. A trace names every\n workspace it touched, so a span not marked as this one's is never answered, whichever trace\n it is in.", - "operationId": "spin.v1.LogService.SearchWorkspaceTraces", + "summary": "ListPasskeys", + "operationId": "spin.v1.PasskeyService.ListPasskeys", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6349,7 +7216,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchWorkspaceTracesRequest" + "$ref": "#/components/schemas/spin.v1.ListPasskeysRequest" } } }, @@ -6371,7 +7238,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.SearchWorkspaceTracesResponse" + "$ref": "#/components/schemas/spin.v1.ListPasskeysResponse" } } } @@ -6379,14 +7246,14 @@ } } }, - "/spin.v1.LogService/ServiceHealth": { + "/spin.v1.PasskeyService/RegisterPasskey": { "post": { "tags": [ - "LogService" + "PasskeyService" ], - "summary": "ServiceHealth", - "description": "ServiceHealth is how each of the installation's services did over a window, as its traces\n and logs say it. An administrator's, as the traces are.", - "operationId": "spin.v1.LogService.ServiceHealth", + "summary": "RegisterPasskey", + "description": "Registers a passkey to the caller's account. The first is registered on their session alone;\n another takes an assertion of one they have, so a session cannot add a passkey of its own.", + "operationId": "spin.v1.PasskeyService.RegisterPasskey", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6411,7 +7278,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ServiceHealthRequest" + "$ref": "#/components/schemas/spin.v1.RegisterPasskeyRequest" } } }, @@ -6433,7 +7300,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ServiceHealthResponse" + "$ref": "#/components/schemas/spin.v1.RegisterPasskeyResponse" } } } @@ -6441,14 +7308,13 @@ } } }, - "/spin.v1.LogService/WorkspaceLogFieldValues": { + "/spin.v1.ProjectService/CreateProject": { "post": { "tags": [ - "LogService" + "ProjectService" ], - "summary": "WorkspaceLogFieldValues", - "description": "WorkspaceLogFieldValues is the same of one workspace's, for whoever may read it.", - "operationId": "spin.v1.LogService.WorkspaceLogFieldValues", + "summary": "CreateProject", + "operationId": "spin.v1.ProjectService.CreateProject", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6473,7 +7339,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.WorkspaceLogFieldValuesRequest" + "$ref": "#/components/schemas/spin.v1.CreateProjectRequest" } } }, @@ -6495,7 +7361,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.WorkspaceLogFieldValuesResponse" + "$ref": "#/components/schemas/spin.v1.CreateProjectResponse" } } } @@ -6503,14 +7369,13 @@ } } }, - "/spin.v1.PasskeyService/BeginPasskeyCeremony": { + "/spin.v1.ProjectService/DeleteProject": { "post": { "tags": [ - "PasskeyService" + "ProjectService" ], - "summary": "BeginPasskeyCeremony", - "description": "A challenge for one ceremony of the caller's, bound to what it is for: a passkey registered, a\n key added, a passkey deleted. Taken once, by the call it is answered in, within minutes.", - "operationId": "spin.v1.PasskeyService.BeginPasskeyCeremony", + "summary": "DeleteProject", + "operationId": "spin.v1.ProjectService.DeleteProject", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6535,7 +7400,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.BeginPasskeyCeremonyRequest" + "$ref": "#/components/schemas/spin.v1.DeleteProjectRequest" } } }, @@ -6557,7 +7422,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.BeginPasskeyCeremonyResponse" + "$ref": "#/components/schemas/spin.v1.DeleteProjectResponse" } } } @@ -6565,14 +7430,14 @@ } } }, - "/spin.v1.PasskeyService/DeletePasskey": { + "/spin.v1.ProjectService/GetPrebuild": { "post": { "tags": [ - "PasskeyService" + "ProjectService" ], - "summary": "DeletePasskey", - "description": "Deletes a passkey of the caller's, with an assertion of one of theirs.", - "operationId": "spin.v1.PasskeyService.DeletePasskey", + "summary": "GetPrebuild", + "description": "One of them whole, with what its build's create tasks wrote, to whoever sees the project.", + "operationId": "spin.v1.ProjectService.GetPrebuild", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6597,7 +7462,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeletePasskeyRequest" + "$ref": "#/components/schemas/spin.v1.GetPrebuildRequest" } } }, @@ -6619,7 +7484,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeletePasskeyResponse" + "$ref": "#/components/schemas/spin.v1.GetPrebuildResponse" } } } @@ -6627,13 +7492,13 @@ } } }, - "/spin.v1.PasskeyService/ListPasskeys": { + "/spin.v1.ProjectService/GetProject": { "post": { "tags": [ - "PasskeyService" + "ProjectService" ], - "summary": "ListPasskeys", - "operationId": "spin.v1.PasskeyService.ListPasskeys", + "summary": "GetProject", + "operationId": "spin.v1.ProjectService.GetProject", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6658,7 +7523,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListPasskeysRequest" + "$ref": "#/components/schemas/spin.v1.GetProjectRequest" } } }, @@ -6680,7 +7545,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListPasskeysResponse" + "$ref": "#/components/schemas/spin.v1.GetProjectResponse" } } } @@ -6688,14 +7553,14 @@ } } }, - "/spin.v1.PasskeyService/RegisterPasskey": { + "/spin.v1.ProjectService/ListPrebuilds": { "post": { "tags": [ - "PasskeyService" + "ProjectService" ], - "summary": "RegisterPasskey", - "description": "Registers a passkey to the caller's account. The first is registered on their session alone;\n another takes an assertion of one they have, so a session cannot add a passkey of its own.", - "operationId": "spin.v1.PasskeyService.RegisterPasskey", + "summary": "ListPrebuilds", + "description": "A project's prebuilds, to whoever sees it; and a build of one of its refs now, by its admins,\n rather than at the next look.", + "operationId": "spin.v1.ProjectService.ListPrebuilds", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6720,7 +7585,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RegisterPasskeyRequest" + "$ref": "#/components/schemas/spin.v1.ListPrebuildsRequest" } } }, @@ -6742,7 +7607,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RegisterPasskeyResponse" + "$ref": "#/components/schemas/spin.v1.ListPrebuildsResponse" } } } @@ -6750,13 +7615,14 @@ } } }, - "/spin.v1.ProjectService/CreateProject": { + "/spin.v1.ProjectService/ListProjectWorkspaces": { "post": { "tags": [ "ProjectService" ], - "summary": "CreateProject", - "operationId": "spin.v1.ProjectService.CreateProject", + "summary": "ListProjectWorkspaces", + "description": "Everybody's workspaces open on a project, to its admins and nobody else: a person it is only\n shared with is refused, and reads their own with ListWorkspaces.", + "operationId": "spin.v1.ProjectService.ListProjectWorkspaces", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6781,7 +7647,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CreateProjectRequest" + "$ref": "#/components/schemas/spin.v1.ListProjectWorkspacesRequest" } } }, @@ -6803,7 +7669,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CreateProjectResponse" + "$ref": "#/components/schemas/spin.v1.ListProjectWorkspacesResponse" } } } @@ -6811,13 +7677,13 @@ } } }, - "/spin.v1.ProjectService/DeleteProject": { + "/spin.v1.ProjectService/ListProjects": { "post": { "tags": [ "ProjectService" ], - "summary": "DeleteProject", - "operationId": "spin.v1.ProjectService.DeleteProject", + "summary": "ListProjects", + "operationId": "spin.v1.ProjectService.ListProjects", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6842,7 +7708,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeleteProjectRequest" + "$ref": "#/components/schemas/spin.v1.ListProjectsRequest" } } }, @@ -6864,7 +7730,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeleteProjectResponse" + "$ref": "#/components/schemas/spin.v1.ListProjectsResponse" } } } @@ -6872,13 +7738,13 @@ } } }, - "/spin.v1.ProjectService/GetProject": { + "/spin.v1.ProjectService/RunPrebuild": { "post": { "tags": [ "ProjectService" ], - "summary": "GetProject", - "operationId": "spin.v1.ProjectService.GetProject", + "summary": "RunPrebuild", + "operationId": "spin.v1.ProjectService.RunPrebuild", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6903,7 +7769,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetProjectRequest" + "$ref": "#/components/schemas/spin.v1.RunPrebuildRequest" } } }, @@ -6925,7 +7791,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetProjectResponse" + "$ref": "#/components/schemas/spin.v1.RunPrebuildResponse" } } } @@ -6933,14 +7799,13 @@ } } }, - "/spin.v1.ProjectService/ListPrebuilds": { + "/spin.v1.ProjectService/ShareProject": { "post": { "tags": [ "ProjectService" ], - "summary": "ListPrebuilds", - "description": "A project's prebuilds, to whoever sees it; and a build of one of its refs now, by its admins,\n rather than at the next look.", - "operationId": "spin.v1.ProjectService.ListPrebuilds", + "summary": "ShareProject", + "operationId": "spin.v1.ProjectService.ShareProject", "parameters": [ { "name": "Connect-Protocol-Version", @@ -6965,7 +7830,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListPrebuildsRequest" + "$ref": "#/components/schemas/spin.v1.ShareProjectRequest" } } }, @@ -6987,7 +7852,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListPrebuildsResponse" + "$ref": "#/components/schemas/spin.v1.ShareProjectResponse" } } } @@ -6995,13 +7860,14 @@ } } }, - "/spin.v1.ProjectService/ListProjects": { + "/spin.v1.ProjectService/UpdateProject": { "post": { "tags": [ "ProjectService" ], - "summary": "ListProjects", - "operationId": "spin.v1.ProjectService.ListProjects", + "summary": "UpdateProject", + "description": "Changed, shared and deleted by its admins. A project with a workspace open on it is not\n deleted.", + "operationId": "spin.v1.ProjectService.UpdateProject", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7026,7 +7892,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListProjectsRequest" + "$ref": "#/components/schemas/spin.v1.UpdateProjectRequest" } } }, @@ -7048,7 +7914,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListProjectsResponse" + "$ref": "#/components/schemas/spin.v1.UpdateProjectResponse" } } } @@ -7056,13 +7922,14 @@ } } }, - "/spin.v1.ProjectService/RunPrebuild": { + "/spin.v1.RunnerTokenService/CreateRegistrationToken": { "post": { "tags": [ - "ProjectService" + "RunnerTokenService" ], - "summary": "RunPrebuild", - "operationId": "spin.v1.ProjectService.RunPrebuild", + "summary": "CreateRegistrationToken", + "description": "Generate a one-time registration token (admin only)", + "operationId": "spin.v1.RunnerTokenService.CreateRegistrationToken", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7087,7 +7954,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RunPrebuildRequest" + "$ref": "#/components/schemas/spin.v1.CreateRegistrationTokenRequest" } } }, @@ -7109,7 +7976,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RunPrebuildResponse" + "$ref": "#/components/schemas/spin.v1.CreateRegistrationTokenResponse" } } } @@ -7117,13 +7984,14 @@ } } }, - "/spin.v1.ProjectService/ShareProject": { + "/spin.v1.RunnerTokenService/ListRegistrationTokens": { "post": { "tags": [ - "ProjectService" + "RunnerTokenService" ], - "summary": "ShareProject", - "operationId": "spin.v1.ProjectService.ShareProject", + "summary": "ListRegistrationTokens", + "description": "List active registration tokens (admin only)", + "operationId": "spin.v1.RunnerTokenService.ListRegistrationTokens", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7148,7 +8016,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ShareProjectRequest" + "$ref": "#/components/schemas/spin.v1.ListRegistrationTokensRequest" } } }, @@ -7170,7 +8038,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ShareProjectResponse" + "$ref": "#/components/schemas/spin.v1.ListRegistrationTokensResponse" } } } @@ -7178,14 +8046,14 @@ } } }, - "/spin.v1.ProjectService/UpdateProject": { + "/spin.v1.RunnerTokenService/RevokeRegistrationToken": { "post": { "tags": [ - "ProjectService" + "RunnerTokenService" ], - "summary": "UpdateProject", - "description": "Changed, shared and deleted by its admins. A project with a workspace open on it is not\n deleted.", - "operationId": "spin.v1.ProjectService.UpdateProject", + "summary": "RevokeRegistrationToken", + "description": "Revoke a registration token (admin only)", + "operationId": "spin.v1.RunnerTokenService.RevokeRegistrationToken", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7210,7 +8078,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateProjectRequest" + "$ref": "#/components/schemas/spin.v1.RevokeRegistrationTokenRequest" } } }, @@ -7232,7 +8100,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.UpdateProjectResponse" + "$ref": "#/components/schemas/spin.v1.RevokeRegistrationTokenResponse" } } } @@ -7240,14 +8108,14 @@ } } }, - "/spin.v1.RunnerTokenService/CreateRegistrationToken": { + "/spin.v1.RunnerTokenService/RevokeRunner": { "post": { "tags": [ "RunnerTokenService" ], - "summary": "CreateRegistrationToken", - "description": "Generate a one-time registration token (admin only)", - "operationId": "spin.v1.RunnerTokenService.CreateRegistrationToken", + "summary": "RevokeRunner", + "description": "Revoke a runner (admin only)", + "operationId": "spin.v1.RunnerTokenService.RevokeRunner", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7272,7 +8140,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CreateRegistrationTokenRequest" + "$ref": "#/components/schemas/spin.v1.RevokeRunnerRequest" } } }, @@ -7294,7 +8162,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.CreateRegistrationTokenResponse" + "$ref": "#/components/schemas/spin.v1.RevokeRunnerResponse" } } } @@ -7302,14 +8170,14 @@ } } }, - "/spin.v1.RunnerTokenService/ListRegistrationTokens": { + "/spin.v1.SSHKeyService/AddSSHKey": { "post": { "tags": [ - "RunnerTokenService" + "SSHKeyService" ], - "summary": "ListRegistrationTokens", - "description": "List active registration tokens (admin only)", - "operationId": "spin.v1.RunnerTokenService.ListRegistrationTokens", + "summary": "AddSSHKey", + "description": "Adds a key, with an assertion of a passkey of the caller's over a PASSKEY_PURPOSE_ADD_SSH_KEY\n challenge naming it.", + "operationId": "spin.v1.SSHKeyService.AddSSHKey", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7334,7 +8202,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListRegistrationTokensRequest" + "$ref": "#/components/schemas/spin.v1.AddSSHKeyRequest" } } }, @@ -7356,7 +8224,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListRegistrationTokensResponse" + "$ref": "#/components/schemas/spin.v1.AddSSHKeyResponse" } } } @@ -7364,14 +8232,14 @@ } } }, - "/spin.v1.RunnerTokenService/RevokeRegistrationToken": { + "/spin.v1.SSHKeyService/DeleteSSHKey": { "post": { "tags": [ - "RunnerTokenService" + "SSHKeyService" ], - "summary": "RevokeRegistrationToken", - "description": "Revoke a registration token (admin only)", - "operationId": "spin.v1.RunnerTokenService.RevokeRegistrationToken", + "summary": "DeleteSSHKey", + "description": "Delete an SSH key from user's account", + "operationId": "spin.v1.SSHKeyService.DeleteSSHKey", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7396,7 +8264,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeRegistrationTokenRequest" + "$ref": "#/components/schemas/spin.v1.DeleteSSHKeyRequest" } } }, @@ -7418,7 +8286,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeRegistrationTokenResponse" + "$ref": "#/components/schemas/spin.v1.DeleteSSHKeyResponse" } } } @@ -7426,14 +8294,14 @@ } } }, - "/spin.v1.RunnerTokenService/RevokeRunner": { + "/spin.v1.SSHKeyService/ListSSHKeys": { "post": { "tags": [ - "RunnerTokenService" + "SSHKeyService" ], - "summary": "RevokeRunner", - "description": "Revoke a runner (admin only)", - "operationId": "spin.v1.RunnerTokenService.RevokeRunner", + "summary": "ListSSHKeys", + "description": "List user's SSH public keys", + "operationId": "spin.v1.SSHKeyService.ListSSHKeys", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7458,7 +8326,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeRunnerRequest" + "$ref": "#/components/schemas/spin.v1.ListSSHKeysRequest" } } }, @@ -7480,7 +8348,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.RevokeRunnerResponse" + "$ref": "#/components/schemas/spin.v1.ListSSHKeysResponse" } } } @@ -7488,14 +8356,14 @@ } } }, - "/spin.v1.SSHKeyService/AddSSHKey": { + "/spin.v1.SettingsService/GetNotificationPreferences": { "post": { "tags": [ - "SSHKeyService" + "SettingsService" ], - "summary": "AddSSHKey", - "description": "Adds a key, with an assertion of a passkey of the caller's over a PASSKEY_PURPOSE_ADD_SSH_KEY\n challenge naming it.", - "operationId": "spin.v1.SSHKeyService.AddSSHKey", + "summary": "GetNotificationPreferences", + "description": "Which of those the caller is emailed about.", + "operationId": "spin.v1.SettingsService.GetNotificationPreferences", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7520,7 +8388,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.AddSSHKeyRequest" + "$ref": "#/components/schemas/spin.v1.GetNotificationPreferencesRequest" } } }, @@ -7542,7 +8410,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.AddSSHKeyResponse" + "$ref": "#/components/schemas/spin.v1.GetNotificationPreferencesResponse" } } } @@ -7550,14 +8418,14 @@ } } }, - "/spin.v1.SSHKeyService/DeleteSSHKey": { + "/spin.v1.SettingsService/GetUserSettings": { "post": { "tags": [ - "SSHKeyService" + "SettingsService" ], - "summary": "DeleteSSHKey", - "description": "Delete an SSH key from user's account", - "operationId": "spin.v1.SSHKeyService.DeleteSSHKey", + "summary": "GetUserSettings", + "description": "User settings", + "operationId": "spin.v1.SettingsService.GetUserSettings", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7582,7 +8450,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeleteSSHKeyRequest" + "$ref": "#/components/schemas/spin.v1.GetUserSettingsRequest" } } }, @@ -7604,7 +8472,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.DeleteSSHKeyResponse" + "$ref": "#/components/schemas/spin.v1.GetUserSettingsResponse" } } } @@ -7612,14 +8480,14 @@ } } }, - "/spin.v1.SSHKeyService/ListSSHKeys": { + "/spin.v1.SettingsService/ListNotifications": { "post": { "tags": [ - "SSHKeyService" + "SettingsService" ], - "summary": "ListSSHKeys", - "description": "List user's SSH public keys", - "operationId": "spin.v1.SSHKeyService.ListSSHKeys", + "summary": "ListNotifications", + "description": "What happened to the caller's workspaces that they are told of, newest first, with whether\n each was sent and how. Recorded whether or not the installation can send email.", + "operationId": "spin.v1.SettingsService.ListNotifications", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7644,7 +8512,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListSSHKeysRequest" + "$ref": "#/components/schemas/spin.v1.ListNotificationsRequest" } } }, @@ -7666,7 +8534,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.ListSSHKeysResponse" + "$ref": "#/components/schemas/spin.v1.ListNotificationsResponse" } } } @@ -7674,14 +8542,13 @@ } } }, - "/spin.v1.SettingsService/GetUserSettings": { + "/spin.v1.SettingsService/UpdateNotificationPreferences": { "post": { "tags": [ "SettingsService" ], - "summary": "GetUserSettings", - "description": "User settings", - "operationId": "spin.v1.SettingsService.GetUserSettings", + "summary": "UpdateNotificationPreferences", + "operationId": "spin.v1.SettingsService.UpdateNotificationPreferences", "parameters": [ { "name": "Connect-Protocol-Version", @@ -7706,7 +8573,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetUserSettingsRequest" + "$ref": "#/components/schemas/spin.v1.UpdateNotificationPreferencesRequest" } } }, @@ -7728,7 +8595,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/spin.v1.GetUserSettingsResponse" + "$ref": "#/components/schemas/spin.v1.UpdateNotificationPreferencesResponse" } } } @@ -9778,7 +10645,7 @@ "WorkspaceService" ], "summary": "AttachVSCodeServer", - "description": "Give a running workspace the VS Code server of a client's commit, while it runs: published\n first when this installation has not got it and fetches servers on its own\n (InstallationSettings.vscode_fetch), refused as FAILED_PRECONDITION when it does not. Asked\n again until it answers attached.", + "description": "Give a running workspace the VS Code server of a client's commit, while it runs: published\n first when this installation has not got it and an administrator accepted the VS Code\n server's terms (AdminService.AcceptThirdPartyTerms), refused as FAILED_PRECONDITION, saying\n so, when nobody did. Asked again until it answers attached.", "operationId": "spin.v1.WorkspaceService.AttachVSCodeServer", "parameters": [ { @@ -13235,6 +14102,30 @@ "title": "APIKey", "additionalProperties": false }, + "spin.v1.AcceptThirdPartyTermsRequest": { + "type": "object", + "properties": { + "termsVersion": { + "type": "string", + "title": "terms_version", + "description": "The version of the text the administrator was shown: one that is not the current one is\n refused, so nobody accepts a text they did not read." + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.ThirdPartyItem" + }, + "title": "items" + } + }, + "title": "AcceptThirdPartyTermsRequest", + "additionalProperties": false + }, + "spin.v1.AcceptThirdPartyTermsResponse": { + "type": "object", + "title": "AcceptThirdPartyTermsResponse", + "additionalProperties": false + }, "spin.v1.ActivateHostRequest": { "type": "object", "properties": { @@ -13737,6 +14628,11 @@ "type": "boolean", "title": "removable", "description": "No disk was cloned from it and it is not the one given: RemoveStoredVolume untags it on the\n way and removes it." + }, + "keptBecause": { + "type": "string", + "title": "kept_because", + "description": "Why it stays, in words, where it may not go." } }, "title": "BaseImage", @@ -14697,6 +15593,12 @@ "title": "prebuild_rebase_every", "format": "int32", "description": "Zero is the installation's default" + }, + "prebuildKeep": { + "type": "integer", + "title": "prebuild_keep", + "format": "int32", + "description": "Zero is one: the newest of each ref" } }, "title": "CreateProjectRequest", @@ -15053,7 +15955,7 @@ "preset": { "type": "string", "title": "preset", - "description": "The preset it is sized by, by name (AdminService.ListResourcePresets): its cores, memory,\n disk and how it grows. Empty is the installation's default preset, or with none marked\n 1 core, 512 MB and 10 GB free. A disabled preset is refused." + "description": "The preset it is sized by, by name (AdminService.ListResourcePresets): its cores, memory,\n disk and how it grows. Empty is the project's preset when project_id names one, otherwise\n the installation's default preset, or with none marked 1 core, 512 MB and 10 GB free. A\n disabled preset is refused." }, "env": { "type": "object", @@ -15080,7 +15982,7 @@ "projectId": { "type": "string", "title": "project_id", - "description": "A project the caller sees: the workspace is the project's - its image, preset and tags, which\n the request then names none of - in team_id, the caller's personal team when empty, and its\n guest clones the project's repository at ref, the project's own when empty. Refused while the\n repository is on a forge the installation connects to (ForgeService) and the caller has not\n connected their account there." + "description": "A project the caller sees: the workspace is the project's - its image and tags, which the\n request then names neither of, and its preset unless preset names another - in team_id, the\n caller's personal team when empty, and its\n guest clones the project's repository at ref, the project's own when empty. Refused while the\n repository is on a forge the installation connects to (ForgeService) and the caller has not\n connected their account there." }, "ref": { "type": "string", @@ -15623,6 +16525,37 @@ "title": "DrainHostResponse", "additionalProperties": false }, + "spin.v1.EmailSettings": { + "type": "object", + "properties": { + "host": { + "type": "string", + "title": "host" + }, + "port": { + "type": "integer", + "title": "port", + "format": "int32", + "description": "465 is TLS from the first byte; any other port is upgraded with STARTTLS where the server\n offers it, and a username is refused over a connection that is not encrypted." + }, + "username": { + "type": "string", + "title": "username" + }, + "passwordSet": { + "type": "boolean", + "title": "password_set" + }, + "from": { + "type": "string", + "title": "from", + "description": "The address mail is sent from, as the server allows this account to send." + } + }, + "title": "EmailSettings", + "additionalProperties": false, + "description": "EmailSettings is the SMTP server the installation sends its notifications through. No host is\n email off: what would have been sent is still recorded, and shown on each person's page." + }, "spin.v1.EnableDevModeRequest": { "type": "object", "title": "EnableDevModeRequest", @@ -15893,6 +16826,21 @@ "type": "boolean", "title": "newest", "description": "Whether a start is given this one." + }, + "volumeId": { + "type": "string", + "title": "volume_id", + "description": "Its volume in the store, which RemoveStoredVolume takes when removable." + }, + "removable": { + "type": "boolean", + "title": "removable", + "description": "Not the newest and nothing runs it: RemoveStoredVolume removes it, and so does the\n collect-releases job on its own." + }, + "keptBecause": { + "type": "string", + "title": "kept_because", + "description": "Why it stays, in words, where it may not go." } }, "title": "ExtensionRelease", @@ -16118,7 +17066,7 @@ "type": "integer", "title": "busy", "format": "int32", - "description": "Workspaces of the class keeping its group up." + "description": "Workspaces of the class, and hosts a root shell holds, keeping its group up." }, "launchFailure": { "type": "string", @@ -16132,6 +17080,19 @@ } ], "title": "launch_failed_at" + }, + "giveBackRefused": { + "type": "string", + "title": "give_back_refused", + "description": "A machine of the group the cloud would not take back, in its own words - a role or a policy\n somebody has to change - and when; it is asked again every quarter hour until it is taken.\n Empty while none is refused." + }, + "giveBackRefusedAt": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "give_back_refused_at" } }, "title": "FleetClass", @@ -16489,6 +17450,26 @@ "title": "GetCurrentUserResponse", "additionalProperties": false }, + "spin.v1.GetEmailSettingsRequest": { + "type": "object", + "title": "GetEmailSettingsRequest", + "additionalProperties": false + }, + "spin.v1.GetEmailSettingsResponse": { + "type": "object", + "properties": { + "settings": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.EmailSettings" + } + ], + "title": "settings" + } + }, + "title": "GetEmailSettingsResponse", + "additionalProperties": false + }, "spin.v1.GetFleetRequest": { "type": "object", "title": "GetFleetRequest", @@ -16721,6 +17702,34 @@ } ], "title": "settings" + }, + "reaches": { + "type": "object", + "title": "reaches", + "additionalProperties": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.SettingReach" + } + ], + "title": "value" + }, + "description": "What each setting touches when saved, by its update_mask path: every path\n UpdateInstallationSettings accepts, and no other." + }, + "runningWorkspaces": { + "type": "integer", + "title": "running_workspaces", + "format": "int32", + "description": "How many workspaces are running now: what a RUNNING_WORKSPACES setting reaches, and what a\n NEW_WORKSPACES one leaves as it is." + }, + "connectedRunners": { + "type": [ + "integer", + "null" + ], + "title": "connected_runners", + "format": "int32", + "description": "How many runners hold their stream to this control plane now: what a NEXT_HEARTBEAT setting\n reaches. Unset where this control plane cannot tell." } }, "title": "GetInstallationSettingsResponse", @@ -16747,6 +17756,30 @@ "title": "GetMonitoringResponse", "additionalProperties": false }, + "spin.v1.GetNotificationPreferencesRequest": { + "type": "object", + "title": "GetNotificationPreferencesRequest", + "additionalProperties": false + }, + "spin.v1.GetNotificationPreferencesResponse": { + "type": "object", + "properties": { + "preferences": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.NotificationPreference" + }, + "title": "preferences", + "description": "One per event a person may be told of, in the order they are shown." + }, + "emailConfigured": { + "type": "boolean", + "title": "email_configured" + } + }, + "title": "GetNotificationPreferencesResponse", + "additionalProperties": false + }, "spin.v1.GetPlatformImagesRequest": { "type": "object", "title": "GetPlatformImagesRequest", @@ -16791,6 +17824,37 @@ "title": "GetPlatformImagesResponse", "additionalProperties": false }, + "spin.v1.GetPrebuildRequest": { + "type": "object", + "properties": { + "projectId": { + "type": "string", + "title": "project_id" + }, + "prebuildId": { + "type": "string", + "title": "prebuild_id" + } + }, + "title": "GetPrebuildRequest", + "additionalProperties": false, + "description": "A prebuild by its id, of the project it names: one of another project is not found." + }, + "spin.v1.GetPrebuildResponse": { + "type": "object", + "properties": { + "prebuild": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.Prebuild" + } + ], + "title": "prebuild" + } + }, + "title": "GetPrebuildResponse", + "additionalProperties": false + }, "spin.v1.GetProjectRequest": { "type": "object", "properties": { @@ -16842,6 +17906,42 @@ "title": "GetRegistrationModeResponse", "additionalProperties": false }, + "spin.v1.GetRunbookRequest": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "id" + } + }, + "title": "GetRunbookRequest", + "additionalProperties": false + }, + "spin.v1.GetRunbookResponse": { + "type": "object", + "properties": { + "runbook": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.Runbook" + } + ], + "title": "runbook" + }, + "markdown": { + "type": "string", + "title": "markdown", + "description": "Its body, markdown without the front matter: the app renders it and nothing else (no raw HTML)." + }, + "sourceUrl": { + "type": "string", + "title": "source_url", + "description": "The file at the commit this release pins, to propose a change from." + } + }, + "title": "GetRunbookResponse", + "additionalProperties": false + }, "spin.v1.GetSecuritySettingsRequest": { "type": "object", "title": "GetSecuritySettingsRequest", @@ -16923,6 +18023,11 @@ "type": "boolean", "title": "development", "description": "True for a development installation, where the mock identity provider may be enabled." + }, + "thirdPartyAccepted": { + "type": "boolean", + "title": "third_party_accepted", + "description": "True where an administrator accepted the terms of any third-party software, as the current\n text: the wizard asks until one has, or until it is told to go on without." } }, "title": "GetSetupStatusResponse", @@ -17080,6 +18185,38 @@ "title": "GetTelemetryStatusResponse", "additionalProperties": false }, + "spin.v1.GetThirdPartyTermsRequest": { + "type": "object", + "title": "GetThirdPartyTermsRequest", + "additionalProperties": false + }, + "spin.v1.GetThirdPartyTermsResponse": { + "type": "object", + "properties": { + "termsVersion": { + "type": "string", + "title": "terms_version", + "description": "The version of the text below, which an acceptance names." + }, + "text": { + "type": "array", + "items": { + "type": "string" + }, + "title": "text", + "description": "The terms, a paragraph each." + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.ThirdPartyTermsItem" + }, + "title": "items" + } + }, + "title": "GetThirdPartyTermsResponse", + "additionalProperties": false + }, "spin.v1.GetTraceRequest": { "type": "object", "properties": { @@ -17335,6 +18472,37 @@ "title": "GetWorkspaceIdentityResponse", "additionalProperties": false }, + "spin.v1.GetWorkspaceNamesRequest": { + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "string" + }, + "title": "ids", + "description": "At most 500: the ids a page of records names." + } + }, + "title": "GetWorkspaceNamesRequest", + "additionalProperties": false + }, + "spin.v1.GetWorkspaceNamesResponse": { + "type": "object", + "properties": { + "names": { + "type": "object", + "title": "names", + "additionalProperties": { + "type": "string", + "title": "value" + }, + "description": "Each id asked for that the installation holds a row for, to its workspace's name." + } + }, + "title": "GetWorkspaceNamesResponse", + "additionalProperties": false + }, "spin.v1.GetWorkspaceRequest": { "type": "object", "properties": { @@ -18099,6 +19267,20 @@ "type": "string", "title": "hostname", "description": "hostname is the name the host's machine goes by, as it last registered it: how a person tells\n one host from another where its id says nothing. Empty for a host that has not registered\n since it was made." + }, + "removal": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.HostRemoval" + } + ], + "title": "removal", + "description": "removal is how this host leaves the fleet, decided by where it came from: the only removal\n the API takes for it, so the dashboard offers that one and no other." + }, + "removalRefused": { + "type": "string", + "title": "removal_refused", + "description": "removal_refused is why that removal cannot run now - a workspace whose disk is there - in\n words an administrator acts on; empty while it can." } }, "title": "Host", @@ -18339,6 +19521,23 @@ "additionalProperties": false, "description": "HostPolicy is what an installation decides about one host. An unset field is the\n installation saying nothing about that setting, which leaves the host on its own default -\n not the same as setting it to nothing." }, + "spin.v1.HostRemoval": { + "type": "string", + "title": "HostRemoval", + "enum": [ + "HOST_REMOVAL_UNSPECIFIED", + "HOST_REMOVAL_REVOKE", + "HOST_REMOVAL_GIVE_BACK", + "HOST_REMOVAL_FORGET" + ], + "description": "HostRemoval is how a host leaves the fleet.\n\n- `HOST_REMOVAL_REVOKE`: A host registered with a token, or a machine of a cloud no group of this installation sizes:\n RevokeRunner. Nothing else can take its machine away.\n- `HOST_REMOVAL_GIVE_BACK`: A machine of an autoscaling group, connected: RemoveHost gives it back to its group, which\n terminates it and is asked for one less. Revoking it would leave the machine running and\n paid for, in a group that counts it.\n- `HOST_REMOVAL_FORGET`: A machine of an autoscaling group, not connected: RemoveHost gives back a machine the group\n still has, and forgets the host now rather than once it has been silent for\n host_forget_after_hours.", + "x-enum-descriptions": [ + "", + "A host registered with a token, or a machine of a cloud no group of this installation sizes:\n RevokeRunner. Nothing else can take its machine away.", + "A machine of an autoscaling group, connected: RemoveHost gives it back to its group, which\n terminates it and is asked for one less. Revoking it would leave the machine running and\n paid for, in a group that counts it.", + "A machine of an autoscaling group, not connected: RemoveHost gives back a machine the group\n still has, and forgets the host now rather than once it has been silent for\n host_forget_after_hours." + ] + }, "spin.v1.HostShell": { "type": "object", "properties": { @@ -18662,11 +19861,6 @@ "title": "telemetry_per_volume_histograms", "description": "Read only: the metrics that cost most to keep, a histogram per volume, which a surface may\n offer to drop as one." }, - "vscodeFetch": { - "type": "boolean", - "title": "vscode_fetch", - "description": "Whether the control plane fetches VS Code servers from Microsoft on its own: the release it\n pins, at start, the newest stable release, looked for daily, and the server of a client's\n commit the installation has not released. False, it fetches none, and a workspace is given\n a server an administrator published; no image carries one." - }, "workspaceTrashDays": { "type": "integer", "title": "workspace_trash_days", @@ -18721,11 +19915,6 @@ "title": "team_secrets_role", "description": "The IAM role a team's secret kept in Secrets Manager or Parameter Store is read under, in a\n session tagged spin-team-id with the team: its policy lets that session read only what carries\n the same tag. Empty, no secret is kept as a reference." }, - "agentsFetch": { - "type": "boolean", - "title": "agents_fetch", - "description": "Whether the control plane fetches the agents' programs - Claude Code, Codex and T3 Code -\n from their publishers on its own: the triple it pins, at start, and the newest release of\n each, looked for daily. False, it fetches none, and a workspace is given a triple an operator\n published; no image carries one." - }, "projectCreation": { "type": "string", "title": "project_creation", @@ -18813,6 +20002,24 @@ } ], "title": "last_succeeded_at" + }, + "title": { + "type": "string", + "title": "title", + "description": "The job as a person names it: \"Storage collection\" for storage-gc." + }, + "purpose": { + "type": "string", + "title": "purpose", + "description": "One sentence of what it does and what stays undone while it fails." + }, + "recentRuns": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.JobRun" + }, + "title": "recent_runs", + "description": "Its newest runs, newest first, at most twenty: what a list of jobs shows each one's recent\n outcomes and durations from, without asking for every job's runs. Each has its id, start,\n end and outcome only; ListJobRuns has the rest." } }, "title": "Job", @@ -19499,7 +20706,31 @@ "format": "int32" } }, - "title": "ListNetworkPoliciesResponse", + "title": "ListNetworkPoliciesResponse", + "additionalProperties": false + }, + "spin.v1.ListNotificationsRequest": { + "type": "object", + "title": "ListNotificationsRequest", + "additionalProperties": false + }, + "spin.v1.ListNotificationsResponse": { + "type": "object", + "properties": { + "notifications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.Notification" + }, + "title": "notifications" + }, + "emailConfigured": { + "type": "boolean", + "title": "email_configured", + "description": "Whether the installation can send email at all." + } + }, + "title": "ListNotificationsResponse", "additionalProperties": false }, "spin.v1.ListPasskeysRequest": { @@ -19542,11 +20773,60 @@ }, "title": "prebuilds", "description": "Newest first." + }, + "storageMeasuredAt": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "storage_measured_at", + "description": "When storage-gc last read the store, which each stored_bytes is as of; unset before it has." + }, + "retireUnusedDays": { + "type": "integer", + "title": "retire_unused_days", + "format": "int32", + "description": "The installation's prebuild_retire_unused_days: a ready prebuild nobody opened a workspace\n from in this many days is retired, its ref's newest included. Zero retires none for that." + }, + "refsNotFound": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.PrebuildRefNotFound" + }, + "title": "refs_not_found", + "description": "The refs the project prebuilds that its forge says the repository has not - a branch deleted\n since it was named - as the prebuilds job last found them: nothing is built of one until the\n forge has it again or the project names it no longer." } }, "title": "ListPrebuildsResponse", "additionalProperties": false }, + "spin.v1.ListProjectWorkspacesRequest": { + "type": "object", + "properties": { + "projectId": { + "type": "string", + "title": "project_id" + } + }, + "title": "ListProjectWorkspacesRequest", + "additionalProperties": false + }, + "spin.v1.ListProjectWorkspacesResponse": { + "type": "object", + "properties": { + "workspaces": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.ProjectWorkspace" + }, + "title": "workspaces", + "description": "Newest first, and at most 500. Not a prebuild's build, and not a deleted one." + } + }, + "title": "ListProjectWorkspacesResponse", + "additionalProperties": false + }, "spin.v1.ListProjectsRequest": { "type": "object", "title": "ListProjectsRequest", @@ -19669,6 +20949,25 @@ "title": "ListResourcePresetsResponse", "additionalProperties": false }, + "spin.v1.ListRunbooksRequest": { + "type": "object", + "title": "ListRunbooksRequest", + "additionalProperties": false + }, + "spin.v1.ListRunbooksResponse": { + "type": "object", + "properties": { + "runbooks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.Runbook" + }, + "title": "runbooks" + } + }, + "title": "ListRunbooksResponse", + "additionalProperties": false + }, "spin.v1.ListSSHKeysRequest": { "type": "object", "properties": { @@ -20104,6 +21403,15 @@ "title": "value" }, "description": "What each listed user still holds, by user id: what an administrator asks before taking\n access away. Kept off User, which other calls return without it." + }, + "refusedRemovals": { + "type": "object", + "title": "refused_removals", + "additionalProperties": { + "type": "string", + "title": "value" + }, + "description": "Why removing a listed user as an administrator, or disabling them, would be refused, by user\n id; absent where it would not be. The refusal is the database's (lockout), so a client that\n never reads this is refused the same." } }, "title": "ListUsersResponse", @@ -20632,6 +21940,152 @@ "additionalProperties": false, "description": "NetworkUsagePoint is what the machine's network carried over a step." }, + "spin.v1.Notification": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "id", + "description": "The workspace event's id." + }, + "workspaceId": { + "type": "string", + "title": "workspace_id" + }, + "workspaceName": { + "type": "string", + "title": "workspace_name" + }, + "event": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.WorkspaceEventType" + } + ], + "title": "event" + }, + "createdAt": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "created_at" + }, + "subject": { + "type": "string", + "title": "subject", + "description": "One line saying what happened." + }, + "body": { + "type": "string", + "title": "body", + "description": "What happened, in full." + }, + "command": { + "type": "string", + "title": "command", + "description": "The command that does what the owner can do about it; empty where nothing is to be done." + }, + "deliveries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.NotificationDelivery" + }, + "title": "deliveries", + "description": "Empty where it was never sent: email off, or this kind turned off." + } + }, + "title": "Notification", + "additionalProperties": false, + "description": "Notification is one event of a workspace's timeline its owner is told of: what happened, and\n what they can do about it." + }, + "spin.v1.NotificationChannel": { + "type": "string", + "title": "NotificationChannel", + "enum": [ + "NOTIFICATION_CHANNEL_UNSPECIFIED", + "NOTIFICATION_CHANNEL_EMAIL" + ], + "description": "How a notification leaves the installation." + }, + "spin.v1.NotificationDelivery": { + "type": "object", + "properties": { + "channel": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.NotificationChannel" + } + ], + "title": "channel" + }, + "state": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.NotificationDeliveryState" + } + ], + "title": "state" + }, + "attempts": { + "type": "integer", + "title": "attempts", + "format": "int32" + }, + "lastError": { + "type": "string", + "title": "last_error", + "description": "What the last attempt that failed was told; empty once one succeeded." + }, + "sentAt": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "sent_at" + } + }, + "title": "NotificationDelivery", + "additionalProperties": false + }, + "spin.v1.NotificationDeliveryState": { + "type": "string", + "title": "NotificationDeliveryState", + "enum": [ + "NOTIFICATION_DELIVERY_STATE_UNSPECIFIED", + "NOTIFICATION_DELIVERY_STATE_PENDING", + "NOTIFICATION_DELIVERY_STATE_SENT", + "NOTIFICATION_DELIVERY_STATE_FAILED" + ], + "description": "Where one notification's delivery on one channel is.\n\n- `NOTIFICATION_DELIVERY_STATE_PENDING`: Not sent yet, or tried and to be tried again\n- `NOTIFICATION_DELIVERY_STATE_SENT`: The channel accepted it\n- `NOTIFICATION_DELIVERY_STATE_FAILED`: Every attempt failed; it is not tried again", + "x-enum-descriptions": [ + "", + "Not sent yet, or tried and to be tried again", + "The channel accepted it", + "Every attempt failed; it is not tried again" + ] + }, + "spin.v1.NotificationPreference": { + "type": "object", + "properties": { + "event": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.WorkspaceEventType" + } + ], + "title": "event" + }, + "email": { + "type": "boolean", + "title": "email" + } + }, + "title": "NotificationPreference", + "additionalProperties": false + }, "spin.v1.ObservedDestination": { "type": "object", "properties": { @@ -21191,7 +22645,7 @@ "log": { "type": "string", "title": "log", - "description": "The tail of what its build said, and why it failed." + "description": "The tail of what its build's create tasks wrote (GetPrebuild only), and why it failed." }, "error": { "type": "string", @@ -21218,12 +22672,56 @@ "title": "workspace_count", "format": "int32", "description": "In ListPrebuilds: the workspaces opened from it that are not deleted, whoever's they are." + }, + "reportedAt": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "reported_at", + "description": "When its build's guest said the checkout and create tasks were done; unset before it did." + }, + "spinYaml": { + "type": "boolean", + "title": "spin_yaml", + "description": "Whether the checkout had a .spin.yaml at its root, as the guest reported: without one the\n build is the clone alone, with no create tasks run. Read only with reported_at." + }, + "storedBytes": { + "type": [ + "string", + "null" + ], + "title": "stored_bytes", + "format": "int64", + "description": "What it keeps in the object store, as storage-gc last read it; unset before a reading\n counted it." } }, "title": "Prebuild", "additionalProperties": false, "description": "A prebuild: one build of a project's ref at a commit, and the snapshot it left." }, + "spin.v1.PrebuildRefNotFound": { + "type": "object", + "properties": { + "ref": { + "type": "string", + "title": "ref" + }, + "since": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "since", + "description": "The job's first look that found it missing." + } + }, + "title": "PrebuildRefNotFound", + "additionalProperties": false, + "description": "A prebuild ref the project's forge has not." + }, "spin.v1.PrebuildState": { "type": "string", "title": "PrebuildState", @@ -21374,16 +22872,107 @@ }, "title": "shared_team_ids" }, - "readyPrebuildCount": { - "type": "integer", - "title": "ready_prebuild_count", - "format": "int32", - "description": "In ListProjects: how many of its prebuilds are ready to open from." + "readyPrebuildCount": { + "type": "integer", + "title": "ready_prebuild_count", + "format": "int32", + "description": "In ListProjects: how many of its prebuilds are ready to open from." + }, + "prebuildKeep": { + "type": "integer", + "title": "prebuild_keep", + "format": "int32", + "description": "How many of each ref's newest ready prebuilds are kept when no workspace was opened from them." + }, + "timeToReady": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.ProjectTimeToReady" + } + ], + "title": "time_to_ready", + "description": "In GetProject: how long its workspaces took to be ready. Unset where none has been." + } + }, + "title": "Project", + "additionalProperties": false, + "description": "A project: a repository and the shape of the workspace that opens it." + }, + "spin.v1.ProjectTimeToReady": { + "type": "object", + "properties": { + "workspaces": { + "type": "integer", + "title": "workspaces", + "format": "int32", + "description": "How many workspaces the times are over: 1 to 20." + }, + "median": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Duration" + } + ], + "title": "median" + }, + "slowest": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Duration" + } + ], + "title": "slowest" + } + }, + "title": "ProjectTimeToReady", + "additionalProperties": false, + "description": "How long a project's workspaces took from their create to their project being ready in them -\n the repository checked out and its create tasks done, as each one's guest first said it, the\n wait for a host and the boot included - over the last 20 that got there. One that never did -\n it failed, or was deleted first - is not counted, and neither is one opened from a prebuild:\n this is what opening without one costs. A workspace whose first boots failed its project counts\n from its create to the boot that went." + }, + "spin.v1.ProjectWorkspace": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "id" + }, + "name": { + "type": "string", + "title": "name" + }, + "ownerId": { + "type": "string", + "title": "owner_id" + }, + "ownerName": { + "type": "string", + "title": "owner_name" + }, + "ownerEmail": { + "type": "string", + "title": "owner_email" + }, + "state": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.WorkspaceState" + } + ], + "title": "state", + "description": "As Workspace.state, DEGRADED included." + }, + "since": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "since", + "description": "Since when it has been in that state: when its guest answered for a running one, and when\n its row last changed for any other." } }, - "title": "Project", + "title": "ProjectWorkspace", "additionalProperties": false, - "description": "A project: a repository and the shape of the workspace that opens it." + "description": "A workspace open on a project, as the project's admins read it: whose it is and how it is, and\n nothing that lets them into it." }, "spin.v1.PublishVSCodeServersRequest": { "type": "object", @@ -21878,6 +23467,43 @@ "title": "RemoveAllowedEmailResponse", "additionalProperties": false }, + "spin.v1.RemoveHostRequest": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "id" + } + }, + "title": "RemoveHostRequest", + "additionalProperties": false + }, + "spin.v1.RemoveHostResponse": { + "type": "object", + "properties": { + "removal": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.HostRemoval" + } + ], + "title": "removal", + "description": "removal is what was done: GIVE_BACK or FORGET." + }, + "givenBack": { + "type": "boolean", + "title": "given_back", + "description": "given_back is the machine terminated and its group asked for one less; false where the\n group no longer had it." + }, + "forgotten": { + "type": "boolean", + "title": "forgotten", + "description": "forgotten is the host's row gone. A host given back while connected is not: it drains under\n its termination hook, and its row goes when its stream ends." + } + }, + "title": "RemoveHostResponse", + "additionalProperties": false + }, "spin.v1.RemoveStoredVolumeRequest": { "type": "object", "properties": { @@ -22109,6 +23735,11 @@ "title": "agent_min_memory_mb", "format": "int32", "description": "What a workspace has to hold for its agent to start there, in MB, for whoever picks a preset." + }, + "fromConfig": { + "type": "boolean", + "title": "from_config", + "description": "Seeded or applied from the installation's config file (the release's presets where it names\n none); false is one an administrator added. An edit since does not change it." } }, "title": "ResourcePreset", @@ -22296,6 +23927,25 @@ "title": "RevokeRunnerResponse", "additionalProperties": false }, + "spin.v1.RevokeThirdPartyTermsRequest": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.ThirdPartyItem" + }, + "title": "items" + } + }, + "title": "RevokeThirdPartyTermsRequest", + "additionalProperties": false + }, + "spin.v1.RevokeThirdPartyTermsResponse": { + "type": "object", + "title": "RevokeThirdPartyTermsResponse", + "additionalProperties": false + }, "spin.v1.RevokeUserAPIKeyRequest": { "type": "object", "properties": { @@ -22364,6 +24014,85 @@ "title": "RunPrebuildResponse", "additionalProperties": false }, + "spin.v1.Runbook": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "id", + "description": "Stable: alert rules and pages link /admin/runbooks/\u003cid\u003e." + }, + "title": { + "type": "string", + "title": "title" + }, + "severity": { + "type": "string", + "title": "severity", + "description": "critical, warning or info." + }, + "owner": { + "type": "string", + "title": "owner", + "description": "The role that keeps it true: operator, security." + }, + "lastReviewed": { + "type": "string", + "title": "last_reviewed", + "description": "YYYY-MM-DD: when it was last held to the release it describes." + }, + "appliesTo": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.RunbookAppliesTo" + } + ], + "title": "applies_to" + } + }, + "title": "Runbook", + "additionalProperties": false + }, + "spin.v1.RunbookAppliesTo": { + "type": "object", + "properties": { + "alerts": { + "type": "array", + "items": { + "type": "string" + }, + "title": "alerts", + "description": "Grafana alert rule uids." + }, + "jobs": { + "type": "array", + "items": { + "type": "string" + }, + "title": "jobs", + "description": "Control plane job names (Job.name)." + }, + "events": { + "type": "array", + "items": { + "type": "string" + }, + "title": "events", + "description": "The notices a workspace's owner gets, by WorkspaceEventType without its prefix: HELD." + }, + "dashboards": { + "type": "array", + "items": { + "type": "string" + }, + "title": "dashboards", + "description": "Grafana dashboard uids." + } + }, + "title": "RunbookAppliesTo", + "additionalProperties": false, + "description": "What sends an operator to a runbook, each as the installation names it." + }, "spin.v1.SSHKey": { "type": "object", "properties": { @@ -23262,6 +24991,27 @@ "title": "SetWorkspaceNetworkWatchResponse", "additionalProperties": false }, + "spin.v1.SettingReach": { + "type": "string", + "title": "SettingReach", + "enum": [ + "SETTING_REACH_UNSPECIFIED", + "SETTING_REACH_RUNNING_WORKSPACES", + "SETTING_REACH_NEW_WORKSPACES", + "SETTING_REACH_NEXT_HEARTBEAT", + "SETTING_REACH_NEXT_REQUEST", + "SETTING_REACH_NEXT_PASS" + ], + "description": "SettingReach is what a saved installation setting touches, and when: each setting declares one\n beside its key (internal/controlplane/settings), so the screen that edits it can say so before\n the save.\n\n- `SETTING_REACH_RUNNING_WORKSPACES`: The workspaces running now, at the control plane's next look at them.\n- `SETTING_REACH_NEW_WORKSPACES`: Workspaces created from now on; those that exist keep what they were made with.\n- `SETTING_REACH_NEXT_HEARTBEAT`: Each runner at its next heartbeat, and the workspaces running on it.\n- `SETTING_REACH_NEXT_REQUEST`: What is asked from now on - a project made, a shell opened, a workspace deleted; what was\n done before keeps the terms it was done under.\n- `SETTING_REACH_NEXT_PASS`: The next pass of the job that applies it: the autoscaler, the prebuilds' retirement, the\n collector's read of its policy, the daily look for a release.", + "x-enum-descriptions": [ + "", + "The workspaces running now, at the control plane's next look at them.", + "Workspaces created from now on; those that exist keep what they were made with.", + "Each runner at its next heartbeat, and the workspaces running on it.", + "What is asked from now on - a project made, a shell opened, a workspace deleted; what was\n done before keeps the terms it was done under.", + "The next pass of the job that applies it: the autoscaler, the prebuilds' retirement, the\n collector's read of its policy, the daily look for a release." + ] + }, "spin.v1.ShareProjectRequest": { "type": "object", "properties": { @@ -24249,6 +25999,11 @@ } ], "title": "created_at" + }, + "refusedRemoval": { + "type": "string", + "title": "refused_removal", + "description": "Why disabling or deleting it would be refused; empty where it would not be. An installation\n provider that the only administrators who can sign in sign in through (lockout)." } }, "title": "TeamIdentityProvider", @@ -24392,6 +26147,117 @@ "title": "TestHostWritebackResponse", "additionalProperties": false }, + "spin.v1.ThirdPartyAcceptance": { + "type": "object", + "properties": { + "termsVersion": { + "type": "string", + "title": "terms_version", + "description": "The version of the text that was accepted; an older one than the response's counts as none." + }, + "acceptedBy": { + "type": "string", + "title": "accepted_by", + "description": "Who accepted, by email: kept as it was when they did." + }, + "acceptedAt": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Timestamp" + } + ], + "title": "accepted_at" + } + }, + "title": "ThirdPartyAcceptance", + "additionalProperties": false, + "description": "ThirdPartyAcceptance is an administrator's acceptance of an item's terms." + }, + "spin.v1.ThirdPartyItem": { + "type": "string", + "title": "ThirdPartyItem", + "enum": [ + "THIRD_PARTY_ITEM_UNSPECIFIED", + "THIRD_PARTY_ITEM_VSCODE_SERVER", + "THIRD_PARTY_ITEM_AGENT_CLIS" + ], + "description": "ThirdPartyItem is what an administrator accepts the terms of, one download at a time: the\n software the control plane fetches together, as one extension.\n\n- `THIRD_PARTY_ITEM_VSCODE_SERVER`: Microsoft's VS Code server and its CLI: the vsc-\u003ccommit\u003e extensions.\n- `THIRD_PARTY_ITEM_AGENT_CLIS`: Claude Code, Codex, T3 Code and the libatomic T3 Code's server is linked against: the agents\n extension.", + "x-enum-descriptions": [ + "", + "Microsoft's VS Code server and its CLI: the vsc-\u003ccommit\u003e extensions.", + "Claude Code, Codex, T3 Code and the libatomic T3 Code's server is linked against: the agents\n extension." + ] + }, + "spin.v1.ThirdPartyPart": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "name" + }, + "maker": { + "type": "string", + "title": "maker", + "description": "Who makes it and serves the download." + }, + "license": { + "type": "string", + "title": "license" + }, + "licenseUrl": { + "type": "string", + "title": "license_url" + } + }, + "title": "ThirdPartyPart", + "additionalProperties": false, + "description": "ThirdPartyPart is one program an item downloads, and the license it comes under." + }, + "spin.v1.ThirdPartyTermsItem": { + "type": "object", + "properties": { + "item": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.ThirdPartyItem" + } + ], + "title": "item" + }, + "name": { + "type": "string", + "title": "name" + }, + "purpose": { + "type": "string", + "title": "purpose", + "description": "What a workspace gets from it." + }, + "parts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.ThirdPartyPart" + }, + "title": "parts" + }, + "acceptance": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.ThirdPartyAcceptance" + } + ], + "title": "acceptance", + "description": "Unset where nobody accepted the terms for it." + }, + "accepted": { + "type": "boolean", + "title": "accepted", + "description": "Whether this installation downloads it: accepted, as the current text." + } + }, + "title": "ThirdPartyTermsItem", + "additionalProperties": false + }, "spin.v1.UndeleteWorkspaceRequest": { "type": "object", "properties": { @@ -24476,6 +26342,53 @@ "title": "UntagImageResponse", "additionalProperties": false }, + "spin.v1.UpdateEmailSettingsRequest": { + "type": "object", + "properties": { + "host": { + "type": "string", + "title": "host" + }, + "port": { + "type": "integer", + "title": "port", + "format": "int32" + }, + "username": { + "type": "string", + "title": "username" + }, + "password": { + "type": [ + "string", + "null" + ], + "title": "password", + "description": "Absent keeps the password there is." + }, + "from": { + "type": "string", + "title": "from" + } + }, + "title": "UpdateEmailSettingsRequest", + "additionalProperties": false + }, + "spin.v1.UpdateEmailSettingsResponse": { + "type": "object", + "properties": { + "settings": { + "allOf": [ + { + "$ref": "#/components/schemas/spin.v1.EmailSettings" + } + ], + "title": "settings" + } + }, + "title": "UpdateEmailSettingsResponse", + "additionalProperties": false + }, "spin.v1.UpdateHostClassRequest": { "type": "object", "properties": { @@ -24567,6 +26480,35 @@ "title": "UpdateNetworkPolicyResponse", "additionalProperties": false }, + "spin.v1.UpdateNotificationPreferencesRequest": { + "type": "object", + "properties": { + "preferences": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.NotificationPreference" + }, + "title": "preferences", + "description": "Each event named is set; one not named keeps what it was." + } + }, + "title": "UpdateNotificationPreferencesRequest", + "additionalProperties": false + }, + "spin.v1.UpdateNotificationPreferencesResponse": { + "type": "object", + "properties": { + "preferences": { + "type": "array", + "items": { + "$ref": "#/components/schemas/spin.v1.NotificationPreference" + }, + "title": "preferences" + } + }, + "title": "UpdateNotificationPreferencesResponse", + "additionalProperties": false + }, "spin.v1.UpdateProjectRequest": { "type": "object", "properties": { @@ -24620,6 +26562,12 @@ "type": "integer", "title": "prebuild_rebase_every", "format": "int32" + }, + "prebuildKeep": { + "type": "integer", + "title": "prebuild_keep", + "format": "int32", + "description": "Zero is one, as at create" } }, "title": "UpdateProjectRequest", @@ -25759,6 +27707,11 @@ "type": "string", "title": "host_name", "description": "host_name is the name host_id's machine registered, for a person to tell hosts apart; empty\n with no host, or one that registered none. Answered by GetWorkspace and ListWorkspaces, so a\n list row says where each runs without a status read per row; never placed or trusted by." + }, + "withoutPrebuild": { + "type": "string", + "title": "without_prebuild", + "description": "without_prebuild is why a workspace opening a project at a ref it prebuilds started from none\n of its prebuilds, and cloned the repository at its first boot: none ready, the ready one of\n another image, its disk not cloneable yet. Empty with from_prebuild_id set, or for a project\n that prebuilds nothing." } }, "title": "Workspace", @@ -26002,9 +27955,11 @@ "WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED", "WORKSPACE_EVENT_TYPE_SUSPENSION_DUE", "WORKSPACE_EVENT_TYPE_KEPT", - "WORKSPACE_EVENT_TYPE_UNRESPONSIVE" + "WORKSPACE_EVENT_TYPE_UNRESPONSIVE", + "WORKSPACE_EVENT_TYPE_REHOMED", + "WORKSPACE_EVENT_TYPE_HELD" ], - "description": "- `WORKSPACE_EVENT_TYPE_CREATED`: Workspace was created\n- `WORKSPACE_EVENT_TYPE_STARTED`: Workspace was started\n- `WORKSPACE_EVENT_TYPE_STOPPED`: Workspace was stopped; its disk is kept, and no snapshot is taken\n- `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`: Manual snapshot\n- `WORKSPACE_EVENT_TYPE_DELETED`: Workspace was deleted\n- `WORKSPACE_EVENT_TYPE_FAILED`: Workspace start failed\n- `WORKSPACE_EVENT_TYPE_RESTORED`: Its disk was put back to a snapshot\n- `WORKSPACE_EVENT_TYPE_RESUMED`: It went on from a snapshot's memory\n- `WORKSPACE_EVENT_TYPE_BOOTED`: Suspended, its memory could not be resumed, and its disk was booted\n- `WORKSPACE_EVENT_TYPE_QUARANTINED`: An administrator held it: stopped, and startable by nobody until released\n- `WORKSPACE_EVENT_TYPE_UNQUARANTINED`: The hold was released: back to stopped, where it was held from\n- `WORKSPACE_EVENT_TYPE_PLACED`: A workspace that waited for a host was given one, and its disk there\n- `WORKSPACE_EVENT_TYPE_TRASHED`: Deleted into the trash: its disk kept, its owner able to undelete it\n- `WORKSPACE_EVENT_TYPE_UNDELETED`: Taken back out of the trash\n- `WORKSPACE_EVENT_TYPE_MOVED`: Suspended on its host and resumed on another, which had room for what it was granted\n- `WORKSPACE_EVENT_TYPE_DISPLACED`: Its host was drained or went away: suspended there, it is resumed on another on its own\n- `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`: A stop on a host that can be taken away could not publish its disk first, so it runs on\n- `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`: Nobody used it for as long as the installation allows: suspended with its processes, a start resumes them\n- `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`: It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them\n- `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`: A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it\n- `WORKSPACE_EVENT_TYPE_KEPT`: Somebody kept it awake until a time: no suspension before it\n- `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`: Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back", + "description": "- `WORKSPACE_EVENT_TYPE_CREATED`: Workspace was created\n- `WORKSPACE_EVENT_TYPE_STARTED`: Workspace was started\n- `WORKSPACE_EVENT_TYPE_STOPPED`: Workspace was stopped; its disk is kept, and no snapshot is taken\n- `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`: Manual snapshot\n- `WORKSPACE_EVENT_TYPE_DELETED`: Workspace was deleted\n- `WORKSPACE_EVENT_TYPE_FAILED`: Workspace start failed\n- `WORKSPACE_EVENT_TYPE_RESTORED`: Its disk was put back to a snapshot\n- `WORKSPACE_EVENT_TYPE_RESUMED`: It went on from a snapshot's memory\n- `WORKSPACE_EVENT_TYPE_BOOTED`: Suspended, its memory could not be resumed, and its disk was booted\n- `WORKSPACE_EVENT_TYPE_QUARANTINED`: An administrator held it: stopped, and startable by nobody until released\n- `WORKSPACE_EVENT_TYPE_UNQUARANTINED`: The hold was released: back to stopped, where it was held from\n- `WORKSPACE_EVENT_TYPE_PLACED`: A workspace that waited for a host was given one, and its disk there\n- `WORKSPACE_EVENT_TYPE_TRASHED`: Deleted into the trash: its disk kept, its owner able to undelete it\n- `WORKSPACE_EVENT_TYPE_UNDELETED`: Taken back out of the trash\n- `WORKSPACE_EVENT_TYPE_MOVED`: Suspended on its host and resumed on another, which had room for what it was granted\n- `WORKSPACE_EVENT_TYPE_DISPLACED`: Its host was drained or went away: suspended there, it is resumed on another on its own\n- `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`: A stop on a host that can be taken away could not publish its disk first, so it runs on\n- `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`: Nobody used it for as long as the installation allows: suspended with its processes, a start resumes them\n- `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`: It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them\n- `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`: A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it\n- `WORKSPACE_EVENT_TYPE_KEPT`: Somebody kept it awake until a time: no suspension before it\n- `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`: Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back\n- `WORKSPACE_EVENT_TYPE_REHOMED`: Its host stopped answering and it was moved to another on its own, giving up what that host had not published\n- `WORKSPACE_EVENT_TYPE_HELD`: Its host stopped answering and moving it would give up more than the installation does on its own: it waits for its owner", "x-enum-descriptions": [ "", "Workspace was created", @@ -26028,7 +27983,9 @@ "It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them", "A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it", "Somebody kept it awake until a time: no suspension before it", - "Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back" + "Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back", + "Its host stopped answering and it was moved to another on its own, giving up what that host had not published", + "Its host stopped answering and moving it would give up more than the installation does on its own: it waits for its owner" ] }, "spin.v1.WorkspaceFailure": { @@ -26298,6 +28255,15 @@ } ], "title": "deadline" + }, + "typical": { + "allOf": [ + { + "$ref": "#/components/schemas/google.protobuf.Duration" + } + ], + "title": "typical", + "description": "typical is how long a start usually takes on the workspace's host class: the median, from\n the request to RUNNING (the same measure as since), of the newest starts that came up there.\n Unset for a transition that is not a start, and where too few have come up to say. Per step\n it is not: what a host says of its phases is kept only while one is under way." } }, "title": "WorkspaceProgress", @@ -26619,6 +28585,9 @@ { "name": "RunnerTokenService" }, + { + "name": "WorkspaceService" + }, { "name": "SettingsService" }, @@ -26626,9 +28595,6 @@ "name": "SetupService", "description": "SetupService handles initial platform setup and admin bootstrap.\n Most endpoints require admin authentication, except GetSetupStatus and PasswordLogin." }, - { - "name": "WorkspaceService" - }, { "name": "ShareService", "description": "ShareService manages snapshot sharing\n Snapshots can be shared with specific users or made public\n Users can create new workspaces from shared snapshots" diff --git a/src/assets/shots/snapshots.png b/src/assets/shots/snapshots.png index 6f5bef789c0b0531f437aa655fd52e073cfa538e..29ff62d663f32dcec05a15fe351ff1f31f7127c8 100644 GIT binary patch literal 65276 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 BV;2Ab literal 64820 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 diff --git a/src/assets/shots/workspace.png b/src/assets/shots/workspace.png index f234c38bacde8c25952dde047f1293931668d378..95014c6eb6692761640c5352ef6b256cc1216981 100644 GIT binary patch literal 108458 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⪙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 literal 108445 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
-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 Ch(q}R diff --git a/src/content/docs/reference/api/adminservice.md b/src/content/docs/reference/api/adminservice.md index 87a02c4..1777dc8 100644 --- a/src/content/docs/reference/api/adminservice.md +++ b/src/content/docs/reference/api/adminservice.md @@ -11,6 +11,23 @@ sidebar: AdminService manages installation-wide settings, user management, and resource presets. Only accessible to instance administrators. +## AcceptThirdPartyTerms + +`POST /spin.v1.AdminService/AcceptThirdPartyTerms` + +Accept the terms, as the version shown, for the items named: this installation then downloads them - the releases this control plane pins at once, and the newest daily. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `termsVersion` | string | The version of the text the administrator was shown: one that is not the current one is refused, so nobody accepts a text they did not read. | +| `items` | list of [ThirdPartyItem](/reference/api/types/#thirdpartyitem) | | + +**Response** + +No fields: `{}`. + ## AddAllowedEmail `POST /spin.v1.AdminService/AddAllowedEmail` @@ -243,6 +260,22 @@ A month of the bill shared out to the workspaces that caused it: the runners' by | `unstoredMicros` | string (int64) | What the volumes' bucket cost for bytes no workspace keeps: the images, what nothing references any more. | | `platform` | list of [ServiceCost](/reference/api/types/#servicecost) | Every other cost - the control plane, the proxy, keys, logs - by service, costliest first. | +## GetEmailSettings + +`POST /spin.v1.AdminService/GetEmailSettings` + +The SMTP server the installation tells people through. The password is never read back. + +**Request** + +No fields: `{}`. + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `settings` | [EmailSettings](/reference/api/types/#emailsettings) | | + ## GetFleetVersions `POST /spin.v1.AdminService/GetFleetVersions` @@ -294,6 +327,9 @@ No fields: `{}`. | Field | Type | What it is | |---|---|---| | `settings` | [InstallationSettings](/reference/api/types/#installationsettings) | | +| `reaches` | map of string to [SettingReach](/reference/api/types/#settingreach) | What each setting touches when saved, by its update_mask path: every path UpdateInstallationSettings accepts, and no other. | +| `runningWorkspaces` | integer (int32) | How many workspaces are running now: what a RUNNING_WORKSPACES setting reaches, and what a NEW_WORKSPACES one leaves as it is. | +| `connectedRunners` | integer or null (int32) | How many runners hold their stream to this control plane now: what a NEXT_HEARTBEAT setting reaches. Unset where this control plane cannot tell. | ## GetMonitoring @@ -346,6 +382,26 @@ No fields: `{}`. |---|---|---| | `mode` | [RegistrationMode](/reference/api/types/#registrationmode) | | +## GetRunbook + +`POST /spin.v1.AdminService/GetRunbook` + +One runbook, its markdown and where its file is at the pinned commit. NOT_FOUND for an id this release's runbooks do not have. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `id` | string | | + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `runbook` | [Runbook](/reference/api/types/#runbook) | | +| `markdown` | string | Its body, markdown without the front matter: the app renders it and nothing else (no raw HTML). | +| `sourceUrl` | string | The file at the commit this release pins, to propose a change from. | + ## GetSecuritySettings `POST /spin.v1.AdminService/GetSecuritySettings` @@ -417,6 +473,24 @@ No fields: `{}`. | `spans` | [TelemetryFlow](/reference/api/types/#telemetryflow) | Into the installation's store, after the traces policy chose which to keep. | | `samples` | [TelemetryFlow](/reference/api/types/#telemetryflow) | Into the installation's store of metrics. | +## GetThirdPartyTerms + +`POST /spin.v1.AdminService/GetThirdPartyTerms` + +The software this installation downloads from its makers, the terms it is used under, and which of it an administrator accepted the terms for: who, when, and which text. Nothing is downloaded of an item whose terms are not accepted (internal/controlplane/thirdparty). + +**Request** + +No fields: `{}`. + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `termsVersion` | string | The version of the text below, which an acceptance names. | +| `text` | list of string | The terms, a paragraph each. | +| `items` | list of [ThirdPartyTermsItem](/reference/api/types/#thirdpartytermsitem) | | + ## GetVSCodeServers `POST /spin.v1.AdminService/GetVSCodeServers` @@ -435,6 +509,24 @@ No fields: `{}`. | `publish` | [VSCodeServerPublish](/reference/api/types/#vscodeserverpublish) | | | `unavailable` | string | Why this control plane cannot publish - no object store, or a build with no machine tools to make the image with - and empty when it can. | +## GetWorkspaceNames + +`POST /spin.v1.AdminService/GetWorkspaceNames` + +The names of the workspaces ids are, whoever owns them and whatever state they are in, a deleted one among them: a record of the platform's logs names a workspace by its id, and ListWorkspaces is the caller's own. An id the installation no longer holds a row for is left out of the answer. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `ids` | list of string | At most 500: the ids a page of records names. | + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `names` | map of string to string | Each id asked for that the installation holds a row for, to its workspace's name. | + ## ListAllowedEmails `POST /spin.v1.AdminService/ListAllowedEmails` @@ -582,6 +674,22 @@ List resource presets | `presets` | list of [ResourcePreset](/reference/api/types/#resourcepreset) | | | `page` | [PageResponse](/reference/api/types/#pageresponse) | | +## ListRunbooks + +`POST /spin.v1.AdminService/ListRunbooks` + +What an operator does when an alert fires, a job fails or an owner is told something went wrong: spin-stack/runbooks at the commit this release pins, served so it is read in the app. + +**Request** + +No fields: `{}`. + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `runbooks` | list of [Runbook](/reference/api/types/#runbook) | | + ## ListUserAPIKeys `POST /spin.v1.AdminService/ListUserAPIKeys` @@ -623,6 +731,7 @@ List all users | `users` | list of [User](/reference/api/types/#user) | | | `page` | [PageResponse](/reference/api/types/#pageresponse) | | | `holdings` | map of string to [UserHoldings](/reference/api/types/#userholdings) | What each listed user still holds, by user id: what an administrator asks before taking access away. Kept off User, which other calls return without it. | +| `refusedRemovals` | map of string to string | Why removing a listed user as an administrator, or disabling them, would be refused, by user id; absent where it would not be. The refusal is the database's (lockout), so a client that never reads this is refused the same. | ## PublishVSCodeServers @@ -705,6 +814,22 @@ No fields: `{}`. No fields: `{}`. +## RevokeThirdPartyTerms + +`POST /spin.v1.AdminService/RevokeThirdPartyTerms` + +Take the acceptance back for the items named: nothing more of them is downloaded. What was downloaded already stays until an administrator removes it. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `items` | list of [ThirdPartyItem](/reference/api/types/#thirdpartyitem) | | + +**Response** + +No fields: `{}`. + ## RevokeUserAPIKey `POST /spin.v1.AdminService/RevokeUserAPIKey` @@ -772,6 +897,28 @@ Take a ref off what it names: no new workspace gets those bytes by it, the disks No fields: `{}`. +## UpdateEmailSettings + +`POST /spin.v1.AdminService/UpdateEmailSettings` + +Set the SMTP server, checked against it - connected to and signed in to - before it is written. An empty host turns email off. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `host` | string | | +| `port` | integer (int32) | | +| `username` | string | | +| `password` | string or null | Absent keeps the password there is. | +| `from` | string | | + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `settings` | [EmailSettings](/reference/api/types/#emailsettings) | | + ## UpdateHostClass `POST /spin.v1.AdminService/UpdateHostClass` diff --git a/src/content/docs/reference/api/hostservice.md b/src/content/docs/reference/api/hostservice.md index dfe2244..f8bba47 100644 --- a/src/content/docs/reference/api/hostservice.md +++ b/src/content/docs/reference/api/hostservice.md @@ -129,6 +129,26 @@ List all hosts (admin only) | `hosts` | list of [Host](/reference/api/types/#host) | | | `page` | [PageResponse](/reference/api/types/#pageresponse) | | +## RemoveHost + +`POST /spin.v1.HostService/RemoveHost` + +Takes a machine of an autoscaling group out of the fleet (admin only), as Host.removal says: given back to its group (GIVE_BACK), or forgotten (FORGET). A host whose removal is REVOKE is refused: RevokeRunner is its removal. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `id` | string | | + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `removal` | [HostRemoval](/reference/api/types/#hostremoval) | removal is what was done: GIVE_BACK or FORGET. | +| `givenBack` | boolean | given_back is the machine terminated and its group asked for one less; false where the group no longer had it. | +| `forgotten` | boolean | forgotten is the host's row gone. A host given back while connected is not: it drains under its termination hook, and its row goes when its stream ends. | + ## SetHostPolicy `POST /spin.v1.HostService/SetHostPolicy` diff --git a/src/content/docs/reference/api/index.md b/src/content/docs/reference/api/index.md index 8be4baf..f027cb8 100644 --- a/src/content/docs/reference/api/index.md +++ b/src/content/docs/reference/api/index.md @@ -25,14 +25,14 @@ curl -s https://app.example.com/spin.v1.WorkspaceService/ListWorkspaces \ - [AdminService](/reference/api/adminservice/): AdminService manages installation-wide settings, user management, and resource presets. Only accessible to instance administrators. - [ExecService](/reference/api/execservice/): ExecService runs commands and moves files in a running workspace, as its root, for a caller who. is no terminal: a program or an agent holding a key with workspace:exec. The control plane logs. in over the same session a terminal's goes over (a host's stream from the guest's vsock, met at. the control plane rather than at the relay) with a certificate of its own for five minutes, and. every call is recorded with who made it and on which credential (audit: workspace_exec). - [ForgeService](/reference/api/forgeservice/): ForgeService is a person's account on a forge, connected through the installation's GitHub App. (spin#758): the control plane keeps the token, lists the person's repositories with it, and a. host's egress proxy sets it on their workspaces' brokered requests. No workspace holds it. -- [HostService](/reference/api/hostservice/): 8 procedures +- [HostService](/reference/api/hostservice/): 9 procedures - [HostShellService](/reference/api/hostshellservice/): HostShellService is a root shell on a host, asked for by an administrator, for a while, with a. reason (spin#712). The host is emptied of its workspaces first - unless the request is an. incident's, which says so - and retired after, whatever happened in it: once a person has had root. on a host it runs no workspace again. Every session is recorded by the control plane, which. carries it; the terminal itself is a WebSocket at /api/host-shells/<id>/terminal. (internal/hostshell). - [LogService](/reference/api/logservice/): LogService is what the installation logged, as its store of logs and traces keeps it. (internal/logstore). Every search is confined by the control plane to what the caller may see; what the caller types is searched inside that and cannot widen it. - [ProjectService](/reference/api/projectservice/): ProjectService is the installation's projects (spin#720): a repository and the shape of the. workspace that opens it (CreateWorkspaceRequest.project_id). Anybody signed in makes one where. the installation lets everybody (InstallationSettings.project_creation), and is its first admin. A project is seen by everybody while it is shared with everyone, and otherwise by its admins and. whom it is shared with; the instance's admins see and administer every one. Whoever sees one. opens workspaces from it, in a team of theirs. - [RunnerTokenService](/reference/api/runnertokenservice/): 4 procedures -- [SettingsService](/reference/api/settingsservice/): 3 procedures -- [SetupService](/reference/api/setupservice/): SetupService handles initial platform setup and admin bootstrap. Most endpoints require admin authentication, except GetSetupStatus and PasswordLogin. - [WorkspaceService](/reference/api/workspaceservice/): 53 procedures +- [SettingsService](/reference/api/settingsservice/): 6 procedures +- [SetupService](/reference/api/setupservice/): SetupService handles initial platform setup and admin bootstrap. Most endpoints require admin authentication, except GetSetupStatus and PasswordLogin. - [ShareService](/reference/api/shareservice/): ShareService manages snapshot sharing. Snapshots can be shared with specific users or made public. Users can create new workspaces from shared snapshots. - [SSHKeyService](/reference/api/sshkeyservice/): SSHKeyService is the keys that log in as the person, to every workspace that lets them in: a key. of their own, for good, or a browser's or a CLI's enrolled for twelve hours. Each is added with an. assertion of a passkey of theirs (PasskeyService), so a session alone adds none. - [TeamService](/reference/api/teamservice/): 18 procedures diff --git a/src/content/docs/reference/api/projectservice.md b/src/content/docs/reference/api/projectservice.md index 85d4595..a2b402f 100644 --- a/src/content/docs/reference/api/projectservice.md +++ b/src/content/docs/reference/api/projectservice.md @@ -29,6 +29,7 @@ ProjectService is the installation's projects (spin#720): a repository and the s | `networkTags` | list of string | | | `prebuildRefs` | list of string | | | `prebuildRebaseEvery` | integer (int32) | Zero is the installation's default | +| `prebuildKeep` | integer (int32) | Zero is one: the newest of each ref | **Response** @@ -50,6 +51,25 @@ ProjectService is the installation's projects (spin#720): a repository and the s No fields: `{}`. +## GetPrebuild + +`POST /spin.v1.ProjectService/GetPrebuild` + +One of them whole, with what its build's create tasks wrote, to whoever sees the project. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `projectId` | string | | +| `prebuildId` | string | | + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `prebuild` | [Prebuild](/reference/api/types/#prebuild) | | + ## GetProject `POST /spin.v1.ProjectService/GetProject` @@ -84,6 +104,27 @@ A project's prebuilds, to whoever sees it; and a build of one of its refs now, b | Field | Type | What it is | |---|---|---| | `prebuilds` | list of [Prebuild](/reference/api/types/#prebuild) | Newest first. | +| `storageMeasuredAt` | `Timestamp` | When storage-gc last read the store, which each stored_bytes is as of; unset before it has. | +| `retireUnusedDays` | integer (int32) | The installation's prebuild_retire_unused_days: a ready prebuild nobody opened a workspace from in this many days is retired, its ref's newest included. Zero retires none for that. | +| `refsNotFound` | list of [PrebuildRefNotFound](/reference/api/types/#prebuildrefnotfound) | The refs the project prebuilds that its forge says the repository has not - a branch deleted since it was named - as the prebuilds job last found them: nothing is built of one until the forge has it again or the project names it no longer. | + +## ListProjectWorkspaces + +`POST /spin.v1.ProjectService/ListProjectWorkspaces` + +Everybody's workspaces open on a project, to its admins and nobody else: a person it is only shared with is refused, and reads their own with ListWorkspaces. + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `projectId` | string | | + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `workspaces` | list of [ProjectWorkspace](/reference/api/types/#projectworkspace) | Newest first, and at most 500. Not a prebuild's build, and not a deleted one. | ## ListProjects @@ -157,6 +198,7 @@ Changed, shared and deleted by its admins. A project with a workspace open on it | `networkTags` | list of string | | | `prebuildRefs` | list of string | | | `prebuildRebaseEvery` | integer (int32) | | +| `prebuildKeep` | integer (int32) | Zero is one, as at create | **Response** diff --git a/src/content/docs/reference/api/settingsservice.md b/src/content/docs/reference/api/settingsservice.md index fa2169b..2f92d8a 100644 --- a/src/content/docs/reference/api/settingsservice.md +++ b/src/content/docs/reference/api/settingsservice.md @@ -4,11 +4,28 @@ description: "spin.v1.SettingsService: each procedure, its request and its respo source: "spin:internal/controlplane/apidocs/spin.v1.openapi.json" editUrl: false sidebar: - order: 11 + order: 12 --- +## GetNotificationPreferences + +`POST /spin.v1.SettingsService/GetNotificationPreferences` + +Which of those the caller is emailed about. + +**Request** + +No fields: `{}`. + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `preferences` | list of [NotificationPreference](/reference/api/types/#notificationpreference) | One per event a person may be told of, in the order they are shown. | +| `emailConfigured` | boolean | | + ## GetUserSettings `POST /spin.v1.SettingsService/GetUserSettings` @@ -25,6 +42,39 @@ No fields: `{}`. |---|---|---| | `settings` | [UserSettings](/reference/api/types/#usersettings) | | +## ListNotifications + +`POST /spin.v1.SettingsService/ListNotifications` + +What happened to the caller's workspaces that they are told of, newest first, with whether each was sent and how. Recorded whether or not the installation can send email. + +**Request** + +No fields: `{}`. + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `notifications` | list of [Notification](/reference/api/types/#notification) | | +| `emailConfigured` | boolean | Whether the installation can send email at all. | + +## UpdateNotificationPreferences + +`POST /spin.v1.SettingsService/UpdateNotificationPreferences` + +**Request** + +| Field | Type | What it is | +|---|---|---| +| `preferences` | list of [NotificationPreference](/reference/api/types/#notificationpreference) | Each event named is set; one not named keeps what it was. | + +**Response** + +| Field | Type | What it is | +|---|---|---| +| `preferences` | list of [NotificationPreference](/reference/api/types/#notificationpreference) | | + ## UpdateUserSettings `POST /spin.v1.SettingsService/UpdateUserSettings` diff --git a/src/content/docs/reference/api/setupservice.md b/src/content/docs/reference/api/setupservice.md index c3c667e..615b9c5 100644 --- a/src/content/docs/reference/api/setupservice.md +++ b/src/content/docs/reference/api/setupservice.md @@ -4,7 +4,7 @@ description: "spin.v1.SetupService: each procedure, its request and its response source: "spin:internal/controlplane/apidocs/spin.v1.openapi.json" editUrl: false sidebar: - order: 12 + order: 13 --- @@ -113,6 +113,7 @@ No fields: `{}`. | `hasStorage` | boolean | True if the object store is configured; until it is, no workspace can be created | | `signedIn` | boolean | True if whoever asked is signed in: the wizard starts at the sign-in until they are, whatever the installation already has. | | `development` | boolean | True for a development installation, where the mock identity provider may be enabled. | +| `thirdPartyAccepted` | boolean | True where an administrator accepted the terms of any third-party software, as the current text: the wizard asks until one has, or until it is told to go on without. | ## PasswordLogin diff --git a/src/content/docs/reference/api/types.md b/src/content/docs/reference/api/types.md index 22593f3..09cfd00 100644 --- a/src/content/docs/reference/api/types.md +++ b/src/content/docs/reference/api/types.md @@ -101,6 +101,7 @@ BaseImage is the base image of one machine release, as published. | `pinned` | boolean | The one this control plane's release pins; given once it is published. | | `volumeId` | string | Its volume in the store, which RemoveStoredVolume takes when removable. | | `removable` | boolean | No disk was cloned from it and it is not the one given: RemoveStoredVolume untags it on the way and removes it. | +| `keptBecause` | string | Why it stays, in words, where it may not go. | ## BillDay @@ -197,6 +198,18 @@ One of: `DEVICE_LOGIN_STATUS_UNSPECIFIED`, `DEVICE_LOGIN_STATUS_PENDING`, `DEVIC | `branch` | string | Branch to clone (default: main) | | `installCommand` | string | Command to run after clone (default: ./install.sh) | +## EmailSettings + +EmailSettings is the SMTP server the installation sends its notifications through. No host is email off: what would have been sent is still recorded, and shown on each person's page. + +| Field | Type | What it is | +|---|---|---| +| `host` | string | | +| `port` | integer (int32) | 465 is TLS from the first byte; any other port is upgraded with STARTTLS where the server offers it, and a username is refused over a connection that is not encrypted. | +| `username` | string | | +| `passwordSet` | boolean | | +| `from` | string | The address mail is sent from, as the server allows this account to send. | + ## ExposedPort | Field | Type | What it is | @@ -221,6 +234,9 @@ ExtensionRelease is one release of an extension: the supervisor, or the VS Code | `releasedAt` | `Timestamp` | | | `workspaces` | string (int64) | How many workspaces run it; one that nothing runs and is not the newest is collectable. | | `newest` | boolean | Whether a start is given this one. | +| `volumeId` | string | Its volume in the store, which RemoveStoredVolume takes when removable. | +| `removable` | boolean | Not the newest and nothing runs it: RemoveStoredVolume removes it, and so does the collect-releases job on its own. | +| `keptBecause` | string | Why it stays, in words, where it may not go. | ## ExtensionVersion @@ -289,9 +305,11 @@ One host class's group, as the control plane last saw it. | `most` | integer (int32) | | | `waiting` | integer (int32) | Workspaces of the class that have nowhere to run yet, and when the first of them started waiting: this is what makes the control plane ask for a machine. | | `oldestWaiting` | `Timestamp` | | -| `busy` | integer (int32) | Workspaces of the class keeping its group up. | +| `busy` | integer (int32) | Workspaces of the class, and hosts a root shell holds, keeping its group up. | | `launchFailure` | string | Why the group has fewer machines running than it was asked for, in its cloud's own words - "AWS could not start a runner: <message>" - and when the cloud said it. Empty while it has as many, or while the cloud said nothing that explains it. | | `launchFailedAt` | `Timestamp` | | +| `giveBackRefused` | string | A machine of the group the cloud would not take back, in its own words - a role or a policy somebody has to change - and when; it is asked again every quarter hour until it is taken. Empty while none is refused. | +| `giveBackRefusedAt` | `Timestamp` | | ## FleetHostVersion @@ -438,6 +456,8 @@ One of: `HEALTH_STATUS_UNSPECIFIED`, `HEALTH_STATUS_OK`, `HEALTH_STATUS_DEGRADED | `streamEnd` | [HostStreamEnd](/reference/api/types/#hoststreamend) | Why the host's last command stream ended, while it is not connected; UNSPECIFIED while it is connected, and where this control plane has not seen one end. stream_end_detail is the error the stream ended with, in its own words. | | `streamEndDetail` | string | | | `hostname` | string | hostname is the name the host's machine goes by, as it last registered it: how a person tells one host from another where its id says nothing. Empty for a host that has not registered since it was made. | +| `removal` | [HostRemoval](/reference/api/types/#hostremoval) | removal is how this host leaves the fleet, decided by where it came from: the only removal the API takes for it, so the dashboard offers that one and no other. | +| `removalRefused` | string | removal_refused is why that removal cannot run now - a workspace whose disk is there - in words an administrator acts on; empty while it can. | ## HostCheck @@ -495,6 +515,12 @@ HostPolicy is what an installation decides about one host. An unset field is the | `maxWorkspaceIoMbPerSecond` | integer or null (int32) | What one machine may read and write per second here, in MiB and in operations, for the machines it starts afterwards. Unset is no bound. | | `maxWorkspaceIoOpsPerSecond` | integer or null (int32) | | +## HostRemoval + +HostRemoval is how a host leaves the fleet. - `HOST_REMOVAL_REVOKE`: A host registered with a token, or a machine of a cloud no group of this installation sizes: RevokeRunner. Nothing else can take its machine away. - `HOST_REMOVAL_GIVE_BACK`: A machine of an autoscaling group, connected: RemoveHost gives it back to its group, which terminates it and is asked for one less. Revoking it would leave the machine running and paid for, in a group that counts it. - `HOST_REMOVAL_FORGET`: A machine of an autoscaling group, not connected: RemoveHost gives back a machine the group still has, and forgets the host now rather than once it has been silent for host_forget_after_hours. + +One of: `HOST_REMOVAL_UNSPECIFIED`, `HOST_REMOVAL_REVOKE`, `HOST_REMOVAL_GIVE_BACK`, `HOST_REMOVAL_FORGET`. + ## HostShell | Field | Type | What it is | @@ -584,7 +610,6 @@ InstallationSettings contains global settings for the Spin installation | `telemetryTracesSlowMs` | integer (int32) | | | `telemetryMetricsDrop` | list of string | The metrics that are not kept, by name; a pattern may begin or end with \*. | | `telemetryPerVolumeHistograms` | list of string | Read only: the metrics that cost most to keep, a histogram per volume, which a surface may offer to drop as one. | -| `vscodeFetch` | boolean | Whether the control plane fetches VS Code servers from Microsoft on its own: the release it pins, at start, the newest stable release, looked for daily, and the server of a client's commit the installation has not released. False, it fetches none, and a workspace is given a server an administrator published; no image carries one. | | `workspaceTrashDays` | integer (int32) | How many days a deleted workspace stays in the trash, whole, for its owner to undelete before it is erased: 0 is no trash, and 7 is what an installation that says nothing keeps. | | `identityAudiences` | list of string | Who a workspace's identity token may be for; empty is anybody. What the installation's issuer gives, not who trusts it: a relying party still decides which subjects it admits. | | `volumeRpoSeconds` | integer (int32) | How far behind the object store a workspace's volume may fall, in seconds, where its preset does not say: what it commits on (v6 §11). 0 is none - it commits on its size and its snapshots alone - and 300 is what an installation that says nothing keeps. | @@ -594,7 +619,6 @@ InstallationSettings contains global settings for the Spin installation | `workspaceMaxRunningMinutes` | integer (int32) | How many minutes a workspace may run at a stretch, used or not, before it is suspended the same way: a process that keeps its cores busy is use to the rule above, and this is what ends it. Counted from its machine's start, which a resume is too. 0 caps none; 720 is what an installation that says nothing keeps, and a week is the most. | | `workspaceLeaseMaxMinutes` | integer (int32) | How many minutes a process may keep its workspace awake at a stretch (a lease: `spin-supervisor keep -- <cmd>`, a .spin.yaml task with keep_awake). While a lease is held and within this of its start, nobody is asked, nothing idle is suspended, and the running cap waits for the lease's end. 0 honours no lease; 480 is what an installation that says nothing keeps, and a week is the most. | | `teamSecretsRole` | string | The IAM role a team's secret kept in Secrets Manager or Parameter Store is read under, in a session tagged spin-team-id with the team: its policy lets that session read only what carries the same tag. Empty, no secret is kept as a reference. | -| `agentsFetch` | boolean | Whether the control plane fetches the agents' programs - Claude Code, Codex and T3 Code - from their publishers on its own: the triple it pins, at start, and the newest release of each, looked for daily. False, it fetches none, and a workspace is given a triple an operator published; no image carries one. | | `projectCreation` | string | Who makes projects (ProjectService.CreateProject): "everyone" signed in, or only the instance's "admins". Empty is everyone. | | `autoscalingIdleMinutes` | integer (int32) | How the runner fleet is sized (GetFleet): the minutes it may be idle before it is emptied, above zero; the quiet hours, HH:MM-HH:MM in the IANA time zone, when it is emptied at once, empty for none; and the most hosts it is asked for, under the group's own maximum - zero is that maximum. Each takes effect at the autoscaler's next pass. | | `autoscalingQuietHours` | string | | @@ -614,6 +638,9 @@ InstallationSettings contains global settings for the Spin installation | `nextRunAt` | `Timestamp` | When the schedule next starts it. | | `lastRun` | [JobRun](/reference/api/types/#jobrun) | Unset until it has run on this installation. | | `lastSucceededAt` | `Timestamp` | | +| `title` | string | The job as a person names it: "Storage collection" for storage-gc. | +| `purpose` | string | One sentence of what it does and what stays undone while it fails. | +| `recentRuns` | list of [JobRun](/reference/api/types/#jobrun) | Its newest runs, newest first, at most twenty: what a list of jobs shows each one's recent outcomes and durations from, without asking for every job's runs. Each has its id, start, end and outcome only; ListJobRuns has the rest. | ## JobRun @@ -747,6 +774,51 @@ NetworkUsagePoint is what the machine's network carried over a step. | `sentBytes` | string (int64) | | | `receivedBytes` | string (int64) | | +## Notification + +Notification is one event of a workspace's timeline its owner is told of: what happened, and what they can do about it. + +| Field | Type | What it is | +|---|---|---| +| `id` | string | The workspace event's id. | +| `workspaceId` | string | | +| `workspaceName` | string | | +| `event` | [WorkspaceEventType](/reference/api/types/#workspaceeventtype) | | +| `createdAt` | `Timestamp` | | +| `subject` | string | One line saying what happened. | +| `body` | string | What happened, in full. | +| `command` | string | The command that does what the owner can do about it; empty where nothing is to be done. | +| `deliveries` | list of [NotificationDelivery](/reference/api/types/#notificationdelivery) | Empty where it was never sent: email off, or this kind turned off. | + +## NotificationChannel + +How a notification leaves the installation. + +One of: `NOTIFICATION_CHANNEL_UNSPECIFIED`, `NOTIFICATION_CHANNEL_EMAIL`. + +## NotificationDelivery + +| Field | Type | What it is | +|---|---|---| +| `channel` | [NotificationChannel](/reference/api/types/#notificationchannel) | | +| `state` | [NotificationDeliveryState](/reference/api/types/#notificationdeliverystate) | | +| `attempts` | integer (int32) | | +| `lastError` | string | What the last attempt that failed was told; empty once one succeeded. | +| `sentAt` | `Timestamp` | | + +## NotificationDeliveryState + +Where one notification's delivery on one channel is. - `NOTIFICATION_DELIVERY_STATE_PENDING`: Not sent yet, or tried and to be tried again - `NOTIFICATION_DELIVERY_STATE_SENT`: The channel accepted it - `NOTIFICATION_DELIVERY_STATE_FAILED`: Every attempt failed; it is not tried again + +One of: `NOTIFICATION_DELIVERY_STATE_UNSPECIFIED`, `NOTIFICATION_DELIVERY_STATE_PENDING`, `NOTIFICATION_DELIVERY_STATE_SENT`, `NOTIFICATION_DELIVERY_STATE_FAILED`. + +## NotificationPreference + +| Field | Type | What it is | +|---|---|---| +| `event` | [WorkspaceEventType](/reference/api/types/#workspaceeventtype) | | +| `email` | boolean | | + ## ObservedDestination ObservedDestination is one address the workspace was allowed to reach, with what the host's ruleset counted and the name its resolver answered with that address, where it holds one. @@ -865,11 +937,23 @@ A prebuild: one build of a project's ref at a commit, and the snapshot it left. | `parentId` | string | The prebuild it was built on, and how many builds it is from the image (0: built from it). | | `depth` | integer (int32) | | | `image` | string | | -| `log` | string | The tail of what its build said, and why it failed. | +| `log` | string | The tail of what its build's create tasks wrote (GetPrebuild only), and why it failed. | | `error` | string | | | `createdAt` | `Timestamp` | | | `builtAt` | `Timestamp` | | | `workspaceCount` | integer (int32) | In ListPrebuilds: the workspaces opened from it that are not deleted, whoever's they are. | +| `reportedAt` | `Timestamp` | When its build's guest said the checkout and create tasks were done; unset before it did. | +| `spinYaml` | boolean | Whether the checkout had a .spin.yaml at its root, as the guest reported: without one the build is the clone alone, with no create tasks run. Read only with reported_at. | +| `storedBytes` | string or null (int64) | What it keeps in the object store, as storage-gc last read it; unset before a reading counted it. | + +## PrebuildRefNotFound + +A prebuild ref the project's forge has not. + +| Field | Type | What it is | +|---|---|---| +| `ref` | string | | +| `since` | `Timestamp` | The job's first look that found it missing. | ## PrebuildState @@ -910,6 +994,32 @@ A project: a repository and the shape of the workspace that opens it. | `sharedUserIds` | list of string | | | `sharedTeamIds` | list of string | | | `readyPrebuildCount` | integer (int32) | In ListProjects: how many of its prebuilds are ready to open from. | +| `prebuildKeep` | integer (int32) | How many of each ref's newest ready prebuilds are kept when no workspace was opened from them. | +| `timeToReady` | [ProjectTimeToReady](/reference/api/types/#projecttimetoready) | In GetProject: how long its workspaces took to be ready. Unset where none has been. | + +## ProjectTimeToReady + +How long a project's workspaces took from their create to their project being ready in them - the repository checked out and its create tasks done, as each one's guest first said it, the wait for a host and the boot included - over the last 20 that got there. One that never did - it failed, or was deleted first - is not counted, and neither is one opened from a prebuild: this is what opening without one costs. A workspace whose first boots failed its project counts from its create to the boot that went. + +| Field | Type | What it is | +|---|---|---| +| `workspaces` | integer (int32) | How many workspaces the times are over: 1 to 20. | +| `median` | `Duration` | | +| `slowest` | `Duration` | | + +## ProjectWorkspace + +A workspace open on a project, as the project's admins read it: whose it is and how it is, and nothing that lets them into it. + +| Field | Type | What it is | +|---|---|---| +| `id` | string | | +| `name` | string | | +| `ownerId` | string | | +| `ownerName` | string | | +| `ownerEmail` | string | | +| `state` | [WorkspaceState](/reference/api/types/#workspacestate) | As Workspace.state, DEGRADED included. | +| `since` | `Timestamp` | Since when it has been in that state: when its guest answered for a running one, and when its row last changed for any other. | ## QuarantineDenial @@ -1001,6 +1111,7 @@ ResourcePreset is a class of workspace: its size, and how a workspace of it may | `rpoSeconds` | integer (int32) | How far behind the object store a workspace of it may fall, in seconds; 0 is the installation's (InstallationSettings.volume_rpo_seconds). | | `hostClass` | string | The host class its workspaces run on (HostClass). | | `agentMinMemoryMb` | integer (int32) | What a workspace has to hold for its agent to start there, in MB, for whoever picks a preset. | +| `fromConfig` | boolean | Seeded or applied from the installation's config file (the release's presets where it names none); false is one an administrator added. An edit since does not change it. | ## Resources @@ -1015,6 +1126,28 @@ Resource allocation for workspaces. Initial values (cpu_cores, memory_mb) are us | `maxMemoryMb` | integer (int32) | Max memory in MB (0 = unlimited) | | `bandwidthMbps` | integer (int32) | What a workspace's network carries each way, in megabits a second (0 = unshaped): its preset's, held on its host by a token bucket on each way out of its machine's namespace. Its vsock - ssh, the editor, forwarded ports - is not shaped. | +## Runbook + +| Field | Type | What it is | +|---|---|---| +| `id` | string | Stable: alert rules and pages link /admin/runbooks/<id>. | +| `title` | string | | +| `severity` | string | critical, warning or info. | +| `owner` | string | The role that keeps it true: operator, security. | +| `lastReviewed` | string | YYYY-MM-DD: when it was last held to the release it describes. | +| `appliesTo` | [RunbookAppliesTo](/reference/api/types/#runbookappliesto) | | + +## RunbookAppliesTo + +What sends an operator to a runbook, each as the installation names it. + +| Field | Type | What it is | +|---|---|---| +| `alerts` | list of string | Grafana alert rule uids. | +| `jobs` | list of string | Control plane job names (Job.name). | +| `events` | list of string | The notices a workspace's owner gets, by WorkspaceEventType without its prefix: HELD. | +| `dashboards` | list of string | Grafana dashboard uids. | + ## SSHKey User's uploaded SSH public key @@ -1071,6 +1204,12 @@ ServiceHealth is one service over a window: the traces begun in it - what it was | `traces` | string (int64) | | | `failedTraces` | string (int64) | | +## SettingReach + +SettingReach is what a saved installation setting touches, and when: each setting declares one beside its key (internal/controlplane/settings), so the screen that edits it can say so before the save. - `SETTING_REACH_RUNNING_WORKSPACES`: The workspaces running now, at the control plane's next look at them. - `SETTING_REACH_NEW_WORKSPACES`: Workspaces created from now on; those that exist keep what they were made with. - `SETTING_REACH_NEXT_HEARTBEAT`: Each runner at its next heartbeat, and the workspaces running on it. - `SETTING_REACH_NEXT_REQUEST`: What is asked from now on - a project made, a shell opened, a workspace deleted; what was done before keeps the terms it was done under. - `SETTING_REACH_NEXT_PASS`: The next pass of the job that applies it: the autoscaler, the prebuilds' retirement, the collector's read of its policy, the daily look for a release. + +One of: `SETTING_REACH_UNSPECIFIED`, `SETTING_REACH_RUNNING_WORKSPACES`, `SETTING_REACH_NEW_WORKSPACES`, `SETTING_REACH_NEXT_HEARTBEAT`, `SETTING_REACH_NEXT_REQUEST`, `SETTING_REACH_NEXT_PASS`. + ## Snapshot A snapshot is a rotation of a workspace's volume, published as a commit. It has no name outside its id. @@ -1241,6 +1380,7 @@ What the supervisor inside the guest last reported. Absent (`connected` false wi | `roleCelExpression` | string | CEL expression for role assignment | | `enabled` | boolean | | | `createdAt` | `Timestamp` | | +| `refusedRemoval` | string | Why disabling or deleting it would be refused; empty where it would not be. An installation provider that the only administrators who can sign in sign in through (lockout). | ## TeamMember @@ -1276,6 +1416,44 @@ TelemetryFlow is what one exporter of the collector did over the last window. | `sent` | string (int64) | | | `failed` | string (int64) | | +## ThirdPartyAcceptance + +ThirdPartyAcceptance is an administrator's acceptance of an item's terms. + +| Field | Type | What it is | +|---|---|---| +| `termsVersion` | string | The version of the text that was accepted; an older one than the response's counts as none. | +| `acceptedBy` | string | Who accepted, by email: kept as it was when they did. | +| `acceptedAt` | `Timestamp` | | + +## ThirdPartyItem + +ThirdPartyItem is what an administrator accepts the terms of, one download at a time: the software the control plane fetches together, as one extension. - `THIRD_PARTY_ITEM_VSCODE_SERVER`: Microsoft's VS Code server and its CLI: the vsc-<commit> extensions. - `THIRD_PARTY_ITEM_AGENT_CLIS`: Claude Code, Codex, T3 Code and the libatomic T3 Code's server is linked against: the agents extension. + +One of: `THIRD_PARTY_ITEM_UNSPECIFIED`, `THIRD_PARTY_ITEM_VSCODE_SERVER`, `THIRD_PARTY_ITEM_AGENT_CLIS`. + +## ThirdPartyPart + +ThirdPartyPart is one program an item downloads, and the license it comes under. + +| Field | Type | What it is | +|---|---|---| +| `name` | string | | +| `maker` | string | Who makes it and serves the download. | +| `license` | string | | +| `licenseUrl` | string | | + +## ThirdPartyTermsItem + +| Field | Type | What it is | +|---|---|---| +| `item` | [ThirdPartyItem](/reference/api/types/#thirdpartyitem) | | +| `name` | string | | +| `purpose` | string | What a workspace gets from it. | +| `parts` | list of [ThirdPartyPart](/reference/api/types/#thirdpartypart) | | +| `acceptance` | [ThirdPartyAcceptance](/reference/api/types/#thirdpartyacceptance) | Unset where nobody accepted the terms for it. | +| `accepted` | boolean | Whether this installation downloads it: accepted, as the current text. | + ## User | Field | Type | What it is | @@ -1394,6 +1572,7 @@ VolumeRekey is a workspace's disk to re-key or being re-keyed. | `projectReportedAt` | `Timestamp` | project_reported_at is when its guest said how its project went in this run, unset until it has: an empty project_error before then is a clone still going, not one that went. project_head is the commit it checked out, as the guest said it; empty when it did not say one. | | `projectHead` | string | | | `hostName` | string | host_name is the name host_id's machine registered, for a person to tell hosts apart; empty with no host, or one that registered none. Answered by GetWorkspace and ListWorkspaces, so a list row says where each runs without a status read per row; never placed or trusted by. | +| `withoutPrebuild` | string | without_prebuild is why a workspace opening a project at a ref it prebuilds started from none of its prebuilds, and cloned the repository at its first boot: none ready, the ready one of another image, its disk not cloneable yet. Empty with from_prebuild_id set, or for a project that prebuilds nothing. | ## WorkspaceAction @@ -1458,9 +1637,9 @@ Timeline event for workspace state changes ## WorkspaceEventType -- `WORKSPACE_EVENT_TYPE_CREATED`: Workspace was created - `WORKSPACE_EVENT_TYPE_STARTED`: Workspace was started - `WORKSPACE_EVENT_TYPE_STOPPED`: Workspace was stopped; its disk is kept, and no snapshot is taken - `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`: Manual snapshot - `WORKSPACE_EVENT_TYPE_DELETED`: Workspace was deleted - `WORKSPACE_EVENT_TYPE_FAILED`: Workspace start failed - `WORKSPACE_EVENT_TYPE_RESTORED`: Its disk was put back to a snapshot - `WORKSPACE_EVENT_TYPE_RESUMED`: It went on from a snapshot's memory - `WORKSPACE_EVENT_TYPE_BOOTED`: Suspended, its memory could not be resumed, and its disk was booted - `WORKSPACE_EVENT_TYPE_QUARANTINED`: An administrator held it: stopped, and startable by nobody until released - `WORKSPACE_EVENT_TYPE_UNQUARANTINED`: The hold was released: back to stopped, where it was held from - `WORKSPACE_EVENT_TYPE_PLACED`: A workspace that waited for a host was given one, and its disk there - `WORKSPACE_EVENT_TYPE_TRASHED`: Deleted into the trash: its disk kept, its owner able to undelete it - `WORKSPACE_EVENT_TYPE_UNDELETED`: Taken back out of the trash - `WORKSPACE_EVENT_TYPE_MOVED`: Suspended on its host and resumed on another, which had room for what it was granted - `WORKSPACE_EVENT_TYPE_DISPLACED`: Its host was drained or went away: suspended there, it is resumed on another on its own - `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`: A stop on a host that can be taken away could not publish its disk first, so it runs on - `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`: Nobody used it for as long as the installation allows: suspended with its processes, a start resumes them - `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`: It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them - `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`: A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it - `WORKSPACE_EVENT_TYPE_KEPT`: Somebody kept it awake until a time: no suspension before it - `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`: Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back +- `WORKSPACE_EVENT_TYPE_CREATED`: Workspace was created - `WORKSPACE_EVENT_TYPE_STARTED`: Workspace was started - `WORKSPACE_EVENT_TYPE_STOPPED`: Workspace was stopped; its disk is kept, and no snapshot is taken - `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`: Manual snapshot - `WORKSPACE_EVENT_TYPE_DELETED`: Workspace was deleted - `WORKSPACE_EVENT_TYPE_FAILED`: Workspace start failed - `WORKSPACE_EVENT_TYPE_RESTORED`: Its disk was put back to a snapshot - `WORKSPACE_EVENT_TYPE_RESUMED`: It went on from a snapshot's memory - `WORKSPACE_EVENT_TYPE_BOOTED`: Suspended, its memory could not be resumed, and its disk was booted - `WORKSPACE_EVENT_TYPE_QUARANTINED`: An administrator held it: stopped, and startable by nobody until released - `WORKSPACE_EVENT_TYPE_UNQUARANTINED`: The hold was released: back to stopped, where it was held from - `WORKSPACE_EVENT_TYPE_PLACED`: A workspace that waited for a host was given one, and its disk there - `WORKSPACE_EVENT_TYPE_TRASHED`: Deleted into the trash: its disk kept, its owner able to undelete it - `WORKSPACE_EVENT_TYPE_UNDELETED`: Taken back out of the trash - `WORKSPACE_EVENT_TYPE_MOVED`: Suspended on its host and resumed on another, which had room for what it was granted - `WORKSPACE_EVENT_TYPE_DISPLACED`: Its host was drained or went away: suspended there, it is resumed on another on its own - `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`: A stop on a host that can be taken away could not publish its disk first, so it runs on - `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`: Nobody used it for as long as the installation allows: suspended with its processes, a start resumes them - `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`: It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them - `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`: A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it - `WORKSPACE_EVENT_TYPE_KEPT`: Somebody kept it awake until a time: no suspension before it - `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`: Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back - `WORKSPACE_EVENT_TYPE_REHOMED`: Its host stopped answering and it was moved to another on its own, giving up what that host had not published - `WORKSPACE_EVENT_TYPE_HELD`: Its host stopped answering and moving it would give up more than the installation does on its own: it waits for its owner -One of: `WORKSPACE_EVENT_TYPE_UNSPECIFIED`, `WORKSPACE_EVENT_TYPE_CREATED`, `WORKSPACE_EVENT_TYPE_STARTED`, `WORKSPACE_EVENT_TYPE_STOPPED`, `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`, `WORKSPACE_EVENT_TYPE_DELETED`, `WORKSPACE_EVENT_TYPE_FAILED`, `WORKSPACE_EVENT_TYPE_RESTORED`, `WORKSPACE_EVENT_TYPE_RESUMED`, `WORKSPACE_EVENT_TYPE_BOOTED`, `WORKSPACE_EVENT_TYPE_QUARANTINED`, `WORKSPACE_EVENT_TYPE_UNQUARANTINED`, `WORKSPACE_EVENT_TYPE_PLACED`, `WORKSPACE_EVENT_TYPE_TRASHED`, `WORKSPACE_EVENT_TYPE_UNDELETED`, `WORKSPACE_EVENT_TYPE_MOVED`, `WORKSPACE_EVENT_TYPE_DISPLACED`, `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`, `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`, `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`, `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`, `WORKSPACE_EVENT_TYPE_KEPT`, `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`. +One of: `WORKSPACE_EVENT_TYPE_UNSPECIFIED`, `WORKSPACE_EVENT_TYPE_CREATED`, `WORKSPACE_EVENT_TYPE_STARTED`, `WORKSPACE_EVENT_TYPE_STOPPED`, `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`, `WORKSPACE_EVENT_TYPE_DELETED`, `WORKSPACE_EVENT_TYPE_FAILED`, `WORKSPACE_EVENT_TYPE_RESTORED`, `WORKSPACE_EVENT_TYPE_RESUMED`, `WORKSPACE_EVENT_TYPE_BOOTED`, `WORKSPACE_EVENT_TYPE_QUARANTINED`, `WORKSPACE_EVENT_TYPE_UNQUARANTINED`, `WORKSPACE_EVENT_TYPE_PLACED`, `WORKSPACE_EVENT_TYPE_TRASHED`, `WORKSPACE_EVENT_TYPE_UNDELETED`, `WORKSPACE_EVENT_TYPE_MOVED`, `WORKSPACE_EVENT_TYPE_DISPLACED`, `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`, `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`, `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`, `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`, `WORKSPACE_EVENT_TYPE_KEPT`, `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`, `WORKSPACE_EVENT_TYPE_REHOMED`, `WORKSPACE_EVENT_TYPE_HELD`. ## WorkspaceFailure @@ -1518,6 +1697,7 @@ WorkspaceProgress is a transition under way. | `phase` | [WorkspacePhase](/reference/api/types/#workspacephase) | phase is what the host is doing now; UNSPECIFIED when it has not said. | | `since` | `Timestamp` | since is when the transition began, and deadline when the control plane gives up on it - a wait for a host, or a start or a stop the host does not finish - and fails the workspace. | | `deadline` | `Timestamp` | | +| `typical` | `Duration` | typical is how long a start usually takes on the workspace's host class: the median, from the request to RUNNING (the same measure as since), of the newest starts that came up there. Unset for a transition that is not a start, and where too few have come up to say. Per step it is not: what a host says of its phases is kept only while one is under way. | ## WorkspaceProxyStatus diff --git a/src/content/docs/reference/api/workspaceservice.md b/src/content/docs/reference/api/workspaceservice.md index 4c25e17..b731f3e 100644 --- a/src/content/docs/reference/api/workspaceservice.md +++ b/src/content/docs/reference/api/workspaceservice.md @@ -4,7 +4,7 @@ description: "spin.v1.WorkspaceService: each procedure, its request and its resp source: "spin:internal/controlplane/apidocs/spin.v1.openapi.json" editUrl: false sidebar: - order: 13 + order: 11 --- @@ -31,7 +31,7 @@ No fields: `{}`. `POST /spin.v1.WorkspaceService/AttachVSCodeServer` -Give a running workspace the VS Code server of a client's commit, while it runs: published first when this installation has not got it and fetches servers on its own (InstallationSettings.vscode_fetch), refused as FAILED_PRECONDITION when it does not. Asked again until it answers attached. +Give a running workspace the VS Code server of a client's commit, while it runs: published first when this installation has not got it and an administrator accepted the VS Code server's terms (AdminService.AcceptThirdPartyTerms), refused as FAILED_PRECONDITION, saying so, when nobody did. Asked again until it answers attached. **Request** @@ -147,11 +147,11 @@ Create a new workspace | `name` | string | Optional, generated if empty | | `teamId` | string | Optional: team ID (personal workspace if empty) | | `image` | string | A published image (ListImages); required unless from_snapshot_id is set | -| `preset` | string | The preset it is sized by, by name (AdminService.ListResourcePresets): its cores, memory, disk and how it grows. Empty is the installation's default preset, or with none marked 1 core, 512 MB and 10 GB free. A disabled preset is refused. | +| `preset` | string | The preset it is sized by, by name (AdminService.ListResourcePresets): its cores, memory, disk and how it grows. Empty is the project's preset when project_id names one, otherwise the installation's default preset, or with none marked 1 core, 512 MB and 10 GB free. A disabled preset is refused. | | `env` | map of string to string | Environment variables | | `fromSnapshotId` | string | Create workspace from a shared snapshot | | `networkTags` | list of string | network_tags are the network policies this workspace runs under, by name - the same idea as a GCP instance's network tags. The host's ruleset names the tag and holds the set of machines carrying it, so this decides which rules apply without naming a rule. Empty runs the workspace under the installation's default, and under "offline" where it declares none: a create that names nothing reaches nothing, rather than everything. A tag the host has no policy for fails the start rather than being ignored: a workspace asking for a policy the node does not have is a question with two answers, and quietly choosing "run it without" is how one ends up less contained than whoever launched it believes. | -| `projectId` | string | A project the caller sees: the workspace is the project's - its image, preset and tags, which the request then names none of - in team_id, the caller's personal team when empty, and its guest clones the project's repository at ref, the project's own when empty. Refused while the repository is on a forge the installation connects to (ForgeService) and the caller has not connected their account there. | +| `projectId` | string | A project the caller sees: the workspace is the project's - its image and tags, which the request then names neither of, and its preset unless preset names another - in team_id, the caller's personal team when empty, and its guest clones the project's repository at ref, the project's own when empty. Refused while the repository is on a forge the installation connects to (ForgeService) and the caller has not connected their account there. | | `ref` | string | | | `requestId` | string | Optional, at most 128 bytes: the client's key for this create, so a retry after an answer it never got is answered with the workspace the first attempt made. The same key with another request is refused (FAILED_PRECONDITION). | | `agentVolumeId` | string | Optional: an agent's home of the caller's to mount (ListAgentVolumes), one no workspace mounts now - the history of a workspace since erased, found again in this one. Empty makes the workspace a new one. Refused while no host has room: a workspace that waits for a host gets its new home when it is placed, and mounts none it was named. | diff --git a/src/content/docs/reference/cli/admin.md b/src/content/docs/reference/cli/admin.md index 5cb6d2b..547886f 100644 --- a/src/content/docs/reference/cli/admin.md +++ b/src/content/docs/reference/cli/admin.md @@ -31,7 +31,7 @@ Available Commands: volume Re-key a workspace's disk Flags: - -h, --help help for admin + -h, --help[=true|false] help for admin Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -57,8 +57,8 @@ Available Commands: by What each workspace, team or owner cost this month, and what nobody did Flags: - -h, --help help for costs - --month string the month, as 2026-10 (default: this month) + -h, --help[=true|false] help for costs + --month string the month, as 2026-10 (default: this month) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -81,8 +81,8 @@ Usage: spin admin costs by [flags] Flags: - -h, --help help for by - --month string the month, as 2026-10 (default: this month) + -h, --help[=true|false] help for by + --month string the month, as 2026-10 (default: this month) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -103,7 +103,7 @@ Usage: spin admin health [flags] Flags: - -h, --help help for health + -h, --help[=true|false] help for health Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -126,7 +126,7 @@ Available Commands: run Run a job now rather than when it is next due Flags: - -h, --help help for jobs + -h, --help[=true|false] help for jobs Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -146,7 +146,7 @@ Usage: spin admin jobs list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -165,7 +165,7 @@ Usage: spin admin jobs run [flags] Flags: - -h, --help help for run + -h, --help[=true|false] help for run Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -190,9 +190,9 @@ Usage: spin admin logs [query] [flags] Flags: - -h, --help help for logs - --limit int32 how many records, newest first: 1 to 1000 (default 100) - --since duration how far back to look, at most 744h (31 days) (default 1h0m0s) + -h, --help[=true|false] help for logs + --limit int32 how many records, newest first: 1 to 1000 (default 100) + --since duration how far back to look, at most 744h (31 days) (default 1h0m0s) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -215,10 +215,11 @@ Available Commands: drain Stop a runner taking new workspaces, until it is activated list List all runners policy What a runner may do, as against what it is + remove Take a runner of an autoscaling group out of the fleet: give it back to its group, or forget it revoke Revoke a runner's access, for a machine that should never connect again Flags: - -h, --help help for runner + -h, --help[=true|false] help for runner Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -240,7 +241,7 @@ Usage: spin admin runner activate [flags] Flags: - -h, --help help for activate + -h, --help[=true|false] help for activate Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -266,9 +267,9 @@ Usage: spin admin runner drain [flags] Flags: - -h, --help help for drain - --leave-stopped With --suspend: leave them stopped until their owners start them (a drain that shrinks the fleet) - --suspend Suspend the runner's running workspaces so they resume elsewhere + -h, --help[=true|false] help for drain + --leave-stopped[=true|false] With --suspend: leave them stopped until their owners start them (a drain that shrinks the fleet) + --suspend[=true|false] Suspend the runner's running workspaces so they resume elsewhere Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -286,7 +287,7 @@ Usage: spin admin runner list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -315,13 +316,13 @@ Usage: Flags: --cpu-cores int32 cores this runner advertises; unset advertises what it has --disk-gb int32 disk this runner advertises; unset advertises what it has - -h, --help help for policy + -h, --help[=true|false] help for policy --max-workspace-cpu-cores int32 the cores one workspace may grow to there --max-workspace-io-mb-per-second int32 MiB one workspace may read, and write, a second there; unset is no bound --max-workspace-io-ops-per-second int32 I/O operations one workspace may read, and write, a second there; unset is no bound --max-workspace-memory-mb int32 the memory one workspace may grow to there --memory-mb int32 memory this runner advertises; unset advertises what it has - --preemptible a stop on this runner is the machine being taken away, not a restart + --preemptible[=true|false] a stop on this runner is the machine being taken away, not a restart --preemption-metadata-url string where that cloud's metadata service answers; empty is its own link-local address --preemption-source string the cloud that announces a reclaim: aws, gcp or azure (implies --preemptible) --shutdown-grace duration how long this runner stays up after a stop signal so its workspaces can be moved off it @@ -335,6 +336,34 @@ Global Flags: --traceparent string the W3C traceparent of the span this command is part of; its own span is sent to the installation unless the profile says telemetry: false ``` +#### spin admin runner remove + +``` +Take a runner that is a machine of an autoscaling group out of the fleet. + +A connected one is cordoned and given back to its group, which terminates the machine and is +asked for one less; it drains as it goes, and its row goes when it has. One that is not connected +is given back if its group still has its machine, and forgotten now, without waiting out +host_forget_after_hours. + +A runner that is the only home of a workspace's disk is refused, naming them: stop them, which +publishes each disk, or move them first. A runner registered with a token is revoked instead +(spin admin runner revoke). + +Usage: + spin admin runner remove [flags] + +Flags: + -h, --help[=true|false] help for remove + -y, --yes[=true|false] Skip confirmation + +Global Flags: + --config string config file (default is $HOME/.spin/config.yaml) + -o, --output string text for a person, or json: one document of what the API answered, and no prose (default "text") + --profile string named profile to use; SPIN_PROFILE names it when this flag does not (default "default") + --traceparent string the W3C traceparent of the span this command is part of; its own span is sent to the installation unless the profile says telemetry: false +``` + #### spin admin runner revoke ``` @@ -353,9 +382,9 @@ Usage: spin admin runner revoke [flags] Flags: - -h, --help help for revoke - --leave-workspaces revoke although workspaces are on this host; each runs again only once recovered elsewhere - -y, --yes Skip confirmation + -h, --help[=true|false] help for revoke + --leave-workspaces[=true|false] revoke although workspaces are on this host; each runs again only once recovered elsewhere + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -389,7 +418,7 @@ Available Commands: recording What a root shell's sessions recorded, asciicast v2, each session's in turn Flags: - -h, --help help for shell + -h, --help[=true|false] help for shell Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -409,7 +438,7 @@ Usage: spin admin shell approve [flags] Flags: - -h, --help help for approve + -h, --help[=true|false] help for approve Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -427,7 +456,7 @@ Usage: spin admin shell close [flags] Flags: - -h, --help help for close + -h, --help[=true|false] help for close Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -445,7 +474,7 @@ Usage: spin admin shell list [runner-id] [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -470,10 +499,10 @@ Usage: spin admin shell open [flags] Flags: - -h, --help help for open - --incident Open on the runner as it is, its workspaces running, without emptying it first - --minutes int32 How long the shell is open once it opens, up to the installation's host_shell_max_minutes (default 30) - --reason string Why: said to whoever approves it, and kept + -h, --help[=true|false] help for open + --incident[=true|false] Open on the runner as it is, its workspaces running, without emptying it first + --minutes int32 How long the shell is open once it opens, up to the installation's host_shell_max_minutes (default 30) + --reason string Why: said to whoever approves it, and kept Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -493,7 +522,7 @@ Usage: spin admin shell recording [flags] Flags: - -h, --help help for recording + -h, --help[=true|false] help for recording Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -518,7 +547,7 @@ Available Commands: untag-image Take a ref off the image it names Flags: - -h, --help help for storage + -h, --help[=true|false] help for storage Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -540,7 +569,7 @@ Usage: spin admin storage explain [flags] Flags: - -h, --help help for explain + -h, --help[=true|false] help for explain Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -559,7 +588,7 @@ Usage: spin admin storage list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -581,8 +610,8 @@ Usage: spin admin storage remove [flags] Flags: - -h, --help help for remove - -y, --yes Skip confirmation + -h, --help[=true|false] help for remove + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -602,7 +631,7 @@ Usage: spin admin storage untag-image [flags] Flags: - -h, --help help for untag-image + -h, --help[=true|false] help for untag-image Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -626,7 +655,7 @@ Available Commands: revoke Revoke a registration token Flags: - -h, --help help for token + -h, --help[=true|false] help for token Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -667,16 +696,16 @@ Flags: --description string Description for the token --disk-gb int32 disk each host it registers advertises; unset advertises what it has --expires duration how long the token registers hosts; unset is the control plane's 24 hours, and at most 30 days - -h, --help help for create + -h, --help[=true|false] help for create --max-workspace-cpu-cores int32 the cores one workspace may grow to there --max-workspace-io-mb-per-second int32 MiB one workspace may read, and write, a second there; unset is no bound --max-workspace-io-ops-per-second int32 I/O operations one workspace may read, and write, a second there; unset is no bound --max-workspace-memory-mb int32 the memory one workspace may grow to there --memory-mb int32 memory each host it registers advertises; unset advertises what it has - --preemptible a stop on each host it registers is the machine being taken away, not a restart + --preemptible[=true|false] a stop on each host it registers is the machine being taken away, not a restart --preemption-metadata-url string where that cloud's metadata service answers; empty is its own link-local address --preemption-source string the cloud that announces a reclaim: aws, gcp or azure (implies --preemptible) - --reusable a pool's token: it registers every host that presents it until it expires + --reusable[=true|false] a pool's token: it registers every host that presents it until it expires --shutdown-grace duration how long each host it registers stays up after a stop signal so its workspaces can be moved off it --team string The team to scope the runner to, by id, path or me --writeback-background-bytes int dirty page cache at which each host it registers starts writing back (vm.dirty_background_bytes), below the limit @@ -698,8 +727,8 @@ Usage: spin admin token list [flags] Flags: - -h, --help help for list - --include-used Include already-used tokens + -h, --help[=true|false] help for list + --include-used[=true|false] Include already-used tokens Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -717,7 +746,7 @@ Usage: spin admin token revoke [flags] Flags: - -h, --help help for revoke + -h, --help[=true|false] help for revoke Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -735,7 +764,7 @@ Usage: spin admin versions [flags] Flags: - -h, --help help for versions + -h, --help[=true|false] help for versions Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -758,7 +787,7 @@ Available Commands: rekeys The disks being re-keyed, and the ones a revoked host's keys marked for it Flags: - -h, --help help for volume + -h, --help[=true|false] help for volume Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -776,14 +805,15 @@ Copy a workspace's disk, whole, under a key of its own, point the workspace at t delete the disk - which destroys the key it was under, and every snapshot of the disk with it: those are what that key opens. What to do when the key is assumed taken, by a host that held it. -The workspace must be stopped or quarantined. A disk something was cloned from is refused. +The workspace is anybody's, named by its id. It must be stopped or quarantined. A disk something +was cloned from is refused. Usage: - spin admin volume rekey [flags] + spin admin volume rekey [flags] Flags: - -h, --help help for rekey - -y, --yes Skip confirmation + -h, --help[=true|false] help for rekey + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -801,7 +831,7 @@ Usage: spin admin volume rekeys [flags] Flags: - -h, --help help for rekeys + -h, --help[=true|false] help for rekeys Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/agent.md b/src/content/docs/reference/cli/agent.md index e01a63c..48f58a0 100644 --- a/src/content/docs/reference/cli/agent.md +++ b/src/content/docs/reference/cli/agent.md @@ -39,11 +39,11 @@ Available Commands: home The agent's homes: volumes that outlive their workspaces Flags: - -h, --help help for agent - -i, --identity string Identity file (private key) - --port int The port on this computer the session forwards T3 Code to (default 3773) - --start Start the workspace first if it is stopped - --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it + -h, --help[=true|false] help for agent + -i, --identity string Identity file (private key) + --port int The port on this computer the session forwards T3 Code to (default 3773) + --start[=true|false] Start the workspace first if it is stopped + --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -71,7 +71,7 @@ Available Commands: list Your agent homes, and which workspace mounts each Flags: - -h, --help help for home + -h, --help[=true|false] help for home Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -91,7 +91,7 @@ Usage: spin agent home delete [flags] Flags: - -h, --help help for delete + -h, --help[=true|false] help for delete Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -109,7 +109,7 @@ Usage: spin agent home list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/api-key.md b/src/content/docs/reference/cli/api-key.md index 918c2be..509dcff 100644 --- a/src/content/docs/reference/cli/api-key.md +++ b/src/content/docs/reference/cli/api-key.md @@ -26,7 +26,7 @@ Available Commands: revoke Revoke an API key Flags: - -h, --help help for api-key + -h, --help[=true|false] help for api-key Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -70,7 +70,7 @@ Usage: Flags: --expires string How long the key lasts, at most a year: a whole number of d, w or y (30d, 2w, 1y), or a duration like 36h (default "90d") - -h, --help help for create + -h, --help[=true|false] help for create --max-cores int32 How many cores their workspaces may hold at once --max-workspaces int32 How many workspaces the key and the keys it delegates may hold at once --project strings A project whose workspaces the key reaches, by id (can be repeated; default: any) @@ -93,7 +93,7 @@ Usage: spin api-key list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -111,8 +111,8 @@ Usage: spin api-key revoke [flags] Flags: - -h, --help help for revoke - -y, --yes Skip confirmation + -h, --help[=true|false] help for revoke + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/code.md b/src/content/docs/reference/cli/code.md index faaed3f..8410854 100644 --- a/src/content/docs/reference/cli/code.md +++ b/src/content/docs/reference/cli/code.md @@ -19,20 +19,24 @@ runs), through whichever the editor has of Microsoft's Remote-SSH extension on Open VSX). --editor names the editor's command when it is not 'code'. With Remote-SSH, before VS Code connects, the workspace is asked whether it has the server for -your VS Code. When it has not, it is given it while it runs - published first if this installation -has not got that version, which takes minutes once and is said as it goes. Where that cannot -be done, VS Code downloads its own server into the workspace (about 220 MB), which this says. +your VS Code. When it has not, it is given it while it runs - prepared first if this installation +has not got that version, once for the whole installation, which this waits for and says as it +goes. Where that cannot be done - nobody accepted the server's terms in Admin → Extensions, or +the publish failed - VS Code downloads its own server into the workspace's temporary directory +(about 220 MB), which this says - or, where that directory has no room for it, refuses with what +resolves it, rather than leave VS Code to fail the download and reconnect without end. With Open Remote - SSH, the editor downloads and runs its own server in the workspace, as that extension is set up to; spin writes the SSH config and opens the folder, and nothing more. Spin installs and configures neither extension. The server an installation -publishes is Microsoft's, licensed for internal use only: one that sells workspaces to others -leaves VS Code to download its own. +publishes is Microsoft's, licensed for an organization's own use. An editor that runs spin itself - the Spinbox extension - names its own commit with --vscode-commit and --no-open: no local 'code' is looked for, the workspace is given that -commit's server as above, the SSH config is written, and nothing is opened. +commit's server as above, the SSH config is written, and nothing is opened. With -o json the +answer is JSON Lines: a {"preparing": {...}} line for each step of a server being prepared, then +the result, whose not_given says why the workspace was not given one. Examples: spin code my-workspace @@ -44,10 +48,10 @@ Usage: Flags: --editor string The editor's command, one with Remote-SSH or Open Remote - SSH installed (default "code") - -h, --help help for code + -h, --help[=true|false] help for code -i, --identity string Identity file (private key); default: the first key this machine holds that your keyring lists - --no-open Write the SSH config and give the workspace the server, and open nothing; needs --vscode-commit - --start Start the workspace first if it is stopped + --no-open[=true|false] Write the SSH config and give the workspace the server, and open nothing; needs --vscode-commit + --start[=true|false] Start the workspace first if it is stopped --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it --vscode-commit string The commit of the VS Code that will connect, instead of asking a local 'code'; needs --no-open --vscode-version string The version of that VS Code, which is only said; needs --vscode-commit diff --git a/src/content/docs/reference/cli/cp.md b/src/content/docs/reference/cli/cp.md index 34a5f50..122263f 100644 --- a/src/content/docs/reference/cli/cp.md +++ b/src/content/docs/reference/cli/cp.md @@ -24,11 +24,11 @@ Usage: spin cp [flags] Flags: - -h, --help help for cp - -i, --identity string Identity file (private key) - --start Start the workspace first if it is stopped - --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it - -u, --user string User to copy as (default "root") + -h, --help[=true|false] help for cp + -i, --identity string Identity file (private key) + --start[=true|false] Start the workspace first if it is stopped + --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it + -u, --user string User to copy as (default "root") Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/exec.md b/src/content/docs/reference/cli/exec.md index 7d0336a..62ef498 100644 --- a/src/content/docs/reference/cli/exec.md +++ b/src/content/docs/reference/cli/exec.md @@ -37,16 +37,16 @@ Usage: spin exec -- [args...] [flags] Flags: - --attach string Print a detached run's output until it ends, and exit with its status - -d, --detach Start the command, print its run id and leave it running - -h, --help help for exec - -i, --identity string Identity file (private key) - --no-tty Do not allocate a terminal - --start Start the workspace first if it is stopped - --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it - -t, --tty Allocate a terminal even if this one is not - -u, --user string User to run the command as (default "root") - -w, --workdir string Directory to run the command in + --attach string Print a detached run's output until it ends, and exit with its status + -d, --detach[=true|false] Start the command, print its run id and leave it running + -h, --help[=true|false] help for exec + -i, --identity string Identity file (private key) + --no-tty[=true|false] Do not allocate a terminal + --start[=true|false] Start the workspace first if it is stopped + --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it + -t, --tty[=true|false] Allocate a terminal even if this one is not + -u, --user string User to run the command as (default "root") + -w, --workdir string Directory to run the command in Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/git.md b/src/content/docs/reference/cli/git.md index 05a452d..76bf949 100644 --- a/src/content/docs/reference/cli/git.md +++ b/src/content/docs/reference/cli/git.md @@ -29,7 +29,7 @@ Available Commands: repos List the repositories your account reaches, or those whose name has query in it Flags: - -h, --help help for git + -h, --help[=true|false] help for git Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -54,9 +54,9 @@ Usage: spin git connect [flags] Flags: - --forge string The forge (default "github") - -h, --help help for connect - --no-browser Do not open the forge's page in a browser + --forge string The forge (default "github") + -h, --help[=true|false] help for connect + --no-browser[=true|false] Do not open the forge's page in a browser Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -75,8 +75,8 @@ Usage: spin git disconnect [flags] Flags: - -h, --help help for disconnect - -y, --yes Skip confirmation + -h, --help[=true|false] help for disconnect + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -94,7 +94,7 @@ Usage: spin git list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -112,8 +112,8 @@ Usage: spin git repos [query] [flags] Flags: - --forge string The forge (default "github") - -h, --help help for repos + --forge string The forge (default "github") + -h, --help[=true|false] help for repos Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/index.md b/src/content/docs/reference/cli/index.md index 4d298f5..1ae7a13 100644 --- a/src/content/docs/reference/cli/index.md +++ b/src/content/docs/reference/cli/index.md @@ -51,7 +51,7 @@ Available Commands: Flags: --config string config file (default is $HOME/.spin/config.yaml) - -h, --help help for spin + -h, --help[=true|false] help for spin -o, --output string text for a person, or json: one document of what the API answered, and no prose (default "text") --profile string named profile to use; SPIN_PROFILE names it when this flag does not (default "default") --traceparent string the W3C traceparent of the span this command is part of; its own span is sent to the installation unless the profile says telemetry: false diff --git a/src/content/docs/reference/cli/login.md b/src/content/docs/reference/cli/login.md index d471782..bceb66c 100644 --- a/src/content/docs/reference/cli/login.md +++ b/src/content/docs/reference/cli/login.md @@ -40,10 +40,10 @@ Usage: spin login [flags] Flags: - --endpoint string API endpoint URL (default: SPIN_ENDPOINT, the profile's, or https://app.spinbox.dev) - -h, --help help for login - --no-browser do not open the code's page in a browser; with -o json, write the code as a first line of JSON - --token-stdin read an API key (Settings > API Keys) from standard input instead of signing in with a code + --endpoint string API endpoint URL (default: SPIN_ENDPOINT, the profile's, or https://app.spinbox.dev) + -h, --help[=true|false] help for login + --no-browser[=true|false] do not open the code's page in a browser; with -o json, write the code as a first line of JSON + --token-stdin[=true|false] read an API key (Settings > API Keys) from standard input instead of signing in with a code Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/logout.md b/src/content/docs/reference/cli/logout.md index 112a798..409f1a4 100644 --- a/src/content/docs/reference/cli/logout.md +++ b/src/content/docs/reference/cli/logout.md @@ -16,7 +16,7 @@ Usage: spin logout [flags] Flags: - -h, --help help for logout + -h, --help[=true|false] help for logout Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/mcp.md b/src/content/docs/reference/cli/mcp.md index c7f2e06..bb91665 100644 --- a/src/content/docs/reference/cli/mcp.md +++ b/src/content/docs/reference/cli/mcp.md @@ -24,7 +24,7 @@ Usage: spin mcp [flags] Flags: - -h, --help help for mcp + -h, --help[=true|false] help for mcp Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/open.md b/src/content/docs/reference/cli/open.md index 32c1e12..990e6f1 100644 --- a/src/content/docs/reference/cli/open.md +++ b/src/content/docs/reference/cli/open.md @@ -17,7 +17,7 @@ its repository among the projects you see; with more than one, --project says wh workspace is made in --team, or your personal team. A repository no project has is one to make a project of first ('spin project create'). -The workspace is the project's shape, and its first access is signed here with a key of your +The workspace is the project's shape, sized by its preset unless --preset names another, and its first access is signed here with a key of your keyring. It ends in 'spin ssh' unless --no-connect. Examples: @@ -29,13 +29,14 @@ Usage: spin open [flags] Flags: - -h, --help help for open - --name string Workspace name (auto-generated if empty) - --no-connect Create the workspace and print it, without connecting - --project string The project to open, by slug, when more than one has the repository - --team string The team the workspace is made in, by id, path or me (your personal team if empty) - --timeout duration How long --wait waits; by default, until the control plane gives up on it - --wait Return once the workspace is running, with --no-connect + -h, --help[=true|false] help for open + --name string Workspace name (auto-generated if empty) + --no-connect[=true|false] Create the workspace and print it, without connecting + --preset string The preset it is sized by, by name (default: the project's) + --project string The project to open, by slug, when more than one has the repository + --team string The team the workspace is made in, by id, path or me (your personal team if empty) + --timeout duration How long --wait waits; by default, until the control plane gives up on it + --wait[=true|false] Return once the workspace is running, with --no-connect Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/port.md b/src/content/docs/reference/cli/port.md index 67df134..9d67396 100644 --- a/src/content/docs/reference/cli/port.md +++ b/src/content/docs/reference/cli/port.md @@ -25,7 +25,7 @@ Available Commands: unexpose Unexpose a port from a workspace Flags: - -h, --help help for port + -h, --help[=true|false] help for port Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -52,7 +52,7 @@ Usage: spin port access [flags] Flags: - -h, --help help for access + -h, --help[=true|false] help for access Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -89,8 +89,8 @@ Usage: Flags: --access string who may reach it: private (the default), whitelist or public --description string Description of the exposed port - -h, --help help for expose - --https The port speaks TLS; the proxy does not verify its certificate, and its URL is {port}s- + -h, --help[=true|false] help for expose + --https[=true|false] The port speaks TLS; the proxy does not verify its certificate, and its URL is {port}s- Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -114,7 +114,7 @@ Usage: spin port grant [flags] Flags: - -h, --help help for grant + -h, --help[=true|false] help for grant Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -137,7 +137,7 @@ Usage: spin port list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -158,7 +158,7 @@ Usage: spin port revoke [flags] Flags: - -h, --help help for revoke + -h, --help[=true|false] help for revoke Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -182,7 +182,7 @@ Usage: spin port unexpose [flags] Flags: - -h, --help help for unexpose + -h, --help[=true|false] help for unexpose Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/project.md b/src/content/docs/reference/cli/project.md index 86bb67e..de74304 100644 --- a/src/content/docs/reference/cli/project.md +++ b/src/content/docs/reference/cli/project.md @@ -34,7 +34,7 @@ Available Commands: update Save a project whole: every flag is what it becomes Flags: - -h, --help help for project + -h, --help[=true|false] help for project Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -60,10 +60,11 @@ Usage: Flags: --description string A line about it - -h, --help help for create + -h, --help[=true|false] help for create --image string The image a workspace of it starts from (default: the installation's) --name string What the project is called --network-tag strings A network policy a workspace of it runs under, by name (repeatable) + --prebuild-keep int32 How many of each ref's newest prebuilds are kept when no workspace was opened from them (default: 1) --prebuild-rebase-every int32 Every how many builds of a ref one is built from the image again (default: 10) --prebuild-ref stringArray A ref it prebuilds: built as it moves, and what opening the project at it is cloned from (repeatable; the builds run as you) --preset string The preset a workspace of it is sized by (default: the installation's) @@ -87,8 +88,8 @@ Usage: spin project delete [flags] Flags: - -h, --help help for delete - -y, --yes Skip confirmation + -h, --help[=true|false] help for delete + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -106,7 +107,7 @@ Usage: spin project list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -126,7 +127,7 @@ Usage: spin project prebuild [flags] Flags: - -h, --help help for prebuild + -h, --help[=true|false] help for prebuild Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -147,7 +148,7 @@ Usage: spin project prebuilds [flags] Flags: - -h, --help help for prebuilds + -h, --help[=true|false] help for prebuilds Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -170,11 +171,11 @@ Usage: spin project share [flags] Flags: - --admin stringArray A person who administers it, by id (repeatable; at least one) - --everyone Everybody signed in sees it - -h, --help help for share - --team stringArray A team whose members see it, by id, path or me (repeatable) - --user stringArray A person who sees it, by id (repeatable) + --admin stringArray A person who administers it, by id (repeatable; at least one) + --everyone[=true|false] Everybody signed in sees it + -h, --help[=true|false] help for share + --team stringArray A team whose members see it, by id, path or me (repeatable) + --user stringArray A person who sees it, by id (repeatable) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -195,10 +196,11 @@ Usage: Flags: --description string A line about it - -h, --help help for update + -h, --help[=true|false] help for update --image string The image a workspace of it starts from (default: the installation's) --name string What the project is called --network-tag strings A network policy a workspace of it runs under, by name (repeatable) + --prebuild-keep int32 How many of each ref's newest prebuilds are kept when no workspace was opened from them (default: 1) --prebuild-rebase-every int32 Every how many builds of a ref one is built from the image again (default: 10) --prebuild-ref stringArray A ref it prebuilds: built as it moves, and what opening the project at it is cloned from (repeatable; the builds run as you) --preset string The preset a workspace of it is sized by (default: the installation's) diff --git a/src/content/docs/reference/cli/settings.md b/src/content/docs/reference/cli/settings.md index 6d8cb6c..d1f4262 100644 --- a/src/content/docs/reference/cli/settings.md +++ b/src/content/docs/reference/cli/settings.md @@ -26,7 +26,7 @@ Available Commands: taskfile Configure startup Taskfile Flags: - -h, --help help for settings + -h, --help[=true|false] help for settings Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -51,11 +51,11 @@ Usage: spin settings dotfiles [flags] Flags: - --branch string Branch to clone (default "main") - --clear Clear dotfiles configuration - -h, --help help for dotfiles - --install string Install command (default "./install.sh") - --repo string Git repository URL + --branch string Branch to clone (default "main") + --clear[=true|false] Clear dotfiles configuration + -h, --help[=true|false] help for dotfiles + --install string Install command (default "./install.sh") + --repo string Git repository URL Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -73,7 +73,7 @@ Usage: spin settings get [flags] Flags: - -h, --help help for get + -h, --help[=true|false] help for get Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -101,7 +101,7 @@ Usage: spin settings set [flags] Flags: - -h, --help help for set + -h, --help[=true|false] help for set Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -124,10 +124,10 @@ Usage: spin settings taskfile [flags] Flags: - --clear Clear Taskfile configuration - --file string Taskfile to upload - -h, --help help for taskfile - --validate string Validate a Taskfile without saving + --clear[=true|false] Clear Taskfile configuration + --file string Taskfile to upload + -h, --help[=true|false] help for taskfile + --validate string Validate a Taskfile without saving Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/share.md b/src/content/docs/reference/cli/share.md index ea495aa..37a74b5 100644 --- a/src/content/docs/reference/cli/share.md +++ b/src/content/docs/reference/cli/share.md @@ -29,7 +29,7 @@ Available Commands: remove Remove a user's access to a snapshot Flags: - -h, --help help for share + -h, --help[=true|false] help for share Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -49,8 +49,8 @@ Usage: spin share add [flags] Flags: - --acknowledge-findings Give the snapshot away although its files hold what looks like credentials - -h, --help help for add + --acknowledge-findings[=true|false] Give the snapshot away although its files hold what looks like credentials + -h, --help[=true|false] help for add Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -68,8 +68,8 @@ Usage: spin share browse [flags] Flags: - -h, --help help for browse - --public Include public snapshots (default true) + -h, --help[=true|false] help for browse + --public[=true|false] Include public snapshots (default true) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -87,7 +87,7 @@ Usage: spin share list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -105,7 +105,7 @@ Usage: spin share private [flags] Flags: - -h, --help help for private + -h, --help[=true|false] help for private Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -123,8 +123,8 @@ Usage: spin share public [flags] Flags: - --acknowledge-findings Give the snapshot away although its files hold what looks like credentials - -h, --help help for public + --acknowledge-findings[=true|false] Give the snapshot away although its files hold what looks like credentials + -h, --help[=true|false] help for public Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -142,7 +142,7 @@ Usage: spin share remove [flags] Flags: - -h, --help help for remove + -h, --help[=true|false] help for remove Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/smoke.md b/src/content/docs/reference/cli/smoke.md index 26ded69..da83edf 100644 --- a/src/content/docs/reference/cli/smoke.md +++ b/src/content/docs/reference/cli/smoke.md @@ -29,7 +29,7 @@ Usage: spin smoke [flags] Flags: - -h, --help help for smoke + -h, --help[=true|false] help for smoke --image string The image to start from (default: the installation's) --network-tag strings Network policy to run under, by name (repeatable) --preset string The preset it is sized by (default: the installation's) diff --git a/src/content/docs/reference/cli/snapshot.md b/src/content/docs/reference/cli/snapshot.md index f9cb0b6..fa7020b 100644 --- a/src/content/docs/reference/cli/snapshot.md +++ b/src/content/docs/reference/cli/snapshot.md @@ -26,7 +26,7 @@ Available Commands: list List a workspace's snapshots, including those of disks it was restored away from Flags: - -h, --help help for snapshot + -h, --help[=true|false] help for snapshot Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -48,11 +48,11 @@ Usage: spin snapshot create [flags] Flags: - --description string What the snapshot is of - -h, --help help for create - --timeout duration How long --wait waits (default 5m0s) - --wait Return once the snapshot is published - --with-memory Keep the running processes too, so a restore resumes them + --description string What the snapshot is of + -h, --help[=true|false] help for create + --timeout duration How long --wait waits (default 5m0s) + --wait[=true|false] Return once the snapshot is published + --with-memory[=true|false] Keep the running processes too, so a restore resumes them Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -70,8 +70,8 @@ Usage: spin snapshot delete [flags] Flags: - -h, --help help for delete - -y, --yes Skip confirmation + -h, --help[=true|false] help for delete + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -97,9 +97,9 @@ Usage: spin snapshot diff [flags] Flags: - --from string The earlier snapshot (default: what the workspace was created from) - -h, --help help for diff - --under string Compare only this path of the filesystem, from its root (default: all of it) + --from string The earlier snapshot (default: what the workspace was created from) + -h, --help[=true|false] help for diff + --under string Compare only this path of the filesystem, from its root (default: all of it) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -117,7 +117,7 @@ Usage: spin snapshot list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/ssh-config.md b/src/content/docs/reference/cli/ssh-config.md index 698ed0c..b2a6fdf 100644 --- a/src/content/docs/reference/cli/ssh-config.md +++ b/src/content/docs/reference/cli/ssh-config.md @@ -25,8 +25,8 @@ Usage: spin ssh-config [flags] Flags: - -h, --help help for ssh-config - -i, --identity string Identity file (private key); default: the first key this machine holds that your keyring lists + -h, --help[=true|false] help for ssh-config + -i, --identity string Identity file (private key); default: the first key this machine holds that your keyring lists Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/ssh-key.md b/src/content/docs/reference/cli/ssh-key.md index 55a02f3..8fa68c1 100644 --- a/src/content/docs/reference/cli/ssh-key.md +++ b/src/content/docs/reference/cli/ssh-key.md @@ -27,7 +27,7 @@ Available Commands: list List the SSH keys you log in with Flags: - -h, --help help for ssh-key + -h, --help[=true|false] help for ssh-key Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -55,8 +55,8 @@ Usage: spin ssh-key add [flags] Flags: - -h, --help help for add - --no-browser print the page where your passkey confirms, instead of opening it + -h, --help[=true|false] help for add + --no-browser[=true|false] print the page where your passkey confirms, instead of opening it Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -74,8 +74,8 @@ Usage: spin ssh-key delete [flags] Flags: - -h, --help help for delete - -y, --yes Skip confirmation + -h, --help[=true|false] help for delete + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -93,7 +93,7 @@ Usage: spin ssh-key list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/ssh.md b/src/content/docs/reference/cli/ssh.md index ebcd39d..621b110 100644 --- a/src/content/docs/reference/cli/ssh.md +++ b/src/content/docs/reference/cli/ssh.md @@ -23,11 +23,11 @@ Usage: spin ssh [ssh-argument...] [flags] Flags: - -h, --help help for ssh - -i, --identity string Identity file (private key) - --start Start the workspace first if it is stopped - --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it - -u, --user string SSH username (certificates are issued for root today) (default "root") + -h, --help[=true|false] help for ssh + -i, --identity string Identity file (private key) + --start[=true|false] Start the workspace first if it is stopped + --timeout duration How long to wait for the workspace to be running; by default, until the control plane gives up on it + -u, --user string SSH username (certificates are issued for root today) (default "root") Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/team.md b/src/content/docs/reference/cli/team.md index c9d9d63..84b887a 100644 --- a/src/content/docs/reference/cli/team.md +++ b/src/content/docs/reference/cli/team.md @@ -29,7 +29,7 @@ Available Commands: secret Manage the secrets the egress proxy adds for a team's workspaces Flags: - -h, --help help for team + -h, --help[=true|false] help for team Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -55,7 +55,7 @@ Usage: Flags: --description string Team description - -h, --help help for create + -h, --help[=true|false] help for create --parent string Parent team ID or path --slug string URL-friendly slug (auto-generated if empty) @@ -76,9 +76,9 @@ Usage: spin team delete [flags] Flags: - -h, --help help for delete - --recursive Delete children too (dangerous!) - -y, --yes Skip confirmation + -h, --help[=true|false] help for delete + --recursive[=true|false] Delete children too (dangerous!) + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -96,7 +96,7 @@ Usage: spin team get [flags] Flags: - -h, --help help for get + -h, --help[=true|false] help for get Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -114,9 +114,9 @@ Usage: spin team list [flags] Flags: - --all Include all descendant teams - -h, --help help for list - --parent string Filter by parent team + --all[=true|false] Include all descendant teams + -h, --help[=true|false] help for list + --parent string Filter by parent team Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -141,7 +141,7 @@ Available Commands: role Update a member's role Flags: - -h, --help help for member + -h, --help[=true|false] help for member Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -161,8 +161,8 @@ Usage: spin team member add [flags] Flags: - -h, --help help for add - --role string Role: owner, admin, member (default "member") + -h, --help[=true|false] help for add + --role string Role: owner, admin, member (default "member") Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -180,7 +180,7 @@ Usage: spin team member list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -198,7 +198,7 @@ Usage: spin team member remove [flags] Flags: - -h, --help help for remove + -h, --help[=true|false] help for remove Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -216,7 +216,7 @@ Usage: spin team member role [flags] Flags: - -h, --help help for role + -h, --help[=true|false] help for role Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -243,7 +243,7 @@ Available Commands: set Make a team's policy, or replace what it allows Flags: - -h, --help help for policy + -h, --help[=true|false] help for policy Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -263,8 +263,8 @@ Usage: spin team policy delete [flags] Flags: - -h, --help help for delete - -y, --yes Skip confirmation + -h, --help[=true|false] help for delete + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -282,7 +282,7 @@ Usage: spin team policy list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -306,8 +306,8 @@ Usage: spin team policy set [flags] Flags: - -h, --help help for set - --rule stringArray Destinations and ports, as dest,dest:port,port (repeatable) + -h, --help[=true|false] help for set + --rule stringArray Destinations and ports, as dest,dest:port,port (repeatable) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -335,7 +335,7 @@ Available Commands: set Set a team's secret, read from standard input or kept in Secrets Manager or Parameter Store Flags: - -h, --help help for secret + -h, --help[=true|false] help for secret Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -355,8 +355,8 @@ Usage: spin team secret delete [flags] Flags: - -h, --help help for delete - -y, --yes Skip confirmation + -h, --help[=true|false] help for delete + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -374,7 +374,7 @@ Usage: spin team secret list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -404,9 +404,9 @@ Usage: spin team secret set [flags] Flags: - -h, --help help for set - --host stringArray A host the secret may be sent to, named exactly (repeatable) - --ref string The ARN of the Secrets Manager secret or the Parameter Store parameter the team keeps the value in + -h, --help[=true|false] help for set + --host stringArray A host the secret may be sent to, named exactly (repeatable) + --ref string The ARN of the Secrets Manager secret or the Parameter Store parameter the team keeps the value in Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/update.md b/src/content/docs/reference/cli/update.md index 504bdb6..7217c9c 100644 --- a/src/content/docs/reference/cli/update.md +++ b/src/content/docs/reference/cli/update.md @@ -21,7 +21,7 @@ Usage: spin update [flags] Flags: - -h, --help help for update + -h, --help[=true|false] help for update Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/version.md b/src/content/docs/reference/cli/version.md index 84df3f9..ec08955 100644 --- a/src/content/docs/reference/cli/version.md +++ b/src/content/docs/reference/cli/version.md @@ -16,7 +16,7 @@ Usage: spin version [flags] Flags: - -h, --help help for version + -h, --help[=true|false] help for version Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/vscode.md b/src/content/docs/reference/cli/vscode.md index 6e06b08..7afc900 100644 --- a/src/content/docs/reference/cli/vscode.md +++ b/src/content/docs/reference/cli/vscode.md @@ -20,7 +20,7 @@ Available Commands: install Install the Spinbox extension that carries this CLI's release into VS Code Flags: - -h, --help help for vscode + -h, --help[=true|false] help for vscode Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -55,8 +55,8 @@ Usage: spin vscode install [flags] Flags: - --editor string The editor's command: code, code-insiders, codium, cursor (default "code") - -h, --help help for install + --editor string The editor's command: code, code-insiders, codium, cursor (default "code") + -h, --help[=true|false] help for install Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/whoami.md b/src/content/docs/reference/cli/whoami.md index af1db7c..9f2ea1c 100644 --- a/src/content/docs/reference/cli/whoami.md +++ b/src/content/docs/reference/cli/whoami.md @@ -16,7 +16,7 @@ Usage: spin whoami [flags] Flags: - -h, --help help for whoami + -h, --help[=true|false] help for whoami Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/cli/workspace.md b/src/content/docs/reference/cli/workspace.md index 7ae9675..472749d 100644 --- a/src/content/docs/reference/cli/workspace.md +++ b/src/content/docs/reference/cli/workspace.md @@ -54,7 +54,7 @@ Available Commands: watch Record where a workspace connects, into its logs Flags: - -h, --help help for workspace + -h, --help[=true|false] help for workspace Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -80,7 +80,7 @@ Usage: spin workspace bandwidth [flags] Flags: - -h, --help help for bandwidth + -h, --help[=true|false] help for bandwidth Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -105,10 +105,10 @@ Usage: spin workspace clone [flags] Flags: - -h, --help help for clone - --name string The clone's name (generated if empty) - --timeout duration How long --wait waits; by default, until the control plane gives up on it - --wait Return once the clone is running + -h, --help[=true|false] help for clone + --name string The clone's name (generated if empty) + --timeout duration How long --wait waits; by default, until the control plane gives up on it + --wait[=true|false] Return once the clone is running Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -132,8 +132,8 @@ Usage: spin workspace console [flags] Flags: - -h, --help help for console - --lines int32 How many lines from the end (default 200) + -h, --help[=true|false] help for console + --lines int32 How many lines from the end (default 200) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -155,8 +155,9 @@ You log in to it with a key you added ('spin ssh-key add'), and so does each gue What it applies of yours - dotfiles, shell, environment, editor settings, Taskfile, and this workspace's own --env over your environment - is your settings, as you saved them. -A project (--project) is the workspace's shape - its image, preset and network policies - and -the repository its guest clones into /workspace/, at --ref or the project's own; +A project (--project) is the workspace's shape - its image and network policies, and its preset +unless --preset names another - and the repository its guest clones into +/workspace/, at --ref or the project's own; the workspace is made in --team, or your personal team. A project whose repository is on GitHub opens once you have connected your GitHub account (Settings → Git in the dashboard). @@ -166,6 +167,7 @@ Examples: spin workspace create --name build --env GOPROXY=direct --network-tag registry-only spin workspace create --name copy --from-snapshot spin workspace create --team /engineering --project qboot --ref release/2 + spin workspace create --project qboot --preset large Usage: spin workspace create [flags] @@ -174,16 +176,16 @@ Flags: --agent-home string An agent's home of yours to mount, by id (spin agent home list): the chats of a workspace since erased --env strings Environment variables (KEY=VALUE) --from-snapshot string Start from a snapshot instead of an image - -h, --help help for create + -h, --help[=true|false] help for create --image string the ref of the disk image to start from, with its version (default: the base image of the machine this installation runs) --name string Workspace name (auto-generated if empty) --network-tag strings Network policy to run under, by name (repeatable) - --preset string The preset it is sized by, by name (default: the installation's) + --preset string The preset it is sized by, by name (default: the project's, or the installation's) --project string A project to open, by slug: its image, preset and policies, and its repository cloned --ref string The branch or tag to open the project at (default: the project's) --team string The team, by id, path or me (your personal team if empty) --timeout duration How long --wait waits; by default, until the control plane gives up on it - --wait Return once the workspace is running + --wait[=true|false] Return once the workspace is running Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -203,10 +205,10 @@ Usage: spin workspace delete [flags] Flags: - --force Delete it in a state a delete is otherwise refused in: one stuck starting or stopping - -h, --help help for delete - --permanently Erase it now instead of keeping it in the trash - -y, --yes Skip confirmation + --force[=true|false] Delete it in a state a delete is otherwise refused in: one stuck starting or stopping + -h, --help[=true|false] help for delete + --permanently[=true|false] Erase it now instead of keeping it in the trash + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -224,7 +226,7 @@ Usage: spin workspace deleted [flags] Flags: - -h, --help help for deleted + -h, --help[=true|false] help for deleted Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -244,8 +246,8 @@ Usage: spin workspace denials [flags] Flags: - -h, --help help for denials - --limit int32 How many of the newest to read (default 100) + -h, --help[=true|false] help for denials + --limit int32 How many of the newest to read (default 100) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -269,7 +271,7 @@ Usage: spin workspace egress [flags] Flags: - -h, --help help for egress + -h, --help[=true|false] help for egress Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -287,7 +289,7 @@ Usage: spin workspace get [flags] Flags: - -h, --help help for get + -h, --help[=true|false] help for get Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -321,11 +323,11 @@ Usage: spin workspace grant [flags] Flags: - --cpu int32 Cores it is to hold - --for duration How long the grant lasts before it is given back on its own (default: until it is given back) - -h, --help help for grant - --memory int32 Memory it is to hold, in MB - --move Move it to a host with room when its own has none (it is paused while it moves) + --cpu int32 Cores it is to hold + --for duration How long the grant lasts before it is given back on its own (default: until it is given back) + -h, --help[=true|false] help for grant + --memory int32 Memory it is to hold, in MB + --move[=true|false] Move it to a host with room when its own has none (it is paused while it moves) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -350,7 +352,7 @@ Available Commands: remove Take a guest out Flags: - -h, --help help for guests + -h, --help[=true|false] help for guests Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -370,8 +372,8 @@ Usage: spin workspace guests add [flags] Flags: - -h, --help help for add - --no-browser print the page where your passkey confirms, instead of opening it + -h, --help[=true|false] help for add + --no-browser[=true|false] print the page where your passkey confirms, instead of opening it Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -389,7 +391,7 @@ Usage: spin workspace guests list [flags] Flags: - -h, --help help for list + -h, --help[=true|false] help for list Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -408,7 +410,7 @@ Usage: spin workspace guests remove [flags] Flags: - -h, --help help for remove + -h, --help[=true|false] help for remove Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -426,8 +428,8 @@ Usage: spin workspace history [flags] Flags: - -h, --help help for history - --limit int32 Number of events to show (default 50) + -h, --help[=true|false] help for history + --limit int32 Number of events to show (default 50) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -449,7 +451,7 @@ Usage: spin workspace keep [flags] Flags: - -h, --help help for keep + -h, --help[=true|false] help for keep Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -467,8 +469,8 @@ Usage: spin workspace list [flags] Flags: - -h, --help help for list - --state string Filter by state (running, stopped, etc.) + -h, --help[=true|false] help for list + --state string Filter by state (running, stopped, etc.) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -494,9 +496,9 @@ Usage: spin workspace logs [query] [flags] Flags: - -h, --help help for logs - --limit int32 how many lines, newest first: 1 to 1000 (default 100) - --since duration how far back to look, at most 744h (31 days) (default 1h0m0s) + -h, --help[=true|false] help for logs + --limit int32 how many lines, newest first: 1 to 1000 (default 100) + --since duration how far back to look, at most 744h (31 days) (default 1h0m0s) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -521,7 +523,7 @@ Usage: spin workspace move [flags] Flags: - -h, --help help for move + -h, --help[=true|false] help for move Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -545,7 +547,7 @@ Usage: spin workspace policies [flags] Flags: - -h, --help help for policies + -h, --help[=true|false] help for policies Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -566,9 +568,9 @@ Usage: spin workspace quarantine [flags] Flags: - -h, --help help for quarantine - --reason string Why it is held: kept on the audit entry for the act - -y, --yes Skip confirmation + -h, --help[=true|false] help for quarantine + --reason string Why it is held: kept on the audit entry for the act + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -592,8 +594,8 @@ Usage: spin workspace recover [flags] Flags: - --accept-data-loss go ahead and give up the work the old host had not published - -h, --help help for recover + --accept-data-loss[=true|false] go ahead and give up the work the old host had not published + -h, --help[=true|false] help for recover Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -613,7 +615,7 @@ Usage: spin workspace release [flags] Flags: - -h, --help help for release + -h, --help[=true|false] help for release Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -636,10 +638,10 @@ Usage: spin workspace reset [flags] Flags: - -h, --help help for reset - --start Start the workspace on the disk it was created from and wait until it is running - --timeout duration How long --start waits; by default, until the control plane gives up on it - -y, --yes Skip confirmation + -h, --help[=true|false] help for reset + --start[=true|false] Start the workspace on the disk it was created from and wait until it is running + --timeout duration How long --start waits; by default, until the control plane gives up on it + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -665,10 +667,10 @@ Usage: spin workspace restore [snapshot-id] [flags] Flags: - -h, --help help for restore - --start Start the workspace on the restored disk and wait until it is running - --timeout duration How long --start waits; by default, until the control plane gives up on it - --with-memory Resume the snapshot's processes too; the workspace may be running + -h, --help[=true|false] help for restore + --start[=true|false] Start the workspace on the restored disk and wait until it is running + --timeout duration How long --start waits; by default, until the control plane gives up on it + --with-memory[=true|false] Resume the snapshot's processes too; the workspace may be running Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -700,7 +702,7 @@ Usage: spin workspace retag [flags] Flags: - -h, --help help for retag + -h, --help[=true|false] help for retag --network-tag strings Network policy to run under, by name (repeatable); the whole set, not an addition Global Flags: @@ -723,10 +725,10 @@ Usage: spin workspace start [flags] Flags: - --from-disk boot a suspended workspace from its disk, dropping the memory it was suspended with - -h, --help help for start - --timeout duration How long --wait waits; by default, until the control plane gives up on it - --wait Return once the workspace is running + --from-disk[=true|false] boot a suspended workspace from its disk, dropping the memory it was suspended with + -h, --help[=true|false] help for start + --timeout duration How long --wait waits; by default, until the control plane gives up on it + --wait[=true|false] Return once the workspace is running Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -749,7 +751,7 @@ Usage: spin workspace status [flags] Flags: - -h, --help help for status + -h, --help[=true|false] help for status Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -770,10 +772,10 @@ Usage: spin workspace stop [flags] Flags: - --force Stop the machine without waiting for the guest; also ends a stop that did not finish - -h, --help help for stop - --timeout duration How long --wait waits; by default, until the control plane gives up on it - --wait Return once the workspace is stopped + --force[=true|false] Stop the machine without waiting for the guest; also ends a stop that did not finish + -h, --help[=true|false] help for stop + --timeout duration How long --wait waits; by default, until the control plane gives up on it + --wait[=true|false] Return once the workspace is stopped Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -800,7 +802,7 @@ Usage: spin workspace suspend [flags] Flags: - -h, --help help for suspend + -h, --help[=true|false] help for suspend Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -820,7 +822,7 @@ Usage: spin workspace threads [flags] Flags: - -h, --help help for threads + -h, --help[=true|false] help for threads Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -840,7 +842,7 @@ Usage: spin workspace undelete [flags] Flags: - -h, --help help for undelete + -h, --help[=true|false] help for undelete Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -861,8 +863,8 @@ Usage: spin workspace unquarantine [flags] Flags: - -h, --help help for unquarantine - -y, --yes Skip confirmation + -h, --help[=true|false] help for unquarantine + -y, --yes[=true|false] Skip confirmation Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -888,10 +890,10 @@ Usage: spin workspace update [flags] Flags: - --env strings Environment variables (KEY=VALUE) - -h, --help help for update - --name string New workspace name - --wake-on-access Resume it, when suspended, for a signed-in visitor of one of its ports (never an anonymous one) + --env strings Environment variables (KEY=VALUE) + -h, --help[=true|false] help for update + --name string New workspace name + --wake-on-access[=true|false] Resume it, when suspended, for a signed-in visitor of one of its ports (never an anonymous one) Global Flags: --config string config file (default is $HOME/.spin/config.yaml) @@ -915,8 +917,8 @@ Usage: spin workspace watch [flags] Flags: - -h, --help help for watch - --off Stop recording where the workspace connects + -h, --help[=true|false] help for watch + --off[=true|false] Stop recording where the workspace connects Global Flags: --config string config file (default is $HOME/.spin/config.yaml) diff --git a/src/content/docs/reference/configuration/file.md b/src/content/docs/reference/configuration/file.md index 91e3e65..e9ddd33 100644 --- a/src/content/docs/reference/configuration/file.md +++ b/src/content/docs/reference/configuration/file.md @@ -56,16 +56,6 @@ settings: # named and only allowing - nothing brokered. Any team may then reach past what the policies # below allow, so it is off unless decided. team_network_policies: false - # Whether the control plane fetches VS Code servers from Microsoft on its own: the newest stable - # release, looked for daily, and the server of a client's commit the installation has not - # released, and at start the release this one pins. Off, it fetches none, and workspaces get - # the servers an administrator published; no image carries one. - vscode_fetch: false - # Whether the control plane fetches the agent CLIs - Claude Code and Codex - from their - # publishers on its own: the pair this release pins at start, and the newest of each, looked - # for daily. Off, it fetches none, and workspaces get the pair an operator published; no image - # carries one. - agents_fetch: false # The IAM role a team's secret kept in Secrets Manager or Parameter Store is read under, in a # session tagged spin-team-id with the team; it reads only a secret or a parameter tagged the # same. Unset, a team's secrets are sealed in the database and none is a reference. @@ -138,7 +128,9 @@ registration: - acme.com - contractor@example.com -# What a person may choose when creating a workspace. One preset may be the default. +# What a person may choose when creating a workspace. One preset may be the default. Left out, +# the installation is given the release's: one, "default", 1 core and 512 MB that grow to what its +# host has, on 10 GB. `presets: []` gives it none. # burst says how a workspace of it grows: fixed (the default) runs at its size; to_preset # starts at the floor (burst_floor_cpu, burst_floor_memory_mb; 1 and 1024 if left out) and # grows to its size; to_host starts at the floor and grows to what its host has. diff --git a/src/content/docs/reference/security/known-gaps.md b/src/content/docs/reference/security/known-gaps.md index 7ec4348..05a884a 100644 --- a/src/content/docs/reference/security/known-gaps.md +++ b/src/content/docs/reference/security/known-gaps.md @@ -9,7 +9,7 @@ sidebar: -The open items of Spinbox's security model, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/security/README.md) at `dafe28616`. The numbers are [its rules](/reference/security/rules/). +The open items of Spinbox's security model, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/security/README.md) at `b7ba5206f`. The numbers are [its rules](/reference/security/rules/). What no line keeps yet. Each is a design change, not a patch, which is why it is here. diff --git a/src/content/docs/reference/security/rules.md b/src/content/docs/reference/security/rules.md index cf43ac7..c14fdc1 100644 --- a/src/content/docs/reference/security/rules.md +++ b/src/content/docs/reference/security/rules.md @@ -9,7 +9,7 @@ sidebar: -The rules every entry point must keep, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/security/README.md) at `dafe28616`. Code cites a rule's number at the line that keeps it. **Gate** is what fails a build when the rule is broken; *none* marks a rule kept only by each place remembering it. What is still open is on [Known gaps](/reference/security/known-gaps/). +The rules every entry point must keep, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/security/README.md) at `b7ba5206f`. Code cites a rule's number at the line that keeps it. **Gate** is what fails a build when the rule is broken; *none* marks a rule kept only by each place remembering it. What is still open is on [Known gaps](/reference/security/known-gaps/). | # | Rule | Gate | |---|---|---| diff --git a/src/content/docs/reference/status/index.md b/src/content/docs/reference/status/index.md index a1783a2..28e6bbe 100644 --- a/src/content/docs/reference/status/index.md +++ b/src/content/docs/reference/status/index.md @@ -9,7 +9,7 @@ sidebar: -Every row of this page is a line of `internal/features` in spin, and a test there resolves it against the tree. A row that says **built** names what shows the feature exists - a procedure the control plane serves, a command the CLI has, or a test - and, under **End to end**, the tests that drive a real runner and its guest and check what the feature did, or what no test checks yet. spin's build checks that each of those tests is there and not quarantined; whether it checks the whole feature is its review's. A row that says **not built** is an item of [`docs/ROADMAP.md`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/ROADMAP.md). The page is written by `task reference` from `spin features` at spin `dafe28616`, and cannot say a feature the binary does not. spin is a private repository: a link to its code opens only for someone with access to it. +Every row of this page is a line of `internal/features` in spin, and a test there resolves it against the tree. A row that says **built** names what shows the feature exists - a procedure the control plane serves, a command the CLI has, or a test - and, under **End to end**, the tests that drive a real runner and its guest and check what the feature did, or what no test checks yet. spin's build checks that each of those tests is there and not quarantined; whether it checks the whole feature is its review's. A row that says **not built** is an item of [`docs/ROADMAP.md`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/ROADMAP.md). The page is written by `task reference` from `spin features` at spin `b7ba5206f`, and cannot say a feature the binary does not. spin is a private repository: a link to its code opens only for someone with access to it. ## Built @@ -17,130 +17,132 @@ Every row of this page is a line of `internal/features` in spin, and a test ther | Feature | Exists | End to end | |---|---|---| -| A machine per workspace: KVM, its own kernel, root, a persistent disk, SSH | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vm_test.go#L189), a test of `internal/e2e` | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vm_test.go#L189) | -| Create, start, stop and delete | [`WorkspaceService/CreateWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_WorkspaceCRUD`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L424) | -| A trash: a deleted workspace stays whole, for its owner to undelete, until its days are up | [`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L381), a test of `internal/e2e` | [`TestATrashedWorkspaceIsWholeWhenItsOwnerUndeletesIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L413)
[`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L381) | -| Idle suspend, with a question before it that a keep answers | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L108), a test of `internal/e2e` | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L108) | -| A workspace that ran as long as the installation allows is suspended | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L70), a test of `internal/e2e` | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L70) | -| A process inside holds its workspace awake while it lives | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L191), a test of `internal/e2e` | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L191) | -| Suspend with the processes where they are; a start resumes them | [`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L36), a test of `internal/e2e` | [`TestE2E_ASuspendedWorkspaceResumesWhereItWas`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L288)
[`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L36) | -| Cores and memory lent while the host has them, and taken back
*A loan refused while the host is full has no test against the stack: the budget is the host's own cores and half its memory, which no lane's workspaces fill.* | [`TestABusyWorkspaceIsLentCoresAndGivesThemBack`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L344), a test of `internal/e2e` | [`TestABusyWorkspaceIsLentCoresAndGivesThemBack`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L344)
[`TestABusyWorkspaceIsLentMemoryAndGivesItBack`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/memory_test.go#L109) | -| A grant of cores and memory of its own, for a while | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L290), a test of `internal/e2e` | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/background_test.go#L290)
[`TestAResumedWorkspaceIsGivenWhatItIsGrantedWhileItRuns`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/resume_grant_test.go#L20) | -| An administrator changes a running workspace's bandwidth, its connections open | [`TestAnAdministratorChangesARunningWorkspacesBandwidth`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/bandwidth_test.go#L118), a test of `internal/e2e` | [`TestAnAdministratorChangesARunningWorkspacesBandwidth`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/bandwidth_test.go#L118)
[`TestAWorkspacesBandwidthHoldsAcrossItsRunsAndItsRunner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/bandwidth_test.go#L172) | -| Move a running workspace to another host, its processes as they are | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/hosts_flows_test.go#L65), a test of `internal/e2e` | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/hosts_flows_test.go#L65) | -| Clone a workspace: its disk, team, project, size, policies and environment, in one | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/clone_test.go#L64), a test of `internal/e2e` | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/clone_test.go#L64) | -| Recover a workspace whose host is gone, at a cost its owner accepts | [`TestHostsAWorkspaceWhoseHostIsGoneIsRecoveredOnAnother`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/hosts_flows_test.go#L100), a test of `internal/e2e` | [`TestHostsAWorkspaceWhoseHostIsGoneIsRecoveredOnAnother`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/hosts_flows_test.go#L100) | -| A workspace outlives its runner | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vm_test.go#L314), a test of `internal/e2e` | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vm_test.go#L314) | -| Quarantine, by an administrator | [`WorkspaceService/QuarantineWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L337) | -| Why a workspace is not behaving: status, console, history | [`spin workspace status`](/reference/cli/workspace/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L337)
[`TestE2E_AWorkspacesConsoleIsWhatItsMachinePrinted`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L370) | -| The owner's shell, environment, editor settings, Taskfile and dotfiles reach the guest as they save them | [`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/env_test.go#L22), a test of `internal/e2e` | [`TestTheOwnersSettingsArriveInTheGuest`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/env_test.go#L74)
[`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/env_test.go#L22) | -| Reset a disk to what it was created from | [`spin workspace reset`](/reference/cli/workspace/) | [`TestE2E_ResetPutsAWorkspaceBackToWhatItWasCreatedFrom`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L1230) | -| Claude Code, Codex and T3 Code on every workspace's PATH, at the versions the release pins, with their own defaults
*Where the installation fetches them (agents_fetch) or an operator publishes them: no image carries Claude Code, which only Anthropic may distribute.* | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/agentclis_test.go#L20), a test of `internal/e2e` | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/agentclis_test.go#L20) | -| An agent UI: T3 Code in a workspace as its agent user, over the owner's SSH session - from `spin agent` on the person's computer, or in the workspace's Agent tab in the dashboard, which frames the client and carries it over a passkey's session
*The lane has no provider credential, so no test has a model answer through the brokered egress: the server is reached, as the agent's user, and nothing is asked of it. The browser's test drives the page with a virtual authenticator, which no real passkey's maker vouches for.* | [`spin agent --port`](/reference/cli/agent/) | [`TestTheSupervisorRunsTheAgentForItsOwner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/t3_test.go#L79)
[`TestE2E_TheAgentIsServedOnThisComputerWhileTheSessionIsOpen`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L94)
[`agent.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/agent.spec.ts#L62): a passkey signs the person in, and the agent runs in their workspace from the dashboard | -| Claude Code and Codex signed in from the agent's page: each CLI's own login, run by the supervisor as the agent's user, its credentials kept in the agent's home and never passing through the page
*The lane has no provider account: it begins a login and sees the provider's page, and finishing one is the unit tests' on each CLI's own output.* | `AgentService/BeginLogin` | [`TestTheSupervisorRunsTheAgentForItsOwner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/t3_test.go#L79) | -| A person signs Claude Code and Codex in once: every workspace of theirs, plain or a project's, is handed the same credentials and hands back each refresh and logout, and a workspace that names a guest holds none
*The lane has no provider account: its login is the file the CLI writes, written as the agent's user. Only a workspace its owner's alone through all it came from holds them: a project opened from its prebuild does, but not a prebuild's build, a copy of another person's snapshot, or one made before the release that keeps the mark.* | [`TestAPersonSignsInToTheAgentOnceForEveryWorkspaceOfTheirs`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/agentcredentials_test.go#L29), a test of `internal/e2e` | [`TestAPersonSignsInToTheAgentOnceForEveryWorkspaceOfTheirs`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/agentcredentials_test.go#L29) | -| The supervisor runs the agent for its owner while it is used: started, paired and listed over the owner's own session on a socket only root opens, and stopped once nobody has used it for half an hour and no chat is at work
*That it stops once idle is the sweep's unit test on a clock the test moves: no lane waits half an hour.* | `AgentService/Start` | [`TestTheSupervisorRunsTheAgentForItsOwner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/t3_test.go#L79) | -| The agent's chats listed on the workspace - titles, paths and times, never a message - reported by its supervisor | [`WorkspaceService/ListAgentThreads`](/reference/api/workspaceservice/) | [`TestTheAgentsThreadsAreListed`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/t3_test.go#L184) | -| The agent's home is a volume of its own: the chats and sessions outlive the workspace, kept in the installation's store as every disk is, and a new workspace mounts them at its creation
*Sealed with the workspace's checkpoints, claimed with the launch beside the disk, and moved with the workspace.* | [`spin workspace create --agent-home`](/reference/cli/workspace/) | [`TestAnAgentsHomeOutlivesItsWorkspace`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/agenthome_test.go#L78) | +| A machine per workspace: KVM, its own kernel, root, a persistent disk, SSH | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vm_test.go#L190), a test of `internal/e2e` | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vm_test.go#L190) | +| Create, start, stop and delete | [`WorkspaceService/CreateWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_WorkspaceCRUD`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L424) | +| A trash: a deleted workspace stays whole, for its owner to undelete, until its days are up | [`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L389), a test of `internal/e2e` | [`TestATrashedWorkspaceIsWholeWhenItsOwnerUndeletesIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L421)
[`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L389) | +| Idle suspend, with a question before it that a keep answers | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L108), a test of `internal/e2e` | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L108) | +| A workspace that ran as long as the installation allows is suspended | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L70), a test of `internal/e2e` | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L70) | +| A process inside holds its workspace awake while it lives | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L199), a test of `internal/e2e` | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L199) | +| Suspend with the processes where they are; a start resumes them | [`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L36), a test of `internal/e2e` | [`TestE2E_ASuspendedWorkspaceResumesWhereItWas`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L288)
[`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L36) | +| Cores and memory lent while the host has them, and taken back
*A loan refused while the host is full has no test against the stack: the budget is the host's own cores and half its memory, which no lane's workspaces fill.* | [`TestABusyWorkspaceIsLentCoresAndGivesThemBack`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L352), a test of `internal/e2e` | [`TestABusyWorkspaceIsLentCoresAndGivesThemBack`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L352)
[`TestABusyWorkspaceIsLentMemoryAndGivesItBack`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/memory_test.go#L109) | +| A grant of cores and memory of its own, for a while | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L298), a test of `internal/e2e` | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/background_test.go#L298)
[`TestAResumedWorkspaceIsGivenWhatItIsGrantedWhileItRuns`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/resume_grant_test.go#L20) | +| An administrator changes a running workspace's bandwidth, its connections open | [`TestAnAdministratorChangesARunningWorkspacesBandwidth`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/bandwidth_test.go#L118), a test of `internal/e2e` | [`TestAnAdministratorChangesARunningWorkspacesBandwidth`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/bandwidth_test.go#L118)
[`TestAWorkspacesBandwidthHoldsAcrossItsRunsAndItsRunner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/bandwidth_test.go#L172) | +| Move a running workspace to another host, its processes as they are | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/hosts_flows_test.go#L65), a test of `internal/e2e` | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/hosts_flows_test.go#L65) | +| Clone a workspace: its disk, team, project, size, policies and environment, in one | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/clone_test.go#L64), a test of `internal/e2e` | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/clone_test.go#L64) | +| Recover a workspace whose host is gone, at a cost its owner accepts | [`TestHostsAWorkspaceWhoseHostIsGoneIsRecoveredOnAnother`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/hosts_flows_test.go#L100), a test of `internal/e2e` | [`TestHostsAWorkspaceWhoseHostIsGoneIsRecoveredOnAnother`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/hosts_flows_test.go#L100) | +| A workspace outlives its runner | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vm_test.go#L341), a test of `internal/e2e` | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vm_test.go#L341) | +| Quarantine, by an administrator | [`WorkspaceService/QuarantineWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L337) | +| Why a workspace is not behaving: status, console, history | [`spin workspace status`](/reference/cli/workspace/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L337)
[`TestE2E_AWorkspacesConsoleIsWhatItsMachinePrinted`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L370) | +| The owner's shell, environment, editor settings, Taskfile and dotfiles reach the guest as they save them | [`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/env_test.go#L22), a test of `internal/e2e` | [`TestTheOwnersSettingsArriveInTheGuest`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/env_test.go#L74)
[`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/env_test.go#L22) | +| Reset a disk to what it was created from | [`spin workspace reset`](/reference/cli/workspace/) | [`TestE2E_ResetPutsAWorkspaceBackToWhatItWasCreatedFrom`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L1230) | +| Claude Code, Codex and T3 Code on every workspace's PATH, at the versions the release pins, with their own defaults
*Where an administrator accepted their terms (Admin → Extensions) or an operator publishes them: no image carries Claude Code, which only Anthropic may distribute.* | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/agentclis_test.go#L24), a test of `internal/e2e` | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/agentclis_test.go#L24) | +| An agent UI: T3 Code in a workspace as its agent user, over the owner's SSH session - from `spin agent` on the person's computer, or in the workspace's Agent tab in the dashboard, which frames the client and carries it over a passkey's session
*The lane has no provider credential, so no test has a model answer through the brokered egress: the server is reached, as the agent's user, and nothing is asked of it. The browser's test drives the page with a virtual authenticator, which no real passkey's maker vouches for.* | [`spin agent --port`](/reference/cli/agent/) | [`TestTheSupervisorRunsTheAgentForItsOwner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/t3_test.go#L79)
[`TestE2E_TheAgentIsServedOnThisComputerWhileTheSessionIsOpen`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L94)
[`agent.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/agent.spec.ts#L62): a passkey signs the person in, and the agent runs in their workspace from the dashboard | +| Claude Code and Codex signed in from the agent's page: each CLI's own login, run by the supervisor as the agent's user, its credentials kept in the agent's home and never passing through the page
*The lane has no provider account: it begins a login and sees the provider's page, and finishing one is the unit tests' on each CLI's own output.* | `AgentService/BeginLogin` | [`TestTheSupervisorRunsTheAgentForItsOwner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/t3_test.go#L79) | +| A person signs Claude Code and Codex in once: every workspace of theirs, plain or a project's, is handed the same credentials and hands back each refresh and logout, and a workspace that names a guest holds none
*The lane has no provider account: its login is the file the CLI writes, written as the agent's user. Only a workspace its owner's alone through all it came from holds them: a project opened from its prebuild does, but not a prebuild's build, a copy of another person's snapshot, or one made before the release that keeps the mark.* | [`TestAPersonSignsInToTheAgentOnceForEveryWorkspaceOfTheirs`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/agentcredentials_test.go#L29), a test of `internal/e2e` | [`TestAPersonSignsInToTheAgentOnceForEveryWorkspaceOfTheirs`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/agentcredentials_test.go#L29) | +| The supervisor runs the agent for its owner while it is used: started, paired and listed over the owner's own session on a socket only root opens, and stopped once nobody has used it for half an hour and no chat is at work
*That it stops once idle is the sweep's unit test on a clock the test moves: no lane waits half an hour.* | `AgentService/Start` | [`TestTheSupervisorRunsTheAgentForItsOwner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/t3_test.go#L79) | +| The agent's chats listed on the workspace - titles, paths and times, never a message - reported by its supervisor | [`WorkspaceService/ListAgentThreads`](/reference/api/workspaceservice/) | [`TestTheAgentsThreadsAreListed`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/t3_test.go#L184) | +| The agent's home is a volume of its own: the chats and sessions outlive the workspace, kept in the installation's store as every disk is, and a new workspace mounts them at its creation
*Sealed with the workspace's checkpoints, claimed with the launch beside the disk, and moved with the workspace.* | [`spin workspace create --agent-home`](/reference/cli/workspace/) | [`TestAnAgentsHomeOutlivesItsWorkspace`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/agenthome_test.go#L78) | ### Teams and projects | Feature | Exists | End to end | |---|---|---| -| Open a repository, branch, commit or pull request from its URL, in the dashboard (/launch) and from the terminal
*From the terminal; the dashboard's /launch page makes the same create and has no test of its own against the stack.* | [`spin open --no-connect`](/reference/cli/open/) | [`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L222) | -| A workspace opened at a commit or a pull request, checked out as pr-<n> | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/project_test.go#L153), a test of `internal/e2e` | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/project_test.go#L153)
[`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L222) | -| Teams, with owner, admin and member | [`spin team member role`](/reference/cli/team/) | [`TestE2E_ATeamRoleIsWhatItsHolderMayDo`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L502) | -| A team's own identity providers | [`TeamService/CreateIdentityProvider`](/reference/api/teamservice/) | [`TestE2E_ATeamsIdentityProviderIsItsAdminsAndSignsNobodyIn`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L534) | +| Open a repository, branch, commit or pull request from its URL, in the dashboard (/launch) and from the terminal
*From the terminal; the dashboard's /launch page makes the same create and has no test of its own against the stack.* | [`spin open --no-connect`](/reference/cli/open/) | [`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L222) | +| A workspace opened at a commit or a pull request, checked out as pr-<n> | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/project_test.go#L153), a test of `internal/e2e` | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/project_test.go#L153)
[`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L222) | +| Teams, with owner, admin and member | [`spin team member role`](/reference/cli/team/) | [`TestE2E_ATeamRoleIsWhatItsHolderMayDo`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L502) | +| A team's own identity providers | [`TeamService/CreateIdentityProvider`](/reference/api/teamservice/) | [`TestE2E_ATeamsIdentityProviderIsItsAdminsAndSignsNobodyIn`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L534) | | Your GitHub account, connected once: private repositories cloned and pushed with nothing on the disk | [`ForgeService/CompleteConnect`](/reference/api/forgeservice/) | not yet: consent takes a person on GitHub's page, and revoking a grant would end the one authorization a lane could live on: checked by hand once per release | | Your GitHub account connected from the CLI, with a code entered on GitHub's page | [`spin git connect`](/reference/cli/git/) | not yet: the code is entered by a person on GitHub's page: checked by hand once per release | | A repository picked from the ones your account reaches | [`spin git repos`](/reference/cli/git/) | not yet: a real GitHub account the lane can search with | -| A team's own network policies, where the installation allows them | [`spin team policy set`](/reference/cli/team/) | [`TestATeamsOwnPolicyIsWhatItsWorkspacesReach`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/team_policy_test.go#L24) | -| Projects of the installation: a repository and the shape of the workspace that opens it, shared with everyone or some | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/project_test.go#L27), a test of `internal/e2e` | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/project_test.go#L27) | -| Prebuilds of a project's refs, as the floor of the workspaces that open them | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/prebuild_test.go#L24), a test of `internal/e2e` | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/prebuild_test.go#L24) | -| A team's workspaces run on the installation's hosts | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/team_test.go#L20), a test of `internal/e2e` | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/team_test.go#L20) | +| A team's own network policies, where the installation allows them | [`spin team policy set`](/reference/cli/team/) | [`TestATeamsOwnPolicyIsWhatItsWorkspacesReach`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/team_policy_test.go#L24) | +| Projects of the installation: a repository and the shape of the workspace that opens it, shared with everyone or some | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/project_test.go#L27), a test of `internal/e2e` | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/project_test.go#L27) | +| Prebuilds of a project's refs, as the floor of the workspaces that open them | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/prebuild_test.go#L24), a test of `internal/e2e` | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/prebuild_test.go#L24) | +| A team's workspaces run on the installation's hosts | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/team_test.go#L20), a test of `internal/e2e` | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/team_test.go#L20) | ### Snapshots | Feature | Exists | End to end | |---|---|---| -| Snapshots of a running workspace's disk | [`WorkspaceService/CreateSnapshot`](/reference/api/workspaceservice/) | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/clone_test.go#L64)
[`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/compaction_test.go#L19) | -| Snapshots with memory, resumed with their processes | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/restore_test.go#L175), a test of `internal/e2e` | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/restore_test.go#L175) | -| Restore a workspace to a snapshot | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/restore_test.go#L29), a test of `internal/e2e` | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/restore_test.go#L29)
[`TestE2E_TheQuickstartsDiffIsWhatTheSiteShows`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/site_e2e_test.go#L24) | -| A diff of the files that changed between two snapshots | [`TestADiffOfTwoSnapshotsIsWhatChangedBetweenThem`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/diff_test.go#L28), a test of `internal/e2e` | [`TestADiffOfTwoSnapshotsNamesWhatWasAddedChangedAndRemoved`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/diff_test.go#L95)
[`TestE2E_TheQuickstartsDiffIsWhatTheSiteShows`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/site_e2e_test.go#L24) | -| Share a snapshot with a person or make it public, and create a workspace from it | [`TestACloneOfASnapshotRegistersAsItself`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/clone_test.go#L23), a test of `internal/e2e` | [`TestASharedSnapshotIsCreatedFromByThePersonItIsSharedWith`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/share_test.go#L21) | -| What looks like a credential is found before a share, and the share refused unless acknowledged | [`ShareService/ShareSnapshot`](/reference/api/shareservice/) | [`TestE2E_ASharedSnapshotIsScannedForCredentials`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L171) | -| A long chain is compacted while the workspace runs | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/compaction_test.go#L19), a test of `internal/e2e` | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/compaction_test.go#L19) | +| Snapshots of a running workspace's disk | [`WorkspaceService/CreateSnapshot`](/reference/api/workspaceservice/) | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/clone_test.go#L64)
[`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/compaction_test.go#L19) | +| Snapshots with memory, resumed with their processes | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/restore_test.go#L175), a test of `internal/e2e` | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/restore_test.go#L175) | +| Restore a workspace to a snapshot | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/restore_test.go#L29), a test of `internal/e2e` | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/restore_test.go#L29)
[`TestE2E_TheQuickstartsDiffIsWhatTheSiteShows`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/site_e2e_test.go#L24) | +| A diff of the files that changed between two snapshots | [`TestADiffOfTwoSnapshotsIsWhatChangedBetweenThem`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/diff_test.go#L28), a test of `internal/e2e` | [`TestADiffOfTwoSnapshotsNamesWhatWasAddedChangedAndRemoved`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/diff_test.go#L95)
[`TestE2E_TheQuickstartsDiffIsWhatTheSiteShows`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/site_e2e_test.go#L24) | +| Share a snapshot with a person or make it public, and create a workspace from it | [`TestACloneOfASnapshotRegistersAsItself`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/clone_test.go#L23), a test of `internal/e2e` | [`TestASharedSnapshotIsCreatedFromByThePersonItIsSharedWith`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/share_test.go#L21) | +| What looks like a credential is found before a share, and the share refused unless acknowledged | [`ShareService/ShareSnapshot`](/reference/api/shareservice/) | [`TestE2E_ASharedSnapshotIsScannedForCredentials`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L171) | +| A long chain is compacted while the workspace runs | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/compaction_test.go#L19), a test of `internal/e2e` | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/compaction_test.go#L19) | ### Network | Feature | Exists | End to end | |---|---|---| -| Egress is closed by default; policies, by tag, name what a workspace may reach | [`TestAnOwnerMayOnlyChooseAPolicyTheInstallationDeclares`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/retag_test.go#L163), a test of `internal/e2e` | [`TestAWorkspaceNamedNoPolicyReachesNothing`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/retag_test.go#L71)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/retag_test.go#L24) | -| A workspace's DNS goes upstream only for what its policy names, so a policy that closes egress closes the tunnel through names | [`TestAWorkspaceAsksItsResolverOnlyWhatItsPolicyNames`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/resolver_test.go#L76), a test of `internal/e2e` | [`TestAWorkspaceAsksItsResolverOnlyWhatItsPolicyNames`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/resolver_test.go#L76) | -| A policy changed reaches the host that runs the workspace | [`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/retag_test.go#L24), a test of `internal/e2e` | [`TestAnEditedPolicyChangesWhatARunningGuestReaches`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/retag_test.go#L100)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/retag_test.go#L24) | -| Brokered names: the host's proxy stands in and adds what the workspace never holds - a team secret, a forge token, its identity, a cloud role
*The team secret's value is read at the origin; the forge token, identity and cloud role injections have no test against the stack.* | [`spin team secret set`](/reference/cli/team/) | [`TestAPersonsRuleAndAnAgentsOnOneNameEachArriveWithTheirOwnInjection`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L99) | -| What a workspace reached, what it looked up and what it was refused | [`spin workspace egress`](/reference/cli/workspace/) | [`TestE2E_EgressIsAnsweredByTheHostTheWorkspaceRunsOn`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L848) | -| Each request to a brokered name as the proxy read it, served or refused and why; and whether each injection's secret is the team's to give | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L27), a test of `internal/e2e` | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L27) | -| The egress proxy is a process of its own, holding no key of the host's, started again by the runner when it ends | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/egress_process_test.go#L21), a test of `internal/e2e` | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/egress_process_test.go#L21) | -| A brokered rule names whose it is, the agent's or the person's: one policy says what each may reach and with what | [`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L71), a test of `internal/e2e` | [`TestAPersonsRuleAndAnAgentsOnOneNameEachArriveWithTheirOwnInjection`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L99)
[`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L71) | -| A WebSocket to a brokered name: its handshake under the rule's headers and scope, then bytes each way
*The rule's header on the handshake is not read at the origin: the lane's WebSocket echo answers frames, not headers.* | [`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L167), a test of `internal/e2e` | [`TestAWebSocketToABrokeredNameCarriesTheGuestsBytesAndRefusesAPathOutOfScope`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L195)
[`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L167) | -| HTTP/2 to a brokered name, the proxy's ALPN the real host's: a rule's headers set stream by stream, gRPC's trailers both ways
*gRPC's trailers are egressproxy's h2 test against an origin of its own; the lane has no gRPC origin to reach.* | [`TestHTTP2ToABrokeredNameIsTheRealHosts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L230), a test of `internal/e2e` | [`TestHTTP2ToABrokeredNameIsTheRealHosts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L230)
[`TestEachStreamOfAnHTTP2ConnectionToABrokeredNameCarriesTheRulesHeader`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L250) | -| Watch where a workspace connects, into its logs | [`spin workspace watch`](/reference/cli/workspace/) | [`TestE2E_AWatchedWorkspacesConnectionsAreInItsLogs`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L388) | -| An agent the supervisor starts is marked, and reaches only brokered names | [`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/seal_test.go#L21), a test of `internal/e2e` | [`TestAnAgentReachesOnlyBrokeredNames`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/brokered_test.go#L137)
[`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/seal_test.go#L21) | -| Published ports at https://{port}-{workspace}.{domain}: private, whitelisted or public | [`spin port expose`](/reference/cli/port/) | [`TestAPublicPortIsReachedWithNoSessionAtAll`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/proxy/lane_test.go#L144)
[`workspace-sign-in.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/workspace-sign-in.spec.ts#L31): a visitor signed in to the dashboard reaches their private port | +| Egress is closed by default; policies, by tag, name what a workspace may reach | [`TestAnOwnerMayOnlyChooseAPolicyTheInstallationDeclares`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/retag_test.go#L163), a test of `internal/e2e` | [`TestAWorkspaceNamedNoPolicyReachesNothing`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/retag_test.go#L71)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/retag_test.go#L24) | +| A workspace's DNS goes upstream only for what its policy names, so a policy that closes egress closes the tunnel through names | [`TestAWorkspaceAsksItsResolverOnlyWhatItsPolicyNames`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/resolver_test.go#L76), a test of `internal/e2e` | [`TestAWorkspaceAsksItsResolverOnlyWhatItsPolicyNames`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/resolver_test.go#L76) | +| A policy changed reaches the host that runs the workspace | [`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/retag_test.go#L24), a test of `internal/e2e` | [`TestAnEditedPolicyChangesWhatARunningGuestReaches`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/retag_test.go#L100)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/retag_test.go#L24) | +| Brokered names: the host's proxy stands in and adds what the workspace never holds - a team secret, a forge token, its identity, a cloud role
*The team secret's value is read at the origin; the forge token, identity and cloud role injections have no test against the stack.* | [`spin team secret set`](/reference/cli/team/) | [`TestAPersonsRuleAndAnAgentsOnOneNameEachArriveWithTheirOwnInjection`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L99) | +| What a workspace reached, what it looked up and what it was refused | [`spin workspace egress`](/reference/cli/workspace/) | [`TestE2E_EgressIsAnsweredByTheHostTheWorkspaceRunsOn`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L848) | +| Each request to a brokered name as the proxy read it, served or refused and why; and whether each injection's secret is the team's to give | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L27), a test of `internal/e2e` | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L27) | +| The egress proxy is a process of its own, holding no key of the host's, started again by the runner when it ends | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/egress_process_test.go#L21), a test of `internal/e2e` | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/egress_process_test.go#L21) | +| A brokered rule names whose it is, the agent's or the person's: one policy says what each may reach and with what | [`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L71), a test of `internal/e2e` | [`TestAPersonsRuleAndAnAgentsOnOneNameEachArriveWithTheirOwnInjection`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L99)
[`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L71) | +| A WebSocket to a brokered name: its handshake under the rule's headers and scope, then bytes each way
*The rule's header on the handshake is not read at the origin: the lane's WebSocket echo answers frames, not headers.* | [`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L167), a test of `internal/e2e` | [`TestAWebSocketToABrokeredNameCarriesTheGuestsBytesAndRefusesAPathOutOfScope`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L195)
[`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L167) | +| HTTP/2 to a brokered name, the proxy's ALPN the real host's: a rule's headers set stream by stream, gRPC's trailers both ways
*gRPC's trailers are egressproxy's h2 test against an origin of its own; the lane has no gRPC origin to reach.* | [`TestHTTP2ToABrokeredNameIsTheRealHosts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L230), a test of `internal/e2e` | [`TestHTTP2ToABrokeredNameIsTheRealHosts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L230)
[`TestEachStreamOfAnHTTP2ConnectionToABrokeredNameCarriesTheRulesHeader`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L250) | +| Watch where a workspace connects, into its logs | [`spin workspace watch`](/reference/cli/workspace/) | [`TestE2E_AWatchedWorkspacesConnectionsAreInItsLogs`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L388) | +| An agent the supervisor starts is marked, and reaches only brokered names | [`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/seal_test.go#L21), a test of `internal/e2e` | [`TestAnAgentReachesOnlyBrokeredNames`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/brokered_test.go#L137)
[`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/seal_test.go#L21) | +| Published ports at https://{port}-{workspace}.{domain}: private, whitelisted or public | [`spin port expose`](/reference/cli/port/) | [`TestAPublicPortIsReachedWithNoSessionAtAll`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/proxy/lane_test.go#L144)
[`workspace-sign-in.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/workspace-sign-in.spec.ts#L31): a visitor signed in to the dashboard reaches their private port | ### Access | Feature | Exists | End to end | |---|---|---| | Sign in with GitHub or an OIDC provider | [`AuthService/StartLogin`](/reference/api/authservice/) | not yet: a GitHub provider: the sign-in through it and the verified email it gives | -| Device login for a terminal | [`AuthService/StartDeviceLogin`](/reference/api/authservice/) | [`TestE2E_Logout`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L1217)
[`auth.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/auth.spec.ts#L18): the CLI's device page stands alone and keeps its code through a sign-in | -| API keys for scripts and agents | [`spin api-key create`](/reference/cli/api-key/) | [`TestE2E_APIKeyCRUD`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L1172) | -| SSH keys, and plain ssh to spin.<workspace> | [`spin ssh-config`](/reference/cli/ssh-config/) | [`TestE2E_SSHConfigCarriesSSHToAWorkspace`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L719) | -| A key logs in only once its person adds it with a passkey: their own for good, a browser's for twelve hours | [`PasskeyService/BeginPasskeyCeremony`](/reference/api/passkeyservice/) | [`TestOnlyTheOwnerAndTheirGuestsLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/login_test.go#L174) | -| Guests of a workspace, let in by its owner with a passkey | [`spin workspace guests`](/reference/cli/workspace/) | [`TestOnlyTheOwnerAndTheirGuestsLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/login_test.go#L174) | -| A workspace's identity, signed by its host, for the audiences its owner allows | [`TestAWorkspacesIdentityIsTheHostsSignatureOfItsSet`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/identity_test.go#L58), a test of `internal/e2e` | [`TestAWorkspacesIdentityIsTheHostsSignatureOfItsSet`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/identity_test.go#L58) | -| VS Code over SSH, with the server the installation publishes and nothing downloaded
*The server is Microsoft's, for Remote-SSH; spin code also opens an editor with Open Remote - SSH, which downloads its own. spin code itself is run by its unit tests only: it opens a desktop editor, which no lane has.* | [`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vscodehotplug_test.go#L23), a test of `internal/e2e` | [`TestTheCarriedVSCodeServerRunsOfflineAndAnswersOverTheSSHTunnel`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vscodeserver_test.go#L86)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vscodehotplug_test.go#L23) | -| Run a command in a workspace, copy files to and from it | [`spin exec`](/reference/cli/exec/) | [`TestE2E_ADetachedRunIsFollowedToItsEndAndFilesGoBothWays`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L306) | -| A program runs a command and reads and writes files in a workspace through the API, with a key that holds workspace:exec, every call recorded with the key it came on | [`ExecService/Exec`](/reference/api/execservice/) | [`TestAKeyWithExecRunsACommandInAWorkspaceAndOneWithoutIsRefused`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/exec_test.go#L36) | -| An agent works in workspaces through `spin mcp` on a key delegated to it: never more than the key it came from - scopes, team, projects, end, how many workspaces and cores its tree holds - and revoked with it | [`spin mcp`](/reference/cli/mcp/) | [`TestE2E_AnAgentDrivesAWorkspaceThroughMCPOnADelegatedKey`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/mcp_e2e_test.go#L62) | -| An agent in a workspace drives others with spin, on a key it gets for the workspace's own SPIFFE identity - a child of the key that made the workspace, through its host, whatever the workspace's network
*No forge in the lane: a workspace reaches no private or host address, and no test repository has a credential in CI yet, so an agent opening a pull request is not run.* | [`AuthService/ExchangeWorkloadToken`](/reference/api/authservice/) | [`TestAnAgentInAWorkspaceDrivesAnotherOnTheIdentityOfItsWorkspace`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/inception_test.go#L97) | +| Device login for a terminal | [`AuthService/StartDeviceLogin`](/reference/api/authservice/) | [`TestE2E_Logout`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L1217)
[`auth.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/auth.spec.ts#L18): the CLI's device page stands alone and keeps its code through a sign-in | +| API keys for scripts and agents | [`spin api-key create`](/reference/cli/api-key/) | [`TestE2E_APIKeyCRUD`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L1172) | +| SSH keys, and plain ssh to spin.<workspace> | [`spin ssh-config`](/reference/cli/ssh-config/) | [`TestE2E_SSHConfigCarriesSSHToAWorkspace`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L719) | +| A key logs in only once its person adds it with a passkey: their own for good, a browser's for twelve hours | [`PasskeyService/BeginPasskeyCeremony`](/reference/api/passkeyservice/) | [`TestOnlyTheOwnerAndTheirGuestsLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/login_test.go#L174) | +| Guests of a workspace, let in by its owner with a passkey | [`spin workspace guests`](/reference/cli/workspace/) | [`TestOnlyTheOwnerAndTheirGuestsLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/login_test.go#L174) | +| A workspace's identity, signed by its host, for the audiences its owner allows | [`TestAWorkspacesIdentityIsTheHostsSignatureOfItsSet`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/identity_test.go#L58), a test of `internal/e2e` | [`TestAWorkspacesIdentityIsTheHostsSignatureOfItsSet`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/identity_test.go#L58) | +| VS Code over SSH, with the server the installation publishes and nothing downloaded
*The server is Microsoft's, for Remote-SSH; spin code also opens an editor with Open Remote - SSH, which downloads its own. spin code itself is run by its unit tests only: it opens a desktop editor, which no lane has.* | [`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vscodehotplug_test.go#L23), a test of `internal/e2e` | [`TestTheCarriedVSCodeServerRunsOfflineAndAnswersOverTheSSHTunnel`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vscodeserver_test.go#L86)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vscodehotplug_test.go#L23) | +| Run a command in a workspace, copy files to and from it | [`spin exec`](/reference/cli/exec/) | [`TestE2E_ADetachedRunIsFollowedToItsEndAndFilesGoBothWays`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L306) | +| A program runs a command and reads and writes files in a workspace through the API, with a key that holds workspace:exec, every call recorded with the key it came on | [`ExecService/Exec`](/reference/api/execservice/) | [`TestAKeyWithExecRunsACommandInAWorkspaceAndOneWithoutIsRefused`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/exec_test.go#L36) | +| An agent works in workspaces through `spin mcp` on a key delegated to it: never more than the key it came from - scopes, team, projects, end, how many workspaces and cores its tree holds - and revoked with it | [`spin mcp`](/reference/cli/mcp/) | [`TestE2E_AnAgentDrivesAWorkspaceThroughMCPOnADelegatedKey`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/mcp_e2e_test.go#L62) | +| An agent in a workspace drives others with spin, on a key it gets for the workspace's own SPIFFE identity - a child of the key that made the workspace, through its host, whatever the workspace's network
*No forge in the lane: a workspace reaches no private or host address, and no test repository has a credential in CI yet, so an agent opening a pull request is not run.* | [`AuthService/ExchangeWorkloadToken`](/reference/api/authservice/) | [`TestAnAgentInAWorkspaceDrivesAnotherOnTheIdentityOfItsWorkspace`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/inception_test.go#L97) | ### Administration | Feature | Exists | End to end | |---|---|---| -| Installation settings seeded from a file; a change in the file is a proposal to apply or dismiss | [`AdminService/DecideConfigChange`](/reference/api/adminservice/) | [`TestTheInstallationFileSeedsAndItsChangesAreAnAdministratorsToDecide`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/config_file_test.go#L92) | -| Resource presets | [`AdminService/CreateResourcePreset`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/admin.spec.ts#L439): an admin's preset sizes a person's workspace, and is gone once deleted | -| Registration: open, by allowlist, or closed | [`AdminService/SetRegistrationMode`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/admin.spec.ts#L235): closed, open and a domain on the allowlist decide who registers
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/admin.spec.ts#L168): the allowlist lets in who it names, and nobody else | -| An audit log | [`AdminService/ListAuditLog`](/reference/api/adminservice/) | [`TestE2E_AnAdministratorsActionIsAuditedWithItsActorAndTarget`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L609)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/admin.spec.ts#L937): admin reads the log and can narrow it to one kind of event | -| The control plane's jobs, and running one now | [`spin admin jobs`](/reference/cli/admin/) | [`TestE2E_Admin`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L1075)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/admin.spec.ts#L730): admin runs a job by hand and sees how it ended | +| Installation settings seeded from a file; a change in the file is a proposal to apply or dismiss | [`AdminService/DecideConfigChange`](/reference/api/adminservice/) | [`TestTheInstallationFileSeedsAndItsChangesAreAnAdministratorsToDecide`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/config_file_test.go#L92) | +| Resource presets | [`AdminService/CreateResourcePreset`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/admin.spec.ts#L444): an admin's preset sizes a person's workspace, and is gone once deleted | +| Registration: open, by allowlist, or closed | [`AdminService/SetRegistrationMode`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/admin.spec.ts#L240): closed, open and a domain on the allowlist decide who registers
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/admin.spec.ts#L173): the allowlist lets in who it names, and nobody else | +| An audit log | [`AdminService/ListAuditLog`](/reference/api/adminservice/) | [`TestE2E_AnAdministratorsActionIsAuditedWithItsActorAndTarget`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L609)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/admin.spec.ts#L972): admin reads the log and can narrow it to one kind of event | +| The control plane's jobs, and running one now | [`spin admin jobs`](/reference/cli/admin/) | [`TestE2E_Admin`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L1075)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/admin.spec.ts#L740): admin runs a job by hand and sees how it ended | | The month's bill, its forecast, and what each workspace cost | [`spin admin costs`](/reference/cli/admin/) | not yet: the cloud's real bill read: no lane has an AWS account, so the bill a test gives the reader stands in for it | -| The store: every volume, whose it is, and taking out what nothing needs | [`spin admin storage list`](/reference/cli/admin/) | [`TestAVolumeNothingNeedsIsTakenOutOfTheStore`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/orphan_test.go#L26) | -| Re-key a workspace's disk | [`spin admin volume rekey`](/reference/cli/admin/) | [`TestARekeyedDiskBootsWithWhatItHeldUnderANewKey`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/rekey_test.go#L24) | -| Runners: registration tokens, drain, activate, revoke, and a policy per host | [`spin admin runner drain`](/reference/cli/admin/) | [`TestARunnerRegisteredWithATokenTheAPIMadeIsRevokedByTheAdmin`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/runner_token_test.go#L99)
[`TestARegistrationTokenExpiredOrRevokedRegistersNothing`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/runner_token_test.go#L148) | +| The store: every volume, whose it is, and taking out what nothing needs | [`spin admin storage list`](/reference/cli/admin/) | [`TestAVolumeNothingNeedsIsTakenOutOfTheStore`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/orphan_test.go#L26) | +| Re-key a workspace's disk | [`spin admin volume rekey`](/reference/cli/admin/) | [`TestARekeyedDiskBootsWithWhatItHeldUnderANewKey`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/rekey_test.go#L24) | +| Runners: registration tokens, drain, activate, revoke, and a policy per host | [`spin admin runner drain`](/reference/cli/admin/) | [`TestARunnerRegisteredWithATokenTheAPIMadeIsRevokedByTheAdmin`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/runner_token_test.go#L99)
[`TestARegistrationTokenExpiredOrRevokedRegistersNothing`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/runner_token_test.go#L148) | | Runners start when a workspace waits for one and stop when nothing runs | [`HostService/GetFleet`](/reference/api/hostservice/) | not yet: an autoscaling group to start and stop: the one group is AWS's, and no lane has an account | -| A root shell on a runner, for a while and with a reason: the runner emptied first, every session recorded under Object Lock, the runner retired after | [`spin admin shell open`](/reference/cli/admin/) | [`TestHostsARootShellOnAHostIsRecordedAndItsHostRetired`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/hosts_test.go#L420) | -| A host that reboots brings its workspaces back | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/restart_test.go#L38), a test of `internal/e2e` | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/restart_test.go#L38) | -| A cloud's reclaim warning empties the host before the machine goes | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/preemption_test.go#L26), a test of `internal/e2e` | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/preemption_test.go#L26) | -| A writeback bound per host, measured on that host before it is taken | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/writeback_test.go#L28), a test of `internal/e2e` | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/writeback_test.go#L28) | -| What is running where: the control plane, each runner and its machine | [`spin admin versions`](/reference/cli/admin/) | [`TestE2E_Admin`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L1075) | +| A root shell on a runner, for a while and with a reason: the runner emptied first, every session recorded under Object Lock, the runner retired after | [`spin admin shell open`](/reference/cli/admin/) | [`TestHostsARootShellOnAHostIsRecordedAndItsHostRetired`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/hosts_test.go#L420) | +| A host that reboots brings its workspaces back | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/restart_test.go#L38), a test of `internal/e2e` | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/restart_test.go#L38) | +| A cloud's reclaim warning empties the host before the machine goes | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/preemption_test.go#L26), a test of `internal/e2e` | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/preemption_test.go#L26) | +| A writeback bound per host, measured on that host before it is taken | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/writeback_test.go#L28), a test of `internal/e2e` | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/writeback_test.go#L28) | +| What is running where: the control plane, each runner and its machine | [`spin admin versions`](/reference/cli/admin/) | [`TestE2E_Admin`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L1075) | +| A workspace whose host never comes back is moved when little would be lost, and its owner is told when it waits for them | [`WorkspaceService/RecoverWorkspace`](/reference/api/workspaceservice/) | not yet: the move without asking and the wait it records are tested against the database (workspaceserver's autorehome tests); the hosts lane recovers by hand, and no lane has an SMTP server to receive the owner's email | ### Observability | Feature | Exists | End to end | |---|---|---| -| Platform logs, workspace logs and traces, searched in the product | [`LogService/SearchPlatformLogs`](/reference/api/logservice/) | [`TestAWorkspacesLinesAndTracesAreFoundBySearchingForIt`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/observe_test.go#L179)
[`TestE2E_TheInstallationsLogsAreSearchable`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L1012) | -| Metrics, with Grafana on the control plane | [`AdminService/GetMonitoring`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/admin.spec.ts#L1223): a series of the lane's host is in the metric store, read through Grafana
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/dashboard/e2e/admin.spec.ts#L1192): admin reads the installation's dashboards without leaving the page | -| A workspace's journal and console are collected as the installation's policy says | [`spin workspace logs`](/reference/cli/workspace/) | [`TestE2E_AWorkspacesConsoleIsKeptAndSearchable`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/e2e_test.go#L1033) | -| A workspace's last hour of CPU, memory and network against what it holds, for its owner
*Kept on the host, so it starts again with a restart of it or a move; the disk's use is not sampled.* | [`WorkspaceService/GetWorkspaceUsage`](/reference/api/workspaceservice/) | [`TestAWorkspacesUsageIsWhatItsHostSampled`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/host_report_test.go#L98) | +| A workspace's owner is told by email when it waits for them or something happened to it, each event switchable
*Held after its host was lost, a stop that could not be taken, stopped for not responding, moved off a lost host. A disk almost full is not an event yet.* | [`SettingsService/UpdateNotificationPreferences`](/reference/api/settingsservice/) | not yet: no lane has an SMTP server: delivery is tested against a generated mail server, with every attempt and retry recorded (internal/controlplane/notify) | +| Platform logs, workspace logs and traces, searched in the product | [`LogService/SearchPlatformLogs`](/reference/api/logservice/) | [`TestAWorkspacesLinesAndTracesAreFoundBySearchingForIt`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/observe_test.go#L179)
[`TestE2E_TheInstallationsLogsAreSearchable`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L1012) | +| Metrics, with Grafana on the control plane | [`AdminService/GetMonitoring`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/admin.spec.ts#L1312): a series of the lane's host is in the metric store, read through Grafana
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/dashboard/e2e/admin.spec.ts#L1281): admin reads the installation's dashboards without leaving the page | +| A workspace's journal and console are collected as the installation's policy says | [`spin workspace logs`](/reference/cli/workspace/) | [`TestE2E_AWorkspacesConsoleIsKeptAndSearchable`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/e2e_test.go#L1033) | +| A workspace's last hour of CPU, memory and network against what it holds, for its owner
*Kept on the host, so it starts again with a restart of it or a move; the disk's use is not sampled.* | [`WorkspaceService/GetWorkspaceUsage`](/reference/api/workspaceservice/) | [`TestAWorkspacesUsageIsWhatItsHostSampled`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/host_report_test.go#L98) | ### Platform | Feature | Exists | End to end | |---|---|---| -| A smoke test of what an installation's API promises, with a workspace of its own | [`spin smoke`](/reference/cli/smoke/) | [`TestE2E_SmokePassesAndLeavesNothingBehind`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/cmd/cli/journeys_e2e_test.go#L437) | -| A host serves only the releases it carries
*A resume whose recorded release was collected since has no test against the stack.* | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/suspend_test.go#L126), a test of `internal/e2e` | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/suspend_test.go#L126)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/internal/e2e/vscodehotplug_test.go#L23) | +| A smoke test of what an installation's API promises, with a workspace of its own | [`spin smoke`](/reference/cli/smoke/) | [`TestE2E_SmokePassesAndLeavesNothingBehind`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/cmd/cli/journeys_e2e_test.go#L437) | +| A host serves only the releases it carries
*A resume whose recorded release was collected since has no test against the stack.* | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/suspend_test.go#L126), a test of `internal/e2e` | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/suspend_test.go#L126)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/internal/e2e/vscodehotplug_test.go#L23) | ## Partly there @@ -152,7 +154,6 @@ Each is an item of `docs/ROADMAP.md`, with the command that checks it. - **What a workspace grew to is asked for and never recorded** (Workspaces) - **Placement cannot be told which kind of host a workspace belongs on** (Workspaces) -- **A workspace whose host never comes back is moved only when little would be lost** (Administration) ## Limits @@ -173,5 +174,5 @@ Not planned: a limit of the platform or of where it runs today. [Limitations](/o - **No multi-factor authentication of Spinbox's own** (Access): Sign in through a provider that enforces it. - **No team invitations** (Access): A person signs in once before they can be added to a team; a workspace's guests are invited by email. - **Team roles are fixed** (Access): Owner, admin and member. -- **Nothing pages anyone** (Observability): Metrics, logs and traces stay inside the installation; alert rules fire in its Grafana and no contact point tells anyone. +- **Nothing pages the operator** (Observability): Metrics, logs and traces stay inside the installation; alert rules fire in its Grafana and no contact point tells anyone. A workspace's owner is emailed when it waits for them. - **An update is one way** (Administration): A release older than the one that last started the database refuses to start on it. diff --git a/src/content/docs/use/access.md b/src/content/docs/use/access.md index 40d32a2..9f3faee 100644 --- a/src/content/docs/use/access.md +++ b/src/content/docs/use/access.md @@ -16,7 +16,7 @@ the audit log. Give it `keys:delegate` and it makes keys of its own for the agen (`spin mcp` serves them the API): each holds no more than it does - its scopes, team, projects, end, and how many workspaces and cores all of them hold - and goes when you revoke it. Why, and what it trades, is -[ADR-0031](https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/decisions/ADR-0031-a-passkey-buys-a-key-the-control-plane-certifies.md). +[ADR-0031](https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/decisions/ADR-0031-a-passkey-buys-a-key-the-control-plane-certifies.md). The control plane decides who logs in, at every session: it certifies a key of yours, for five minutes, into a workspace you own or are a guest of. It also holds what it needs to serve you: your diff --git a/src/content/docs/use/dashboard.md b/src/content/docs/use/dashboard.md index cd860c5..7d4943e 100644 --- a/src/content/docs/use/dashboard.md +++ b/src/content/docs/use/dashboard.md @@ -7,7 +7,7 @@ editUrl: false -The dashboard is at `https://app.`. These screenshots are of spin v20261108.01, taken by spin's dashboard suite on its end-to-end stack - real workspaces on a real runner - each by a test that first checks the screen shows what its title says. Everything here is also in the [CLI](/reference/cli/) and the [API](/reference/api/). +The dashboard is at `https://app.`. These screenshots are of spin v20261110.01, taken by spin's dashboard suite on its end-to-end stack - real workspaces on a real runner - each by a test that first checks the screen shows what its title says. Everything here is also in the [CLI](/reference/cli/) and the [API](/reference/api/). ## A person's workspaces diff --git a/src/data/features.json b/src/data/features.json index 0c506b0..32fab04 100644 --- a/src/data/features.json +++ b/src/data/features.json @@ -516,7 +516,7 @@ "name": "Claude Code, Codex and T3 Code on every workspace's PATH, at the versions the release pins, with their own defaults", "state": "built", "proof": "e2e:TestTheAgentCLIsAreOnPathWithThePinnedVersions", - "note": "Where the installation fetches them (agents_fetch) or an operator publishes them: no image carries Claude Code, which only Anthropic may distribute.", + "note": "Where an administrator accepted their terms (Admin → Extensions) or an operator publishes them: no image carries Claude Code, which only Anthropic may distribute.", "endToEnd": [ "go:internal/e2e.TestTheAgentCLIsAreOnPathWithThePinnedVersions" ] @@ -859,10 +859,19 @@ }, { "area": "Administration", - "name": "A workspace whose host never comes back is moved only when little would be lost", - "state": "not", - "proof": "", - "note": "" + "name": "A workspace whose host never comes back is moved when little would be lost, and its owner is told when it waits for them", + "state": "built", + "proof": "rpc:spin.v1.WorkspaceService/RecoverWorkspace", + "note": "", + "endToEndGap": "the move without asking and the wait it records are tested against the database (workspaceserver's autorehome tests); the hosts lane recovers by hand, and no lane has an SMTP server to receive the owner's email" + }, + { + "area": "Observability", + "name": "A workspace's owner is told by email when it waits for them or something happened to it, each event switchable", + "state": "built", + "proof": "rpc:spin.v1.SettingsService/UpdateNotificationPreferences", + "note": "Held after its host was lost, a stop that could not be taken, stopped for not responding, moved off a lost host. A disk almost full is not an event yet.", + "endToEndGap": "no lane has an SMTP server: delivery is tested against a generated mail server, with every attempt and retry recorded (internal/controlplane/notify)" }, { "area": "Observability", @@ -1034,10 +1043,10 @@ }, { "area": "Observability", - "name": "Nothing pages anyone", + "name": "Nothing pages the operator", "state": "limit", "proof": "", - "note": "Metrics, logs and traces stay inside the installation; alert rules fire in its Grafana and no contact point tells anyone." + "note": "Metrics, logs and traces stay inside the installation; alert rules fire in its Grafana and no contact point tells anyone. A workspace's owner is emailed when it waits for them." }, { "area": "Administration", diff --git a/src/data/figures.json b/src/data/figures.json index 1fdb488..627c827 100644 --- a/src/data/figures.json +++ b/src/data/figures.json @@ -1,6 +1,6 @@ { "datapath": { - "source": "https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/network/datapath", + "source": "https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/network/datapath", "width": 552, "words": [ "How a packet leaves a workspace", @@ -56,7 +56,7 @@ ] }, "egress-policy": { - "source": "https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/network/egress-policy", + "source": "https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/network/egress-policy", "width": 923, "words": [ "What the forward chain decides, in order", @@ -173,7 +173,7 @@ ] }, "isolation": { - "source": "https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/network/isolation", + "source": "https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/network/isolation", "width": 499, "words": [ "Same address, different segment", @@ -220,7 +220,7 @@ ] }, "traffic": { - "source": "https://github.com/spin-stack/spin/blob/dafe286161a95bb1dd1dba3a99f722946ad65961/docs/security/traffic", + "source": "https://github.com/spin-stack/spin/blob/b7ba5206f12ba93a829a48e354be7fce6bc65db4/docs/security/traffic", "width": 1889, "words": [ "Traffic: every arrow is a connection opened in its direction, and nothing else is let in", diff --git a/src/data/pricing.json b/src/data/pricing.json index e7db360..c0878db 100644 --- a/src/data/pricing.json +++ b/src/data/pricing.json @@ -1,6 +1,6 @@ { - "generated": "2026-11-09", - "published": "2026-11-07T00:28:52Z", + "generated": "2026-11-11", + "published": "2026-11-10T17:38:52Z", "source": "https://b0.p.awsstatic.com/pricing/2.0/meteredUnitMaps/ec2/USD/current/ec2-ondemand-without-sec-sel/\u003cregion\u003e/Linux/index.json", "machines": { "controlPlane": "t8i.medium", diff --git a/src/data/reference.json b/src/data/reference.json index 2dc40f5..993e8f7 100644 --- a/src/data/reference.json +++ b/src/data/reference.json @@ -1,8 +1,8 @@ { "spin": { "installs": "v20261027.01", - "commit": "dafe286161a95bb1dd1dba3a99f722946ad65961", - "tag": "v20261108.01", + "commit": "b7ba5206f12ba93a829a48e354be7fce6bc65db4", + "tag": "v20261110.01", "machine": "v20261026.01" }, "terraform": { @@ -10,15 +10,15 @@ "release": "v20261027.02" }, "brand": { - "commit": "85864c646d05aeedc46af942df0f86674283333d" + "commit": "e5d547cff92ba84137e7d3af0eae5eee04c63cd8" }, "counts": { - "built": 89, + "built": 91, "partial": 0, - "notBuilt": 3, + "notBuilt": 2, "limits": 17, "endToEnd": 83, - "gap": 6 + "gap": 8 }, - "openapiSha256": "3633dc4c9651092c47f1bf60cecde510322e2e148472f8aff582abca2c0dc0cc" + "openapiSha256": "df426012d8424746aed6a141797c96a4e0495082d4dad613dac78bad6b738929" } diff --git a/src/data/shots.json b/src/data/shots.json index f176373..61a6918 100644 --- a/src/data/shots.json +++ b/src/data/shots.json @@ -1,6 +1,6 @@ { - "release": "v20261108.01", - "commit": "dafe286161a95bb1dd1dba3a99f722946ad65961", + "release": "v20261110.01", + "commit": "b7ba5206f12ba93a829a48e354be7fce6bc65db4", "shots": [ { "name": "workspaces", diff --git a/versions.yaml b/versions.yaml index 46abb2f..9c4ca6e 100644 --- a/versions.yaml +++ b/versions.yaml @@ -7,8 +7,8 @@ - name: spin kind: git source: https://github.com/spin-stack/spin - version: v20261108.01 - pin: dafe286161a95bb1dd1dba3a99f722946ad65961 + version: v20261110.01 + pin: b7ba5206f12ba93a829a48e354be7fce6bc65db4 track: github-release note: >- The release the site documents (D2: the newest, exactly). The daily sync moves it to the next @@ -29,7 +29,7 @@ kind: git source: https://github.com/spin-stack/brand version: main - pin: 85864c646d05aeedc46af942df0f86674283333d + pin: e5d547cff92ba84137e7d3af0eae5eee04c63cd8 track: branch note: >- The palette and the logos. brand cuts no releases, so its main is what it has to say. The From cba28457a93dea2b8e965592262eeec9bf24aa60 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 11 Nov 2026 20:10:10 -0300 Subject: [PATCH 2/3] refgen: a flag that takes no value is read as the CLI now prints it spin v20261110.01's help prints one as --wait[=true|false], which the flag reader took for no flag at all: every --wait, --start and --with-memory a page quotes failed. Co-Authored-By: Claude Fable 5.2 --- tools/refgen/commands.go | 3 ++- tools/refgen/prose_test.go | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tools/refgen/commands.go b/tools/refgen/commands.go index 7be8fd3..c89213e 100644 --- a/tools/refgen/commands.go +++ b/tools/refgen/commands.go @@ -107,7 +107,8 @@ var ( fence = regexp.MustCompile("^```(bash|sh|shell|console)\\s*$") // A cobra flag line: " -o, --output string text" or " --wait text". The type, // when there is one, is a single word before the description's run of spaces. - flagLine = regexp.MustCompile(`^\s+(?:-(\w), )?--([\w-]+)(?: (\w+))?(?:\s{2,}|$)`) + // A flag that takes no value is printed with the values it may be given, --wait[=true|false]. + flagLine = regexp.MustCompile(`^\s+(?:-(\w), )?--([\w-]+)(?:\[=[^\]\s]*\])?(?: (\w+))?(?:\s{2,}|$)`) ) type shellLine struct { diff --git a/tools/refgen/prose_test.go b/tools/refgen/prose_test.go index 2999002..ace71d9 100644 --- a/tools/refgen/prose_test.go +++ b/tools/refgen/prose_test.go @@ -102,3 +102,20 @@ func TestSpinDocBecomesAPage(t *testing.T) { t.Errorf("shellFences:\n%s\nwant:\n%s", got, want) } } + +// A flag is read from the help whether it takes a value, takes none, or is printed with the +// values a flag that takes none may be given. +func TestFlagsOfReadsEveryFormAFlagIsPrintedIn(t *testing.T) { + flags := flagsOf("Usage:\n spin x [flags]\n\nFlags:\n" + + " -h, --help[=true|false] help for x\n" + + " --name string Workspace name\n" + + " --wait[=true|false] Return once it runs\n" + + " --force Do not wait\n\nGlobal Flags:\n" + + " -o, --output string text or json\n") + for name, value := range map[string]bool{"help": false, "h": false, "name": true, "wait": false, "force": false, "output": true, "o": true} { + f, ok := flags[name] + if !ok || f.value != value { + t.Errorf("--%s: read %v, takes a value %v; want read, takes a value %v", name, ok, f.value, value) + } + } +} From 6cd080626e851251b52b7ce23d8db57dbc5b96a0 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 11 Nov 2026 20:10:10 -0300 Subject: [PATCH 3/3] pages: read against spin v20261110.01, and what it changed in them The check named twenty-one reads of seventeen pages; each file's diff was read against its pages, and four changed. VS Code's server is prepared once an administrator has accepted its terms, not by vscode_fetch, and spin code refuses where its download has no room. A group's runner is taken out with spin admin runner remove. An installation that names no presets is given one. A workspace's owner is told by email when it waits for them, which the board's limit now says of the operator alone. Co-Authored-By: Claude Fable 5.2 --- src/content/docs/admin/configuration.md | 4 ++-- src/content/docs/admin/hosts.mdx | 12 ++++++++++-- src/content/docs/admin/observability.md | 4 ++-- src/content/docs/concepts/images.md | 4 ++-- src/content/docs/concepts/network.mdx | 4 ++-- src/content/docs/concepts/runners.mdx | 14 +++++++++----- src/content/docs/concepts/snapshots.md | 6 +++--- src/content/docs/concepts/volumes.mdx | 4 ++-- src/content/docs/concepts/workspaces.md | 11 ++++++----- src/content/docs/overview/evaluate.md | 4 ++-- src/content/docs/overview/how-it-works.mdx | 8 ++++---- src/content/docs/overview/index.md | 2 +- src/content/docs/overview/limitations.md | 5 +++-- src/content/docs/overview/one-machine.md | 4 ++-- src/content/docs/security/data.md | 4 ++-- src/content/docs/security/identity.md | 4 ++-- src/content/docs/security/supply-chain.md | 4 ++-- src/content/docs/use/cli.md | 8 ++++---- src/content/docs/use/editors.md | 18 +++++++++--------- 19 files changed, 69 insertions(+), 55 deletions(-) diff --git a/src/content/docs/admin/configuration.md b/src/content/docs/admin/configuration.md index f394a35..d68b787 100644 --- a/src/content/docs/admin/configuration.md +++ b/src/content/docs/admin/configuration.md @@ -2,8 +2,8 @@ title: Installation settings description: "How an installation is configured: the file that seeds it, the dashboard that edits it, and how a changed file becomes a proposal." reads: - - "spin:configs/spin-example.yaml@v20261108.01" - - "spin:internal/controlplane/installconfig/apply.go@v20261108.01" + - "spin:configs/spin-example.yaml@v20261110.01" + - "spin:internal/controlplane/installconfig/apply.go@v20261110.01" --- An installation's settings live in its database, and an administrator edits all of them in the diff --git a/src/content/docs/admin/hosts.mdx b/src/content/docs/admin/hosts.mdx index d42165d..fece0e6 100644 --- a/src/content/docs/admin/hosts.mdx +++ b/src/content/docs/admin/hosts.mdx @@ -2,8 +2,8 @@ title: Operating hosts description: Drain, activate and revoke runners, see what runs where, replace a runner's machine, and add a runner outside the autoscaling group. reads: - - "spin:docs/runners.md@v20261108.01" - - "spin:cmd/cli/cmd/admin.go@v20261108.01" + - "spin:docs/runners.md@v20261110.01" + - "spin:cmd/cli/cmd/admin.go@v20261110.01" - "spin-terraform-aws:modules/runners/main.tf@v20261027.02" --- @@ -49,6 +49,14 @@ behind, what a revoke refuses, and how the capacity comes back. ## Replacing a runner's machine on AWS +A runner of the group that should go for good is given back to it, which terminates the machine +and is asked for one less. It drains as it goes, and one that is the only home of a workspace's +disk is refused, naming them: + +```bash +spin admin runner remove +``` + After a revoke, or when a runner is wedged, terminate its instance without lowering the group's size. The group starts another, which joins by its role: diff --git a/src/content/docs/admin/observability.md b/src/content/docs/admin/observability.md index a777c90..1a9c126 100644 --- a/src/content/docs/admin/observability.md +++ b/src/content/docs/admin/observability.md @@ -68,8 +68,8 @@ minute. ## What is not there -- **Nothing pages anyone.** Alert rules fire in the installation's Grafana, and no contact point - tells anyone. +- **Nothing pages the operator.** Alert rules fire in the installation's Grafana, and no contact + point tells anyone. A workspace's owner is emailed when it waits for them. - The collector accepts OpenTelemetry from whatever its security group lets in: the proxy and the runners. - AWS keeps its own records outside the installation: the VPC flow log and every machine's boot diff --git a/src/content/docs/concepts/images.md b/src/content/docs/concepts/images.md index a1f2b6d..e7ec073 100644 --- a/src/content/docs/concepts/images.md +++ b/src/content/docs/concepts/images.md @@ -2,8 +2,8 @@ title: Images description: What an image is in Spinbox, the default image, how an administrator publishes and retires images, and how to build your own starting point from a snapshot. reads: - - "spin:docs/storage/README.md@v20261108.01" - - "spin:cmd/cli/cmd/admin_storage.go@v20261108.01" + - "spin:docs/storage/README.md@v20261110.01" + - "spin:cmd/cli/cmd/admin_storage.go@v20261110.01" --- An image is a disk a workspace can start from. In Spinbox an image **is** a published snapshot diff --git a/src/content/docs/concepts/network.mdx b/src/content/docs/concepts/network.mdx index 3928373..e1bfb45 100644 --- a/src/content/docs/concepts/network.mdx +++ b/src/content/docs/concepts/network.mdx @@ -2,8 +2,8 @@ title: Network and egress description: How network policies control where a workspace connects, what is always blocked, how DNS works, and how to see what it reached. reads: - - "spin:docs/network/README.md@v20261108.01" - - "spin:configs/spin-example.yaml@v20261108.01" + - "spin:docs/network/README.md@v20261110.01" + - "spin:configs/spin-example.yaml@v20261110.01" --- import Figure from '../../../components/Figure.astro'; diff --git a/src/content/docs/concepts/runners.mdx b/src/content/docs/concepts/runners.mdx index ad641a1..38e7302 100644 --- a/src/content/docs/concepts/runners.mdx +++ b/src/content/docs/concepts/runners.mdx @@ -2,9 +2,9 @@ title: Runners and hosts description: What a runner is, how it joins, how workspaces are placed on it, how runners scale from zero, and what happens when one is lost. reads: - - "spin:docs/runners.md@v20261108.01" - - "spin:internal/controlplane/domain/autoscale/autoscale.go@v20261108.01" - - "spin:internal/controlplane/domain/hostclass/hostclass.go@v20261108.01" + - "spin:docs/runners.md@v20261110.01" + - "spin:internal/controlplane/domain/autoscale/autoscale.go@v20261110.01" + - "spin:internal/controlplane/domain/hostclass/hostclass.go@v20261110.01" - "spin-terraform-aws:modules/runners/main.tf@v20261027.02" --- @@ -97,6 +97,10 @@ had not yet uploaded. lost and waits for `--accept-data-loss`. - An administrator can let the control plane move workspaces on its own, after a runner has been silent for `rehome_after_seconds`, when no more than `rehome_max_unpublished_bytes` would - be lost. This is off by default. + be lost: [the workspace is moved, and its owner is told when it waits for them instead](). + This is off by default. -Nothing tells an owner that a workspace is stranded yet. +[The owner is told by email](): +when a workspace is held after its host was lost, when a stop could not be taken, when it was +stopped for not responding, and when it was moved off a lost host. Each event can be switched +off. diff --git a/src/content/docs/concepts/snapshots.md b/src/content/docs/concepts/snapshots.md index af66864..0d9a9a6 100644 --- a/src/content/docs/concepts/snapshots.md +++ b/src/content/docs/concepts/snapshots.md @@ -2,9 +2,9 @@ title: Snapshots and rollback description: Disk and memory snapshots, restoring and resetting a workspace, diffing two snapshots, cloning, and sharing a snapshot with others. reads: - - "spin:cmd/cli/cmd/snapshot.go@v20261108.01" - - "spin:cmd/cli/cmd/share.go@v20261108.01" - - "spin:docs/storage/README.md@v20261108.01" + - "spin:cmd/cli/cmd/snapshot.go@v20261110.01" + - "spin:cmd/cli/cmd/share.go@v20261110.01" + - "spin:docs/storage/README.md@v20261110.01" --- A snapshot is a point in a workspace's life that you can come back to. It is read-only and diff --git a/src/content/docs/concepts/volumes.mdx b/src/content/docs/concepts/volumes.mdx index db0daf4..574b87a 100644 --- a/src/content/docs/concepts/volumes.mdx +++ b/src/content/docs/concepts/volumes.mdx @@ -2,8 +2,8 @@ title: Disks and storage description: "How a workspace's disk is stored: layers in the bucket, a cache on the runner, encryption, when work is uploaded, and what deleting removes." reads: - - "spin:docs/storage/README.md@v20261108.01" - - "spin:internal/storage/qcow/manager.go@v20261108.01" + - "spin:docs/storage/README.md@v20261110.01" + - "spin:internal/storage/qcow/manager.go@v20261110.01" --- import Value from '../../../components/Value.astro'; diff --git a/src/content/docs/concepts/workspaces.md b/src/content/docs/concepts/workspaces.md index ffe97b5..c9aba83 100644 --- a/src/content/docs/concepts/workspaces.md +++ b/src/content/docs/concepts/workspaces.md @@ -2,9 +2,9 @@ title: Workspaces description: What a workspace is, its states, its resources and disk, what runs inside it, and how it is started, stopped, suspended and recovered. reads: - - "spin:cmd/cli/cmd/workspace.go@v20261108.01" - - "spin:docs/reconciliation.md@v20261108.01" - - "spin:docs/workspace-filesystem.md@v20261108.01" + - "spin:cmd/cli/cmd/workspace.go@v20261110.01" + - "spin:docs/reconciliation.md@v20261110.01" + - "spin:docs/workspace-filesystem.md@v20261110.01" --- A workspace is a virtual machine that belongs to a person, or to a team. It has its own @@ -40,8 +40,9 @@ spin workspace create --name retry --from-snapshot --wait A workspace is sized by a **preset**: its cores, its memory and its free disk. An administrator defines the presets (for example `small` and `large`) and marks one as the default. See -[Installation settings](/admin/configuration/). An installation with no default preset gives -1 core, 512 MB and 10 GB of free disk. +[Installation settings](/admin/configuration/). An installation whose configuration names no +presets is given one, `default`: 1 core and 512 MB, which grow to what its runner has, on 10 GB +of free disk. A preset is fixed, starting at its size and staying there, or it bursts: it starts at a floor and may grow up to its size, or up to whatever its runner has room for. A running workspace diff --git a/src/content/docs/overview/evaluate.md b/src/content/docs/overview/evaluate.md index e51fe71..678e47c 100644 --- a/src/content/docs/overview/evaluate.md +++ b/src/content/docs/overview/evaluate.md @@ -2,8 +2,8 @@ title: Evaluate Spinbox description: What Spinbox is, what it costs, how to try it on one Linux machine, what this release does not do, and how to install it - in that order. reads: - - "spin:hack/kvm-runner-check.sh@v20261108.01" - - "spin:taskfiles/e2e.yml@v20261108.01" + - "spin:hack/kvm-runner-check.sh@v20261110.01" + - "spin:taskfiles/e2e.yml@v20261110.01" - "spin-terraform-aws:README.md@v20261027.02" --- diff --git a/src/content/docs/overview/how-it-works.mdx b/src/content/docs/overview/how-it-works.mdx index 1fe5a78..dc69329 100644 --- a/src/content/docs/overview/how-it-works.mdx +++ b/src/content/docs/overview/how-it-works.mdx @@ -2,10 +2,10 @@ title: How it works description: The pieces of an installation (control plane, proxy, runners, database, bucket), how they connect, and how a workspace comes to run. reads: - - "spin:docs/reconciliation.md@v20261108.01" - - "spin:docs/storage/README.md@v20261108.01" - - "spin:internal/pgserver/server.go@v20261108.01" - - "spin:docs/releases.md@v20261108.01" + - "spin:docs/reconciliation.md@v20261110.01" + - "spin:docs/storage/README.md@v20261110.01" + - "spin:internal/pgserver/server.go@v20261110.01" + - "spin:docs/releases.md@v20261110.01" --- import Figure from '../../../components/Figure.astro'; diff --git a/src/content/docs/overview/index.md b/src/content/docs/overview/index.md index 4990a05..3f1a415 100644 --- a/src/content/docs/overview/index.md +++ b/src/content/docs/overview/index.md @@ -2,7 +2,7 @@ title: What is Spinbox description: What Spinbox is, who it is for, what it lets you do, and the projects an installation is made of. reads: - - "spin:internal/features/features.go@v20261108.01" + - "spin:internal/features/features.go@v20261110.01" --- Spinbox runs **workspaces**: virtual machines that a person or a program uses to run code. You diff --git a/src/content/docs/overview/limitations.md b/src/content/docs/overview/limitations.md index 7d6fad6..a20644c 100644 --- a/src/content/docs/overview/limitations.md +++ b/src/content/docs/overview/limitations.md @@ -55,8 +55,9 @@ The open items of the security model are listed in [Known gaps](/reference/secur ## Operations -- **Nothing pages anyone.** Metrics, logs and traces are kept inside the installation. Alert - rules fire in its Grafana, and no contact point tells anyone. +- **Nothing pages the operator.** Metrics, logs and traces are kept inside the installation. + Alert rules fire in its Grafana, and no contact point tells anyone. A workspace's owner is + emailed when it waits for them. - **An update is one way.** A release older than the one that last started the database refuses to start on it. Going back past a schema change is a point-in-time restore of the database. diff --git a/src/content/docs/overview/one-machine.md b/src/content/docs/overview/one-machine.md index 09bca32..80858a9 100644 --- a/src/content/docs/overview/one-machine.md +++ b/src/content/docs/overview/one-machine.md @@ -2,8 +2,8 @@ title: Try it on one machine description: The development stack on a single Linux host with KVM - from git clone to a running workspace and a command in it. Not an installation. reads: - - "spin:taskfiles/e2e.yml@v20261108.01" - - "spin:hack/kvm-runner-check.sh@v20261108.01" + - "spin:taskfiles/e2e.yml@v20261110.01" + - "spin:hack/kvm-runner-check.sh@v20261110.01" --- This is the **development stack**: the control plane, the proxy and the stores in containers, diff --git a/src/content/docs/security/data.md b/src/content/docs/security/data.md index f378e8d..88ec560 100644 --- a/src/content/docs/security/data.md +++ b/src/content/docs/security/data.md @@ -2,8 +2,8 @@ title: Data and encryption description: How disks, memory snapshots and the installation's secrets are encrypted, where each key lives, and what each kind of delete destroys. reads: - - "spin:docs/security/README.md@v20261108.01" - - "spin:docs/storage/README.md@v20261108.01" + - "spin:docs/security/README.md@v20261110.01" + - "spin:docs/storage/README.md@v20261110.01" - "spin-terraform-aws:modules/controlplane/attested_key.tf@v20261027.02" --- diff --git a/src/content/docs/security/identity.md b/src/content/docs/security/identity.md index 5eb61bf..414fb5a 100644 --- a/src/content/docs/security/identity.md +++ b/src/content/docs/security/identity.md @@ -2,8 +2,8 @@ title: Identity and access description: How users, API keys, runners and machines prove who they are, how every request is authorized, and what limits each machine's cloud role. reads: - - "spin:docs/security/README.md@v20261108.01" - - "spin:internal/controlplane/server/middleware/scopes.go@v20261108.01" + - "spin:docs/security/README.md@v20261110.01" + - "spin:internal/controlplane/server/middleware/scopes.go@v20261110.01" - "spin-terraform-aws:modules/controlplane/boundary.tf@v20261027.02" --- diff --git a/src/content/docs/security/supply-chain.md b/src/content/docs/security/supply-chain.md index 7d8728a..f1c7726 100644 --- a/src/content/docs/security/supply-chain.md +++ b/src/content/docs/security/supply-chain.md @@ -2,8 +2,8 @@ title: Supply chain description: How a release is built, signed and verified, how Spin OS makes every machine run exactly what the release signed, and what each image is made of. reads: - - "spin:docs/releases.md@v20261108.01" - - "spin:docs/machine.md@v20261108.01" + - "spin:docs/releases.md@v20261110.01" + - "spin:docs/machine.md@v20261110.01" --- ## Releases are signed diff --git a/src/content/docs/use/cli.md b/src/content/docs/use/cli.md index f388709..09e8365 100644 --- a/src/content/docs/use/cli.md +++ b/src/content/docs/use/cli.md @@ -2,10 +2,10 @@ title: The CLI description: Install the spin CLI, sign in, use profiles for several installations, and get JSON output for scripts. reads: - - "spin:cmd/cli/cmd/root.go@v20261108.01" - - "spin:cmd/cli/cmd/auth.go@v20261108.01" - - "spin:cmd/cli/cmd/errcode.go@v20261108.01" - - "spin:taskfiles/release.yml@v20261108.01" + - "spin:cmd/cli/cmd/root.go@v20261110.01" + - "spin:cmd/cli/cmd/auth.go@v20261110.01" + - "spin:cmd/cli/cmd/errcode.go@v20261110.01" + - "spin:taskfiles/release.yml@v20261110.01" --- `spin` is one binary. It does everything the dashboard does for a user, and the diff --git a/src/content/docs/use/editors.md b/src/content/docs/use/editors.md index 0fcf35e..d51b08f 100644 --- a/src/content/docs/use/editors.md +++ b/src/content/docs/use/editors.md @@ -2,10 +2,10 @@ title: Editors and SSH description: Connect to a workspace with spin ssh, plain ssh, scp and rsync, VS Code Remote-SSH, or the terminal in the dashboard. reads: - - "spin:cmd/cli/cmd/ssh.go@v20261108.01" - - "spin:cmd/cli/cmd/sshconfig.go@v20261108.01" - - "spin:cmd/cli/cmd/code.go@v20261108.01" - - "spin:cmd/cli/cmd/exec.go@v20261108.01" + - "spin:cmd/cli/cmd/ssh.go@v20261110.01" + - "spin:cmd/cli/cmd/sshconfig.go@v20261110.01" + - "spin:cmd/cli/cmd/code.go@v20261110.01" + - "spin:cmd/cli/cmd/exec.go@v20261110.01" --- Every way into a workspace goes through the installation's relay. You never need network access @@ -71,11 +71,11 @@ carries a server: an administrator publishes them from **Admin → Storage**. Before VS Code connects, `spin code` asks the workspace whether it has the server for your VS Code. If it has not, and the installation has published that version, the running workspace -is given it. If the installation has not, it is published first only when the installation -fetches servers from Microsoft on its own (`vscode_fetch` in the -[configuration file](/reference/configuration/file/), off by default), which takes minutes the -first time. Otherwise VS Code downloads its own server into the workspace, about 220 MB, and -`spin code` says so before connecting. +is given it. If the installation has not, it prepares that version first, once for the whole +installation, where an administrator has accepted the server's terms (**Admin → Extensions**). +Otherwise VS Code downloads its own server into the workspace, about 220 MB, and `spin code` +says so before connecting; where the workspace has no room for that download, it refuses and +says what would free it. The server is Microsoft's, and its [licence](https://code.visualstudio.com/license/server) allows it for an organization's own internal use only. An installation that offers workspaces

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 x$DZl$>;FfGADeqND%- diff --git a/src/assets/shots/workspaces.png b/src/assets/shots/workspaces.png index 4f6a3e8568171c59813f7044e7bea24723ff3515..fc7f800f25241f6452e2371acc86ae63061a4c39 100644 GIT binary patch literal 47555 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 literal 47585 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