Skip to content

feat(MARSOHS-1935): add persistent workspace commands to harness-runtime - #2018

Open
sanpj2292 wants to merge 4 commits into
mainfrom
prao/MARSOHS-1935/feat.workspaces
Open

sanpj2292 wants to merge 4 commits into
mainfrom
prao/MARSOHS-1935/feat.workspaces

Conversation

@sanpj2292

@sanpj2292 sanpj2292 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds persistent workspace support to doctl harness-runtime: a separate set of files with its own id that outlives sessions and is attached to one session at a time. Ticket: MARSOHS-1935.

The API is behind a per-team feature flag and is not generally available yet, so calls return 501 for teams that are not enrolled.

Depends on godo

This uses the new workspace methods and the WorkspaceID request field from digitalocean/godo#1138, which is not released yet. The godo version is not bumped here, so this branch does not compile against the vendored godo v1.217.0 and CI will fail until godo is released and go.mod and vendor/ are updated. Marked draft for that reason.

Changes

  • doctl harness-runtime workspace (alias workspaces):
    • create --size-gib <n> [--name <label>] [--idempotency-key <key>]
    • list [--page-size N] [--page-token T]
    • get <workspace-id>
    • delete <workspace-id> [--force], which is permanent and asks for confirmation unless --force is given.
  • Idempotent create: create sends one Idempotency-Key per command, a generated UUID unless --idempotency-key is given. A script that reruns the whole command should pass its own key. The size is required, and <= 0 is refused before any request; the upper bound is left to the server.
  • --workspace <id> on create and launch: attaches an existing workspace to the new session. A workspace is chosen per session and is never part of an agents.yaml manifest, so it is valid only with --from-config, where it is sent in the request body.
    • With a manifest (--spec, a positional file, or ./agents.yaml), --harness, --template, or launch of an existing session, doctl fails before any request. The message says to save the manifest as an Agent Config (config create --spec <file> --name <name>) and then create the session from it.
  • Output: the session card and session list show the workspace id when one is set, and -o json carries it. Workspaces have their own table (ID, Name, State, Size, Used, Attached Session, Last Saved, Created).
  • Errors: a 409 on create with --workspace shows the server's message plus a hint that the previous session may still be saving. A 501 now shows "Not available yet" without retry advice. This card is shared, so it applies to every agent command that gets a 501.
  • Help: remove says a workspace the session held is saved and kept, never deleted.
  • The do wrapper and its mock gain the four workspace methods. The mock was regenerated with the repo's own mockgen command.

Testing

  • With godo temporarily replaced by the local branch: gofmt, go vet and go build are clean, and the displayers, do, pkg, internal and root packages pass.
  • commands passes except TestRegistryLogout, which also fails on a clean checkout of main (it needs the native keychain).
  • New unit tests cover argument validation, key generation and use, the body field for --from-config, each refused source sending nothing (manifest, positional manifest, ./agents.yaml, --harness, --template, launch), delete confirmation and --force, the 409 hint, and the help wording.
  • Also run against a preview environment with a locally built binary: the workspace commands reach the API with the right requests (the Idempotency-Key header and paging parameters) and show the 501 card while the feature is off for the team. Nothing past that can be tested until the API is enabled.

Notes

  • config start-session does not take --workspace; only create and launch do.
  • pydo and godo changes for the same ticket are in separate PRs.

Add `doctl harness-runtime workspace` with create, list, get and delete.
Create sends one Idempotency-Key per command, or the one given with
--idempotency-key. Delete is permanent and asks for confirmation unless
--force is given.

Add --workspace <id> to create and launch. It names the workspace per session
and is never part of an agents.yaml manifest: with --from-config it is sent in
the request body, with a manifest as a query parameter. It is refused for
--harness sessions. Session output shows the workspace id when set, a 409 on
create with --workspace explains that the previous session may still be
saving, and a 501 reads as "Not available yet" instead of suggesting a retry.

Requires the godo change that adds the workspace methods. The godo version is
not bumped here.
…config

--workspace is now valid only with --from-config, where it is sent in the
request body. A manifest, a positional manifest, --harness, --template and
launch of a new session fail before any request with a message that points to
`config create` followed by `create --from-config`. The manifest create path no
longer carries a workspace, and the --dry-run notice about it is removed.

Update the help, flag usage, examples and the workspace card hint, and replace
the manifest routing tests with tests that each refused source sends nothing.
@sanpj2292
sanpj2292 marked this pull request as ready for review October 6, 2026 12:12
A 409 on create with --workspace no longer gets a "try again in a minute"
tip. The server now words each conflict for what the caller can do: still
being saved, attached to another session (remove it first) or not usable.
A retry is wrong for the last two, and the same create can also 409 for
reasons unrelated to the workspace, such as the session limit.

Use a UUID in the help examples and test fixtures, since a workspace id is
a 36-character UUID and anything else is a 404.
--state lists only workspaces in one state, for example AVAILABLE to see the
workspaces a new session can use. An empty page that still has a next page
token says so instead of reporting no workspaces.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant